diff options
author | Théophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com> | 2022-03-01 13:58:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-01 13:58:17 +0100 |
commit | 47dec825c5daeeb9d615eb4d1eead3dbaa06c7c9 (patch) | |
tree | 9d4426dfe847570906487649c32c5b320697705c /tests | |
parent | 79152e307e7eef667c3de9c21571d017654a7c32 (diff) | |
parent | dc92b01885c0c49d094148b1c4dc871ccdd265ad (diff) |
Merge pull request #6181 from obsidiansystems/auto-uid-allocation
Auto uid allocation -- update with latest master
Diffstat (limited to 'tests')
61 files changed, 1069 insertions, 162 deletions
diff --git a/tests/big-derivation-attr.nix b/tests/big-derivation-attr.nix new file mode 100644 index 000000000..35c1187f6 --- /dev/null +++ b/tests/big-derivation-attr.nix @@ -0,0 +1,13 @@ +let + sixteenBytes = "0123456789abcdef"; + times16 = s: builtins.concatStringsSep "" [s s s s s s s s s s s s s s s s]; + exp = n: x: if n == 1 then x else times16 (exp (n - 1) x); + sixteenMegabyte = exp 6 sixteenBytes; +in +assert builtins.stringLength sixteenMegabyte == 16777216; +derivation { + name = "big-derivation-attr"; + builder = "/x"; + system = "y"; + bigAttr = sixteenMegabyte; +} diff --git a/tests/binary-cache.sh b/tests/binary-cache.sh index d7bc1507b..2368884f7 100644 --- a/tests/binary-cache.sh +++ b/tests/binary-cache.sh @@ -14,6 +14,17 @@ outPath=$(nix-build dependencies.nix --no-out-link) nix copy --to file://$cacheDir $outPath +# Test copying build logs to the binary cache. +nix log --store file://$cacheDir $outPath 2>&1 | grep 'is not available' +nix store copy-log --to file://$cacheDir $outPath +nix log --store file://$cacheDir $outPath | grep FOO +rm -rf $TEST_ROOT/var/log/nix +nix log $outPath 2>&1 | grep 'is not available' +nix log --substituters file://$cacheDir $outPath | grep FOO + +# Test copying build logs from the binary cache. +nix store copy-log --from file://$cacheDir $(nix-store -qd $outPath) +nix log $outPath | grep FOO basicDownloadTests() { # No uploading tests bcause upload with force HTTP doesn't work. diff --git a/tests/build-remote.sh b/tests/build-remote.sh index 27d85a83d..806c6d261 100644 --- a/tests/build-remote.sh +++ b/tests/build-remote.sh @@ -53,3 +53,16 @@ nix path-info --store $TEST_ROOT/machine3 --all \ | grep -v builder-build-remote-input-1.sh \ | grep -v builder-build-remote-input-2.sh \ | grep builder-build-remote-input-3.sh + +# Behavior of keep-failed +out="$(nix-build 2>&1 failing.nix \ + --builders "$(join_by '; ' "${builders[@]}")" \ + --keep-failed \ + --store $TEST_ROOT/machine0 \ + -j0 \ + --arg busybox $busybox)" || true + +[[ "$out" =~ .*"note: keeping build directory".* ]] + +build_dir="$(grep "note: keeping build" <<< "$out" | sed -E "s/^(.*)note: keeping build directory '(.*)'(.*)$/\2/")" +[[ "foo" = $(<"$build_dir"/bar) ]] diff --git a/tests/ca-shell.nix b/tests/ca-shell.nix new file mode 100644 index 000000000..ad2ab6aff --- /dev/null +++ b/tests/ca-shell.nix @@ -0,0 +1 @@ +{ ... }@args: import ./shell.nix (args // { contentAddressed = true; }) diff --git a/tests/ca/build-with-garbage-path.sh b/tests/ca/build-with-garbage-path.sh index 9aa08a899..884cd2802 100755 --- a/tests/ca/build-with-garbage-path.sh +++ b/tests/ca/build-with-garbage-path.sh @@ -8,7 +8,7 @@ requireDaemonNewerThan "2.4pre20210621" # Get the output path of `rootCA`, and put some garbage instead outPath="$(nix-build ./content-addressed.nix -A rootCA --no-out-link)" -nix-store --delete "$outPath" +nix-store --delete $(nix-store -q --referrers-closure "$outPath") touch "$outPath" # The build should correctly remove the garbage and put the expected path instead diff --git a/tests/ca/import-derivation.sh b/tests/ca/import-derivation.sh new file mode 100644 index 000000000..e98e0fbd0 --- /dev/null +++ b/tests/ca/import-derivation.sh @@ -0,0 +1,6 @@ +source common.sh + +export NIX_TESTS_CA_BY_DEFAULT=1 + +cd .. && source import-derivation.sh + diff --git a/tests/ca/repl.sh b/tests/ca/repl.sh new file mode 100644 index 000000000..3808c7cb2 --- /dev/null +++ b/tests/ca/repl.sh @@ -0,0 +1,5 @@ +source common.sh + +export NIX_TESTS_CA_BY_DEFAULT=1 + +cd .. && source repl.sh diff --git a/tests/ca/signatures.sh b/tests/ca/signatures.sh index 4b4e468f7..0c7d974ea 100644 --- a/tests/ca/signatures.sh +++ b/tests/ca/signatures.sh @@ -22,8 +22,8 @@ testOneCopy () { rm -rf "$REMOTE_STORE_DIR" attrPath="$1" - nix copy --to $REMOTE_STORE "$attrPath" --file ./content-addressed.nix \ - --secret-key-files "$TEST_ROOT/sk1" + nix copy -vvvv --to $REMOTE_STORE "$attrPath" --file ./content-addressed.nix \ + --secret-key-files "$TEST_ROOT/sk1" --show-trace ensureCorrectlyCopied "$attrPath" diff --git a/tests/check.nix b/tests/check.nix index ec455ae2d..ed91ff845 100644 --- a/tests/check.nix +++ b/tests/check.nix @@ -50,6 +50,6 @@ with import ./config.nix; fetchurl = import <nix/fetchurl.nix> { url = "file://" + toString ./lang/eval-okay-xml.exp.xml; - sha256 = "0kg4sla7ihm8ijr8cb3117fhl99zrc2bwy1jrngsfmkh8bav4m0v"; + sha256 = "sha256-behBlX+DQK/Pjvkuc8Tx68Jwi4E5v86wDq+ZLaHyhQE="; }; } diff --git a/tests/common.sh.in b/tests/common.sh.in index 7daab2460..e485329ba 100644 --- a/tests/common.sh.in +++ b/tests/common.sh.in @@ -36,8 +36,9 @@ export PATH=@bindir@:$PATH if [[ -n "${NIX_CLIENT_PACKAGE:-}" ]]; then export PATH="$NIX_CLIENT_PACKAGE/bin":$PATH fi +DAEMON_PATH="$PATH" if [[ -n "${NIX_DAEMON_PACKAGE:-}" ]]; then - export NIX_DAEMON_COMMAND="$NIX_DAEMON_PACKAGE/bin/nix-daemon" + DAEMON_PATH="${NIX_DAEMON_PACKAGE}/bin:$DAEMON_PATH" fi coreutils=@coreutils@ @@ -89,21 +90,27 @@ startDaemon() { # Start the daemon, wait for the socket to appear. !!! # ‘nix-daemon’ should have an option to fork into the background. rm -f $NIX_DAEMON_SOCKET_PATH - ${NIX_DAEMON_COMMAND:-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 + for i in {0..100}; do kill -0 $pidDaemon || break - sleep 1 + sleep 0.1 done kill -9 $pidDaemon || true wait $pidDaemon || true @@ -126,7 +133,7 @@ isDaemonNewer () { [[ -n "${NIX_DAEMON_PACKAGE:-}" ]] || return 0 local requiredVersion="$1" local daemonVersion=$($NIX_DAEMON_PACKAGE/bin/nix-daemon --version | cut -d' ' -f3) - return [[ $(nix eval --expr "builtins.compareVersions ''$daemonVersion'' ''2.4''") -ge 0 ]] + [[ $(nix eval --expr "builtins.compareVersions ''$daemonVersion'' ''$requiredVersion''") -ge 0 ]] } requireDaemonNewerThan () { diff --git a/tests/compression-levels.sh b/tests/compression-levels.sh new file mode 100644 index 000000000..85f12974a --- /dev/null +++ b/tests/compression-levels.sh @@ -0,0 +1,22 @@ +source common.sh + +clearStore +clearCache + +outPath=$(nix-build dependencies.nix --no-out-link) + +cacheURI="file://$cacheDir?compression=xz&compression-level=0" + +nix copy --to $cacheURI $outPath + +FILESIZES=$(cat ${cacheDir}/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}') + +clearCache + +cacheURI="file://$cacheDir?compression=xz&compression-level=5" + +nix copy --to $cacheURI $outPath + +FILESIZES2=$(cat ${cacheDir}/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}') + +[[ $FILESIZES -gt $FILESIZES2 ]] diff --git a/tests/config.sh b/tests/config.sh index 01c78f2c3..3d0da3cef 100644 --- a/tests/config.sh +++ b/tests/config.sh @@ -50,4 +50,4 @@ exp_cores=$(nix show-config | grep '^cores' | cut -d '=' -f 2 | xargs) exp_features=$(nix show-config | grep '^experimental-features' | cut -d '=' -f 2 | xargs) [[ $prev != $exp_cores ]] [[ $exp_cores == "4242" ]] -[[ $exp_features == "nix-command flakes" ]] +[[ $exp_features == "flakes nix-command" ]] diff --git a/tests/dependencies.builder0.sh b/tests/dependencies.builder0.sh index c37bf909a..9b11576e0 100644 --- a/tests/dependencies.builder0.sh +++ b/tests/dependencies.builder0.sh @@ -4,7 +4,7 @@ mkdir $out echo $(cat $input1/foo)$(cat $input2/bar) > $out/foobar -ln -s $input2 $out/input-2 +ln -s $input2 $out/reference-to-input-2 # Self-reference. ln -s $out $out/self diff --git a/tests/dependencies.nix b/tests/dependencies.nix index e320d81c9..45aca1793 100644 --- a/tests/dependencies.nix +++ b/tests/dependencies.nix @@ -27,6 +27,8 @@ let { input1 = input1 + "/."; input2 = "${input2}/."; input1_drv = input1; + input2_drv = input2; + input0_drv = input0; meta.description = "Random test package"; }; diff --git a/tests/eval-store.sh b/tests/eval-store.sh index 9ab7a87be..679da5741 100644 --- a/tests/eval-store.sh +++ b/tests/eval-store.sh @@ -1,6 +1,8 @@ source common.sh -requireDaemonNewerThan "2.4pre20210727" +# Using `--eval-store` with the daemon will eventually copy everything +# to the build store, invalidating most of the tests here +needLocalStore eval_store=$TEST_ROOT/eval-store diff --git a/tests/failing.nix b/tests/failing.nix new file mode 100644 index 000000000..2a0350d4d --- /dev/null +++ b/tests/failing.nix @@ -0,0 +1,22 @@ +{ busybox }: +with import ./config.nix; +let + + mkDerivation = args: + derivation ({ + 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 {}; }; +in +{ + + failing = mkDerivation { + name = "failing"; + buildCommand = '' + echo foo > bar + exit 1 + ''; + }; +} diff --git a/tests/fetchGitSubmodules.sh b/tests/fetchGitSubmodules.sh index 03d46088e..5f104355f 100644 --- a/tests/fetchGitSubmodules.sh +++ b/tests/fetchGitSubmodules.sh @@ -42,8 +42,8 @@ r1=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \ r2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = false; }).outPath") r3=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath") -[[ $r1 == $r3 ]] -[[ $r2 != $r1 ]] +[[ $r1 == $r2 ]] +[[ $r2 != $r3 ]] r4=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; }).outPath") r5=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = false; }).outPath") @@ -52,13 +52,13 @@ r7=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; ref = \"master r8=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).outPath") [[ $r1 == $r4 ]] -[[ $r4 == $r6 ]] +[[ $r4 == $r5 ]] [[ $r3 == $r6 ]] [[ $r6 == $r7 ]] [[ $r7 == $r8 ]] have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; }).submodules") -[[ $have_submodules == true ]] +[[ $have_submodules == false ]] have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = false; }).submodules") [[ $have_submodules == false ]] @@ -66,8 +66,8 @@ have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \ have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).submodules") [[ $have_submodules == true ]] -pathWithoutSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = false; }).outPath") -pathWithSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath") +pathWithoutSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath") +pathWithSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath") pathWithSubmodulesAgain=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath") pathWithSubmodulesAgainWithRef=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath") diff --git a/tests/fixed.nix b/tests/fixed.nix index 76580ffa1..babe71504 100644 --- a/tests/fixed.nix +++ b/tests/fixed.nix @@ -21,6 +21,14 @@ rec { (f ./fixed.builder2.sh "recursive" "sha1" "vw46m23bizj4n8afrc0fj19wrp7mj3c0") ]; + # Expression to test that `nix-build --check` also throws an error if the hash of + # fixed-output derivation has changed even if the hash exists in the store (in this + # case the hash exists because of `fixed.builder2.sh`, but building a derivation + # with the same hash and a different result must throw an error). + check = [ + (f ./fixed.builder1.sh "recursive" "md5" "3670af73070fa14077ad74e0f5ea4e42") + ]; + good2 = [ # Yes, this looks fscked up: builder2 doesn't have that result. # But Nix sees that an output with the desired hash already diff --git a/tests/fixed.sh b/tests/fixed.sh index 90c4c8c32..f1e1ce420 100644 --- a/tests/fixed.sh +++ b/tests/fixed.sh @@ -15,6 +15,11 @@ nix path-info --json $path | grep fixed:md5:2qk15sxzzjlnpjk9brn7j8ppcd echo 'testing good...' nix-build fixed.nix -A good --no-out-link +if isDaemonNewer "2.4pre20210927"; then + echo 'testing --check...' + nix-build fixed.nix -A check --check && fail "should fail" +fi + echo 'testing good2...' nix-build fixed.nix -A good2 --no-out-link diff --git a/tests/flake-bundler.sh b/tests/flake-bundler.sh new file mode 100644 index 000000000..9496b8f92 --- /dev/null +++ b/tests/flake-bundler.sh @@ -0,0 +1,37 @@ +source common.sh + +clearStore +rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local + +cp ./simple.nix ./simple.builder.sh ./config.nix $TEST_HOME + +cd $TEST_HOME + +cat <<EOF > flake.nix +{ + outputs = {self}: { + bundlers.$system = rec { + simple = drv: + if drv?type && drv.type == "derivation" + then drv + 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 .#bundlers.$system.default .#packages.$system.default +nix bundle --bundler .#bundlers.$system.simple .#packages.$system.default + +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 new file mode 100644 index 000000000..e92c16f87 --- /dev/null +++ b/tests/flake-local-settings.sh @@ -0,0 +1,45 @@ +source common.sh + +clearStore +rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local + +cp ./simple.nix ./simple.builder.sh ./config.nix $TEST_HOME + +cd $TEST_HOME + +rm -f post-hook-ran +cat <<EOF > echoing-post-hook.sh +#!/bin/sh + +echo "ThePostHookRan as \$0" > $PWD/post-hook-ran +EOF +chmod +x echoing-post-hook.sh + +cat <<EOF > flake.nix +{ + nixConfig.post-build-hook = ./echoing-post-hook.sh; + nixConfig.allow-dirty = false; # See #5621 + + outputs = a: { + packages.$system.default = import ./simple.nix; + }; +} +EOF + +# Without --accept-flake-config, the post hook should not run. +nix build < /dev/null +(! [[ -f post-hook-ran ]]) +clearStore + +nix build --accept-flake-config +test -f post-hook-ran || fail "The post hook should have ran" + +# Make sure that the path to the post hook doesn’t change if we change +# something in the flake. +# Otherwise the user would have to re-validate the setting each time. +mv post-hook-ran previous-post-hook-run +echo "# Dummy comment" >> flake.nix +clearStore +nix build --accept-flake-config +diff -q post-hook-ran previous-post-hook-run || \ + fail "Both post hook runs should report the same filename" diff --git a/tests/flake-searching.sh b/tests/flake-searching.sh new file mode 100644 index 000000000..db241f6d2 --- /dev/null +++ b/tests/flake-searching.sh @@ -0,0 +1,52 @@ +source common.sh + +if [[ -z $(type -p git) ]]; then + echo "Git not installed; skipping flake search tests" + exit 99 +fi + +clearStore + +cp ./simple.nix ./simple.builder.sh ./config.nix $TEST_HOME +cd $TEST_HOME +mkdir -p foo/subdir +echo '{ outputs = _: {}; }' > foo/flake.nix +cat <<EOF > flake.nix +{ + inputs.foo.url = "$PWD/foo"; + outputs = a: { + packages.$system = rec { + test = import ./simple.nix; + default = test; + }; + }; +} +EOF +mkdir subdir +pushd subdir + +success=("" . .# .#test ../subdir ../subdir#test "$PWD") +failure=("path:$PWD") + +for i in "${success[@]}"; do + nix build $i || fail "flake should be found by searching up directories" +done + +for i in "${failure[@]}"; do + ! nix build $i || fail "flake should not search up directories when using 'path:'" +done + +popd + +nix build --override-input foo . || fail "flake should search up directories when not an installable" + +sed "s,$PWD/foo,$PWD/foo/subdir,g" -i flake.nix +! nix build || fail "flake should not search upwards when part of inputs" + +pushd subdir +git init +for i in "${success[@]}" "${failure[@]}"; do + ! nix build $i || fail "flake should not search past a git repository" +done +rm -rf .git +popd diff --git a/tests/flakes.sh b/tests/flakes.sh index 2ede7f72c..ea629ae70 100644 --- a/tests/flakes.sh +++ b/tests/flakes.sh @@ -5,11 +5,6 @@ if [[ -z $(type -p git) ]]; then exit 99 fi -if [[ -z $(type -p hg) ]]; then - echo "Mercurial not installed; skipping flake tests" - exit 99 -fi - clearStore rm -rf $TEST_HOME/.cache $TEST_HOME/.config @@ -46,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; @@ -133,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 ]] @@ -145,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) @@ -254,6 +251,14 @@ cat > $flake3Dir/flake.nix <<EOF url = git+file://$nonFlakeDir; flake = false; }; + nonFlakeFile = { + url = path://$nonFlakeDir/README.md; + flake = false; + }; + nonFlakeFile2 = { + url = "$nonFlakeDir/README.md"; + flake = false; + }; }; description = "Fnord"; @@ -266,8 +271,12 @@ cat > $flake3Dir/flake.nix <<EOF mkDerivation { inherit system; name = "fnord"; + dummy = builtins.readFile (builtins.path { name = "source"; path = ./.; filter = path: type: baseNameOf path == "config.nix"; } + "/config.nix"); + dummy2 = builtins.readFile (builtins.path { name = "source"; path = inputs.flake1; filter = path: type: baseNameOf path == "simple.nix"; } + "/simple.nix"); buildCommand = '' cat \${inputs.nonFlake}/README.md > \$out + [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]] + [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]] ''; }; }; @@ -363,13 +372,13 @@ cat > $templatesDir/flake.nix <<EOF description = "Some templates"; outputs = { self }: { - templates = { + templates = rec { trivial = { path = ./trivial; description = "A trivial flake"; }; + default = trivial; }; - defaultTemplate = self.templates.trivial; }; } EOF @@ -381,8 +390,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 @@ -489,17 +500,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 @@ -579,45 +588,52 @@ nix build -o $TEST_ROOT/result git+file://$flakeGitBare # Test Mercurial flakes. rm -rf $flake5Dir -hg init $flake5Dir +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; }; } EOF -hg add $flake5Dir/flake.nix -hg commit --config ui.username=foobar@example.org $flake5Dir -m 'Initial commit' +if [[ -n $(type -p hg) ]]; then + hg init $flake5Dir -nix build -o $TEST_ROOT/result hg+file://$flake5Dir -[[ -e $TEST_ROOT/result/hello ]] + hg add $flake5Dir/flake.nix + hg commit --config ui.username=foobar@example.org $flake5Dir -m 'Initial commit' + + nix build -o $TEST_ROOT/result hg+file://$flake5Dir + [[ -e $TEST_ROOT/result/hello ]] -(! nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revision) + (! nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revision) -nix eval hg+file://$flake5Dir#expr + nix eval hg+file://$flake5Dir#expr -nix eval hg+file://$flake5Dir#expr + nix eval hg+file://$flake5Dir#expr -(! nix eval hg+file://$flake5Dir#expr --no-allow-dirty) + (! nix eval hg+file://$flake5Dir#expr --no-allow-dirty) -(! nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revision) + (! nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revision) -hg commit --config ui.username=foobar@example.org $flake5Dir -m 'Add lock file' + hg commit --config ui.username=foobar@example.org $flake5Dir -m 'Add lock file' -nix flake metadata --json hg+file://$flake5Dir --refresh | jq -e -r .revision -nix flake metadata --json hg+file://$flake5Dir -[[ $(nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revCount) = 1 ]] + nix flake metadata --json hg+file://$flake5Dir --refresh | jq -e -r .revision + nix flake metadata --json hg+file://$flake5Dir + [[ $(nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revCount) = 1 ]] -nix build -o $TEST_ROOT/result hg+file://$flake5Dir --no-registries --no-allow-dirty -nix build -o $TEST_ROOT/result hg+file://$flake5Dir --no-use-registries --no-allow-dirty + nix build -o $TEST_ROOT/result hg+file://$flake5Dir --no-registries --no-allow-dirty + nix build -o $TEST_ROOT/result hg+file://$flake5Dir --no-use-registries --no-allow-dirty +fi -# Test tarball flakes -tar cfz $TEST_ROOT/flake.tar.gz -C $TEST_ROOT --exclude .hg flake5 +# Test path flakes. +rm -rf $flake5Dir/.hg $flake5Dir/flake.lock +nix flake lock path://$flake5Dir + +# Test tarball flakes. +tar cfz $TEST_ROOT/flake.tar.gz -C $TEST_ROOT flake5 nix build -o $TEST_ROOT/result file://$TEST_ROOT/flake.tar.gz @@ -632,8 +648,8 @@ nix build -o $TEST_ROOT/result "file://$TEST_ROOT/flake.tar.gz?narHash=sha256-qQ # Test --override-input. git -C $flake3Dir reset --hard -nix flake lock $flake3Dir --override-input flake2/flake1 flake5 -vvvvv -[[ $(jq .nodes.flake1_2.locked.url $flake3Dir/flake.lock) =~ flake5 ]] +nix flake lock $flake3Dir --override-input flake2/flake1 file://$TEST_ROOT/flake.tar.gz -vvvvv +[[ $(jq .nodes.flake1_2.locked.url $flake3Dir/flake.lock) =~ flake.tar.gz ]] nix flake lock $flake3Dir --override-input flake2/flake1 flake1 [[ $(jq -r .nodes.flake1_2.locked.rev $flake3Dir/flake.lock) =~ $hash2 ]] @@ -702,11 +718,10 @@ cat > $flakeFollowsA/flake.nix <<EOF inputs = { B = { url = "path:./flakeB"; - inputs.foobar.follows = "D"; + inputs.foobar.follows = "foobar"; }; - D.url = "path:./flakeD"; - foobar.url = "path:./flakeE"; + foobar.url = "path:$flakeFollowsA/flakeE"; }; outputs = { ... }: {}; } @@ -716,7 +731,8 @@ cat > $flakeFollowsB/flake.nix <<EOF { description = "Flake B"; inputs = { - foobar.url = "path:./../flakeE"; + foobar.url = "path:$flakeFollowsA/flakeE"; + goodoo.follows = "C/goodoo"; C = { url = "path:./flakeC"; inputs.foobar.follows = "foobar"; @@ -730,7 +746,8 @@ cat > $flakeFollowsC/flake.nix <<EOF { description = "Flake C"; inputs = { - foobar.url = "path:./../../flakeE"; + foobar.url = "path:$flakeFollowsA/flakeE"; + goodoo.follows = "foobar"; }; outputs = { ... }: {}; } @@ -746,7 +763,7 @@ EOF cat > $flakeFollowsE/flake.nix <<EOF { - description = "Flake D"; + description = "Flake E"; inputs = {}; outputs = { ... }: {}; } @@ -755,18 +772,51 @@ EOF git -C $flakeFollowsA add flake.nix flakeB/flake.nix \ flakeB/flakeC/flake.nix flakeD/flake.nix flakeE/flake.nix +nix flake metadata $flakeFollowsA + +nix flake update $flakeFollowsA + +oldLock="$(cat "$flakeFollowsA/flake.lock")" + +# Ensure that locking twice doesn't change anything + nix flake lock $flakeFollowsA +newLock="$(cat "$flakeFollowsA/flake.lock")" + +diff <(echo "$newLock") <(echo "$oldLock") + [[ $(jq -c .nodes.B.inputs.C $flakeFollowsA/flake.lock) = '"C"' ]] -[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["D"]' ]] +[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["foobar"]' ]] [[ $(jq -c .nodes.C.inputs.foobar $flakeFollowsA/flake.lock) = '["B","foobar"]' ]] +# Ensure removing follows from flake.nix removes them from the lockfile + +cat > $flakeFollowsA/flake.nix <<EOF +{ + description = "Flake A"; + inputs = { + B = { + url = "path:./flakeB"; + inputs.nonFlake.follows = "D"; + }; + D.url = "path:./flakeD"; + }; + outputs = { ... }: {}; +} +EOF + +nix flake lock $flakeFollowsA + +[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '"foobar"' ]] +jq -r -c '.nodes | keys | .[]' $flakeFollowsA/flake.lock | grep "^foobar$" + # Ensure a relative path is not allowed to go outside the store path cat > $flakeFollowsA/flake.nix <<EOF { description = "Flake A"; inputs = { - B.url = "path:./../../flakeB"; + B.url = "path:../flakeB"; }; outputs = { ... }: {}; } @@ -774,7 +824,7 @@ EOF git -C $flakeFollowsA add flake.nix -nix flake lock $flakeFollowsA 2>&1 | grep 'this is a security violation' +nix flake lock $flakeFollowsA 2>&1 | grep 'points outside' # Test flake in store does not evaluate rm -rf $badFlakeDir diff --git a/tests/function-trace.sh b/tests/function-trace.sh index 3b7f364e3..0b7f49d82 100755 --- a/tests/function-trace.sh +++ b/tests/function-trace.sh @@ -60,8 +60,6 @@ function-trace exited (string):1:1 at expect_trace '(x: x) 1 2' " function-trace entered (string):1:1 at function-trace exited (string):1:1 at -function-trace entered (string):1:1 at -function-trace exited (string):1:1 at " # Not a function diff --git a/tests/gc-non-blocking.sh b/tests/gc-non-blocking.sh new file mode 100644 index 000000000..0d781485d --- /dev/null +++ b/tests/gc-non-blocking.sh @@ -0,0 +1,33 @@ +# Test whether the collector is non-blocking, i.e. a build can run in +# parallel with it. +source common.sh + +needLocalStore "the GC test needs a synchronisation point" + +clearStore + +fifo=$TEST_ROOT/test.fifo +mkfifo "$fifo" + +dummy=$(nix store add-path ./simple.nix) + +running=$TEST_ROOT/running +touch $running + +(_NIX_TEST_GC_SYNC=$fifo nix-store --gc -vvvvv; rm $running) & +pid=$! + +sleep 2 + +outPath=$(nix-build --max-silent-time 60 -o "$TEST_ROOT/result" -E " + with import ./config.nix; + mkDerivation { + name = \"non-blocking\"; + buildCommand = \"set -x; test -e $running; mkdir \$out; echo > $fifo\"; + }") + +wait $pid + +(! test -e $running) +(! test -e $dummy) +test -e $outPath diff --git a/tests/gc.sh b/tests/gc.sh index cf0e2c32d..ad09a8b39 100644 --- a/tests/gc.sh +++ b/tests/gc.sh @@ -1,5 +1,7 @@ source common.sh +clearStore + drvPath=$(nix-instantiate dependencies.nix) outPath=$(nix-store -rvv "$drvPath") @@ -16,18 +18,24 @@ if nix-store --gc --print-dead | grep -E $outPath$; then false; fi nix-store --gc --print-dead -inUse=$(readLink $outPath/input-2) +inUse=$(readLink $outPath/reference-to-input-2) if nix-store --delete $inUse; then false; fi test -e $inUse if nix-store --delete $outPath; then false; fi test -e $outPath +for i in $NIX_STORE_DIR/*; do + if [[ $i =~ /trash ]]; then continue; fi # compat with old daemon + touch $i.lock + touch $i.chroot +done + nix-collect-garbage # Check that the root and its dependencies haven't been deleted. cat $outPath/foobar -cat $outPath/input-2/bar +cat $outPath/reference-to-input-2/bar # Check that the derivation has been GC'd. if test -e $drvPath; then false; fi @@ -38,3 +46,7 @@ nix-collect-garbage # Check that the output has been GC'd. if test -e $outPath/foobar; then false; fi + +# Check that the store is empty. +rmdir $NIX_STORE_DIR/.links +rmdir $NIX_STORE_DIR diff --git a/tests/lang/eval-okay-groupBy.exp b/tests/lang/eval-okay-groupBy.exp new file mode 100644 index 000000000..bfca5652a --- /dev/null +++ b/tests/lang/eval-okay-groupBy.exp @@ -0,0 +1 @@ +{ "1" = [ 9 ]; "2" = [ 8 ]; "3" = [ 13 29 ]; "4" = [ 3 4 10 11 17 18 ]; "5" = [ 0 23 26 28 ]; "6" = [ 1 12 21 27 30 ]; "7" = [ 7 22 ]; "8" = [ 14 ]; "9" = [ 19 ]; b = [ 16 25 ]; c = [ 24 ]; d = [ 2 ]; e = [ 5 6 15 31 ]; f = [ 20 ]; } diff --git a/tests/lang/eval-okay-groupBy.nix b/tests/lang/eval-okay-groupBy.nix new file mode 100644 index 000000000..862d89dbd --- /dev/null +++ b/tests/lang/eval-okay-groupBy.nix @@ -0,0 +1,5 @@ +with import ./lib.nix; + +builtins.groupBy (n: + builtins.substring 0 1 (builtins.hashString "sha256" (toString n)) +) (range 0 31) diff --git a/tests/lang/eval-okay-regression-20220122.exp b/tests/lang/eval-okay-regression-20220122.exp new file mode 100644 index 000000000..00750edc0 --- /dev/null +++ b/tests/lang/eval-okay-regression-20220122.exp @@ -0,0 +1 @@ +3 diff --git a/tests/lang/eval-okay-regression-20220122.nix b/tests/lang/eval-okay-regression-20220122.nix new file mode 100644 index 000000000..694e9a13b --- /dev/null +++ b/tests/lang/eval-okay-regression-20220122.nix @@ -0,0 +1 @@ +((_: _) 1) + ((__: __) 2) diff --git a/tests/lang/eval-okay-regression-20220125.exp b/tests/lang/eval-okay-regression-20220125.exp new file mode 100644 index 000000000..00750edc0 --- /dev/null +++ b/tests/lang/eval-okay-regression-20220125.exp @@ -0,0 +1 @@ +3 diff --git a/tests/lang/eval-okay-regression-20220125.nix b/tests/lang/eval-okay-regression-20220125.nix new file mode 100644 index 000000000..485502373 --- /dev/null +++ b/tests/lang/eval-okay-regression-20220125.nix @@ -0,0 +1,2 @@ +((__curPosFoo: __curPosFoo) 1) + ((__curPosBar: __curPosBar) 2) + diff --git a/tests/lang/eval-okay-sort.exp b/tests/lang/eval-okay-sort.exp index 148b93516..899119e20 100644 --- a/tests/lang/eval-okay-sort.exp +++ b/tests/lang/eval-okay-sort.exp @@ -1 +1 @@ -[ [ 42 77 147 249 483 526 ] [ 526 483 249 147 77 42 ] [ "bar" "fnord" "foo" "xyzzy" ] [ { key = 1; value = "foo"; } { key = 1; value = "fnord"; } { key = 2; value = "bar"; } ] ] +[ [ 42 77 147 249 483 526 ] [ 526 483 249 147 77 42 ] [ "bar" "fnord" "foo" "xyzzy" ] [ { key = 1; value = "foo"; } { key = 1; value = "fnord"; } { key = 2; value = "bar"; } ] [ [ ] [ ] [ 1 ] [ 1 4 ] [ 1 5 ] [ 1 6 ] [ 2 ] [ 2 3 ] [ 3 ] [ 3 ] ] ] diff --git a/tests/lang/eval-okay-sort.nix b/tests/lang/eval-okay-sort.nix index 8299c3a4a..50aa78e40 100644 --- a/tests/lang/eval-okay-sort.nix +++ b/tests/lang/eval-okay-sort.nix @@ -4,5 +4,17 @@ with builtins; (sort (x: y: y < x) [ 483 249 526 147 42 77 ]) (sort lessThan [ "foo" "bar" "xyzzy" "fnord" ]) (sort (x: y: x.key < y.key) - [ { key = 1; value = "foo"; } { key = 2; value = "bar"; } { key = 1; value = "fnord"; } ]) + [ { key = 1; value = "foo"; } { key = 2; value = "bar"; } { key = 1; value = "fnord"; } ]) + (sort lessThan [ + [ 1 6 ] + [ ] + [ 2 3 ] + [ 3 ] + [ 1 5 ] + [ 2 ] + [ 1 ] + [ ] + [ 1 4 ] + [ 3 ] + ]) ] diff --git a/tests/lang/eval-okay-xml.exp.xml b/tests/lang/eval-okay-xml.exp.xml index 92b75e0b8..20099326c 100644 --- a/tests/lang/eval-okay-xml.exp.xml +++ b/tests/lang/eval-okay-xml.exp.xml @@ -31,9 +31,9 @@ <attr name="f"> <function> <attrspat> - <attr name="z" /> <attr name="x" /> <attr name="y" /> + <attr name="z" /> </attrspat> </function> </attr> diff --git a/tests/lang/eval-okay-zipAttrsWith.exp b/tests/lang/eval-okay-zipAttrsWith.exp new file mode 100644 index 000000000..9c0b15d22 --- /dev/null +++ b/tests/lang/eval-okay-zipAttrsWith.exp @@ -0,0 +1 @@ +{ "0" = { n = "0"; v = [ 5 23 29 ]; }; "1" = { n = "1"; v = [ 7 30 ]; }; "2" = { n = "2"; v = [ 18 ]; }; "4" = { n = "4"; v = [ 10 ]; }; "5" = { n = "5"; v = [ 15 25 26 31 ]; }; "6" = { n = "6"; v = [ 3 14 ]; }; "7" = { n = "7"; v = [ 12 ]; }; "8" = { n = "8"; v = [ 2 6 8 9 ]; }; "9" = { n = "9"; v = [ 0 16 ]; }; a = { n = "a"; v = [ 17 21 22 27 ]; }; c = { n = "c"; v = [ 11 24 ]; }; d = { n = "d"; v = [ 4 13 28 ]; }; e = { n = "e"; v = [ 20 ]; }; f = { n = "f"; v = [ 1 19 ]; }; } diff --git a/tests/lang/eval-okay-zipAttrsWith.nix b/tests/lang/eval-okay-zipAttrsWith.nix new file mode 100644 index 000000000..877d4e5fa --- /dev/null +++ b/tests/lang/eval-okay-zipAttrsWith.nix @@ -0,0 +1,9 @@ +with import ./lib.nix; + +let + str = builtins.hashString "sha256" "test"; +in +builtins.zipAttrsWith + (n: v: { inherit n v; }) + (map (n: { ${builtins.substring n 1 str} = n; }) + (range 0 31)) diff --git a/tests/local-store.sh b/tests/local-store.sh index 4ec3d64b0..0247346f1 100644 --- a/tests/local-store.sh +++ b/tests/local-store.sh @@ -15,6 +15,5 @@ PATH1=$(nix path-info --store ./x $CORRECT_PATH) PATH2=$(nix path-info --store "$PWD/x" $CORRECT_PATH) [ $CORRECT_PATH == $PATH2 ] -# FIXME we could also test the query parameter version: -# PATH3=$(nix path-info --store "local?store=$PWD/x" $CORRECT_PATH) -# [ $CORRECT_PATH == $PATH3 ] +PATH3=$(nix path-info --store "local?root=$PWD/x" $CORRECT_PATH) +[ $CORRECT_PATH == $PATH3 ] diff --git a/tests/local.mk b/tests/local.mk index b100e7f15..53a9179a3 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -1,64 +1,102 @@ 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.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 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 \ + 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 \ + 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 \ - pure-eval.sh \ - check.sh \ - plugins.sh \ - search.sh \ + compression-levels.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 \ + 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 \ - compute-levels.sh \ - 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 - # parallel.sh + db-migration.sh \ + nix-profile.sh \ + pass-as-file.sh \ + describe-stores.sh \ + store-ping.sh + +ifeq ($(HAVE_LIBCPUID), 1) + nix_tests += compute-levels.sh +endif install-tests += $(foreach x, $(nix_tests), tests/$(x)) diff --git a/tests/multiple-outputs.sh b/tests/multiple-outputs.sh index 0bca12b42..0d45ad35b 100644 --- a/tests/multiple-outputs.sh +++ b/tests/multiple-outputs.sh @@ -76,7 +76,10 @@ if nix-build multiple-outputs.nix -A cyclic --no-out-link; then exit 1 fi +# Do a GC. This should leave an empty store. echo "collecting garbage..." rm $TEST_ROOT/result* nix-store --gc --keep-derivations --keep-outputs nix-store --gc --print-roots +rm -rf $NIX_STORE_DIR/.links +rmdir $NIX_STORE_DIR diff --git a/tests/nix-channel.sh b/tests/nix-channel.sh index 63c0f97ba..54b8f5979 100644 --- a/tests/nix-channel.sh +++ b/tests/nix-channel.sh @@ -35,16 +35,14 @@ grep -q 'item.*attrPath="foo".*name="dependencies-top"' $TEST_ROOT/meta.xml nix-env -i dependencies-top [ -e $TEST_HOME/.nix-profile/foobar ] -clearProfiles -rm -f $TEST_HOME/.nix-channels - # Test updating from a tarball -nix-channel --add file://$TEST_ROOT/foo/nixexprs.tar.bz2 foo +nix-channel --add file://$TEST_ROOT/foo/nixexprs.tar.bz2 bar nix-channel --update # Do a query. nix-env -qa \* --meta --xml --out-path > $TEST_ROOT/meta.xml grep -q 'meta.*description.*Random test package' $TEST_ROOT/meta.xml +grep -q 'item.*attrPath="bar".*name="dependencies-top"' $TEST_ROOT/meta.xml grep -q 'item.*attrPath="foo".*name="dependencies-top"' $TEST_ROOT/meta.xml # Do an install. diff --git a/tests/nix-shell.sh b/tests/nix-shell.sh index a31d35887..3241d7a0f 100644 --- a/tests/nix-shell.sh +++ b/tests/nix-shell.sh @@ -3,59 +3,53 @@ source common.sh clearStore if [[ -n ${CONTENT_ADDRESSED:-} ]]; then - nix-shell () { - command nix-shell --arg contentAddressed true "$@" - } - - nix_develop() { - nix develop --arg contentAddressed true "$@" - } + shellDotNix="$PWD/ca-shell.nix" else - nix_develop() { - nix develop "$@" - } + shellDotNix="$PWD/shell.nix" fi +export NIX_PATH=nixpkgs="$shellDotNix" + # Test nix-shell -A export IMPURE_VAR=foo export SELECTED_IMPURE_VAR=baz -export NIX_BUILD_SHELL=$SHELL -output=$(nix-shell --pure shell.nix -A shellDrv --run \ + +output=$(nix-shell --pure "$shellDotNix" -A shellDrv --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $TEST_inNixShell"') [ "$output" = " - foo - bar - true" ] # Test --keep -output=$(nix-shell --pure --keep SELECTED_IMPURE_VAR shell.nix -A shellDrv --run \ +output=$(nix-shell --pure --keep SELECTED_IMPURE_VAR "$shellDotNix" -A shellDrv --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $SELECTED_IMPURE_VAR"') [ "$output" = " - foo - bar - baz" ] # Test nix-shell on a .drv -[[ $(nix-shell --pure $(nix-instantiate shell.nix -A shellDrv) --run \ +[[ $(nix-shell --pure $(nix-instantiate "$shellDotNix" -A shellDrv) --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $TEST_inNixShell"') = " - foo - bar - false" ]] -[[ $(nix-shell --pure $(nix-instantiate shell.nix -A shellDrv) --run \ +[[ $(nix-shell --pure $(nix-instantiate "$shellDotNix" -A shellDrv) --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $TEST_inNixShell"') = " - foo - bar - false" ]] # Test nix-shell on a .drv symlink # Legacy: absolute path and .drv extension required -nix-instantiate shell.nix -A shellDrv --add-root $TEST_ROOT/shell.drv +nix-instantiate "$shellDotNix" -A shellDrv --add-root $TEST_ROOT/shell.drv [[ $(nix-shell --pure $TEST_ROOT/shell.drv --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX"') = " - foo - bar" ]] # New behaviour: just needs to resolve to a derivation in the store -nix-instantiate shell.nix -A shellDrv --add-root $TEST_ROOT/shell +nix-instantiate "$shellDotNix" -A shellDrv --add-root $TEST_ROOT/shell [[ $(nix-shell --pure $TEST_ROOT/shell --run \ 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX"') = " - foo - bar" ]] # Test nix-shell -p -output=$(NIX_PATH=nixpkgs=shell.nix nix-shell --pure -p foo bar --run 'echo "$(foo) $(bar)"') +output=$(NIX_PATH=nixpkgs="$shellDotNix" nix-shell --pure -p foo bar --run 'echo "$(foo) $(bar)"') [ "$output" = "foo bar" ] # Test nix-shell -p --arg x y -output=$(NIX_PATH=nixpkgs=shell.nix nix-shell --pure -p foo --argstr fooContents baz --run 'echo "$(foo)"') +output=$(NIX_PATH=nixpkgs="$shellDotNix" nix-shell --pure -p foo --argstr fooContents baz --run 'echo "$(foo)"') [ "$output" = "baz" ] # Test nix-shell shebang mode @@ -91,18 +85,18 @@ output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.rb abc ruby) [ "$output" = '-e load(ARGV.shift) -- '"$TEST_ROOT"'/spaced \'\''"shell.shebang.rb abc ruby' ] # Test 'nix develop'. -nix_develop -f shell.nix shellDrv -c bash -c '[[ -n $stdenv ]]' +nix develop -f "$shellDotNix" shellDrv -c bash -c '[[ -n $stdenv ]]' # Ensure `nix develop -c` preserves stdin -echo foo | nix develop -f shell.nix shellDrv -c cat | grep -q foo +echo foo | nix develop -f "$shellDotNix" shellDrv -c cat | grep -q foo # Ensure `nix develop -c` actually executes the command if stdout isn't a terminal -nix_develop -f shell.nix shellDrv -c echo foo |& grep -q foo +nix develop -f "$shellDotNix" shellDrv -c echo foo |& grep -q foo # Test 'nix print-dev-env'. -[[ $(nix print-dev-env -f shell.nix shellDrv --json | jq -r .variables.arr1.value[2]) = '3 4' ]] +[[ $(nix print-dev-env -f "$shellDotNix" shellDrv --json | jq -r .variables.arr1.value[2]) = '3 4' ]] -source <(nix print-dev-env -f shell.nix shellDrv) +source <(nix print-dev-env -f "$shellDotNix" shellDrv) [[ -n $stdenv ]] [[ ${arr1[2]} = "3 4" ]] [[ ${arr2[1]} = $'\n' ]] diff --git a/tests/nix_path.sh b/tests/nix_path.sh new file mode 100644 index 000000000..d3657abf0 --- /dev/null +++ b/tests/nix_path.sh @@ -0,0 +1,11 @@ +# Regression for https://github.com/NixOS/nix/issues/5998 and https://github.com/NixOS/nix/issues/5980 + +source common.sh + +export NIX_PATH=non-existent=/non-existent/but-unused-anyways:by-absolute-path=$PWD:by-relative-path=. + +nix-instantiate --eval -E '<by-absolute-path/simple.nix>' --restrict-eval +nix-instantiate --eval -E '<by-relative-path/simple.nix>' --restrict-eval + +# Should ideally also test this, but there’s no pure way to do it, so just trust me that it works +# nix-instantiate --eval -E '<nixpkgs>' -I nixpkgs=channel:nixos-unstable --restrict-eval diff --git a/tests/nss-preload.nix b/tests/nss-preload.nix new file mode 100644 index 000000000..2610d2b30 --- /dev/null +++ b/tests/nss-preload.nix @@ -0,0 +1,123 @@ +{ nixpkgs, system, overlay }: + +with import (nixpkgs + "/nixos/lib/testing-python.nix") { + inherit system; + extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ]; +}; + +makeTest ( + +rec { + name = "nss-preload"; + + nodes = { + http_dns = { lib, pkgs, config, ... }: { + networking.firewall.enable = false; + networking.interfaces.eth1.ipv6.addresses = lib.mkForce [ + { address = "fd21::1"; prefixLength = 64; } + ]; + networking.interfaces.eth1.ipv4.addresses = lib.mkForce [ + { address = "192.168.0.1"; prefixLength = 24; } + ]; + + services.unbound = { + enable = true; + enableRootTrustAnchor = false; + settings = { + server = { + interface = [ "192.168.0.1" "fd21::1" "::1" "127.0.0.1" ]; + access-control = [ "192.168.0.0/24 allow" "fd21::/64 allow" "::1 allow" "127.0.0.0/8 allow" ]; + local-data = [ + ''"example.com. IN A 192.168.0.1"'' + ''"example.com. IN AAAA fd21::1"'' + ''"tarballs.nixos.org. IN A 192.168.0.1"'' + ''"tarballs.nixos.org. IN AAAA fd21::1"'' + ]; + }; + }; + }; + + services.nginx = { + enable = true; + virtualHosts."example.com" = { + root = pkgs.runCommand "testdir" {} '' + mkdir "$out" + echo hello world > "$out/index.html" + ''; + }; + }; + }; + + # client consumes a remote resolver + client = { lib, nodes, pkgs, ... }: { + networking.useDHCP = false; + networking.nameservers = [ + (lib.head nodes.http_dns.config.networking.interfaces.eth1.ipv6.addresses).address + (lib.head nodes.http_dns.config.networking.interfaces.eth1.ipv4.addresses).address + ]; + networking.interfaces.eth1.ipv6.addresses = [ + { address = "fd21::10"; prefixLength = 64; } + ]; + networking.interfaces.eth1.ipv4.addresses = [ + { address = "192.168.0.10"; prefixLength = 24; } + ]; + + nix.sandboxPaths = lib.mkForce []; + nix.binaryCaches = lib.mkForce []; + nix.useSandbox = lib.mkForce true; + }; + }; + + nix-fetch = pkgs.writeText "fetch.nix" '' + derivation { + # This derivation is an copy from what is available over at + # nix.git:corepkgs/fetchurl.nix + builder = "builtin:fetchurl"; + + # We're going to fetch data from the http_dns instance created before + # we expect the content to be the same as the content available there. + # ``` + # $ nix-hash --type sha256 --to-base32 $(echo "hello world" | sha256sum | cut -d " " -f 1) + # 0ix4jahrkll5zg01wandq78jw3ab30q4nscph67rniqg5x7r0j59 + # ``` + outputHash = "0ix4jahrkll5zg01wandq78jw3ab30q4nscph67rniqg5x7r0j59"; + outputHashAlgo = "sha256"; + outputHashMode = "flat"; + + name = "example.com"; + url = "http://example.com"; + + unpack = false; + executable = false; + + system = "builtin"; + + preferLocalBuild = true; + + impureEnvVars = [ + "http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy" + ]; + + urls = [ "http://example.com" ]; + } + ''; + + testScript = { nodes, ... }: '' + http_dns.wait_for_unit("nginx") + http_dns.wait_for_open_port(80) + http_dns.wait_for_unit("unbound") + http_dns.wait_for_open_port(53) + + client.start() + client.wait_for_unit('multi-user.target') + + with subtest("can fetch data from a remote server outside sandbox"): + client.succeed("nix --version >&2") + client.succeed("curl -vvv http://example.com/index.html >&2") + + with subtest("nix-build can lookup dns and fetch data"): + client.succeed(""" + nix-build ${nix-fetch} >&2 + """) + ''; +}) diff --git a/tests/plugins/plugintest.cc b/tests/plugins/plugintest.cc index c085d3329..cd7c9f8b1 100644 --- a/tests/plugins/plugintest.cc +++ b/tests/plugins/plugintest.cc @@ -16,9 +16,9 @@ static GlobalConfig::Register rs(&mySettings); static void prim_anotherNull (EvalState & state, const Pos & pos, Value ** args, Value & v) { if (mySettings.settingSet) - mkNull(v); + v.mkNull(); else - mkBool(v, false); + v.mkBool(false); } static RegisterPrimOp rp("anotherNull", 0, prim_anotherNull); diff --git a/tests/pure-eval.sh b/tests/pure-eval.sh index c994fbb98..1a4568ea6 100644 --- a/tests/pure-eval.sh +++ b/tests/pure-eval.sh @@ -6,7 +6,13 @@ nix eval --expr 'assert 1 + 2 == 3; true' [[ $(nix eval --impure --expr 'builtins.readFile ./pure-eval.sh') =~ clearStore ]] -(! nix eval --expr 'builtins.readFile ./pure-eval.sh') +missingImpureErrorMsg=$(! nix eval --expr 'builtins.readFile ./pure-eval.sh' 2>&1) + +echo "$missingImpureErrorMsg" | grep -q -- --impure || \ + fail "The error message should mention the “--impure” flag to unblock users" + +[[ $(nix eval --expr 'builtins.pathExists ./pure-eval.sh') == false ]] || \ + fail "Calling 'pathExists' on a non-authorised path should return false" (! nix eval --expr builtins.currentTime) (! nix eval --expr builtins.currentSystem) diff --git a/tests/readfile-context.builder.sh b/tests/readfile-context.builder.sh new file mode 100644 index 000000000..7084a08cb --- /dev/null +++ b/tests/readfile-context.builder.sh @@ -0,0 +1 @@ +echo "$input" > $out diff --git a/tests/readfile-context.nix b/tests/readfile-context.nix new file mode 100644 index 000000000..600036a94 --- /dev/null +++ b/tests/readfile-context.nix @@ -0,0 +1,19 @@ +with import ./config.nix; + +let + + input = import ./simple.nix; + + dependent = mkDerivation { + name = "dependent"; + builder = ./readfile-context.builder.sh; + input = "${input}/hello"; + }; + + readDependent = mkDerivation { + name = "read-dependent"; + builder = ./readfile-context.builder.sh; + input = builtins.readFile dependent; + }; + +in readDependent diff --git a/tests/readfile-context.sh b/tests/readfile-context.sh new file mode 100644 index 000000000..31e70ddb1 --- /dev/null +++ b/tests/readfile-context.sh @@ -0,0 +1,16 @@ +source common.sh + +clearStore + +outPath=$(nix-build --no-out-link readfile-context.nix) + +# Set a GC root. +ln -s $outPath "$NIX_STATE_DIR"/gcroots/foo + +# Check that file exists. +[ "$(cat $(cat $outPath))" = "Hello World!" ] + +nix-collect-garbage + +# Check that file still exists. +[ "$(cat $(cat $outPath))" = "Hello World!" ] diff --git a/tests/repair.sh b/tests/repair.sh index 12dcde8ea..c8f07b1c6 100644 --- a/tests/repair.sh +++ b/tests/repair.sh @@ -30,7 +30,7 @@ nix-store --verify-path $path2 chmod u+w $path2 touch $path2/bad -nix-store --delete $(nix-store -qd $path2) +nix-store --delete $(nix-store -q --referrers-closure $(nix-store -qd $path2)) (! nix-store --verify --check-contents --repair) @@ -74,3 +74,50 @@ if [ "$(nix-hash $path2)" != "$hash" -o -e $path2/bad ]; then echo "path not repaired properly" >&2 exit 1 fi + +# Check that --repair-path also checks content of optimised symlinks (1/2) +nix-store --verify-path $path2 + +if (! nix-store --optimize); then + echo "nix-store --optimize failed to optimize the store" >&2 + exit 1 +fi +chmod u+w $path2/bar +echo 'rabrab' > $path2/bar # different length + +if nix-store --verify-path $path2; then + echo "nix-store --verify-path did not detect .links file corruption" >&2 + exit 1 +fi + +nix-store --repair-path $path2 --option auto-optimise-store true + +if [ "$(nix-hash $path2)" != "$hash" -o "BAR" != "$(< $path2/bar)" ]; then + echo "path not repaired properly" >&2 + exit 1 +fi + +# Check that --repair-path also checks content of optimised symlinks (2/2) +nix-store --verify-path $path2 + +if (! nix-store --optimize); then + echo "nix-store --optimize failed to optimize the store" >&2 + exit 1 +fi +chmod u+w $path2 +chmod u+w $path2/bar +sed -e 's/./X/g' < $path2/bar > $path2/tmp # same length, different content. +cp $path2/tmp $path2/bar +rm $path2/tmp + +if nix-store --verify-path $path2; then + echo "nix-store --verify-path did not detect .links file corruption" >&2 + exit 1 +fi + +nix-store --repair-path $path2 --substituters "file://$cacheDir" --no-require-sigs --option auto-optimise-store true + +if [ "$(nix-hash $path2)" != "$hash" -o "BAR" != "$(< $path2/bar)" ]; then + echo "path not repaired properly" >&2 + exit 1 +fi diff --git a/tests/repl.sh b/tests/repl.sh index 4e3059517..6505f1741 100644 --- a/tests/repl.sh +++ b/tests/repl.sh @@ -1,18 +1,65 @@ source common.sh replCmds=" +simple = 1 simple = import ./simple.nix :b simple +:log simple +" + +replFailingCmds=" +failing = import ./simple-failing.nix +:b failing +:log failing +" + +replUndefinedVariable=" +import ./undefined-variable.nix " testRepl () { local nixArgs=("$@") - local outPath=$(nix repl "${nixArgs[@]}" <<< "$replCmds" |& + local replOutput="$(nix repl "${nixArgs[@]}" <<< "$replCmds")" + echo "$replOutput" + local outPath=$(echo "$replOutput" |& grep -o -E "$NIX_STORE_DIR/\w*-simple") nix path-info "${nixArgs[@]}" "$outPath" + # simple.nix prints a PATH during build + echo "$replOutput" | grep -qs 'PATH=' || fail "nix repl :log doesn't output logs" + local replOutput="$(nix repl "${nixArgs[@]}" <<< "$replFailingCmds" 2>&1)" + echo "$replOutput" + echo "$replOutput" | grep -qs 'This should fail' \ + || fail "nix repl :log doesn't output logs for a failed derivation" + local replOutput="$(nix repl --show-trace "${nixArgs[@]}" <<< "$replUndefinedVariable" 2>&1)" + echo "$replOutput" + echo "$replOutput" | grep -qs "while evaluating the file" \ + || fail "nix repl --show-trace doesn't show the trace" } # Simple test, try building a drv 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/search.sh b/tests/search.sh index ee3261687..52e12f381 100644 --- a/tests/search.sh +++ b/tests/search.sh @@ -23,3 +23,16 @@ clearCache nix search -f search.nix '' |grep -q foo nix search -f search.nix '' |grep -q bar nix search -f search.nix '' |grep -q hello + +## Tests for multiple regex/match highlighting + +e=$'\x1b' # grep doesn't support \e, \033 or even \x1b +# Multiple overlapping regexes +(( $(nix search -f search.nix '' 'oo' 'foo' 'oo' | grep "$e\[32;1mfoo$e\\[0;1m" | wc -l) == 1 )) +(( $(nix search -f search.nix '' 'broken b' 'en bar' | grep "$e\[32;1mbroken bar$e\\[0m" | wc -l) == 1 )) + +# Multiple matches +# Searching for 'o' should yield the 'o' in 'broken bar', the 'oo' in foo and 'o' in hello +(( $(nix search -f search.nix '' 'o' | grep -Eo "$e\[32;1mo{1,2}$e\[(0|0;1)m" | wc -l) == 3 )) +# Searching for 'b' should yield the 'b' in bar and the two 'b's in 'broken bar' +(( $(nix search -f search.nix '' 'b' | grep -Eo "$e\[32;1mb$e\[(0|0;1)m" | wc -l) == 3 )) diff --git a/tests/shell.nix b/tests/shell.nix index 4912d295a..92d94fbc2 100644 --- a/tests/shell.nix +++ b/tests/shell.nix @@ -74,6 +74,10 @@ let pkgs = rec { ''; bash = shell; + bashInteractive = runCommand "bash" {} '' + mkdir -p $out/bin + ln -s ${shell} $out/bin/bash + ''; # ruby "interpreter" that outputs "$@" ruby = runCommand "ruby" {} '' diff --git a/tests/simple-failing.nix b/tests/simple-failing.nix new file mode 100644 index 000000000..d176c9c51 --- /dev/null +++ b/tests/simple-failing.nix @@ -0,0 +1,12 @@ +with import ./config.nix; + +mkDerivation { + name = "simple-failing"; + builder = builtins.toFile "builder.sh" + '' + echo "This should fail" + exit 1 + ''; + PATH = ""; + goodPath = path; +} diff --git a/tests/simple.sh b/tests/simple.sh index 15bd2bd16..50d44f93f 100644 --- a/tests/simple.sh +++ b/tests/simple.sh @@ -25,3 +25,9 @@ if test "$outPath" != "/foo/lfy1s6ca46rm5r6w4gg9hc0axiakjcnm-dependencies.drv"; echo "hashDerivationModulo appears broken, got $outPath" exit 1 fi + +outPath="$(NIX_REMOTE=local?store=/foo\&real=$TEST_ROOT/real-store nix-instantiate --readonly-mode big-derivation-attr.nix)" +if test "$outPath" != "/foo/xxiwa5zlaajv6xdjynf9yym9g319d6mn-big-derivation-attr.drv"; then + echo "big-derivation-attr.nix hash appears broken, got $outPath. Memory corruption in large drv attr?" + exit 1 +fi diff --git a/tests/sourcehut-flakes.nix b/tests/sourcehut-flakes.nix new file mode 100644 index 000000000..d1d89d149 --- /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 '${nixpkgs.rev} refs/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/store-ping.sh b/tests/store-ping.sh new file mode 100644 index 000000000..f9427cf0a --- /dev/null +++ b/tests/store-ping.sh @@ -0,0 +1,13 @@ +source common.sh + +STORE_INFO=$(nix store ping 2>&1) + +echo "$STORE_INFO" | grep "Store URL: ${NIX_REMOTE}" + +if [[ -v NIX_DAEMON_PACKAGE ]] && isDaemonNewer "2.7.0pre20220126"; then + DAEMON_VERSION=$($NIX_DAEMON_PACKAGE/bin/nix-daemon --version | cut -d' ' -f3) + echo "$STORE_INFO" | grep "Version: $DAEMON_VERSION" +fi + +expect 127 NIX_REMOTE=unix:$PWD/store nix store ping || \ + fail "nix store ping on a non-existent store should fail" diff --git a/tests/structured-attrs.sh b/tests/structured-attrs.sh index e585ce37f..378dbc735 100644 --- a/tests/structured-attrs.sh +++ b/tests/structured-attrs.sh @@ -2,7 +2,7 @@ source common.sh # 27ce722638 required some incompatible changes to the nix file, so skip this # tests for the older versions -requireDaemonNewerThan "2.4pre20210622" +requireDaemonNewerThan "2.4pre20210712" clearStore diff --git a/tests/undefined-variable.nix b/tests/undefined-variable.nix new file mode 100644 index 000000000..579985497 --- /dev/null +++ b/tests/undefined-variable.nix @@ -0,0 +1 @@ +let f = builtins.toFile "test-file.nix" "asd"; in import f diff --git a/tests/user-envs.nix b/tests/user-envs.nix index 43eff1a68..6ac896ed8 100644 --- a/tests/user-envs.nix +++ b/tests/user-envs.nix @@ -9,7 +9,8 @@ assert foo == "foo"; let makeDrv = name: progName: (mkDerivation { - inherit name progName system; + name = assert progName != "fail"; name; + inherit progName system; builder = ./user-envs.builder.sh; } // { meta = { @@ -26,4 +27,5 @@ in (makeDrv "foo-2.0" "foo") (makeDrv "bar-0.1.1" "bar") (makeDrv "foo-0.1" "foo" // { meta.priority = 10; }) + (makeDrv "fail-0.1" "fail") ] diff --git a/tests/why-depends.sh b/tests/why-depends.sh new file mode 100644 index 000000000..c12941e76 --- /dev/null +++ b/tests/why-depends.sh @@ -0,0 +1,21 @@ +source common.sh + +clearStore + +cp ./dependencies.nix ./dependencies.builder0.sh ./config.nix $TEST_HOME + +cd $TEST_HOME + +nix-build ./dependencies.nix -A input0_drv -o dep +nix-build ./dependencies.nix -o toplevel + +FAST_WHY_DEPENDS_OUTPUT=$(nix why-depends ./toplevel ./dep) +PRECISE_WHY_DEPENDS_OUTPUT=$(nix why-depends ./toplevel ./dep --precise) + +# Both outputs should show that `input-2` is in the dependency chain +echo "$FAST_WHY_DEPENDS_OUTPUT" | grep -q input-2 +echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grep -q input-2 + +# But only the “precise” one should refere to `reference-to-input-2` +echo "$FAST_WHY_DEPENDS_OUTPUT" | (! grep -q reference-to-input-2) +echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grep -q reference-to-input-2 |