mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-26 00:43:20 +00:00
471cbdd062
This can be used to separate lists for example with commas, when creating argument strings. This works with both structuredAttrs disabled and enabled.
417 lines
15 KiB
Nix
417 lines
15 KiB
Nix
# To run these tests:
|
|
# nix-build -A tests.stdenv
|
|
|
|
{ stdenv
|
|
, pkgs
|
|
, lib
|
|
, testers
|
|
}:
|
|
|
|
let
|
|
# early enough not to rebuild gcc but late enough to have patchelf
|
|
earlyPkgs = stdenv.__bootPackages.stdenv.__bootPackages;
|
|
earlierPkgs = stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages;
|
|
# use a early stdenv so when hacking on stdenv this test can be run quickly
|
|
bootStdenv = stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv;
|
|
pkgsStructured = import pkgs.path { config = { structuredAttrsByDefault = true; }; inherit (stdenv.hostPlatform) system; };
|
|
bootStdenvStructuredAttrsByDefault = pkgsStructured.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv;
|
|
|
|
runCommand = earlierPkgs.runCommand;
|
|
|
|
|
|
ccWrapperSubstitutionsTest = { name, stdenv', extraAttrs ? { } }:
|
|
|
|
stdenv'.cc.overrideAttrs (previousAttrs: ({
|
|
inherit name;
|
|
|
|
postFixup = previousAttrs.postFixup + ''
|
|
declare -p wrapperName
|
|
echo "env.wrapperName = $wrapperName"
|
|
[[ $wrapperName == "CC_WRAPPER" ]] || (echo "'\$wrapperName' was not 'CC_WRAPPER'" && false)
|
|
declare -p suffixSalt
|
|
echo "env.suffixSalt = $suffixSalt"
|
|
[[ $suffixSalt == "${stdenv'.cc.suffixSalt}" ]] || (echo "'\$suffxSalt' was not '${stdenv'.cc.suffixSalt}'" && false)
|
|
|
|
grep -q "@out@" $out/bin/cc || echo "@out@ in $out/bin/cc was substituted"
|
|
grep -q "@suffixSalt@" $out/bin/cc && (echo "$out/bin/cc contains unsubstituted variables" && false)
|
|
|
|
touch $out
|
|
'';
|
|
} // extraAttrs));
|
|
|
|
testEnvAttrset = { name, stdenv', extraAttrs ? { } }:
|
|
stdenv'.mkDerivation
|
|
({
|
|
inherit name;
|
|
env = {
|
|
string = "testing-string";
|
|
};
|
|
|
|
passAsFile = [ "buildCommand" ];
|
|
buildCommand = ''
|
|
declare -p string
|
|
echo "env.string = $string"
|
|
[[ $string == "testing-string" ]] || (echo "'\$string' was not 'testing-string'" && false)
|
|
[[ "$(declare -p string)" == 'declare -x string="testing-string"' ]] || (echo "'\$string' was not exported" && false)
|
|
touch $out
|
|
'';
|
|
} // extraAttrs);
|
|
|
|
testPrependAndAppendToVar = { name, stdenv', extraAttrs ? { } }:
|
|
stdenv'.mkDerivation
|
|
({
|
|
inherit name;
|
|
env = {
|
|
string = "testing-string";
|
|
};
|
|
|
|
passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ];
|
|
buildCommand = ''
|
|
declare -p string
|
|
appendToVar string hello
|
|
# test that quoted strings work
|
|
prependToVar string "world"
|
|
declare -p string
|
|
|
|
declare -A associativeArray=(["X"]="Y")
|
|
[[ $(appendToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "appendToVar did not throw appending to associativeArray" && false)
|
|
[[ $(prependToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not throw prepending associativeArray" && false)
|
|
|
|
[[ $string == "world testing-string hello" ]] || (echo "'\$string' was not 'world testing-string hello'" && false)
|
|
|
|
# test appending to a unset variable
|
|
appendToVar nonExistant created hello
|
|
declare -p nonExistant
|
|
if [[ -n $__structuredAttrs ]]; then
|
|
[[ "''${nonExistant[@]}" == "created hello" ]]
|
|
else
|
|
# there's a extra " " in front here and a extra " " in the end of prependToVar
|
|
# shouldn't matter because these functions will mostly be used for $*Flags and the Flag variable will in most cases already exist
|
|
[[ "$nonExistant" == " created hello" ]]
|
|
fi
|
|
|
|
eval "$extraTest"
|
|
|
|
touch $out
|
|
'';
|
|
} // extraAttrs);
|
|
|
|
testConcatTo = { name, stdenv', extraAttrs ? { } }:
|
|
stdenv'.mkDerivation
|
|
({
|
|
inherit name;
|
|
|
|
string = "a b";
|
|
list = ["c" "d"];
|
|
|
|
passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ];
|
|
buildCommand = ''
|
|
declare -A associativeArray=(["X"]="Y")
|
|
[[ $(concatTo nowhere associativeArray 2>&1) =~ "trying to use" ]] || (echo "concatTo did not throw concatenating associativeArray" && false)
|
|
|
|
declare -a flagsArray
|
|
concatTo flagsArray string list
|
|
declare -p flagsArray
|
|
[[ "''${flagsArray[0]}" == "a" ]] || (echo "'\$flagsArray[0]' was not 'a'" && false)
|
|
[[ "''${flagsArray[1]}" == "b" ]] || (echo "'\$flagsArray[1]' was not 'b'" && false)
|
|
[[ "''${flagsArray[2]}" == "c" ]] || (echo "'\$flagsArray[2]' was not 'c'" && false)
|
|
[[ "''${flagsArray[3]}" == "d" ]] || (echo "'\$flagsArray[3]' was not 'd'" && false)
|
|
|
|
# test concatenating to unset variable
|
|
concatTo nonExistant string list
|
|
declare -p nonExistant
|
|
[[ "''${nonExistant[0]}" == "a" ]] || (echo "'\$nonExistant[0]' was not 'a'" && false)
|
|
[[ "''${nonExistant[1]}" == "b" ]] || (echo "'\$nonExistant[1]' was not 'b'" && false)
|
|
[[ "''${nonExistant[2]}" == "c" ]] || (echo "'\$nonExistant[2]' was not 'c'" && false)
|
|
[[ "''${nonExistant[3]}" == "d" ]] || (echo "'\$nonExistant[3]' was not 'd'" && false)
|
|
|
|
eval "$extraTest"
|
|
|
|
touch $out
|
|
'';
|
|
} // extraAttrs);
|
|
|
|
testConcatStringsSep = { name, stdenv' }:
|
|
stdenv'.mkDerivation
|
|
{
|
|
inherit name;
|
|
|
|
passAsFile = [ "buildCommand" ];
|
|
buildCommand = ''
|
|
declare -A associativeArray=(["X"]="Y")
|
|
[[ $(concatStringsSep ";" associativeArray 2>&1) =~ "trying to use" ]] || (echo "concatStringsSep did not throw concatenating associativeArray" && false)
|
|
|
|
string="lorem ipsum dolor sit amet"
|
|
stringWithSep="$(concatStringsSep ";" string)"
|
|
[[ "$stringWithSep" == "lorem;ipsum;dolor;sit;amet" ]] || (echo "'\$stringWithSep' was not 'lorem;ipsum;dolor;sit;amet'" && false)
|
|
|
|
array=("lorem ipsum" "dolor" "sit amet")
|
|
arrayWithSep="$(concatStringsSep ";" array)"
|
|
[[ "$arrayWithSep" == "lorem ipsum;dolor;sit amet" ]] || (echo "'\$arrayWithSep' was not 'lorem ipsum;dolor;sit amet'" && false)
|
|
|
|
touch $out
|
|
'';
|
|
};
|
|
in
|
|
|
|
{
|
|
# Disable on Darwin due to assumptions with __bootPackages
|
|
__attrsFailEvaluation = stdenv.isDarwin;
|
|
|
|
# tests for hooks in `stdenv.defaultNativeBuildInputs`
|
|
hooks = lib.recurseIntoAttrs (import ./hooks.nix { stdenv = bootStdenv; pkgs = earlyPkgs; inherit lib; });
|
|
|
|
outputs-no-out = runCommand "outputs-no-out-assert" {
|
|
result = earlierPkgs.testers.testBuildFailure (bootStdenv.mkDerivation {
|
|
NIX_DEBUG = 1;
|
|
name = "outputs-no-out";
|
|
outputs = ["foo"];
|
|
buildPhase = ":";
|
|
installPhase = ''
|
|
touch $foo
|
|
'';
|
|
});
|
|
|
|
# Assumption: the first output* variable to be configured is
|
|
# _overrideFirst outputDev "dev" "out"
|
|
expectedMsg = "error: _assignFirst: could not find a non-empty variable whose name to assign to outputDev.\n The following variables were all unset or empty:\n dev out";
|
|
} ''
|
|
grep -F "$expectedMsg" $result/testBuildFailure.log >/dev/null
|
|
touch $out
|
|
'';
|
|
|
|
test-env-attrset = testEnvAttrset { name = "test-env-attrset"; stdenv' = bootStdenv; };
|
|
|
|
# Test compatibility with derivations using `env` as a regular variable.
|
|
test-env-derivation = bootStdenv.mkDerivation rec {
|
|
name = "test-env-derivation";
|
|
env = bootStdenv.mkDerivation {
|
|
name = "foo";
|
|
buildCommand = ''
|
|
mkdir "$out"
|
|
touch "$out/bar"
|
|
'';
|
|
};
|
|
|
|
passAsFile = [ "buildCommand" ];
|
|
buildCommand = ''
|
|
declare -p env
|
|
[[ $env == "${env}" ]]
|
|
touch "$out"
|
|
'';
|
|
};
|
|
|
|
# Check that mkDerivation rejects MD5 hashes
|
|
rejectedHashes = lib.recurseIntoAttrs {
|
|
md5 =
|
|
let drv = runCommand "md5 outputHash rejected" {
|
|
outputHash = "md5-fPt7dxVVP7ffY3MxkQdwVw==";
|
|
} "true";
|
|
in assert !(builtins.tryEval drv).success; {};
|
|
};
|
|
|
|
test-inputDerivation = let
|
|
inherit (stdenv.mkDerivation {
|
|
dep1 = derivation { name = "dep1"; builder = "/bin/sh"; args = [ "-c" ": > $out" ]; system = builtins.currentSystem; };
|
|
dep2 = derivation { name = "dep2"; builder = "/bin/sh"; args = [ "-c" ": > $out" ]; system = builtins.currentSystem; };
|
|
passAsFile = [ "dep2" ];
|
|
}) inputDerivation;
|
|
in
|
|
runCommand "test-inputDerivation" {
|
|
exportReferencesGraph = [ "graph" inputDerivation ];
|
|
} ''
|
|
grep ${inputDerivation.dep1} graph
|
|
grep ${inputDerivation.dep2} graph
|
|
touch $out
|
|
'';
|
|
|
|
test-inputDerivation-fixed-output = let
|
|
inherit (stdenv.mkDerivation {
|
|
dep1 = derivation { name = "dep1"; builder = "/bin/sh"; args = [ "-c" ": > $out" ]; system = builtins.currentSystem; };
|
|
dep2 = derivation { name = "dep2"; builder = "/bin/sh"; args = [ "-c" ": > $out" ]; system = builtins.currentSystem; };
|
|
name = "meow";
|
|
outputHash = "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=";
|
|
outputHashMode = "flat";
|
|
outputHashAlgo = "sha256";
|
|
buildCommand = ''
|
|
touch $out
|
|
'';
|
|
passAsFile = [ "dep2" ];
|
|
}) inputDerivation;
|
|
in
|
|
runCommand "test-inputDerivation" {
|
|
exportReferencesGraph = [ "graph" inputDerivation ];
|
|
} ''
|
|
grep ${inputDerivation.dep1} graph
|
|
grep ${inputDerivation.dep2} graph
|
|
touch $out
|
|
'';
|
|
|
|
test-prepend-append-to-var = testPrependAndAppendToVar {
|
|
name = "test-prepend-append-to-var";
|
|
stdenv' = bootStdenv;
|
|
};
|
|
|
|
test-concat-to = testConcatTo {
|
|
name = "test-concat-to";
|
|
stdenv' = bootStdenv;
|
|
};
|
|
|
|
test-concat-strings-sep = testConcatStringsSep {
|
|
name = "test-concat-strings-sep";
|
|
stdenv' = bootStdenv;
|
|
};
|
|
|
|
test-structured-env-attrset = testEnvAttrset {
|
|
name = "test-structured-env-attrset";
|
|
stdenv' = bootStdenv;
|
|
extraAttrs = { __structuredAttrs = true; };
|
|
};
|
|
|
|
test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest {
|
|
name = "test-cc-wrapper-substitutions";
|
|
stdenv' = bootStdenv;
|
|
};
|
|
|
|
structuredAttrsByDefault = lib.recurseIntoAttrs {
|
|
|
|
hooks = lib.recurseIntoAttrs (import ./hooks.nix { stdenv = bootStdenvStructuredAttrsByDefault; pkgs = earlyPkgs; inherit lib; });
|
|
|
|
test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest {
|
|
name = "test-cc-wrapper-substitutions-structuredAttrsByDefault";
|
|
stdenv' = bootStdenvStructuredAttrsByDefault;
|
|
};
|
|
|
|
test-structured-env-attrset = testEnvAttrset {
|
|
name = "test-structured-env-attrset-structuredAttrsByDefault";
|
|
stdenv' = bootStdenvStructuredAttrsByDefault;
|
|
};
|
|
|
|
test-prepend-append-to-var = testPrependAndAppendToVar {
|
|
name = "test-prepend-append-to-var-structuredAttrsByDefault";
|
|
stdenv' = bootStdenvStructuredAttrsByDefault;
|
|
extraAttrs = {
|
|
# will be a bash indexed array in attrs.sh
|
|
# declare -a list=('a' 'b' )
|
|
# and a json array in attrs.json
|
|
# "list":["a","b"]
|
|
list = [ "a" "b" ];
|
|
# will be a bash associative array(dictionary) in attrs.sh
|
|
# declare -A array=(['a']='1' ['b']='2' )
|
|
# and a json object in attrs.json
|
|
# {"array":{"a":"1","b":"2"}
|
|
array = { a = "1"; b = "2"; };
|
|
extraTest = ''
|
|
declare -p array
|
|
array+=(["c"]="3")
|
|
declare -p array
|
|
|
|
[[ "''${array[c]}" == "3" ]] || (echo "c element of '\$array' was not '3'" && false)
|
|
|
|
declare -p list
|
|
prependToVar list hello
|
|
# test that quoted strings work
|
|
appendToVar list "world"
|
|
declare -p list
|
|
|
|
[[ "''${list[0]}" == "hello" ]] || (echo "first element of '\$list' was not 'hello'" && false)
|
|
[[ "''${list[1]}" == "a" ]] || (echo "first element of '\$list' was not 'a'" && false)
|
|
[[ "''${list[-1]}" == "world" ]] || (echo "last element of '\$list' was not 'world'" && false)
|
|
'';
|
|
};
|
|
};
|
|
|
|
test-concat-to = testConcatTo {
|
|
name = "test-concat-to-structuredAttrsByDefault";
|
|
stdenv' = bootStdenvStructuredAttrsByDefault;
|
|
extraAttrs = {
|
|
# test that whitespace is kept in the bash array for structuredAttrs
|
|
listWithSpaces = [ "c c" "d d" ];
|
|
extraTest = ''
|
|
declare -a flagsWithSpaces
|
|
concatTo flagsWithSpaces string listWithSpaces
|
|
declare -p flagsWithSpaces
|
|
[[ "''${flagsWithSpaces[0]}" == "a" ]] || (echo "'\$flagsWithSpaces[0]' was not 'a'" && false)
|
|
[[ "''${flagsWithSpaces[1]}" == "b" ]] || (echo "'\$flagsWithSpaces[1]' was not 'b'" && false)
|
|
[[ "''${flagsWithSpaces[2]}" == "c c" ]] || (echo "'\$flagsWithSpaces[2]' was not 'c c'" && false)
|
|
[[ "''${flagsWithSpaces[3]}" == "d d" ]] || (echo "'\$flagsWithSpaces[3]' was not 'd d'" && false)
|
|
'';
|
|
};
|
|
};
|
|
|
|
test-concat-strings-sep = testConcatStringsSep {
|
|
name = "test-concat-strings-sep-structuredAttrsByDefault";
|
|
stdenv' = bootStdenvStructuredAttrsByDefault;
|
|
};
|
|
|
|
test-golden-example-structuredAttrs =
|
|
let
|
|
goldenSh = earlyPkgs.writeText "goldenSh" ''
|
|
declare -A EXAMPLE_ATTRS=(['foo']='bar' )
|
|
declare EXAMPLE_BOOL_FALSE=
|
|
declare EXAMPLE_BOOL_TRUE=1
|
|
declare EXAMPLE_INT=123
|
|
declare EXAMPLE_INT_NEG=-123
|
|
declare -a EXAMPLE_LIST=('foo' 'bar' )
|
|
declare EXAMPLE_STR='foo bar'
|
|
'';
|
|
goldenJson = earlyPkgs.writeText "goldenSh" ''
|
|
{
|
|
"EXAMPLE_ATTRS": {
|
|
"foo": "bar"
|
|
},
|
|
"EXAMPLE_BOOL_FALSE": false,
|
|
"EXAMPLE_BOOL_TRUE": true,
|
|
"EXAMPLE_INT": 123,
|
|
"EXAMPLE_INT_NEG": -123,
|
|
"EXAMPLE_LIST": [
|
|
"foo",
|
|
"bar"
|
|
],
|
|
"EXAMPLE_NESTED_ATTRS": {
|
|
"foo": {
|
|
"bar": "baz"
|
|
}
|
|
},
|
|
"EXAMPLE_NESTED_LIST": [
|
|
[
|
|
"foo",
|
|
"bar"
|
|
],
|
|
[
|
|
"baz"
|
|
]
|
|
],
|
|
"EXAMPLE_STR": "foo bar"
|
|
}
|
|
'';
|
|
in
|
|
bootStdenvStructuredAttrsByDefault.mkDerivation {
|
|
name = "test-golden-example-structuredAttrsByDefault";
|
|
nativeBuildInputs = [ earlyPkgs.jq ];
|
|
|
|
EXAMPLE_BOOL_TRUE = true;
|
|
EXAMPLE_BOOL_FALSE = false;
|
|
EXAMPLE_INT = 123;
|
|
EXAMPLE_INT_NEG = -123;
|
|
EXAMPLE_STR = "foo bar";
|
|
EXAMPLE_LIST = [ "foo" "bar" ];
|
|
EXAMPLE_NESTED_LIST = [ [ "foo" "bar" ] [ "baz" ] ];
|
|
EXAMPLE_ATTRS = { foo = "bar"; };
|
|
EXAMPLE_NESTED_ATTRS = { foo.bar = "baz"; };
|
|
|
|
inherit goldenSh;
|
|
inherit goldenJson;
|
|
|
|
buildCommand = ''
|
|
mkdir -p $out
|
|
cat $NIX_ATTRS_SH_FILE | grep "EXAMPLE" | grep -v -E 'installPhase|jq' > $out/sh
|
|
jq 'with_entries(select(.key|match("EXAMPLE")))' $NIX_ATTRS_JSON_FILE > $out/json
|
|
diff $out/sh $goldenSh
|
|
diff $out/json $goldenJson
|
|
'';
|
|
};
|
|
|
|
};
|
|
}
|