Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598# 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 *"; 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)
empty_array=() empty_string=""
declare -a flagsArray concatTo flagsArray string list notset=e=f empty_array=g empty_string=h declare -p flagsArray [[ "''${flagsArray[0]}" == "a" ]] || (echo "'\$flagsArray[0]' was not 'a'" && false) [[ "''${flagsArray[1]}" == "*" ]] || (echo "'\$flagsArray[1]' was not '*'" && false) [[ "''${flagsArray[2]}" == "c" ]] || (echo "'\$flagsArray[2]' was not 'c'" && false) [[ "''${flagsArray[3]}" == "d" ]] || (echo "'\$flagsArray[3]' was not 'd'" && false) [[ "''${flagsArray[4]}" == "e=f" ]] || (echo "'\$flagsArray[4]' was not 'e=f'" && false) [[ "''${flagsArray[5]}" == "g" ]] || (echo "'\$flagsArray[5]' was not 'g'" && false) [[ "''${flagsArray[6]}" == "h" ]] || (echo "'\$flagsArray[6]' was not 'h'" && false)
# test concatenating to unset variable concatTo nonExistant string list notset=e=f empty_array=g empty_string=h declare -p nonExistant [[ "''${nonExistant[0]}" == "a" ]] || (echo "'\$nonExistant[0]' was not 'a'" && false) [[ "''${nonExistant[1]}" == "*" ]] || (echo "'\$nonExistant[1]' was not '*'" && false) [[ "''${nonExistant[2]}" == "c" ]] || (echo "'\$nonExistant[2]' was not 'c'" && false) [[ "''${nonExistant[3]}" == "d" ]] || (echo "'\$nonExistant[3]' was not 'd'" && false) [[ "''${nonExistant[4]}" == "e=f" ]] || (echo "'\$nonExistant[4]' was not 'e=f'" && false) [[ "''${nonExistant[5]}" == "g" ]] || (echo "'\$nonExistant[5]' was not 'g'" && false) [[ "''${nonExistant[6]}" == "h" ]] || (echo "'\$nonExistant[6]' was not 'h'" && false)
eval "$extraTest"
touch $out ''; } // extraAttrs );
testConcatStringsSep = { name, stdenv' }: stdenv'.mkDerivation { inherit name;
# NOTE: Testing with "&" as separator is intentional, because unquoted # "&" has a special meaning in the "${var//pattern/replacement}" syntax. # Cf. https://github.com/NixOS/nixpkgs/pull/318614#discussion_r1706191919 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)
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)
array=("lorem ipsum" "dolor" "sit amet") arrayWithSep="$(concatStringsSep " and " array)" [[ "$arrayWithSep" == "lorem ipsum and dolor and sit amet" ]] || (echo "'\$arrayWithSep' was not 'lorem ipsum and dolor and sit amet'" && false)
touch $out ''; };in
{ # 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; };
# 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; };
ensure-no-execve-in-setup-sh = derivation { name = "ensure-no-execve-in-setup-sh"; system = stdenv.system; builder = "${stdenv.bootstrapTools}/bin/bash"; PATH = "${pkgs.strace}/bin:${stdenv.bootstrapTools}/bin"; initialPath = [ stdenv.bootstrapTools pkgs.strace ]; args = [ "-c" '' countCall() { echo "$stats" | tr -s ' ' | grep "$1" | cut -d ' ' -f5 }
# prevent setup.sh from running `nproc` when cores=0 # (this would mess up the syscall stats) export NIX_BUILD_CORES=1
echo "Analyzing setup.sh with strace" stats=$(strace -fc bash -c ". ${../../stdenv/generic/setup.sh}" 2>&1) echo "$stats" | head -n15
# fail if execve calls is > 1 stats=$(strace -fc bash -c ". ${../../stdenv/generic/setup.sh}" 2>&1) execveCalls=$(countCall execve) if [ "$execveCalls" -gt 1 ]; then echo "execve calls: $execveCalls; expected: 1" echo "ERROR: setup.sh should not launch additional processes when being sourced" exit 1 else echo "setup.sh doesn't launch extra processes when sourcing, as expected" fi
touch $out '' ]; } // { meta = { }; };
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]}" == "*" ]] || (echo "'\$flagsWithSpaces[1]' was not '*'" && 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 ''; }; };}