diff options
author | Ben Burdette <bburdette@protonmail.com> | 2022-04-07 13:42:01 -0600 |
---|---|---|
committer | Ben Burdette <bburdette@protonmail.com> | 2022-04-07 13:42:01 -0600 |
commit | 1a93ac8133381eb692416c4e46b1706faa5cd89f (patch) | |
tree | 9a559f977ad6213c055099f6f2ab6be96f0c551b /tests | |
parent | d2ec9b4e15718e42720787140d7825dcbfd73249 (diff) | |
parent | 8b1e328d5d0ae7d3a4a8f6012ec065b59674ed4a (diff) |
Merge remote-tracking branch 'upstream/master' into upstream-merge
Diffstat (limited to 'tests')
41 files changed, 819 insertions, 132 deletions
diff --git a/tests/bash-profile.sh b/tests/bash-profile.sh new file mode 100644 index 000000000..e2e0d1090 --- /dev/null +++ b/tests/bash-profile.sh @@ -0,0 +1,9 @@ +source common.sh + +sed -e "s|@localstatedir@|$TEST_ROOT/profile-var|g" -e "s|@coreutils@|$coreutils|g" < ../scripts/nix-profile.sh.in > $TEST_ROOT/nix-profile.sh + +user=$(whoami) +rm -rf $TEST_HOME $TEST_ROOT/profile-var +mkdir -p $TEST_HOME +USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set" +USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency diff --git a/tests/binary-cache.sh b/tests/binary-cache.sh index 2368884f7..0361ac6a8 100644 --- a/tests/binary-cache.sh +++ b/tests/binary-cache.sh @@ -1,6 +1,6 @@ source common.sh -needLocalStore "“--no-require-sigs” can’t be used with the daemon" +needLocalStore "'--no-require-sigs' can’t be used with the daemon" # We can produce drvs directly into the binary cache clearStore diff --git a/tests/build-dry.sh b/tests/build-dry.sh index e72533e70..f0f38e9a0 100644 --- a/tests/build-dry.sh +++ b/tests/build-dry.sh @@ -50,3 +50,22 @@ nix build -f dependencies.nix -o $RESULT --dry-run nix build -f dependencies.nix -o $RESULT [[ -h $RESULT ]] + +################################################### +# Check the JSON output +clearStore +clearCache + +RES=$(nix build -f dependencies.nix --dry-run --json) + +if [[ -z "$NIX_TESTS_CA_BY_DEFAULT" ]]; then + echo "$RES" | jq '.[0] | [ + (.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")), + (.outputs.out | test("'$NIX_STORE_DIR'")) + ] | all' +else + echo "$RES" | jq '.[0] | [ + (.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")), + .outputs.out == null + ] | all' +fi diff --git a/tests/build-hook-ca-fixed.nix b/tests/build-hook-ca-fixed.nix index ec7171ac9..4cb9e85d1 100644 --- a/tests/build-hook-ca-fixed.nix +++ b/tests/build-hook-ca-fixed.nix @@ -11,13 +11,13 @@ let args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" "if [ -e .attrs.sh ]; then source .attrs.sh; fi; eval \"$buildCommand\"")]; outputHashMode = "recursive"; outputHashAlgo = "sha256"; - } // removeAttrs args ["builder" "meta"]) - // { meta = args.meta or {}; }; + } // removeAttrs args ["builder" "meta" "passthru"]) + // { meta = args.meta or {}; passthru = args.passthru or {}; }; input1 = mkDerivation { shell = busybox; name = "build-remote-input-1"; - buildCommand = "echo FOO > $out"; + buildCommand = "echo hi-input1; echo FOO > $out"; requiredSystemFeatures = ["foo"]; outputHash = "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="; }; @@ -25,7 +25,7 @@ let input2 = mkDerivation { shell = busybox; name = "build-remote-input-2"; - buildCommand = "echo BAR > $out"; + buildCommand = "echo hi; echo BAR > $out"; requiredSystemFeatures = ["bar"]; outputHash = "sha256-XArauVH91AVwP9hBBQNlkX9ccuPpSYx9o0zeIHb6e+Q="; }; @@ -34,6 +34,7 @@ let shell = busybox; name = "build-remote-input-3"; buildCommand = '' + echo hi-input3 read x < ${input2} echo $x BAZ > $out ''; @@ -46,6 +47,7 @@ in mkDerivation { shell = busybox; name = "build-remote"; + passthru = { inherit input1 input2 input3; }; buildCommand = '' read x < ${input1} diff --git a/tests/build-hook.nix b/tests/build-hook.nix index eb16676f0..643334caa 100644 --- a/tests/build-hook.nix +++ b/tests/build-hook.nix @@ -9,20 +9,20 @@ let inherit system; builder = busybox; args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" "if [ -e .attrs.sh ]; then source .attrs.sh; fi; eval \"$buildCommand\"")]; - } // removeAttrs args ["builder" "meta"]) - // { meta = args.meta or {}; }; + } // removeAttrs args ["builder" "meta" "passthru"]) + // { meta = args.meta or {}; passthru = args.passthru or {}; }; input1 = mkDerivation { shell = busybox; name = "build-remote-input-1"; - buildCommand = "echo FOO > $out"; + buildCommand = "echo hi-input1; echo FOO > $out"; requiredSystemFeatures = ["foo"]; }; input2 = mkDerivation { shell = busybox; name = "build-remote-input-2"; - buildCommand = "echo BAR > $out"; + buildCommand = "echo hi; echo BAR > $out"; requiredSystemFeatures = ["bar"]; }; @@ -30,6 +30,7 @@ let shell = busybox; name = "build-remote-input-3"; buildCommand = '' + echo hi-input3 read x < ${input2} echo $x BAZ > $out ''; @@ -41,6 +42,7 @@ in mkDerivation { shell = busybox; name = "build-remote"; + passthru = { inherit input1 input2 input3; }; buildCommand = '' read x < ${input1} diff --git a/tests/build-remote-content-addressed-floating.sh b/tests/build-remote-content-addressed-floating.sh index 13ef47d2d..1f474dde0 100644 --- a/tests/build-remote-content-addressed-floating.sh +++ b/tests/build-remote-content-addressed-floating.sh @@ -2,7 +2,7 @@ source common.sh file=build-hook-ca-floating.nix -sed -i 's/experimental-features .*/& ca-derivations/' "$NIX_CONF_DIR"/nix.conf +enableFeatures "ca-derivations ca-references" CONTENT_ADDRESSED=true diff --git a/tests/build-remote.sh b/tests/build-remote.sh index 806c6d261..094366872 100644 --- a/tests/build-remote.sh +++ b/tests/build-remote.sh @@ -54,6 +54,14 @@ nix path-info --store $TEST_ROOT/machine3 --all \ | grep -v builder-build-remote-input-2.sh \ | grep builder-build-remote-input-3.sh + +# Temporarily disabled because of https://github.com/NixOS/nix/issues/6209 +if [[ -z "$CONTENT_ADDRESSED" ]]; then + for i in input1 input3; do + nix log --store $TEST_ROOT/machine0 --file "$file" --arg busybox $busybox passthru."$i" | grep hi-$i + done +fi + # Behavior of keep-failed out="$(nix-build 2>&1 failing.nix \ --builders "$(join_by '; ' "${builders[@]}")" \ diff --git a/tests/build.sh b/tests/build.sh index c77f620f7..13a0f42be 100644 --- a/tests/build.sh +++ b/tests/build.sh @@ -1,15 +1,27 @@ source common.sh -expectedJSONRegex='\[\{"drvPath":".*multiple-outputs-a.drv","outputs":\{"first":".*multiple-outputs-a-first","second":".*multiple-outputs-a-second"}},\{"drvPath":".*multiple-outputs-b.drv","outputs":\{"out":".*multiple-outputs-b"}}]' +clearStore + +# Make sure that 'nix build' only returns the outputs we asked for. +nix build -f multiple-outputs.nix --json a --no-link | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | keys | length == 1) and + (.outputs.first | match(".*multiple-outputs-a-first"))) +' + nix build -f multiple-outputs.nix --json a.all b.all --no-link | jq --exit-status ' (.[0] | (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | keys | length == 2) and (.outputs.first | match(".*multiple-outputs-a-first")) and (.outputs.second | match(".*multiple-outputs-a-second"))) and (.[1] | (.drvPath | match(".*multiple-outputs-b.drv")) and + (.outputs | keys | length == 1) and (.outputs.out | match(".*multiple-outputs-b"))) ' + testNormalization () { clearStore outPath=$(nix-build ./simple.nix --no-out-link) diff --git a/tests/ca/build-dry.sh b/tests/ca/build-dry.sh new file mode 100644 index 000000000..9a72075ec --- /dev/null +++ b/tests/ca/build-dry.sh @@ -0,0 +1,6 @@ +source common.sh + +export NIX_TESTS_CA_BY_DEFAULT=1 + +cd .. && source build-dry.sh + diff --git a/tests/ca/build.sh b/tests/ca/build.sh index c8877f87f..92f8b429a 100644 --- a/tests/ca/build.sh +++ b/tests/ca/build.sh @@ -37,7 +37,7 @@ testCutoffFor () { } testCutoff () { - # Don't directly build depenentCA, that way we'll make sure we dodn't rely on + # Don't directly build dependentCA, that way we'll make sure we don't rely on # dependent derivations always being already built. #testDerivation dependentCA testCutoffFor transitivelyDependentCA diff --git a/tests/ca/common.sh b/tests/ca/common.sh index c5aa34334..b9d415863 100644 --- a/tests/ca/common.sh +++ b/tests/ca/common.sh @@ -1,5 +1,5 @@ source ../common.sh -sed -i 's/experimental-features .*/& ca-derivations ca-references/' "$NIX_CONF_DIR"/nix.conf +enableFeatures "ca-derivations ca-references" restartDaemon diff --git a/tests/ca/content-addressed.nix b/tests/ca/content-addressed.nix index d328fc92c..1be3eeb6e 100644 --- a/tests/ca/content-addressed.nix +++ b/tests/ca/content-addressed.nix @@ -64,8 +64,7 @@ rec { dependentFixedOutput = mkDerivation { name = "dependent-fixed-output"; outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - outputHash = "sha256-QvtAMbUl/uvi+LCObmqOhvNOapHdA2raiI4xG5zI5pA="; + outputHash = "sha512-7aJcmSuEuYP5tGKcmGY8bRr/lrCjJlOxP2mIUjO/vMQeg6gx/65IbzRWES8EKiPDOs9z+wF30lEfcwxM/cT4pw=="; buildCommand = '' cat ${dependentCA}/dep echo foo > $out diff --git a/tests/ca/duplicate-realisation-in-closure.sh b/tests/ca/duplicate-realisation-in-closure.sh index 74c5d25fd..da9cd8fb4 100644 --- a/tests/ca/duplicate-realisation-in-closure.sh +++ b/tests/ca/duplicate-realisation-in-closure.sh @@ -2,8 +2,6 @@ source ./common.sh requireDaemonNewerThan "2.4pre20210625" -sed -i 's/experimental-features .*/& ca-derivations ca-references/' "$NIX_CONF_DIR"/nix.conf - export REMOTE_STORE_DIR="$TEST_ROOT/remote_store" export REMOTE_STORE="file://$REMOTE_STORE_DIR" diff --git a/tests/ca/nix-copy.sh b/tests/ca/nix-copy.sh index 2e0dea2d2..7a8307a4e 100755 --- a/tests/ca/nix-copy.sh +++ b/tests/ca/nix-copy.sh @@ -2,9 +2,6 @@ source common.sh -# Globally enable the ca derivations experimental flag -sed -i 's/experimental-features = .*/& ca-derivations ca-references/' "$NIX_CONF_DIR/nix.conf" - export REMOTE_STORE_DIR="$TEST_ROOT/remote_store" export REMOTE_STORE="file://$REMOTE_STORE_DIR" diff --git a/tests/ca/nix-run.sh b/tests/ca/nix-run.sh index 81402af10..5f46518e8 100755 --- a/tests/ca/nix-run.sh +++ b/tests/ca/nix-run.sh @@ -2,8 +2,6 @@ source common.sh -sed -i 's/experimental-features .*/& ca-derivations ca-references nix-command flakes/' "$NIX_CONF_DIR"/nix.conf - FLAKE_PATH=path:$PWD nix run --no-write-lock-file $FLAKE_PATH#runnable diff --git a/tests/ca/nix-shell.sh b/tests/ca/nix-shell.sh index 7f1a3a73e..1c5a6639f 100755 --- a/tests/ca/nix-shell.sh +++ b/tests/ca/nix-shell.sh @@ -2,8 +2,6 @@ source common.sh -sed -i 's/experimental-features .*/& ca-derivations ca-references nix-command flakes/' "$NIX_CONF_DIR"/nix.conf - CONTENT_ADDRESSED=true cd .. source ./nix-shell.sh diff --git a/tests/ca/post-hook.sh b/tests/ca/post-hook.sh index 1c9d4f700..705bde9d4 100755 --- a/tests/ca/post-hook.sh +++ b/tests/ca/post-hook.sh @@ -4,8 +4,6 @@ source common.sh requireDaemonNewerThan "2.4pre20210626" -sed -i 's/experimental-features .*/& ca-derivations ca-references nix-command flakes/' "$NIX_CONF_DIR"/nix.conf - export NIX_TESTS_CA_BY_DEFAULT=1 cd .. source ./post-hook.sh diff --git a/tests/ca/recursive.sh b/tests/ca/recursive.sh index 648bf0a91..0354d23b4 100755 --- a/tests/ca/recursive.sh +++ b/tests/ca/recursive.sh @@ -4,8 +4,6 @@ source common.sh requireDaemonNewerThan "2.4pre20210623" -sed -i 's/experimental-features .*/& ca-derivations ca-references nix-command flakes/' "$NIX_CONF_DIR"/nix.conf - export NIX_TESTS_CA_BY_DEFAULT=1 cd .. source ./recursive.sh diff --git a/tests/ca/signatures.sh b/tests/ca/signatures.sh index 0c7d974ea..eb18a4130 100644 --- a/tests/ca/signatures.sh +++ b/tests/ca/signatures.sh @@ -1,8 +1,5 @@ source common.sh -# Globally enable the ca derivations experimental flag -sed -i 's/experimental-features = .*/& ca-derivations ca-references/' "$NIX_CONF_DIR/nix.conf" - clearStore clearCache diff --git a/tests/common.sh.in b/tests/common.sh.in index 61abab1d7..8ce28d318 100644 --- a/tests/common.sh.in +++ b/tests/common.sh.in @@ -87,26 +87,31 @@ startDaemon() { if [[ "$NIX_REMOTE" == daemon ]]; then return fi - # Start the daemon, wait for the socket to appear. !!! - # ‘nix-daemon’ should have an option to fork into the background. + # Start the daemon, wait for the socket to appear. rm -f $NIX_DAEMON_SOCKET_PATH - PATH=$DAEMON_PATH nix daemon & - for ((i = 0; i < 30; i++)); do - if [[ -S $NIX_DAEMON_SOCKET_PATH ]]; then break; fi - sleep 1 - done + PATH=$DAEMON_PATH nix-daemon& pidDaemon=$! + for ((i = 0; i < 300; i++)); do + if [[ -S $NIX_DAEMON_SOCKET_PATH ]]; then + DAEMON_STARTED=1 + break; + fi + sleep 0.1 + done + if [[ -z ${DAEMON_STARTED+x} ]]; then + fail "Didn’t manage to start the daemon" + fi trap "killDaemon" EXIT export NIX_REMOTE=daemon } killDaemon() { kill $pidDaemon - for i in {0.10}; do - kill -0 $pidDaemon || break - sleep 1 + for i in {0..100}; do + kill -0 $pidDaemon 2> /dev/null || break + sleep 0.1 done - kill -9 $pidDaemon || true + kill -9 $pidDaemon 2> /dev/null || true wait $pidDaemon || true trap "" EXIT } @@ -167,10 +172,15 @@ needLocalStore() { } # Just to make it easy to find which tests should be fixed -buggyNeedLocalStore () { +buggyNeedLocalStore() { needLocalStore } +enableFeatures() { + local features="$1" + sed -i 's/experimental-features .*/& '"$features"'/' "$NIX_CONF_DIR"/nix.conf +} + set -x if [[ -n "${NIX_DAEMON_PACKAGE:-}" ]]; then diff --git a/tests/eval.nix b/tests/eval.nix new file mode 100644 index 000000000..befbd17a9 --- /dev/null +++ b/tests/eval.nix @@ -0,0 +1,5 @@ +{ + int = 123; + str = "foo"; + attr.foo = "bar"; +} diff --git a/tests/eval.sh b/tests/eval.sh new file mode 100644 index 000000000..2e5ceb969 --- /dev/null +++ b/tests/eval.sh @@ -0,0 +1,29 @@ +source common.sh + +clearStore + +testStdinHeredoc=$(nix eval -f - <<EOF +{ + bar = 3 + 1; + foo = 2 + 2; +} +EOF +) +[[ $testStdinHeredoc == '{ bar = 4; foo = 4; }' ]] + +nix eval --expr 'assert 1 + 2 == 3; true' + +[[ $(nix eval int -f "./eval.nix") == 123 ]] +[[ $(nix eval str -f "./eval.nix") == '"foo"' ]] +[[ $(nix eval str --raw -f "./eval.nix") == 'foo' ]] +[[ $(nix eval attr -f "./eval.nix") == '{ foo = "bar"; }' ]] +[[ $(nix eval attr --json -f "./eval.nix") == '{"foo":"bar"}' ]] +[[ $(nix eval int -f - < "./eval.nix") == 123 ]] + + +nix-instantiate --eval -E 'assert 1 + 2 == 3; true' +[[ $(nix-instantiate -A int --eval "./eval.nix") == 123 ]] +[[ $(nix-instantiate -A str --eval "./eval.nix") == '"foo"' ]] +[[ $(nix-instantiate -A attr --eval "./eval.nix") == '{ foo = "bar"; }' ]] +[[ $(nix-instantiate -A attr --eval --json "./eval.nix") == '{"foo":"bar"}' ]] +[[ $(nix-instantiate -A int --eval - < "./eval.nix") == 123 ]] diff --git a/tests/fetchClosure.sh b/tests/fetchClosure.sh new file mode 100644 index 000000000..96e4bb741 --- /dev/null +++ b/tests/fetchClosure.sh @@ -0,0 +1,70 @@ +source common.sh + +enableFeatures "fetch-closure" +needLocalStore "'--no-require-sigs' can’t be used with the daemon" + +clearStore +clearCacheCache + +# Initialize binary cache. +nonCaPath=$(nix build --json --file ./dependencies.nix | jq -r .[].outputs.out) +caPath=$(nix store make-content-addressed --json $nonCaPath | jq -r '.rewrites | map(.) | .[]') +nix copy --to file://$cacheDir $nonCaPath + +# Test basic fetchClosure rewriting from non-CA to CA. +clearStore + +[ ! -e $nonCaPath ] +[ ! -e $caPath ] + +[[ $(nix eval -v --raw --expr " + builtins.fetchClosure { + fromStore = \"file://$cacheDir\"; + fromPath = $nonCaPath; + toPath = $caPath; + } +") = $caPath ]] + +[ ! -e $nonCaPath ] +[ -e $caPath ] + +# In impure mode, we can use non-CA paths. +[[ $(nix eval --raw --no-require-sigs --impure --expr " + builtins.fetchClosure { + fromStore = \"file://$cacheDir\"; + fromPath = $nonCaPath; + } +") = $nonCaPath ]] + +[ -e $nonCaPath ] + +# 'toPath' set to empty string should fail but print the expected path. +nix eval -v --json --expr " + builtins.fetchClosure { + fromStore = \"file://$cacheDir\"; + fromPath = $nonCaPath; + toPath = \"\"; + } +" 2>&1 | grep "error: rewriting.*$nonCaPath.*yielded.*$caPath" + +# If fromPath is CA, then toPath isn't needed. +nix copy --to file://$cacheDir $caPath + +[[ $(nix eval -v --raw --expr " + builtins.fetchClosure { + fromStore = \"file://$cacheDir\"; + fromPath = $caPath; + } +") = $caPath ]] + +# Check that URL query parameters aren't allowed. +clearStore +narCache=$TEST_ROOT/nar-cache +rm -rf $narCache +(! nix eval -v --raw --expr " + builtins.fetchClosure { + fromStore = \"file://$cacheDir?local-nar-cache=$narCache\"; + fromPath = $caPath; + } +") +(! [ -e $narCache ]) diff --git a/tests/fetchGit.sh b/tests/fetchGit.sh index 89294d8d2..9179e2071 100644 --- a/tests/fetchGit.sh +++ b/tests/fetchGit.sh @@ -7,11 +7,13 @@ fi clearStore -repo=$TEST_ROOT/git +# Intentionally not in a canonical form +# See https://github.com/NixOS/nix/issues/6195 +repo=$TEST_ROOT/./git export _NIX_FORCE_HTTP=1 -rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix $TEST_ROOT/worktree $TEST_ROOT/shallow +rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix $TEST_ROOT/worktree $TEST_ROOT/shallow $TEST_ROOT/minimal git init $repo git -C $repo config user.email "foobar@example.com" @@ -147,8 +149,13 @@ path3=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath") # (check dirty-tree handling was used) [[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).rev") = 0000000000000000000000000000000000000000 ]] [[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).shortRev") = 0000000 ]] +# Making a dirty tree clean again and fetching it should +# record correct revision information. See: #4140 +echo world > $repo/hello +[[ $(nix eval --impure --raw --expr "(builtins.fetchGit $repo).rev") = $rev2 ]] # Committing shouldn't change store path, or switch to using 'master' +echo dev > $repo/hello git -C $repo commit -m 'Bla5' -a path4=$(nix eval --impure --raw --expr "(builtins.fetchGit $repo).outPath") [[ $(cat $path4/hello) = dev ]] @@ -170,6 +177,14 @@ NIX=$(command -v nix) path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outPath") [[ $path3 = $path5 ]] +# Fetching from a repo with only a specific revision and no branches should +# not fall back to copying files and record correct revision information. See: #5302 +mkdir $TEST_ROOT/minimal +git -C $TEST_ROOT/minimal init +git -C $TEST_ROOT/minimal fetch $repo $rev2 +git -C $TEST_ROOT/minimal checkout $rev2 +[[ $(nix eval --impure --raw --expr "(builtins.fetchGit { url = $TEST_ROOT/minimal; }).rev") = $rev2 ]] + # Fetching a shallow repo shouldn't work by default, because we can't # return a revCount. git clone --depth 1 file://$repo $TEST_ROOT/shallow @@ -193,3 +208,11 @@ rev4_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$ # The name argument should be handled path9=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; name = \"foo\"; }).outPath") [[ $path9 =~ -foo$ ]] + +# should fail if there is no repo +rm -rf $repo/.git +(! nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") + +# should succeed for a repo without commits +git init $repo +path10=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") diff --git a/tests/fetchPath.sh b/tests/fetchPath.sh new file mode 100644 index 000000000..29be38ce2 --- /dev/null +++ b/tests/fetchPath.sh @@ -0,0 +1,6 @@ +source common.sh + +touch $TEST_ROOT/foo -t 202211111111 +# We only check whether 2022-11-1* **:**:** is the last modified date since +# `lastModified` is transformed into UTC in `builtins.fetchTarball`. +[[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]] diff --git a/tests/fetchurl.sh b/tests/fetchurl.sh index 3d1685f43..b41d8c4b7 100644 --- a/tests/fetchurl.sh +++ b/tests/fetchurl.sh @@ -9,6 +9,10 @@ outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file: cmp $outPath fetchurl.sh +# Do not re-fetch paths already present. +outPath2=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///does-not-exist/must-remain-unused/fetchurl.sh --argstr sha256 $hash --no-out-link) +test "$outPath" == "$outPath2" + # Now using a base-64 hash. clearStore diff --git a/tests/flake-bundler.sh b/tests/flake-bundler.sh index 699920f60..9496b8f92 100644 --- a/tests/flake-bundler.sh +++ b/tests/flake-bundler.sh @@ -10,26 +10,28 @@ cd $TEST_HOME cat <<EOF > flake.nix { outputs = {self}: { - bundlers.$system.simple = drv: + bundlers.$system = rec { + simple = drv: if drv?type && drv.type == "derivation" then drv - else self.defaultPackage.$system; - defaultBundler.$system = self.bundlers.$system.simple; - defaultPackage.$system = import ./simple.nix; - defaultApp.$system = { - type = "app"; - program = "\${import ./simple.nix}/hello"; - }; + else self.packages.$system.default; + default = simple; + }; + packages.$system.default = import ./simple.nix; + apps.$system.default = { + type = "app"; + program = "\${import ./simple.nix}/hello"; + }; }; } EOF nix build .# nix bundle --bundler .# .# -nix bundle --bundler .#defaultBundler.$system .#defaultPackage.$system -nix bundle --bundler .#bundlers.$system.simple .#defaultPackage.$system +nix bundle --bundler .#bundlers.$system.default .#packages.$system.default +nix bundle --bundler .#bundlers.$system.simple .#packages.$system.default -nix bundle --bundler .#defaultBundler.$system .#defaultApp.$system -nix bundle --bundler .#bundlers.$system.simple .#defaultApp.$system +nix bundle --bundler .#bundlers.$system.default .#apps.$system.default +nix bundle --bundler .#bundlers.$system.simple .#apps.$system.default clearStore diff --git a/tests/flake-local-settings.sh b/tests/flake-local-settings.sh index 7765fe379..e92c16f87 100644 --- a/tests/flake-local-settings.sh +++ b/tests/flake-local-settings.sh @@ -21,7 +21,7 @@ cat <<EOF > flake.nix nixConfig.allow-dirty = false; # See #5621 outputs = a: { - defaultPackage.$system = import ./simple.nix; + packages.$system.default = import ./simple.nix; }; } EOF diff --git a/tests/flake-searching.sh b/tests/flake-searching.sh index bc55f2bdc..db241f6d2 100644 --- a/tests/flake-searching.sh +++ b/tests/flake-searching.sh @@ -15,8 +15,10 @@ cat <<EOF > flake.nix { inputs.foo.url = "$PWD/foo"; outputs = a: { - defaultPackage.$system = import ./simple.nix; - packages.$system.test = import ./simple.nix; + packages.$system = rec { + test = import ./simple.nix; + default = test; + }; }; } EOF diff --git a/tests/flakes.sh b/tests/flakes.sh index db178967f..46e6a7982 100644 --- a/tests/flakes.sh +++ b/tests/flakes.sh @@ -41,8 +41,10 @@ cat > $flake1Dir/flake.nix <<EOF description = "Bla bla"; outputs = inputs: rec { - packages.$system.foo = import ./simple.nix; - defaultPackage.$system = packages.$system.foo; + packages.$system = rec { + foo = import ./simple.nix; + default = foo; + }; # To test "nix flake init". legacyPackages.x86_64-linux.hello = import ./simple.nix; @@ -128,7 +130,7 @@ hash2=$(nix flake metadata flake1 --json --refresh | jq -r .revision) nix build -o $TEST_ROOT/result flake1#foo [[ -e $TEST_ROOT/result/hello ]] -# Test defaultPackage. +# Test packages.default. nix build -o $TEST_ROOT/result flake1 [[ -e $TEST_ROOT/result/hello ]] @@ -140,11 +142,11 @@ nix build -o $flake1Dir/result git+file://$flake1Dir nix path-info $flake1Dir/result # 'getFlake' on a mutable flakeref should fail in pure mode, but succeed in impure mode. -(! nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").defaultPackage.$system") -nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").defaultPackage.$system" --impure +(! nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").packages.$system.default") +nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").packages.$system.default" --impure # 'getFlake' on an immutable flakeref should succeed even in pure mode. -nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"git+file://$flake1Dir?rev=$hash2\").defaultPackage.$system" +nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"git+file://$flake1Dir?rev=$hash2\").packages.$system.default" # Building a flake with an unlocked dependency should fail in pure mode. (! nix build -o $TEST_ROOT/result flake2#bar --no-registries) @@ -370,13 +372,16 @@ cat > $templatesDir/flake.nix <<EOF description = "Some templates"; outputs = { self }: { - templates = { + templates = rec { trivial = { path = ./trivial; description = "A trivial flake"; + welcomeText = '' + Welcome to my trivial flake + ''; }; + default = trivial; }; - defaultTemplate = self.templates.trivial; }; } EOF @@ -388,8 +393,10 @@ cat > $templatesDir/trivial/flake.nix <<EOF description = "A flake for building Hello World"; outputs = { self, nixpkgs }: { - packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello; - defaultPackage.x86_64-linux = self.packages.x86_64-linux.hello; + packages.x86_64-linux = rec { + hello = nixpkgs.legacyPackages.x86_64-linux.hello; + default = hello; + }; }; } EOF @@ -496,17 +503,15 @@ EOF cat > $flake3Dir/flake.nix <<EOF { outputs = { flake1, self }: { - defaultPackage = { - system-1 = "foo"; - system-2 = "bar"; - }; + packages.system-1.default = "foo"; + packages.system-2.default = "bar"; }; } EOF checkRes=$(nix flake check --keep-going $flake3Dir 2>&1 && fail "nix flake check should have failed" || true) -echo "$checkRes" | grep -q "defaultPackage.system-1" -echo "$checkRes" | grep -q "defaultPackage.system-2" +echo "$checkRes" | grep -q "packages.system-1.default" +echo "$checkRes" | grep -q "packages.system-2.default" # Test 'follows' inputs. cat > $flake3Dir/flake.nix <<EOF @@ -591,7 +596,7 @@ mkdir $flake5Dir cat > $flake5Dir/flake.nix <<EOF { outputs = { self, flake1 }: { - defaultPackage.$system = flake1.defaultPackage.$system; + packages.$system.default = flake1.packages.$system.default; expr = assert builtins.pathExists ./flake.lock; 123; }; } diff --git a/tests/impure-derivations.nix b/tests/impure-derivations.nix new file mode 100644 index 000000000..98547e6c1 --- /dev/null +++ b/tests/impure-derivations.nix @@ -0,0 +1,63 @@ +with import ./config.nix; + +rec { + + impure = mkDerivation { + name = "impure"; + outputs = [ "out" "stuff" ]; + buildCommand = + '' + echo impure + x=$(< $TEST_ROOT/counter) + mkdir $out $stuff + echo $x > $out/n + ln -s $out/n $stuff/bla + printf $((x + 1)) > $TEST_ROOT/counter + ''; + __impure = true; + impureEnvVars = [ "TEST_ROOT" ]; + }; + + impureOnImpure = mkDerivation { + name = "impure-on-impure"; + buildCommand = + '' + echo impure-on-impure + x=$(< ${impure}/n) + mkdir $out + printf X$x > $out/n + ln -s ${impure.stuff} $out/symlink + ln -s $out $out/self + ''; + __impure = true; + }; + + # This is not allowed. + inputAddressed = mkDerivation { + name = "input-addressed"; + buildCommand = + '' + cat ${impure} > $out + ''; + }; + + contentAddressed = mkDerivation { + name = "content-addressed"; + buildCommand = + '' + echo content-addressed + x=$(< ${impureOnImpure}/n) + printf ''${x:0:1} > $out + ''; + outputHashMode = "recursive"; + outputHash = "sha256-eBYxcgkuWuiqs4cKNgKwkb3vY/HR0vVsJnqe8itJGcQ="; + }; + + inputAddressedAfterCA = mkDerivation { + name = "input-addressed-after-ca"; + buildCommand = + '' + cat ${contentAddressed} > $out + ''; + }; +} diff --git a/tests/impure-derivations.sh b/tests/impure-derivations.sh new file mode 100644 index 000000000..35ae3f5d3 --- /dev/null +++ b/tests/impure-derivations.sh @@ -0,0 +1,57 @@ +source common.sh + +requireDaemonNewerThan "2.8pre20220311" + +enableFeatures "ca-derivations ca-references impure-derivations" +restartDaemon + +set -o pipefail + +clearStore + +# Basic test of impure derivations: building one a second time should not use the previous result. +printf 0 > $TEST_ROOT/counter + +json=$(nix build -L --no-link --json --file ./impure-derivations.nix impure.all) +path1=$(echo $json | jq -r .[].outputs.out) +path1_stuff=$(echo $json | jq -r .[].outputs.stuff) +[[ $(< $path1/n) = 0 ]] +[[ $(< $path1_stuff/bla) = 0 ]] + +[[ $(nix path-info --json $path1 | jq .[].ca) =~ fixed:r:sha256: ]] + +path2=$(nix build -L --no-link --json --file ./impure-derivations.nix impure | jq -r .[].outputs.out) +[[ $(< $path2/n) = 1 ]] + +# Test impure derivations that depend on impure derivations. +path3=$(nix build -L --no-link --json --file ./impure-derivations.nix impureOnImpure | jq -r .[].outputs.out) +[[ $(< $path3/n) = X2 ]] + +path4=$(nix build -L --no-link --json --file ./impure-derivations.nix impureOnImpure | jq -r .[].outputs.out) +[[ $(< $path4/n) = X3 ]] + +# Test that (self-)references work. +[[ $(< $path4/symlink/bla) = 3 ]] +[[ $(< $path4/self/n) = X3 ]] + +# Input-addressed derivations cannot depend on impure derivations directly. +(! nix build -L --no-link --json --file ./impure-derivations.nix inputAddressed 2>&1) | grep 'depends on impure derivation' + +drvPath=$(nix eval --json --file ./impure-derivations.nix impure.drvPath | jq -r .) +[[ $(nix show-derivation $drvPath | jq ".[\"$drvPath\"].outputs.out.impure") = true ]] +[[ $(nix show-derivation $drvPath | jq ".[\"$drvPath\"].outputs.stuff.impure") = true ]] + +# Fixed-output derivations *can* depend on impure derivations. +path5=$(nix build -L --no-link --json --file ./impure-derivations.nix contentAddressed | jq -r .[].outputs.out) +[[ $(< $path5) = X ]] +[[ $(< $TEST_ROOT/counter) = 5 ]] + +# And they should not be rebuilt. +path5=$(nix build -L --no-link --json --file ./impure-derivations.nix contentAddressed | jq -r .[].outputs.out) +[[ $(< $path5) = X ]] +[[ $(< $TEST_ROOT/counter) = 5 ]] + +# Input-addressed derivations can depend on fixed-output derivations that depend on impure derivations. +path6=$(nix build -L --no-link --json --file ./impure-derivations.nix inputAddressedAfterCA | jq -r .[].outputs.out) +[[ $(< $path6) = X ]] +[[ $(< $TEST_ROOT/counter) = 5 ]] diff --git a/tests/local.mk b/tests/local.mk index 47717fa67..668b34500 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -1,72 +1,104 @@ nix_tests = \ - hash.sh lang.sh add.sh simple.sh dependencies.sh \ - config.sh \ - gc.sh \ + flakes.sh \ ca/gc.sh \ - gc-concurrent.sh \ - gc-non-blocking.sh \ + gc.sh \ + remote-store.sh \ + lang.sh \ + fetchMercurial.sh \ gc-auto.sh \ - referrers.sh user-envs.sh logging.sh nix-build.sh misc.sh fixed.sh \ - gc-runtime.sh check-refs.sh filter-source.sh \ - local-store.sh remote-store.sh export.sh export-graph.sh \ - db-migration.sh \ - timeout.sh secure-drv-outputs.sh nix-channel.sh \ - multiple-outputs.sh import-derivation.sh ca/import-derivation.sh fetchurl.sh optimise-store.sh \ + user-envs.sh \ binary-cache.sh \ + multiple-outputs.sh \ + ca/build.sh \ + nix-build.sh \ + gc-concurrent.sh \ + repair.sh \ + fixed.sh \ + export-graph.sh \ + timeout.sh \ + fetchGitRefs.sh \ + gc-runtime.sh \ + tarball.sh \ + fetchGit.sh \ + fetchurl.sh \ + fetchPath.sh \ + simple.sh \ + referrers.sh \ + optimise-store.sh \ substitute-with-invalid-ca.sh \ - binary-cache-build-remote.sh \ - nix-profile.sh repair.sh dump-db.sh case-hack.sh \ - check-reqs.sh pass-as-file.sh tarball.sh restricted.sh \ - placeholders.sh nix-shell.sh \ - linux-sandbox.sh \ - build-dry.sh \ + ca/concurrent-builds.sh \ + signing.sh \ + ca/build-with-garbage-path.sh \ + hash.sh \ + gc-non-blocking.sh \ + check.sh \ + ca/substitute.sh \ + nix-shell.sh \ + ca/signatures.sh \ + ca/nix-shell.sh \ + ca/nix-copy.sh \ + check-refs.sh \ build-remote-input-addressed.sh \ + secure-drv-outputs.sh \ + restricted.sh \ + fetchGitSubmodules.sh \ + flake-searching.sh \ + ca/duplicate-realisation-in-closure.sh \ + readfile-context.sh \ + nix-channel.sh \ + recursive.sh \ + dependencies.sh \ + check-reqs.sh \ build-remote-content-addressed-fixed.sh \ build-remote-content-addressed-floating.sh \ - ssh-relay.sh \ nar-access.sh \ + pure-eval.sh \ + eval.sh \ + ca/post-hook.sh \ + repl.sh \ + ca/repl.sh \ + ca/recursive.sh \ + binary-cache-build-remote.sh \ + search.sh \ + logging.sh \ + export.sh \ + config.sh \ + add.sh \ + local-store.sh \ + filter-source.sh \ + misc.sh \ + dump-db.sh \ + linux-sandbox.sh \ + build-dry.sh \ structured-attrs.sh \ - fetchGit.sh \ - fetchGitRefs.sh \ - fetchGitSubmodules.sh \ - fetchMercurial.sh \ - signing.sh \ shell.sh \ brotli.sh \ zstd.sh \ compression-levels.sh \ - pure-eval.sh \ - check.sh \ - plugins.sh \ - search.sh \ nix-copy-ssh.sh \ post-hook.sh \ - ca/post-hook.sh \ function-trace.sh \ - recursive.sh \ - describe-stores.sh \ - flakes.sh \ flake-local-settings.sh \ - flake-searching.sh \ - flake-bundler.sh \ + eval-store.sh \ + why-depends.sh \ + import-derivation.sh \ + ca/import-derivation.sh \ + nix_path.sh \ + case-hack.sh \ + placeholders.sh \ + ssh-relay.sh \ + plugins.sh \ build.sh \ - repl.sh ca/repl.sh \ - ca/build.sh \ - ca/build-with-garbage-path.sh \ - ca/duplicate-realisation-in-closure.sh \ - ca/substitute.sh \ - ca/signatures.sh \ - ca/nix-shell.sh \ ca/nix-run.sh \ - ca/recursive.sh \ - ca/concurrent-builds.sh \ - ca/nix-copy.sh \ - eval-store.sh \ - readfile-context.sh \ + db-migration.sh \ + bash-profile.sh \ + pass-as-file.sh \ + describe-stores.sh \ + nix-profile.sh \ + suggestions.sh \ store-ping.sh \ - nix_path.sh \ - why-depends.sh - # parallel.sh + fetchClosure.sh \ + impure-derivations.sh ifeq ($(HAVE_LIBCPUID), 1) nix_tests += compute-levels.sh diff --git a/tests/logging.sh b/tests/logging.sh index c894ad3ff..1481b9b36 100644 --- a/tests/logging.sh +++ b/tests/logging.sh @@ -13,3 +13,14 @@ rm -rf $NIX_LOG_DIR (! nix-store -l $path) nix-build dependencies.nix --no-out-link --compress-build-log [ "$(nix-store -l $path)" = FOO ] + +# test whether empty logs work fine with `nix log`. +builder="$(mktemp)" +echo -e "#!/bin/sh\nmkdir \$out" > "$builder" +outp="$(nix-build -E \ + 'with import ./config.nix; mkDerivation { name = "fnord"; builder = '"$builder"'; }' \ + --out-link "$(mktemp -d)/result")" + +test -d "$outp" + +nix log "$outp" diff --git a/tests/nix-profile.sh b/tests/nix-profile.sh index e2e0d1090..a7a4d4fa2 100644 --- a/tests/nix-profile.sh +++ b/tests/nix-profile.sh @@ -1,9 +1,97 @@ source common.sh -sed -e "s|@localstatedir@|$TEST_ROOT/profile-var|g" -e "s|@coreutils@|$coreutils|g" < ../scripts/nix-profile.sh.in > $TEST_ROOT/nix-profile.sh +clearStore +clearProfiles -user=$(whoami) -rm -rf $TEST_HOME $TEST_ROOT/profile-var -mkdir -p $TEST_HOME -USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set" -USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency +enableFeatures "ca-derivations ca-references" +restartDaemon + +# Make a flake. +flake1Dir=$TEST_ROOT/flake1 +mkdir -p $flake1Dir + +cat > $flake1Dir/flake.nix <<EOF +{ + description = "Bla bla"; + + outputs = { self }: with import ./config.nix; rec { + packages.$system.default = mkDerivation { + name = "profile-test-\${builtins.readFile ./version}"; + builder = builtins.toFile "builder.sh" + '' + mkdir -p \$out/bin + cat > \$out/bin/hello <<EOF + #! ${shell} + echo Hello \${builtins.readFile ./who} + EOF + chmod +x \$out/bin/hello + echo DONE + ''; + __contentAddressed = import ./ca.nix; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + }; + }; +} +EOF + +printf World > $flake1Dir/who +printf 1.0 > $flake1Dir/version +printf false > $flake1Dir/ca.nix + +cp ./config.nix $flake1Dir/ + +# Test upgrading from nix-env. +nix-env -f ./user-envs.nix -i foo-1.0 +nix profile list | grep '0 - - .*-foo-1.0' +nix profile install $flake1Dir -L +[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]] +nix profile history +nix profile history | grep "packages.$system.default: ∅ -> 1.0" +nix profile diff-closures | grep 'env-manifest.nix: ε → ∅' + +# Test upgrading a package. +printf NixOS > $flake1Dir/who +printf 2.0 > $flake1Dir/version +nix profile upgrade 1 +[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello NixOS" ]] +nix profile history | grep "packages.$system.default: 1.0 -> 2.0" + +# Test 'history', 'diff-closures'. +nix profile diff-closures + +# Test rollback. +nix profile rollback +[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]] + +# Test uninstall. +[ -e $TEST_HOME/.nix-profile/bin/foo ] +nix profile remove 0 +(! [ -e $TEST_HOME/.nix-profile/bin/foo ]) +nix profile history | grep 'foo: 1.0 -> ∅' +nix profile diff-closures | grep 'Version 3 -> 4' + +# Test installing a non-flake package. +nix profile install --file ./simple.nix '' +[[ $(cat $TEST_HOME/.nix-profile/hello) = "Hello World!" ]] +nix profile remove 1 +nix profile install $(nix-build --no-out-link ./simple.nix) +[[ $(cat $TEST_HOME/.nix-profile/hello) = "Hello World!" ]] + +# Test wipe-history. +nix profile wipe-history +[[ $(nix profile history | grep Version | wc -l) -eq 1 ]] + +# Test upgrade to CA package. +printf true > $flake1Dir/ca.nix +printf 3.0 > $flake1Dir/version +nix profile upgrade 0 +nix profile history | grep "packages.$system.default: 1.0 -> 3.0" + +# Test new install of CA package. +nix profile remove 0 +printf 4.0 > $flake1Dir/version +printf Utrecht > $flake1Dir/who +nix profile install $flake1Dir +[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello Utrecht" ]] +[[ $(nix path-info --json $(realpath $TEST_HOME/.nix-profile/bin/hello) | jq -r .[].ca) =~ fixed:r:sha256: ]] diff --git a/tests/repl.sh b/tests/repl.sh index 0e23a98db..6505f1741 100644 --- a/tests/repl.sh +++ b/tests/repl.sh @@ -40,3 +40,26 @@ testRepl () { testRepl # Same thing (kind-of), but with a remote store. testRepl --store "$TEST_ROOT/store?real=$NIX_STORE_DIR" + +testReplResponse () { + local response="$(nix repl <<< "$1")" + echo "$response" | grep -qs "$2" \ + || fail "repl command set: + +$1 + +does not respond with: + +$2 + +but with: + +$response" +} + +# :a uses the newest version of a symbol +testReplResponse ' +:a { a = "1"; } +:a { a = "2"; } +"result: ${a}" +' "result: 2" diff --git a/tests/sourcehut-flakes.nix b/tests/sourcehut-flakes.nix new file mode 100644 index 000000000..6a1930904 --- /dev/null +++ b/tests/sourcehut-flakes.nix @@ -0,0 +1,156 @@ +{ nixpkgs, system, overlay }: + +with import (nixpkgs + "/nixos/lib/testing-python.nix") +{ + inherit system; + extraConfigurations = [{ nixpkgs.overlays = [ overlay ]; }]; +}; + +let + # Generate a fake root CA and a fake git.sr.ht certificate. + cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; } + '' + mkdir -p $out + + openssl genrsa -out ca.key 2048 + openssl req -new -x509 -days 36500 -key ca.key \ + -subj "/C=NL/ST=Denial/L=Springfield/O=Dis/CN=Root CA" -out $out/ca.crt + + openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \ + -subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=git.sr.ht" -out server.csr + openssl x509 -req -extfile <(printf "subjectAltName=DNS:git.sr.ht") \ + -days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt + ''; + + registry = pkgs.writeTextFile { + name = "registry"; + text = '' + { + "flakes": [ + { + "from": { + "type": "indirect", + "id": "nixpkgs" + }, + "to": { + "type": "sourcehut", + "owner": "~NixOS", + "repo": "nixpkgs" + } + } + ], + "version": 2 + } + ''; + destination = "/flake-registry.json"; + }; + + nixpkgs-repo = pkgs.runCommand "nixpkgs-flake" { } + '' + dir=NixOS-nixpkgs-${nixpkgs.shortRev} + cp -prd ${nixpkgs} $dir + + # Set the correct timestamp in the tarball. + find $dir -print0 | xargs -0 touch -t ${builtins.substring 0 12 nixpkgs.lastModifiedDate}.${builtins.substring 12 2 nixpkgs.lastModifiedDate} -- + + mkdir -p $out/archive + tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference + + echo 'ref: refs/heads/master' > $out/HEAD + + mkdir -p $out/info + echo -e '${nixpkgs.rev}\trefs/heads/master' > $out/info/refs + ''; + +in + +makeTest ( + + { + name = "sourcehut-flakes"; + + nodes = + { + # Impersonate git.sr.ht + sourcehut = + { config, pkgs, ... }: + { + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + services.httpd.extraConfig = '' + ErrorLog syslog:local6 + ''; + services.httpd.virtualHosts."git.sr.ht" = + { + forceSSL = true; + sslServerKey = "${cert}/server.key"; + sslServerCert = "${cert}/server.crt"; + servedDirs = + [ + { + urlPath = "/~NixOS/nixpkgs"; + dir = nixpkgs-repo; + } + { + urlPath = "/~NixOS/flake-registry/blob/master"; + dir = registry; + } + ]; + }; + }; + + client = + { config, lib, pkgs, nodes, ... }: + { + virtualisation.writableStore = true; + virtualisation.diskSize = 2048; + virtualisation.pathsInNixDB = [ pkgs.hello pkgs.fuse ]; + virtualisation.memorySize = 4096; + nix.binaryCaches = lib.mkForce [ ]; + nix.extraOptions = '' + experimental-features = nix-command flakes + flake-registry = https://git.sr.ht/~NixOS/flake-registry/blob/master/flake-registry.json + ''; + environment.systemPackages = [ pkgs.jq ]; + networking.hosts.${(builtins.head nodes.sourcehut.config.networking.interfaces.eth1.ipv4.addresses).address} = + [ "git.sr.ht" ]; + security.pki.certificateFiles = [ "${cert}/ca.crt" ]; + }; + }; + + testScript = { nodes }: '' + # fmt: off + import json + import time + + start_all() + + sourcehut.wait_for_unit("httpd.service") + + client.succeed("curl -v https://git.sr.ht/ >&2") + client.succeed("nix registry list | grep nixpkgs") + + rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision") + assert rev.strip() == "${nixpkgs.rev}", "revision mismatch" + + client.succeed("nix registry pin nixpkgs") + + client.succeed("nix flake info nixpkgs --tarball-ttl 0 >&2") + + # Shut down the web server. The flake should be cached on the client. + sourcehut.succeed("systemctl stop httpd.service") + + info = json.loads(client.succeed("nix flake info nixpkgs --json")) + date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified'])) + assert date == "${nixpkgs.lastModifiedDate}", "time mismatch" + + client.succeed("nix build nixpkgs#hello") + + # The build shouldn't fail even with --tarball-ttl 0 (the server + # being down should not be a fatal error). + client.succeed("nix build nixpkgs#fuse --tarball-ttl 0") + ''; + + }) diff --git a/tests/suggestions.sh b/tests/suggestions.sh new file mode 100644 index 000000000..f18fefef9 --- /dev/null +++ b/tests/suggestions.sh @@ -0,0 +1,44 @@ +source common.sh + +clearStore + +cd "$TEST_HOME" + +cat <<EOF > flake.nix +{ + outputs = a: { + packages.$system = { + foo = 1; + fo1 = 1; + fo2 = 1; + fooo = 1; + foooo = 1; + fooooo = 1; + fooooo1 = 1; + fooooo2 = 1; + fooooo3 = 1; + fooooo4 = 1; + fooooo5 = 1; + fooooo6 = 1; + }; + }; +} +EOF + +# Probable typo in the requested attribute path. Suggest some close possibilities +NIX_BUILD_STDERR_WITH_SUGGESTIONS=$(! nix build .\#fob 2>&1 1>/dev/null) +[[ "$NIX_BUILD_STDERR_WITH_SUGGESTIONS" =~ "Did you mean one of fo1, fo2, foo or fooo?" ]] || \ + fail "The nix build stderr should suggest the three closest possiblities" + +# None of the possible attributes is close to `bar`, so shouldn’t suggest anything +NIX_BUILD_STDERR_WITH_NO_CLOSE_SUGGESTION=$(! nix build .\#bar 2>&1 1>/dev/null) +[[ ! "$NIX_BUILD_STDERR_WITH_NO_CLOSE_SUGGESTION" =~ "Did you mean" ]] || \ + fail "The nix build stderr shouldn’t suggest anything if there’s nothing relevant to suggest" + +NIX_EVAL_STDERR_WITH_SUGGESTIONS=$(! nix build --impure --expr '(builtins.getFlake (builtins.toPath ./.)).packages.'$system'.fob' 2>&1 1>/dev/null) +[[ "$NIX_EVAL_STDERR_WITH_SUGGESTIONS" =~ "Did you mean one of fo1, fo2, foo or fooo?" ]] || \ + fail "The evaluator should suggest the three closest possiblities" + +NIX_EVAL_STDERR_WITH_SUGGESTIONS=$(! nix build --impure --expr '({ foo }: foo) { foo = 1; fob = 2; }' 2>&1 1>/dev/null) +[[ "$NIX_EVAL_STDERR_WITH_SUGGESTIONS" =~ "Did you mean foo?" ]] || \ + fail "The evaluator should suggest the three closest possiblities" diff --git a/tests/tarball.sh b/tests/tarball.sh index 1301922a5..d5cab879c 100644 --- a/tests/tarball.sh +++ b/tests/tarball.sh @@ -26,10 +26,14 @@ test_tarball() { nix-build -o $TEST_ROOT/result '<foo>' -I foo=file://$tarball nix-build -o $TEST_ROOT/result -E "import (fetchTarball file://$tarball)" + # Do not re-fetch paths already present + nix-build -o $TEST_ROOT/result -E "import (fetchTarball { url = file:///does-not-exist/must-remain-unused/$tarball; sha256 = \"$hash\"; })" nix-build -o $TEST_ROOT/result -E "import (fetchTree file://$tarball)" nix-build -o $TEST_ROOT/result -E "import (fetchTree { type = \"tarball\"; url = file://$tarball; })" nix-build -o $TEST_ROOT/result -E "import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })" + # Do not re-fetch paths already present + nix-build -o $TEST_ROOT/result -E "import (fetchTree { type = \"tarball\"; url = file:///does-not-exist/must-remain-unused/$tarball; narHash = \"$hash\"; })" nix-build -o $TEST_ROOT/result -E "import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"sha256-xdKv2pq/IiwLSnBBJXW8hNowI4MrdZfW+SYqDQs7Tzc=\"; })" 2>&1 | grep 'NAR hash mismatch in input' nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })) ? submodules)" >&2 diff --git a/tests/user-envs.nix b/tests/user-envs.nix index 6ac896ed8..46f8b51dd 100644 --- a/tests/user-envs.nix +++ b/tests/user-envs.nix @@ -8,6 +8,8 @@ assert foo == "foo"; let + platforms = let x = "foobar"; in [ x x ]; + makeDrv = name: progName: (mkDerivation { name = assert progName != "fail"; name; inherit progName system; @@ -15,6 +17,7 @@ let } // { meta = { description = "A silly test package with some \${escaped anti-quotation} in it"; + inherit platforms; }; }); diff --git a/tests/user-envs.sh b/tests/user-envs.sh index aebf6a2a2..d63fe780a 100644 --- a/tests/user-envs.sh +++ b/tests/user-envs.sh @@ -9,7 +9,6 @@ clearProfiles # Query installed: should be empty. test "$(nix-env -p $profiles/test -q '*' | wc -l)" -eq 0 -mkdir -p $TEST_HOME nix-env --switch-profile $profiles/test # Query available: should contain several. @@ -18,6 +17,16 @@ outPath10=$(nix-env -f ./user-envs.nix -qa --out-path --no-name '*' | grep foo-1 drvPath10=$(nix-env -f ./user-envs.nix -qa --drv-path --no-name '*' | grep foo-1.0) [ -n "$outPath10" -a -n "$drvPath10" ] +# Query with json +nix-env -f ./user-envs.nix -qa --json | jq -e '.[] | select(.name == "bar-0.1") | [ + .outputName == "out", + .outputs.out == null +] | all' +nix-env -f ./user-envs.nix -qa --json --out-path | jq -e '.[] | select(.name == "bar-0.1") | [ + .outputName == "out", + (.outputs.out | test("'$NIX_STORE_DIR'.*-0\\.1")) +] | all' + # Query descriptions. nix-env -f ./user-envs.nix -qa '*' --description | grep -q silly rm -rf $HOME/.nix-defexpr |