aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-11-03 17:43:40 +0100
committerEelco Dolstra <edolstra@gmail.com>2022-11-03 17:43:40 +0100
commitb95faccf03e5213b6087626ab8d46e0704aad6b5 (patch)
treef9d560f2004f951d8efbf1024292a88366d8efd7 /tests
parent47dec825c5daeeb9d615eb4d1eead3dbaa06c7c9 (diff)
parentdd1970c233a82328445b69e903574e14115ee933 (diff)
Merge remote-tracking branch 'origin/master' into auto-uid-allocation
Diffstat (limited to 'tests')
-rw-r--r--tests/bash-profile.sh9
-rw-r--r--tests/binary-cache.sh2
-rw-r--r--tests/build-dry.sh23
-rw-r--r--tests/build-hook-ca-fixed.nix10
-rw-r--r--tests/build-hook.nix10
-rw-r--r--tests/build-remote-content-addressed-floating.sh2
-rw-r--r--tests/build-remote.sh17
-rw-r--r--tests/build.sh57
-rw-r--r--tests/ca-shell.nix2
-rw-r--r--tests/ca/build-dry.sh6
-rw-r--r--tests/ca/build.sh2
-rw-r--r--tests/ca/common.sh2
-rw-r--r--tests/ca/content-addressed.nix7
-rw-r--r--tests/ca/duplicate-realisation-in-closure.sh2
-rwxr-xr-xtests/ca/nix-copy.sh3
-rwxr-xr-xtests/ca/nix-run.sh2
-rwxr-xr-xtests/ca/nix-shell.sh2
-rwxr-xr-xtests/ca/post-hook.sh2
-rwxr-xr-xtests/ca/recursive.sh2
-rwxr-xr-xtests/ca/selfref-gc.sh11
-rw-r--r--tests/ca/signatures.sh3
-rw-r--r--tests/ca/substitute.sh3
-rw-r--r--tests/check.sh14
-rw-r--r--tests/common.sh.in46
-rw-r--r--tests/completions.sh62
-rw-r--r--tests/eval.nix5
-rw-r--r--tests/eval.sh31
-rw-r--r--tests/fetchClosure.sh70
-rw-r--r--tests/fetchGit.sh47
-rw-r--r--tests/fetchMercurial.sh10
-rw-r--r--tests/fetchPath.sh6
-rw-r--r--tests/fetchTree-file.sh105
-rw-r--r--tests/fetchurl.sh4
-rw-r--r--tests/flakes/bundle.sh (renamed from tests/flake-bundler.sh)9
-rw-r--r--tests/flakes/check.sh89
-rw-r--r--tests/flakes/circular.sh49
-rw-r--r--tests/flakes/common.sh73
-rw-r--r--tests/flakes/config.sh (renamed from tests/flake-local-settings.sh)5
-rw-r--r--tests/flakes/flakes.sh (renamed from tests/flakes.sh)426
-rw-r--r--tests/flakes/follow-paths.sh150
-rw-r--r--tests/flakes/init.sh87
-rw-r--r--tests/flakes/mercurial.sh46
-rw-r--r--tests/flakes/run.sh29
-rw-r--r--tests/flakes/search-root.sh (renamed from tests/flake-searching.sh)24
-rw-r--r--tests/fmt.sh35
-rwxr-xr-xtests/fmt.simple.sh1
-rw-r--r--tests/github-flakes.nix106
-rw-r--r--tests/impure-derivations.nix63
-rw-r--r--tests/impure-derivations.sh57
-rw-r--r--tests/installer/default.nix220
-rw-r--r--tests/installer/vagrant_insecure_key27
-rw-r--r--tests/lang.sh13
-rw-r--r--tests/lang/eval-okay-eq.exp1
-rw-r--r--tests/lang/eval-okay-eq.exp.disabled1
-rw-r--r--tests/lang/eval-okay-fromjson.nix49
-rw-r--r--tests/lang/eval-okay-versions.nix3
-rw-r--r--tests/lang/parse-fail-eof-in-string.nix3
-rw-r--r--tests/local.mk34
-rw-r--r--tests/logging.sh11
-rw-r--r--tests/multiple-outputs.nix7
-rw-r--r--tests/nix-copy-closure.nix4
-rw-r--r--tests/nix-profile.sh143
-rw-r--r--tests/nix-shell.sh8
-rw-r--r--tests/nss-preload.nix70
-rw-r--r--tests/path-from-hash-part.sh10
-rw-r--r--tests/plugins.sh5
-rw-r--r--tests/plugins/plugintest.cc2
-rw-r--r--tests/post-hook.sh6
-rw-r--r--tests/pure-eval.sh2
-rwxr-xr-xtests/push-to-store.sh4
-rw-r--r--tests/remote-builds.nix2
-rw-r--r--tests/repl.sh76
-rw-r--r--tests/search.sh14
-rw-r--r--tests/selfref-gc.sh30
-rw-r--r--tests/setuid.nix4
-rw-r--r--tests/shell-hello.nix11
-rw-r--r--tests/shell.sh4
-rw-r--r--tests/signing.sh2
-rw-r--r--tests/sourcehut-flakes.nix15
-rw-r--r--tests/suggestions.sh44
-rw-r--r--tests/tarball.sh4
-rw-r--r--tests/user-envs.nix3
-rw-r--r--tests/user-envs.sh11
83 files changed, 2069 insertions, 602 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..5f29239dc 100644
--- a/tests/build-dry.sh
+++ b/tests/build-dry.sh
@@ -18,9 +18,6 @@ nix-build --no-out-link dependencies.nix --dry-run 2>&1 | grep "will be built"
# Now new command:
nix build -f dependencies.nix --dry-run 2>&1 | grep "will be built"
-# TODO: XXX: FIXME: #1793
-# Disable this part of the test until the problem is resolved:
-if [ -n "$ISSUE_1795_IS_FIXED" ]; then
clearStore
clearCache
@@ -28,7 +25,6 @@ clearCache
nix build -f dependencies.nix --dry-run 2>&1 | grep "will be built"
# Now old command:
nix-build --no-out-link dependencies.nix --dry-run 2>&1 | grep "will be built"
-fi
###################################################
# Check --dry-run doesn't create links with --dry-run
@@ -50,3 +46,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..e83b42b41 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"
CONTENT_ADDRESSED=true
diff --git a/tests/build-remote.sh b/tests/build-remote.sh
index 806c6d261..e73c37ea4 100644
--- a/tests/build-remote.sh
+++ b/tests/build-remote.sh
@@ -34,6 +34,14 @@ outPath=$(readlink -f $TEST_ROOT/result)
grep 'FOO BAR BAZ' $TEST_ROOT/machine0/$outPath
+testPrintOutPath=$(nix build -L -v -f $file --no-link --print-out-paths --max-jobs 0 \
+ --arg busybox $busybox \
+ --store $TEST_ROOT/machine0 \
+ --builders "$(join_by '; ' "${builders[@]}")"
+)
+
+[[ $testPrintOutPath =~ store.*build-remote ]]
+
set -o pipefail
# Ensure that input1 was built on store1 due to the required feature.
@@ -54,8 +62,17 @@ 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 \
+ --no-out-link \
--builders "$(join_by '; ' "${builders[@]}")" \
--keep-failed \
--store $TEST_ROOT/machine0 \
diff --git a/tests/build.sh b/tests/build.sh
index c77f620f7..fc6825e25 100644
--- a/tests/build.sh
+++ b/tests/build.sh
@@ -1,15 +1,68 @@
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"}}]'
-nix build -f multiple-outputs.nix --json a.all b.all --no-link | jq --exit-status '
+clearStore
+
+set -o pipefail
+
+# Make sure that 'nix build' returns all outputs by default.
+nix build -f multiple-outputs.nix --json a b --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")))
'
+
+# Test output selection using the '^' syntax.
+nix build -f multiple-outputs.nix --json a^first --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-a.drv")) and
+ (.outputs | keys == ["first"]))
+'
+
+nix build -f multiple-outputs.nix --json a^second,first --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-a.drv")) and
+ (.outputs | keys == ["first", "second"]))
+'
+
+nix build -f multiple-outputs.nix --json 'a^*' --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-a.drv")) and
+ (.outputs | keys == ["first", "second"]))
+'
+
+# Test that 'outputsToInstall' is respected by default.
+nix build -f multiple-outputs.nix --json e --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-e.drv")) and
+ (.outputs | keys == ["a", "b"]))
+'
+
+# But not when it's overriden.
+nix build -f multiple-outputs.nix --json e^a --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-e.drv")) and
+ (.outputs | keys == ["a"]))
+'
+
+nix build -f multiple-outputs.nix --json 'e^*' --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-e.drv")) and
+ (.outputs | keys == ["a", "b", "c"]))
+'
+
+# Make sure that `--impure` works (regression test for https://github.com/NixOS/nix/issues/6488)
+nix build --impure -f multiple-outputs.nix --json e --no-link | jq --exit-status '
+ (.[0] |
+ (.drvPath | match(".*multiple-outputs-e.drv")) and
+ (.outputs | keys == ["a", "b"]))
+'
+
testNormalization () {
clearStore
outPath=$(nix-build ./simple.nix --no-out-link)
diff --git a/tests/ca-shell.nix b/tests/ca-shell.nix
index ad2ab6aff..36e1d1526 100644
--- a/tests/ca-shell.nix
+++ b/tests/ca-shell.nix
@@ -1 +1 @@
-{ ... }@args: import ./shell.nix (args // { contentAddressed = true; })
+{ inNixShell ? false, ... }@args: import ./shell.nix (args // { contentAddressed = true; })
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..b104b5a78 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"
restartDaemon
diff --git a/tests/ca/content-addressed.nix b/tests/ca/content-addressed.nix
index d328fc92c..81bc4bf5c 100644
--- a/tests/ca/content-addressed.nix
+++ b/tests/ca/content-addressed.nix
@@ -23,7 +23,7 @@ rec {
};
rootCA = mkCADerivation {
name = "rootCA";
- outputs = [ "out" "dev" "foo"];
+ outputs = [ "out" "dev" "foo" ];
buildCommand = ''
echo "building a CA derivation"
echo "The seed is ${toString seed}"
@@ -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
@@ -76,7 +75,7 @@ rec {
buildCommand = ''
mkdir -p $out/bin
echo ${rootCA} # Just to make it depend on it
- echo "" > $out/bin/${name}
+ echo "#! ${shell}" > $out/bin/${name}
chmod +x $out/bin/${name}
'';
};
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/selfref-gc.sh b/tests/ca/selfref-gc.sh
new file mode 100755
index 000000000..248778894
--- /dev/null
+++ b/tests/ca/selfref-gc.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+source common.sh
+
+requireDaemonNewerThan "2.4pre20210626"
+
+enableFeatures "ca-derivations nix-command flakes"
+
+export NIX_TESTS_CA_BY_DEFAULT=1
+cd ..
+source ./selfref-gc.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/ca/substitute.sh b/tests/ca/substitute.sh
index 3d9001bb8..819f3fd85 100644
--- a/tests/ca/substitute.sh
+++ b/tests/ca/substitute.sh
@@ -25,7 +25,8 @@ buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0 transi
# Check that the thing we’ve just substituted has its realisation stored
nix realisation info --file ./content-addressed.nix transitivelyDependentCA
# Check that its dependencies have it too
-nix realisation info --file ./content-addressed.nix dependentCA rootCA
+nix realisation info --file ./content-addressed.nix dependentCA
+# nix realisation info --file ./content-addressed.nix rootCA --outputs out
# Same thing, but
# 1. With non-ca derivations
diff --git a/tests/check.sh b/tests/check.sh
index ab48ff865..495202781 100644
--- a/tests/check.sh
+++ b/tests/check.sh
@@ -40,6 +40,14 @@ nix-build check.nix -A deterministic --argstr checkBuildId $checkBuildId \
if grep -q 'may not be deterministic' $TEST_ROOT/log; then false; fi
checkBuildTempDirRemoved $TEST_ROOT/log
+nix build -f check.nix deterministic --rebuild --repeat 1 \
+ --argstr checkBuildId $checkBuildId --keep-failed --no-link \
+ 2> $TEST_ROOT/log
+if grep -q 'checking is not possible' $TEST_ROOT/log; then false; fi
+# Repeat is set to 1, ie. nix should build deterministic twice.
+if [ "$(grep "checking outputs" $TEST_ROOT/log | wc -l)" -ne 2 ]; then false; fi
+checkBuildTempDirRemoved $TEST_ROOT/log
+
nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \
--no-out-link 2> $TEST_ROOT/log
checkBuildTempDirRemoved $TEST_ROOT/log
@@ -50,6 +58,12 @@ grep 'may not be deterministic' $TEST_ROOT/log
[ "$status" = "104" ]
checkBuildTempDirRemoved $TEST_ROOT/log
+nix build -f check.nix nondeterministic --rebuild --repeat 1 \
+ --argstr checkBuildId $checkBuildId --keep-failed --no-link \
+ 2> $TEST_ROOT/log || status=$?
+grep 'may not be deterministic' $TEST_ROOT/log
+checkBuildTempDirRemoved $TEST_ROOT/log
+
nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \
--no-out-link --check --keep-failed 2> $TEST_ROOT/log || status=$?
grep 'may not be deterministic' $TEST_ROOT/log
diff --git a/tests/common.sh.in b/tests/common.sh.in
index e485329ba..73c2d2309 100644
--- a/tests/common.sh.in
+++ b/tests/common.sh.in
@@ -50,6 +50,8 @@ export busybox="@sandbox_shell@"
export version=@PACKAGE_VERSION@
export system=@system@
+export BUILD_SHARED_LIBS=@BUILD_SHARED_LIBS@
+
export IMPURE_VAR1=foo
export IMPURE_VAR2=bar
@@ -87,8 +89,7 @@ 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&
pidDaemon=$!
@@ -109,20 +110,20 @@ startDaemon() {
killDaemon() {
kill $pidDaemon
for i in {0..100}; do
- kill -0 $pidDaemon || break
+ 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
}
restartDaemon() {
- [[ -z "${pidDaemon:-}" ]] && return 0
+ [[ -z "${pidDaemon:-}" ]] && return 0
- killDaemon
- unset NIX_REMOTE
- startDaemon
+ killDaemon
+ unset NIX_REMOTE
+ startDaemon
}
if [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true; then
@@ -158,11 +159,12 @@ expect() {
local expected res
expected="$1"
shift
- set +e
- "$@"
- res="$?"
- set -e
- [[ $res -eq $expected ]]
+ "$@" || res="$?"
+ if [[ $res -ne $expected ]]; then
+ echo "Expected '$expected' but got '$res' while running '$*'"
+ return 1
+ fi
+ return 0
}
needLocalStore() {
@@ -173,14 +175,30 @@ 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
startDaemon
fi
+onError() {
+ set +x
+ echo "$0: test failed at:" >&2
+ for ((i = 1; i < ${#BASH_SOURCE[@]}; i++)); do
+ if [[ -z ${BASH_SOURCE[i]} ]]; then break; fi
+ echo " ${FUNCNAME[i]} in ${BASH_SOURCE[i]}:${BASH_LINENO[i-1]}" >&2
+ done
+}
+
+trap onError ERR
+
fi # COMMON_SH_SOURCED
diff --git a/tests/completions.sh b/tests/completions.sh
new file mode 100644
index 000000000..522aa1c86
--- /dev/null
+++ b/tests/completions.sh
@@ -0,0 +1,62 @@
+source common.sh
+
+cd "$TEST_ROOT"
+
+mkdir -p dep
+cat <<EOF > dep/flake.nix
+{
+ outputs = i: { };
+}
+EOF
+mkdir -p foo
+cat <<EOF > foo/flake.nix
+{
+ inputs.a.url = "path:$(realpath dep)";
+
+ outputs = i: {
+ sampleOutput = 1;
+ };
+}
+EOF
+mkdir -p bar
+cat <<EOF > bar/flake.nix
+{
+ inputs.b.url = "path:$(realpath dep)";
+
+ outputs = i: {
+ sampleOutput = 1;
+ };
+}
+EOF
+
+# Test the completion of a subcommand
+[[ "$(NIX_GET_COMPLETIONS=1 nix buil)" == $'normal\nbuild\t' ]]
+[[ "$(NIX_GET_COMPLETIONS=2 nix flake metad)" == $'normal\nmetadata\t' ]]
+
+# Filename completion
+[[ "$(NIX_GET_COMPLETIONS=2 nix build ./f)" == $'filenames\n./foo\t' ]]
+[[ "$(NIX_GET_COMPLETIONS=2 nix build ./nonexistent)" == $'filenames' ]]
+
+# Input override completion
+[[ "$(NIX_GET_COMPLETIONS=4 nix build ./foo --override-input '')" == $'normal\na\t' ]]
+[[ "$(NIX_GET_COMPLETIONS=5 nix flake show ./foo --override-input '')" == $'normal\na\t' ]]
+## With multiple input flakes
+[[ "$(NIX_GET_COMPLETIONS=5 nix build ./foo ./bar --override-input '')" == $'normal\na\t\nb\t' ]]
+## With tilde expansion
+[[ "$(HOME=$PWD NIX_GET_COMPLETIONS=4 nix build '~/foo' --override-input '')" == $'normal\na\t' ]]
+## Out of order
+[[ "$(NIX_GET_COMPLETIONS=3 nix build --update-input '' ./foo)" == $'normal\na\t' ]]
+[[ "$(NIX_GET_COMPLETIONS=4 nix build ./foo --update-input '' ./bar)" == $'normal\na\t\nb\t' ]]
+
+# Cli flag completion
+NIX_GET_COMPLETIONS=2 nix build --log-form | grep -- "--log-format"
+
+# Config option completion
+## With `--option`
+NIX_GET_COMPLETIONS=3 nix build --option allow-import-from | grep -- "allow-import-from-derivation"
+## As a cli flag – not working atm
+# NIX_GET_COMPLETIONS=2 nix build --allow-import-from | grep -- "allow-import-from-derivation"
+
+# Attr path completions
+[[ "$(NIX_GET_COMPLETIONS=2 nix eval ./foo\#sam)" == $'attrs\n./foo#sampleOutput\t' ]]
+[[ "$(NIX_GET_COMPLETIONS=4 nix eval --file ./foo/flake.nix outp)" == $'attrs\noutputs\t' ]]
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..d74976019
--- /dev/null
+++ b/tests/eval.sh
@@ -0,0 +1,31 @@
+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 ]]
+
+# Check if toFile can be utilized during restricted eval
+[[ $(nix eval --restrict-eval --expr 'import (builtins.toFile "source" "42")') == 42 ]]
+
+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..44050c878
--- /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 --no-link | 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..4ceba0293 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"
@@ -22,12 +24,14 @@ touch $repo/.gitignore
git -C $repo add hello .gitignore
git -C $repo commit -m 'Bla1'
rev1=$(git -C $repo rev-parse HEAD)
+git -C $repo tag -a tag1 -m tag1
echo world > $repo/hello
git -C $repo commit -m 'Bla2' -a
git -C $repo worktree add $TEST_ROOT/worktree
echo hello >> $TEST_ROOT/worktree/hello
rev2=$(git -C $repo rev-parse HEAD)
+git -C $repo tag -a tag2 -m tag2
# Fetch a worktree
unset _NIX_FORCE_HTTP
@@ -147,13 +151,26 @@ 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 ]]
[[ $path3 = $path4 ]]
+# Using remote path with branch other than 'master' should fetch the HEAD revision.
+# (--tarball-ttl 0 to prevent using the cached repo above)
+export _NIX_FORCE_HTTP=1
+path4=$(nix eval --tarball-ttl 0 --impure --raw --expr "(builtins.fetchGit $repo).outPath")
+[[ $(cat $path4/hello) = dev ]]
+[[ $path3 = $path4 ]]
+unset _NIX_FORCE_HTTP
+
# Confirm same as 'dev' branch
path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outPath")
[[ $path3 = $path5 ]]
@@ -170,6 +187,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 +218,21 @@ 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$ ]]
+
+# Specifying a ref without a rev shouldn't pick a cached rev for a different ref
+export _NIX_FORCE_HTTP=1
+rev_tag1_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"refs/tags/tag1\"; }).rev")
+rev_tag1=$(git -C $repo rev-parse refs/tags/tag1)
+[[ $rev_tag1_nix = $rev_tag1 ]]
+rev_tag2_nix=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"refs/tags/tag2\"; }).rev")
+rev_tag2=$(git -C $repo rev-parse refs/tags/tag2)
+[[ $rev_tag2_nix = $rev_tag2 ]]
+unset _NIX_FORCE_HTTP
+
+# 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/fetchMercurial.sh b/tests/fetchMercurial.sh
index 726840664..5c64ffd26 100644
--- a/tests/fetchMercurial.sh
+++ b/tests/fetchMercurial.sh
@@ -7,7 +7,9 @@ fi
clearStore
-repo=$TEST_ROOT/hg
+# Intentionally not in a canonical form
+# See https://github.com/NixOS/nix/issues/6195
+repo=$TEST_ROOT/./hg
rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix
@@ -28,6 +30,12 @@ echo world > $repo/hello
hg commit --cwd $repo -m 'Bla2'
rev2=$(hg log --cwd $repo -r tip --template '{node}')
+# Fetch an unclean branch.
+echo unclean > $repo/hello
+path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath")
+[[ $(cat $path/hello) = unclean ]]
+hg revert --cwd $repo --all
+
# Fetch the default branch.
path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath")
[[ $(cat $path/hello) = world ]]
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/fetchTree-file.sh b/tests/fetchTree-file.sh
new file mode 100644
index 000000000..f0c530466
--- /dev/null
+++ b/tests/fetchTree-file.sh
@@ -0,0 +1,105 @@
+source common.sh
+
+clearStore
+
+cd "$TEST_ROOT"
+
+test_fetch_file () {
+ echo foo > test_input
+
+ input_hash="$(nix hash path test_input)"
+
+ nix eval --impure --file - <<EOF
+ let
+ tree = builtins.fetchTree { type = "file"; url = "file://$PWD/test_input"; };
+ in
+ assert (tree.narHash == "$input_hash");
+ tree
+EOF
+}
+
+# Make sure that `http(s)` and `file` flake inputs are properly extracted when
+# they should be, and treated as opaque files when they should be
+test_file_flake_input () {
+ rm -fr "$TEST_ROOT/testFlake";
+ mkdir "$TEST_ROOT/testFlake";
+ pushd testFlake
+
+ mkdir inputs
+ echo foo > inputs/test_input_file
+ tar cfa test_input.tar.gz inputs
+ cp test_input.tar.gz test_input_no_ext
+ input_tarball_hash="$(nix hash path test_input.tar.gz)"
+ input_directory_hash="$(nix hash path inputs)"
+
+ cat <<EOF > flake.nix
+ {
+ inputs.no_ext_default_no_unpack = {
+ url = "file://$PWD/test_input_no_ext";
+ flake = false;
+ };
+ inputs.no_ext_explicit_unpack = {
+ url = "tarball+file://$PWD/test_input_no_ext";
+ flake = false;
+ };
+ inputs.tarball_default_unpack = {
+ url = "file://$PWD/test_input.tar.gz";
+ flake = false;
+ };
+ inputs.tarball_explicit_no_unpack = {
+ url = "file+file://$PWD/test_input.tar.gz";
+ flake = false;
+ };
+ outputs = { ... }: {};
+ }
+EOF
+
+ nix flake update
+ nix eval --file - <<EOF
+ with (builtins.fromJSON (builtins.readFile ./flake.lock));
+
+ # Url inputs whose extension doesn’t match a known archive format should
+ # not be unpacked by default
+ assert (nodes.no_ext_default_no_unpack.locked.type == "file");
+ assert (nodes.no_ext_default_no_unpack.locked.unpack or false == false);
+ assert (nodes.no_ext_default_no_unpack.locked.narHash == "$input_tarball_hash");
+
+ # For backwards compatibility, flake inputs that correspond to the
+ # old 'tarball' fetcher should still have their type set to 'tarball'
+ assert (nodes.tarball_default_unpack.locked.type == "tarball");
+ # Unless explicitely specified, the 'unpack' parameter shouldn’t appear here
+ # because that would break older Nix versions
+ assert (!nodes.tarball_default_unpack.locked ? unpack);
+ assert (nodes.tarball_default_unpack.locked.narHash == "$input_directory_hash");
+
+ # Explicitely passing the unpack parameter should enforce the desired behavior
+ assert (nodes.no_ext_explicit_unpack.locked.narHash == nodes.tarball_default_unpack.locked.narHash);
+ assert (nodes.tarball_explicit_no_unpack.locked.narHash == nodes.no_ext_default_no_unpack.locked.narHash);
+ true
+EOF
+ popd
+
+ [[ -z "${NIX_DAEMON_PACKAGE}" ]] && return 0
+
+ # Ensure that a lockfile generated by the current Nix for tarball inputs
+ # can still be read by an older Nix
+
+ cat <<EOF > flake.nix
+ {
+ inputs.tarball = {
+ url = "file://$PWD/test_input.tar.gz";
+ flake = false;
+ };
+ outputs = { self, tarball }: {
+ foo = builtins.readFile "${tarball}/test_input_file";
+ };
+ }
+ nix flake update
+
+ clearStore
+ "$NIX_DAEMON_PACKAGE/bin/nix" eval .#foo
+EOF
+}
+
+test_fetch_file
+test_file_flake_input
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/flakes/bundle.sh
index 9496b8f92..67bbb05ac 100644
--- a/tests/flake-bundler.sh
+++ b/tests/flakes/bundle.sh
@@ -1,9 +1,6 @@
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
+cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
cd $TEST_HOME
@@ -25,6 +22,7 @@ cat <<EOF > flake.nix
};
}
EOF
+
nix build .#
nix bundle --bundler .# .#
nix bundle --bundler .#bundlers.$system.default .#packages.$system.default
@@ -32,6 +30,3 @@ 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/flakes/check.sh b/tests/flakes/check.sh
new file mode 100644
index 000000000..f572aa75c
--- /dev/null
+++ b/tests/flakes/check.sh
@@ -0,0 +1,89 @@
+source common.sh
+
+flakeDir=$TEST_ROOT/flake3
+mkdir -p $flakeDir
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ overlay = final: prev: {
+ };
+ };
+}
+EOF
+
+nix flake check $flakeDir
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ overlay = finalll: prev: {
+ };
+ };
+}
+EOF
+
+(! nix flake check $flakeDir)
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ nixosModules.foo = {
+ a.b.c = 123;
+ foo = true;
+ };
+ };
+}
+EOF
+
+nix flake check $flakeDir
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ nixosModules.foo = {
+ a.b.c = 123;
+ foo = assert false; true;
+ };
+ };
+}
+EOF
+
+(! nix flake check $flakeDir)
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ nixosModule = { config, pkgs, ... }: {
+ a.b.c = 123;
+ };
+ };
+}
+EOF
+
+nix flake check $flakeDir
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ nixosModule = { config, pkgs }: {
+ a.b.c = 123;
+ };
+ };
+}
+EOF
+
+(! nix flake check $flakeDir)
+
+cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ packages.system-1.default = "foo";
+ packages.system-2.default = "bar";
+ };
+}
+EOF
+
+checkRes=$(nix flake check --keep-going $flakeDir 2>&1 && fail "nix flake check should have failed" || true)
+echo "$checkRes" | grep -q "packages.system-1.default"
+echo "$checkRes" | grep -q "packages.system-2.default"
diff --git a/tests/flakes/circular.sh b/tests/flakes/circular.sh
new file mode 100644
index 000000000..09cd02edf
--- /dev/null
+++ b/tests/flakes/circular.sh
@@ -0,0 +1,49 @@
+# Test circular flake dependencies.
+source ./common.sh
+
+requireGit
+
+flakeA=$TEST_ROOT/flakeA
+flakeB=$TEST_ROOT/flakeB
+
+createGitRepo $flakeA
+createGitRepo $flakeB
+
+cat > $flakeA/flake.nix <<EOF
+{
+ inputs.b.url = git+file://$flakeB;
+ inputs.b.inputs.a.follows = "/";
+
+ outputs = { self, b }: {
+ foo = 123 + b.bar;
+ xyzzy = 1000;
+ };
+}
+EOF
+
+git -C $flakeA add flake.nix
+
+cat > $flakeB/flake.nix <<EOF
+{
+ inputs.a.url = git+file://$flakeA;
+
+ outputs = { self, a }: {
+ bar = 456 + a.xyzzy;
+ };
+}
+EOF
+
+git -C $flakeB add flake.nix
+git -C $flakeB commit -a -m 'Foo'
+
+[[ $(nix eval $flakeA#foo) = 1579 ]]
+[[ $(nix eval $flakeA#foo) = 1579 ]]
+
+sed -i $flakeB/flake.nix -e 's/456/789/'
+git -C $flakeB commit -a -m 'Foo'
+
+[[ $(nix eval --update-input b $flakeA#foo) = 1912 ]]
+
+# Test list-inputs with circular dependencies
+nix flake metadata $flakeA
+
diff --git a/tests/flakes/common.sh b/tests/flakes/common.sh
new file mode 100644
index 000000000..c333733c2
--- /dev/null
+++ b/tests/flakes/common.sh
@@ -0,0 +1,73 @@
+source ../common.sh
+
+registry=$TEST_ROOT/registry.json
+
+requireGit() {
+ if [[ -z $(type -p git) ]]; then
+ echo "Git not installed; skipping flake tests"
+ exit 99
+ fi
+}
+
+writeSimpleFlake() {
+ local flakeDir="$1"
+ cat > $flakeDir/flake.nix <<EOF
+{
+ description = "Bla bla";
+
+ outputs = inputs: rec {
+ packages.$system = rec {
+ foo = import ./simple.nix;
+ default = foo;
+ };
+
+ # To test "nix flake init".
+ legacyPackages.x86_64-linux.hello = import ./simple.nix;
+ };
+}
+EOF
+
+ cp ../simple.nix ../simple.builder.sh ../config.nix $flakeDir/
+}
+
+createSimpleGitFlake() {
+ local flakeDir="$1"
+ writeSimpleFlake $flakeDir
+ git -C $flakeDir add flake.nix simple.nix simple.builder.sh config.nix
+ git -C $flakeDir commit -m 'Initial'
+}
+
+writeDependentFlake() {
+ local flakeDir="$1"
+ cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self, flake1 }: {
+ packages.$system.default = flake1.packages.$system.default;
+ expr = assert builtins.pathExists ./flake.lock; 123;
+ };
+}
+EOF
+}
+
+writeTrivialFlake() {
+ local flakeDir="$1"
+ cat > $flakeDir/flake.nix <<EOF
+{
+ outputs = { self }: {
+ expr = 123;
+ };
+}
+EOF
+}
+
+createGitRepo() {
+ local repo="$1"
+ local extraArgs="$2"
+
+ rm -rf $repo $repo.tmp
+ mkdir -p $repo
+
+ git -C $repo init $extraArgs
+ git -C $repo config user.email "foobar@example.com"
+ git -C $repo config user.name "Foobar"
+}
diff --git a/tests/flake-local-settings.sh b/tests/flakes/config.sh
index e92c16f87..d1941a6be 100644
--- a/tests/flake-local-settings.sh
+++ b/tests/flakes/config.sh
@@ -1,9 +1,6 @@
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
+cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
cd $TEST_HOME
diff --git a/tests/flakes.sh b/tests/flakes/flakes.sh
index ea629ae70..267e2cd6f 100644
--- a/tests/flakes.sh
+++ b/tests/flakes/flakes.sh
@@ -1,60 +1,30 @@
-source common.sh
+source ./common.sh
-if [[ -z $(type -p git) ]]; then
- echo "Git not installed; skipping flake tests"
- exit 99
-fi
+requireGit
clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config
-registry=$TEST_ROOT/registry.json
-
flake1Dir=$TEST_ROOT/flake1
flake2Dir=$TEST_ROOT/flake2
flake3Dir=$TEST_ROOT/flake3
flake5Dir=$TEST_ROOT/flake5
-flake6Dir=$TEST_ROOT/flake6
flake7Dir=$TEST_ROOT/flake7
-templatesDir=$TEST_ROOT/templates
nonFlakeDir=$TEST_ROOT/nonFlake
badFlakeDir=$TEST_ROOT/badFlake
-flakeA=$TEST_ROOT/flakeA
-flakeB=$TEST_ROOT/flakeB
flakeGitBare=$TEST_ROOT/flakeGitBare
-flakeFollowsA=$TEST_ROOT/follows/flakeA
-flakeFollowsB=$TEST_ROOT/follows/flakeA/flakeB
-flakeFollowsC=$TEST_ROOT/follows/flakeA/flakeB/flakeC
-flakeFollowsD=$TEST_ROOT/follows/flakeA/flakeD
-flakeFollowsE=$TEST_ROOT/follows/flakeA/flakeE
-
-for repo in $flake1Dir $flake2Dir $flake3Dir $flake7Dir $templatesDir $nonFlakeDir $flakeA $flakeB $flakeFollowsA; do
- rm -rf $repo $repo.tmp
- mkdir -p $repo
- git -C $repo init
- git -C $repo config user.email "foobar@example.com"
- git -C $repo config user.name "Foobar"
-done
-
-cat > $flake1Dir/flake.nix <<EOF
-{
- description = "Bla bla";
- outputs = inputs: rec {
- packages.$system = rec {
- foo = import ./simple.nix;
- default = foo;
- };
+for repo in $flake1Dir $flake2Dir $flake3Dir $flake7Dir $nonFlakeDir; do
+ # Give one repo a non-main initial branch.
+ extraArgs=
+ if [[ $repo == $flake2Dir ]]; then
+ extraArgs="--initial-branch=main"
+ fi
- # To test "nix flake init".
- legacyPackages.x86_64-linux.hello = import ./simple.nix;
- };
-}
-EOF
+ createGitRepo "$repo" "$extraArgs"
+done
-cp ./simple.nix ./simple.builder.sh ./config.nix $flake1Dir/
-git -C $flake1Dir add flake.nix simple.nix simple.builder.sh config.nix
-git -C $flake1Dir commit -m 'Initial'
+createSimpleGitFlake $flake1Dir
cat > $flake2Dir/flake.nix <<EOF
{
@@ -98,12 +68,10 @@ nix registry add --registry $registry flake1 git+file://$flake1Dir
nix registry add --registry $registry flake2 git+file://$flake2Dir
nix registry add --registry $registry flake3 git+file://$flake3Dir
nix registry add --registry $registry flake4 flake3
-nix registry add --registry $registry flake5 hg+file://$flake5Dir
nix registry add --registry $registry nixpkgs flake1
-nix registry add --registry $registry templates git+file://$templatesDir
# Test 'nix flake list'.
-[[ $(nix registry list | wc -l) == 7 ]]
+[[ $(nix registry list | wc -l) == 5 ]]
# Test 'nix flake metadata'.
nix flake metadata flake1
@@ -156,6 +124,7 @@ nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"git+file://$flake1Di
# But should succeed in impure mode.
(! nix build -o $TEST_ROOT/result flake2#bar --impure)
nix build -o $TEST_ROOT/result flake2#bar --impure --no-write-lock-file
+nix eval --expr "builtins.getFlake \"$flake2Dir\"" --impure
# Building a local flake with an unlocked dependency should fail with --no-update-lock-file.
nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
@@ -165,11 +134,11 @@ nix build -o $TEST_ROOT/result $flake2Dir#bar --no-write-lock-file
nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
nix build -o $TEST_ROOT/result $flake2Dir#bar --commit-lock-file
[[ -e $flake2Dir/flake.lock ]]
-[[ -z $(git -C $flake2Dir diff master) ]]
+[[ -z $(git -C $flake2Dir diff main || echo failed) ]]
# Rerunning the build should not change the lockfile.
nix build -o $TEST_ROOT/result $flake2Dir#bar
-[[ -z $(git -C $flake2Dir diff master) ]]
+[[ -z $(git -C $flake2Dir diff main || echo failed) ]]
# Building with a lockfile should not require a fetch of the registry.
nix build -o $TEST_ROOT/result --flake-registry file:///no-registry.json $flake2Dir#bar --refresh
@@ -178,7 +147,7 @@ nix build -o $TEST_ROOT/result --no-use-registries $flake2Dir#bar --refresh
# Updating the flake should not change the lockfile.
nix flake lock $flake2Dir
-[[ -z $(git -C $flake2Dir diff master) ]]
+[[ -z $(git -C $flake2Dir diff main || echo failed) ]]
# Now we should be able to build the flake in pure mode.
nix build -o $TEST_ROOT/result flake2#bar
@@ -213,7 +182,7 @@ nix build -o $TEST_ROOT/result $flake3Dir#"sth sth"
nix build -o $TEST_ROOT/result $flake3Dir#"sth%20sth"
# Check whether it saved the lockfile
-(! [[ -z $(git -C $flake3Dir diff master) ]])
+[[ -n $(git -C $flake3Dir diff master) ]]
git -C $flake3Dir add flake.lock
@@ -283,7 +252,7 @@ cat > $flake3Dir/flake.nix <<EOF
}
EOF
-cp ./config.nix $flake3Dir
+cp ../config.nix $flake3Dir
git -C $flake3Dir add flake.nix config.nix
git -C $flake3Dir commit -m 'Add nonFlakeInputs'
@@ -313,10 +282,10 @@ nix build -o $TEST_ROOT/result flake4#xyzzy
# Test 'nix flake update' and --override-flake.
nix flake lock $flake3Dir
-[[ -z $(git -C $flake3Dir diff master) ]]
+[[ -z $(git -C $flake3Dir diff master || echo failed) ]]
nix flake update $flake3Dir --override-flake flake2 nixpkgs
-[[ ! -z $(git -C $flake3Dir diff master) ]]
+[[ ! -z $(git -C $flake3Dir diff master || echo failed) ]]
# Make branch "removeXyzzy" where flake3 doesn't have xyzzy anymore
git -C $flake3Dir checkout -b removeXyzzy
@@ -358,158 +327,19 @@ nix build -o $TEST_ROOT/result flake4/removeXyzzy#sth
# Testing the nix CLI
nix registry add flake1 flake3
-[[ $(nix registry list | wc -l) == 8 ]]
+[[ $(nix registry list | wc -l) == 6 ]]
nix registry pin flake1
-[[ $(nix registry list | wc -l) == 8 ]]
+[[ $(nix registry list | wc -l) == 6 ]]
nix registry pin flake1 flake3
-[[ $(nix registry list | wc -l) == 8 ]]
+[[ $(nix registry list | wc -l) == 6 ]]
nix registry remove flake1
-[[ $(nix registry list | wc -l) == 7 ]]
-
-# Test 'nix flake init'.
-cat > $templatesDir/flake.nix <<EOF
-{
- description = "Some templates";
-
- outputs = { self }: {
- templates = rec {
- trivial = {
- path = ./trivial;
- description = "A trivial flake";
- };
- default = trivial;
- };
- };
-}
-EOF
-
-mkdir $templatesDir/trivial
-
-cat > $templatesDir/trivial/flake.nix <<EOF
-{
- description = "A flake for building Hello World";
-
- outputs = { self, nixpkgs }: {
- packages.x86_64-linux = rec {
- hello = nixpkgs.legacyPackages.x86_64-linux.hello;
- default = hello;
- };
- };
-}
-EOF
-
-git -C $templatesDir add flake.nix trivial/flake.nix
-git -C $templatesDir commit -m 'Initial'
-
-nix flake check templates
-nix flake show templates
-nix flake show templates --json | jq
-
-(cd $flake7Dir && nix flake init)
-(cd $flake7Dir && nix flake init) # check idempotence
-git -C $flake7Dir add flake.nix
-nix flake check $flake7Dir
-nix flake show $flake7Dir
-nix flake show $flake7Dir --json | jq
-git -C $flake7Dir commit -a -m 'Initial'
-
-# Test 'nix flake new'.
-rm -rf $flake6Dir
-nix flake new -t templates#trivial $flake6Dir
-nix flake new -t templates#trivial $flake6Dir # check idempotence
-nix flake check $flake6Dir
+[[ $(nix registry list | wc -l) == 5 ]]
# Test 'nix flake clone'.
rm -rf $TEST_ROOT/flake1-v2
nix flake clone flake1 --dest $TEST_ROOT/flake1-v2
[ -e $TEST_ROOT/flake1-v2/flake.nix ]
-# More 'nix flake check' tests.
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- overlay = final: prev: {
- };
- };
-}
-EOF
-
-nix flake check $flake3Dir
-
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- overlay = finalll: prev: {
- };
- };
-}
-EOF
-
-(! nix flake check $flake3Dir)
-
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- nixosModules.foo = {
- a.b.c = 123;
- foo = true;
- };
- };
-}
-EOF
-
-nix flake check $flake3Dir
-
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- nixosModules.foo = {
- a.b.c = 123;
- foo = assert false; true;
- };
- };
-}
-EOF
-
-(! nix flake check $flake3Dir)
-
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- nixosModule = { config, pkgs, ... }: {
- a.b.c = 123;
- };
- };
-}
-EOF
-
-nix flake check $flake3Dir
-
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- nixosModule = { config, pkgs }: {
- a.b.c = 123;
- };
- };
-}
-EOF
-
-(! nix flake check $flake3Dir)
-
-cat > $flake3Dir/flake.nix <<EOF
-{
- outputs = { flake1, self }: {
- 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 "packages.system-1.default"
-echo "$checkRes" | grep -q "packages.system-2.default"
-
# Test 'follows' inputs.
cat > $flake3Dir/flake.nix <<EOF
{
@@ -552,6 +382,10 @@ nix flake lock $flake3Dir
[[ $(jq -c .nodes.root.inputs.bar $flake3Dir/flake.lock) = '["flake2"]' ]]
# Test overriding inputs of inputs.
+writeTrivialFlake $flake7Dir
+git -C $flake7Dir add flake.nix
+git -C $flake7Dir commit -m 'Initial'
+
cat > $flake3Dir/flake.nix <<EOF
{
inputs.flake2.inputs.flake1 = {
@@ -586,50 +420,9 @@ rm -rf $flakeGitBare
git clone --bare $flake1Dir $flakeGitBare
nix build -o $TEST_ROOT/result git+file://$flakeGitBare
-# Test Mercurial flakes.
-rm -rf $flake5Dir
-mkdir $flake5Dir
-
-cat > $flake5Dir/flake.nix <<EOF
-{
- outputs = { self, flake1 }: {
- packages.$system.default = flake1.packages.$system.default;
- expr = assert builtins.pathExists ./flake.lock; 123;
- };
-}
-EOF
-
-if [[ -n $(type -p hg) ]]; then
- hg init $flake5Dir
-
- 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 eval hg+file://$flake5Dir#expr
-
- nix eval hg+file://$flake5Dir#expr
-
- (! nix eval hg+file://$flake5Dir#expr --no-allow-dirty)
-
- (! nix flake metadata --json hg+file://$flake5Dir | jq -e -r .revision)
-
- 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 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 path flakes.
-rm -rf $flake5Dir/.hg $flake5Dir/flake.lock
+mkdir -p $flake5Dir
+writeDependentFlake $flake5Dir
nix flake lock path://$flake5Dir
# Test tarball flakes.
@@ -667,165 +460,6 @@ nix flake lock $flake3Dir --update-input flake2/flake1
# Test 'nix flake metadata --json'.
nix flake metadata $flake3Dir --json | jq .
-# Test circular flake dependencies.
-cat > $flakeA/flake.nix <<EOF
-{
- inputs.b.url = git+file://$flakeB;
- inputs.b.inputs.a.follows = "/";
-
- outputs = { self, nixpkgs, b }: {
- foo = 123 + b.bar;
- xyzzy = 1000;
- };
-}
-EOF
-
-git -C $flakeA add flake.nix
-
-cat > $flakeB/flake.nix <<EOF
-{
- inputs.a.url = git+file://$flakeA;
-
- outputs = { self, nixpkgs, a }: {
- bar = 456 + a.xyzzy;
- };
-}
-EOF
-
-git -C $flakeB add flake.nix
-git -C $flakeB commit -a -m 'Foo'
-
-[[ $(nix eval $flakeA#foo) = 1579 ]]
-[[ $(nix eval $flakeA#foo) = 1579 ]]
-
-sed -i $flakeB/flake.nix -e 's/456/789/'
-git -C $flakeB commit -a -m 'Foo'
-
-[[ $(nix eval --update-input b $flakeA#foo) = 1912 ]]
-
-# Test list-inputs with circular dependencies
-nix flake metadata $flakeA
-
-# Test flake follow paths
-mkdir -p $flakeFollowsB
-mkdir -p $flakeFollowsC
-mkdir -p $flakeFollowsD
-mkdir -p $flakeFollowsE
-
-cat > $flakeFollowsA/flake.nix <<EOF
-{
- description = "Flake A";
- inputs = {
- B = {
- url = "path:./flakeB";
- inputs.foobar.follows = "foobar";
- };
-
- foobar.url = "path:$flakeFollowsA/flakeE";
- };
- outputs = { ... }: {};
-}
-EOF
-
-cat > $flakeFollowsB/flake.nix <<EOF
-{
- description = "Flake B";
- inputs = {
- foobar.url = "path:$flakeFollowsA/flakeE";
- goodoo.follows = "C/goodoo";
- C = {
- url = "path:./flakeC";
- inputs.foobar.follows = "foobar";
- };
- };
- outputs = { ... }: {};
-}
-EOF
-
-cat > $flakeFollowsC/flake.nix <<EOF
-{
- description = "Flake C";
- inputs = {
- foobar.url = "path:$flakeFollowsA/flakeE";
- goodoo.follows = "foobar";
- };
- outputs = { ... }: {};
-}
-EOF
-
-cat > $flakeFollowsD/flake.nix <<EOF
-{
- description = "Flake D";
- inputs = {};
- outputs = { ... }: {};
-}
-EOF
-
-cat > $flakeFollowsE/flake.nix <<EOF
-{
- description = "Flake E";
- inputs = {};
- outputs = { ... }: {};
-}
-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) = '["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";
- };
- outputs = { ... }: {};
-}
-EOF
-
-git -C $flakeFollowsA add flake.nix
-
-nix flake lock $flakeFollowsA 2>&1 | grep 'points outside'
-
# Test flake in store does not evaluate
rm -rf $badFlakeDir
mkdir $badFlakeDir
diff --git a/tests/flakes/follow-paths.sh b/tests/flakes/follow-paths.sh
new file mode 100644
index 000000000..19cc1bafa
--- /dev/null
+++ b/tests/flakes/follow-paths.sh
@@ -0,0 +1,150 @@
+source ./common.sh
+
+requireGit
+
+flakeFollowsA=$TEST_ROOT/follows/flakeA
+flakeFollowsB=$TEST_ROOT/follows/flakeA/flakeB
+flakeFollowsC=$TEST_ROOT/follows/flakeA/flakeB/flakeC
+flakeFollowsD=$TEST_ROOT/follows/flakeA/flakeD
+flakeFollowsE=$TEST_ROOT/follows/flakeA/flakeE
+
+# Test following path flakerefs.
+createGitRepo $flakeFollowsA
+mkdir -p $flakeFollowsB
+mkdir -p $flakeFollowsC
+mkdir -p $flakeFollowsD
+mkdir -p $flakeFollowsE
+
+cat > $flakeFollowsA/flake.nix <<EOF
+{
+ description = "Flake A";
+ inputs = {
+ B = {
+ url = "path:./flakeB";
+ inputs.foobar.follows = "foobar";
+ };
+
+ foobar.url = "path:$flakeFollowsA/flakeE";
+ };
+ outputs = { ... }: {};
+}
+EOF
+
+cat > $flakeFollowsB/flake.nix <<EOF
+{
+ description = "Flake B";
+ inputs = {
+ foobar.url = "path:$flakeFollowsA/flakeE";
+ goodoo.follows = "C/goodoo";
+ C = {
+ url = "path:./flakeC";
+ inputs.foobar.follows = "foobar";
+ };
+ };
+ outputs = { ... }: {};
+}
+EOF
+
+cat > $flakeFollowsC/flake.nix <<EOF
+{
+ description = "Flake C";
+ inputs = {
+ foobar.url = "path:$flakeFollowsA/flakeE";
+ goodoo.follows = "foobar";
+ };
+ outputs = { ... }: {};
+}
+EOF
+
+cat > $flakeFollowsD/flake.nix <<EOF
+{
+ description = "Flake D";
+ inputs = {};
+ outputs = { ... }: {};
+}
+EOF
+
+cat > $flakeFollowsE/flake.nix <<EOF
+{
+ description = "Flake E";
+ inputs = {};
+ outputs = { ... }: {};
+}
+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
+
+nix flake lock $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) = '["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";
+ };
+ 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";
+ };
+ outputs = { ... }: {};
+}
+EOF
+
+git -C $flakeFollowsA add flake.nix
+
+nix flake lock $flakeFollowsA 2>&1 | grep 'points outside'
+
+# Non-existant follows should print a warning.
+cat >$flakeFollowsA/flake.nix <<EOF
+{
+ description = "Flake A";
+ inputs.B = {
+ url = "path:./flakeB";
+ inputs.invalid.follows = "D";
+ inputs.invalid2.url = "path:./flakeD";
+ };
+ inputs.D.url = "path:./flakeD";
+ outputs = { ... }: {};
+}
+EOF
+
+git -C $flakeFollowsA add flake.nix
+
+nix flake lock $flakeFollowsA 2>&1 | grep "warning: input 'B' has an override for a non-existent input 'invalid'"
+nix flake lock $flakeFollowsA 2>&1 | grep "warning: input 'B' has an override for a non-existent input 'invalid2'"
diff --git a/tests/flakes/init.sh b/tests/flakes/init.sh
new file mode 100644
index 000000000..36cb9956a
--- /dev/null
+++ b/tests/flakes/init.sh
@@ -0,0 +1,87 @@
+source ./common.sh
+
+requireGit
+
+templatesDir=$TEST_ROOT/templates
+flakeDir=$TEST_ROOT/flake
+nixpkgsDir=$TEST_ROOT/nixpkgs
+
+nix registry add --registry $registry templates git+file://$templatesDir
+nix registry add --registry $registry nixpkgs git+file://$nixpkgsDir
+
+createGitRepo $nixpkgsDir
+createSimpleGitFlake $nixpkgsDir
+
+# Test 'nix flake init'.
+createGitRepo $templatesDir
+
+cat > $templatesDir/flake.nix <<EOF
+{
+ description = "Some templates";
+
+ outputs = { self }: {
+ templates = rec {
+ trivial = {
+ path = ./trivial;
+ description = "A trivial flake";
+ welcomeText = ''
+ Welcome to my trivial flake
+ '';
+ };
+ default = trivial;
+ };
+ };
+}
+EOF
+
+mkdir $templatesDir/trivial
+
+cat > $templatesDir/trivial/flake.nix <<EOF
+{
+ description = "A flake for building Hello World";
+
+ outputs = { self, nixpkgs }: {
+ packages.x86_64-linux = rec {
+ hello = nixpkgs.legacyPackages.x86_64-linux.hello;
+ default = hello;
+ };
+ };
+}
+EOF
+echo a > $templatesDir/trivial/a
+echo b > $templatesDir/trivial/b
+
+git -C $templatesDir add flake.nix trivial/
+git -C $templatesDir commit -m 'Initial'
+
+nix flake check templates
+nix flake show templates
+nix flake show templates --json | jq
+
+createGitRepo $flakeDir
+(cd $flakeDir && nix flake init)
+(cd $flakeDir && nix flake init) # check idempotence
+git -C $flakeDir add flake.nix
+nix flake check $flakeDir
+nix flake show $flakeDir
+nix flake show $flakeDir --json | jq
+git -C $flakeDir commit -a -m 'Initial'
+
+# Test 'nix flake init' with benign conflicts
+createGitRepo "$flakeDir"
+echo a > $flakeDir/a
+(cd $flakeDir && nix flake init) # check idempotence
+
+# Test 'nix flake init' with conflicts
+createGitRepo "$flakeDir"
+echo b > $flakeDir/a
+pushd $flakeDir
+(! nix flake init) |& grep "refusing to overwrite existing file '$flakeDir/a'"
+popd
+git -C $flakeDir commit -a -m 'Changed'
+
+# Test 'nix flake new'.
+rm -rf $flakeDir
+nix flake new -t templates#trivial $flakeDir
+nix flake new -t templates#trivial $flakeDir # check idempotence
+nix flake check $flakeDir
diff --git a/tests/flakes/mercurial.sh b/tests/flakes/mercurial.sh
new file mode 100644
index 000000000..2614006c8
--- /dev/null
+++ b/tests/flakes/mercurial.sh
@@ -0,0 +1,46 @@
+source ./common.sh
+
+if [[ -z $(type -p hg) ]]; then
+ echo "Mercurial not installed; skipping"
+ exit 99
+fi
+
+flake1Dir=$TEST_ROOT/flake-hg1
+mkdir -p $flake1Dir
+writeSimpleFlake $flake1Dir
+hg init $flake1Dir
+
+nix registry add --registry $registry flake1 hg+file://$flake1Dir
+
+flake2Dir=$TEST_ROOT/flake-hg2
+mkdir -p $flake2Dir
+writeDependentFlake $flake2Dir
+hg init $flake2Dir
+
+hg add $flake1Dir/*
+hg commit --config ui.username=foobar@example.org $flake1Dir -m 'Initial commit'
+
+hg add $flake2Dir/flake.nix
+hg commit --config ui.username=foobar@example.org $flake2Dir -m 'Initial commit'
+
+nix build -o $TEST_ROOT/result hg+file://$flake2Dir
+[[ -e $TEST_ROOT/result/hello ]]
+
+(! nix flake metadata --json hg+file://$flake2Dir | jq -e -r .revision)
+
+nix eval hg+file://$flake2Dir#expr
+
+nix eval hg+file://$flake2Dir#expr
+
+(! nix eval hg+file://$flake2Dir#expr --no-allow-dirty)
+
+(! nix flake metadata --json hg+file://$flake2Dir | jq -e -r .revision)
+
+hg commit --config ui.username=foobar@example.org $flake2Dir -m 'Add lock file'
+
+nix flake metadata --json hg+file://$flake2Dir --refresh | jq -e -r .revision
+nix flake metadata --json hg+file://$flake2Dir
+[[ $(nix flake metadata --json hg+file://$flake2Dir | jq -e -r .revCount) = 1 ]]
+
+nix build -o $TEST_ROOT/result hg+file://$flake2Dir --no-registries --no-allow-dirty
+nix build -o $TEST_ROOT/result hg+file://$flake2Dir --no-use-registries --no-allow-dirty
diff --git a/tests/flakes/run.sh b/tests/flakes/run.sh
new file mode 100644
index 000000000..9fa51d1c7
--- /dev/null
+++ b/tests/flakes/run.sh
@@ -0,0 +1,29 @@
+source ../common.sh
+
+clearStore
+rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
+cp ../shell-hello.nix ../config.nix $TEST_HOME
+cd $TEST_HOME
+
+cat <<EOF > flake.nix
+{
+ outputs = {self}: {
+ packages.$system.pkgAsPkg = (import ./shell-hello.nix).hello;
+ packages.$system.appAsApp = self.packages.$system.appAsApp;
+
+ apps.$system.pkgAsApp = self.packages.$system.pkgAsPkg;
+ apps.$system.appAsApp = {
+ type = "app";
+ program = "\${(import ./shell-hello.nix).hello}/bin/hello";
+ };
+ };
+}
+EOF
+nix run --no-write-lock-file .#appAsApp
+nix run --no-write-lock-file .#pkgAsPkg
+
+! nix run --no-write-lock-file .#pkgAsApp || fail "'nix run' shouldn’t accept an 'app' defined under 'packages'"
+! nix run --no-write-lock-file .#appAsPkg || fail "elements of 'apps' should be of type 'app'"
+
+clearStore
+
diff --git a/tests/flake-searching.sh b/tests/flakes/search-root.sh
index db241f6d2..d8586dc8a 100644
--- a/tests/flake-searching.sh
+++ b/tests/flakes/search-root.sh
@@ -1,15 +1,11 @@
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
+writeSimpleFlake $TEST_HOME
cd $TEST_HOME
mkdir -p foo/subdir
+
echo '{ outputs = _: {}; }' > foo/flake.nix
cat <<EOF > flake.nix
{
@@ -43,10 +39,12 @@ nix build --override-input foo . || fail "flake should search up directories whe
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
+if [[ -n $(type -p git) ]]; then
+ 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
+fi
diff --git a/tests/fmt.sh b/tests/fmt.sh
new file mode 100644
index 000000000..254681ca2
--- /dev/null
+++ b/tests/fmt.sh
@@ -0,0 +1,35 @@
+source common.sh
+
+set -o pipefail
+
+clearStore
+rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
+
+cp ./simple.nix ./simple.builder.sh ./fmt.simple.sh ./config.nix $TEST_HOME
+
+cd $TEST_HOME
+
+nix fmt --help | grep "Format"
+
+cat << EOF > flake.nix
+{
+ outputs = _: {
+ formatter.$system =
+ with import ./config.nix;
+ mkDerivation {
+ name = "formatter";
+ buildCommand = ''
+ mkdir -p \$out/bin
+ echo "#! ${shell}" > \$out/bin/formatter
+ cat \${./fmt.simple.sh} >> \$out/bin/formatter
+ chmod +x \$out/bin/formatter
+ '';
+ };
+ };
+}
+EOF
+nix fmt ./file ./folder | grep 'Formatting: ./file ./folder'
+nix flake check
+nix flake show | grep -P "package 'formatter'"
+
+clearStore
diff --git a/tests/fmt.simple.sh b/tests/fmt.simple.sh
new file mode 100755
index 000000000..4c8c67ebb
--- /dev/null
+++ b/tests/fmt.simple.sh
@@ -0,0 +1 @@
+echo Formatting: "${@}"
diff --git a/tests/github-flakes.nix b/tests/github-flakes.nix
index 7ac397d81..43a4f1432 100644
--- a/tests/github-flakes.nix
+++ b/tests/github-flakes.nix
@@ -7,7 +7,7 @@ with import (nixpkgs + "/nixos/lib/testing-python.nix") {
let
- # Generate a fake root CA and a fake github.com certificate.
+ # Generate a fake root CA and a fake api.github.com / github.com / channels.nixos.org certificate.
cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; }
''
mkdir -p $out
@@ -18,7 +18,7 @@ let
openssl req -newkey rsa:2048 -nodes -keyout $out/server.key \
-subj "/C=CN/ST=Denial/L=Springfield/O=Dis/CN=github.com" -out server.csr
- openssl x509 -req -extfile <(printf "subjectAltName=DNS:api.github.com,DNS:github.com,DNS:raw.githubusercontent.com") \
+ openssl x509 -req -extfile <(printf "subjectAltName=DNS:api.github.com,DNS:github.com,DNS:channels.nixos.org") \
-days 36500 -in server.csr -CA $out/ca.crt -CAkey ca.key -CAcreateserial -out $out/server.crt
'';
@@ -37,6 +37,17 @@ let
"owner": "NixOS",
"repo": "nixpkgs"
}
+ },
+ {
+ "from": {
+ "type": "indirect",
+ "id": "private-flake"
+ },
+ "to": {
+ "type": "github",
+ "owner": "fancy-enterprise",
+ "repo": "private-flake"
+ }
}
],
"version": 2
@@ -45,20 +56,40 @@ let
destination = "/flake-registry.json";
};
- api = pkgs.runCommand "nixpkgs-flake" {}
+ private-flake-rev = "9f1dd0df5b54a7dc75b618034482ed42ce34383d";
+
+ private-flake-api = pkgs.runCommand "private-flake" {}
''
- mkdir -p $out/tarball
+ mkdir -p $out/{commits,tarball}
- 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} --
- tar cfz $out/tarball/${nixpkgs.rev} $dir --hard-dereference
+ # Setup https://docs.github.com/en/rest/commits/commits#get-a-commit
+ echo '{"sha": "${private-flake-rev}"}' > $out/commits/HEAD
+
+ # Setup tarball download via API
+ dir=private-flake
+ mkdir $dir
+ echo '{ outputs = {...}: {}; }' > $dir/flake.nix
+ tar cfz $out/tarball/${private-flake-rev} $dir --hard-dereference
+ '';
+ nixpkgs-api = pkgs.runCommand "nixpkgs-flake" {}
+ ''
mkdir -p $out/commits
+
+ # Setup https://docs.github.com/en/rest/commits/commits#get-a-commit
echo '{"sha": "${nixpkgs.rev}"}' > $out/commits/HEAD
'';
+ archive = pkgs.runCommand "nixpkgs-flake" {}
+ ''
+ mkdir -p $out/archive
+
+ 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} --
+ tar cfz $out/archive/${nixpkgs.rev}.tar.gz $dir --hard-dereference
+ '';
in
makeTest (
@@ -67,7 +98,7 @@ makeTest (
name = "github-flakes";
nodes =
- { # Impersonate github.com and api.github.com.
+ {
github =
{ config, pkgs, ... }:
{ networking.firewall.allowedTCPPorts = [ 80 443 ];
@@ -77,12 +108,12 @@ makeTest (
services.httpd.extraConfig = ''
ErrorLog syslog:local6
'';
- services.httpd.virtualHosts."github.com" =
+ services.httpd.virtualHosts."channels.nixos.org" =
{ forceSSL = true;
sslServerKey = "${cert}/server.key";
sslServerCert = "${cert}/server.crt";
servedDirs =
- [ { urlPath = "/NixOS/flake-registry/raw/master";
+ [ { urlPath = "/";
dir = registry;
}
];
@@ -93,7 +124,20 @@ makeTest (
sslServerCert = "${cert}/server.crt";
servedDirs =
[ { urlPath = "/repos/NixOS/nixpkgs";
- dir = api;
+ dir = nixpkgs-api;
+ }
+ { urlPath = "/repos/fancy-enterprise/private-flake";
+ dir = private-flake-api;
+ }
+ ];
+ };
+ services.httpd.virtualHosts."github.com" =
+ { forceSSL = true;
+ sslServerKey = "${cert}/server.key";
+ sslServerCert = "${cert}/server.crt";
+ servedDirs =
+ [ { urlPath = "/NixOS/nixpkgs";
+ dir = archive;
}
];
};
@@ -103,13 +147,12 @@ makeTest (
{ config, lib, pkgs, nodes, ... }:
{ virtualisation.writableStore = true;
virtualisation.diskSize = 2048;
- virtualisation.pathsInNixDB = [ pkgs.hello pkgs.fuse ];
+ virtualisation.additionalPaths = [ pkgs.hello pkgs.fuse ];
virtualisation.memorySize = 4096;
nix.binaryCaches = lib.mkForce [ ];
nix.extraOptions = "experimental-features = nix-command flakes";
- environment.systemPackages = [ pkgs.jq ];
networking.hosts.${(builtins.head nodes.github.config.networking.interfaces.eth1.ipv4.addresses).address} =
- [ "github.com" "api.github.com" "raw.githubusercontent.com" ];
+ [ "channels.nixos.org" "api.github.com" "github.com" ];
security.pki.certificateFiles = [ "${cert}/ca.crt" ];
};
};
@@ -121,22 +164,39 @@ makeTest (
start_all()
+ def cat_log():
+ github.succeed("cat /var/log/httpd/*.log >&2")
+
github.wait_for_unit("httpd.service")
client.succeed("curl -v https://github.com/ >&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"
+ out = client.succeed("nix registry list")
+ print(out)
+ assert "github:NixOS/nixpkgs" in out, "nixpkgs flake not found"
+ assert "github:fancy-enterprise/private-flake" in out, "private flake not found"
+ cat_log()
+
+ # If no github access token is provided, nix should use the public archive url...
+ out = client.succeed("nix flake metadata nixpkgs --json")
+ print(out)
+ info = json.loads(out)
+ assert info["revision"] == "${nixpkgs.rev}", f"revision mismatch: {info['revision']} != ${nixpkgs.rev}"
+ cat_log()
+
+ # ... otherwise it should use the API
+ out = client.succeed("nix flake metadata private-flake --json --access-tokens github.com=ghp_000000000000000000000000000000000000 --tarball-ttl 0")
+ print(out)
+ info = json.loads(out)
+ assert info["revision"] == "${private-flake-rev}", f"revision mismatch: {info['revision']} != ${private-flake-rev}"
+ cat_log()
client.succeed("nix registry pin nixpkgs")
-
- client.succeed("nix flake info nixpkgs --tarball-ttl 0 >&2")
+ client.succeed("nix flake metadata nixpkgs --tarball-ttl 0 >&2")
# Shut down the web server. The flake should be cached on the client.
github.succeed("systemctl stop httpd.service")
- info = json.loads(client.succeed("nix flake info nixpkgs --json"))
+ info = json.loads(client.succeed("nix flake metadata nixpkgs --json"))
date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified']))
assert date == "${nixpkgs.lastModifiedDate}", "time mismatch"
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/installer/default.nix b/tests/installer/default.nix
new file mode 100644
index 000000000..32aa7889a
--- /dev/null
+++ b/tests/installer/default.nix
@@ -0,0 +1,220 @@
+{ binaryTarballs
+, nixpkgsFor
+}:
+
+let
+
+ installScripts = {
+ install-default = {
+ script = ''
+ tar -xf ./nix.tar.xz
+ mv ./nix-* nix
+ ./nix/install --no-channel-add
+ '';
+ };
+
+ install-force-no-daemon = {
+ script = ''
+ tar -xf ./nix.tar.xz
+ mv ./nix-* nix
+ ./nix/install --no-daemon
+ '';
+ };
+
+ install-force-daemon = {
+ script = ''
+ tar -xf ./nix.tar.xz
+ mv ./nix-* nix
+ ./nix/install --daemon --no-channel-add
+ '';
+ };
+ };
+
+ disableSELinux = "sudo setenforce 0";
+
+ images = {
+
+ /*
+ "ubuntu-14-04" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/ubuntu/boxes/trusty64/versions/20190514.0.0/providers/virtualbox.box";
+ hash = "sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8=";
+ };
+ rootDisk = "box-disk1.vmdk";
+ system = "x86_64-linux";
+ };
+ */
+
+ "ubuntu-16-04" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/ubuntu1604/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-lO4oYQR2tCh5auxAYe6bPOgEqOgv3Y3GC1QM1tEEEU8=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ };
+
+ "ubuntu-22-04" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/ubuntu2204/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-HNll0Qikw/xGIcogni5lz01vUv+R3o8xowP2EtqjuUQ=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ };
+
+ "fedora-36" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/fedora36/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-rxPgnDnFkTDwvdqn2CV3ZUo3re9AdPtSZ9SvOHNvaks=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ postBoot = disableSELinux;
+ };
+
+ # Currently fails with 'error while loading shared libraries:
+ # libsodium.so.23: cannot stat shared object: Invalid argument'.
+ /*
+ "rhel-6" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/rhel6/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-QwzbvRoRRGqUCQptM7X/InRWFSP2sqwRt2HaaO6zBGM=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ };
+ */
+
+ "rhel-7" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/rhel7/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ };
+
+ "rhel-8" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/rhel8/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-zFOPjSputy1dPgrQRixBXmlyN88cAKjJ21VvjSWUCUY=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ postBoot = disableSELinux;
+ };
+
+ "rhel-9" = {
+ image = import <nix/fetchurl.nix> {
+ url = "https://app.vagrantup.com/generic/boxes/rhel9/versions/4.1.12/providers/libvirt.box";
+ hash = "sha256-vL/FbB3kK1rcSaR627nWmScYGKGk4seSmAdq6N5diMg=";
+ };
+ rootDisk = "box.img";
+ system = "x86_64-linux";
+ postBoot = disableSELinux;
+ extraQemuOpts = "-cpu Westmere-v2";
+ };
+
+ };
+
+ makeTest = imageName: testName:
+ let image = images.${imageName}; in
+ with nixpkgsFor.${image.system};
+ runCommand
+ "installer-test-${imageName}-${testName}"
+ { buildInputs = [ qemu_kvm openssh ];
+ image = image.image;
+ postBoot = image.postBoot or "";
+ installScript = installScripts.${testName}.script;
+ binaryTarball = binaryTarballs.${system};
+ }
+ ''
+ shopt -s nullglob
+
+ echo "Unpacking Vagrant box $image..."
+ tar xvf $image
+
+ image_type=$(qemu-img info ${image.rootDisk} | sed 's/file format: \(.*\)/\1/; t; d')
+
+ qemu-img create -b ./${image.rootDisk} -F "$image_type" -f qcow2 ./disk.qcow2
+
+ extra_qemu_opts="${image.extraQemuOpts or ""}"
+
+ # Add the config disk, required by the Ubuntu images.
+ config_drive=$(echo *configdrive.vmdk || true)
+ if [[ -n $config_drive ]]; then
+ extra_qemu_opts+=" -drive id=disk2,file=$config_drive,if=virtio"
+ fi
+
+ echo "Starting qemu..."
+ qemu-kvm -m 4096 -nographic \
+ -drive id=disk1,file=./disk.qcow2,if=virtio \
+ -netdev user,id=net0,restrict=yes,hostfwd=tcp::20022-:22 -device virtio-net-pci,netdev=net0 \
+ $extra_qemu_opts &
+ qemu_pid=$!
+ trap "kill $qemu_pid" EXIT
+
+ if ! [ -e ./vagrant_insecure_key ]; then
+ cp ${./vagrant_insecure_key} vagrant_insecure_key
+ fi
+
+ chmod 0400 ./vagrant_insecure_key
+
+ ssh_opts="-o StrictHostKeyChecking=no -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa -i ./vagrant_insecure_key"
+ ssh="ssh -p 20022 -q $ssh_opts vagrant@localhost"
+
+ echo "Waiting for SSH..."
+ for ((i = 0; i < 120; i++)); do
+ echo "[ssh] Trying to connect..."
+ if $ssh -- true; then
+ echo "[ssh] Connected!"
+ break
+ fi
+ if ! kill -0 $qemu_pid; then
+ echo "qemu died unexpectedly"
+ exit 1
+ fi
+ sleep 1
+ done
+
+ if [[ -n $postBoot ]]; then
+ echo "Running post-boot commands..."
+ $ssh "set -ex; $postBoot"
+ fi
+
+ echo "Copying installer..."
+ scp -P 20022 $ssh_opts $binaryTarball/nix-*.tar.xz vagrant@localhost:nix.tar.xz
+
+ echo "Running installer..."
+ $ssh "set -eux; $installScript"
+
+ echo "Testing Nix installation..."
+ $ssh <<EOF
+ set -ex
+
+ # FIXME: get rid of this; ideally ssh should just work.
+ source ~/.bash_profile || true
+ source ~/.bash_login || true
+ source ~/.profile || true
+ source /etc/bashrc || true
+
+ nix-env --version
+ nix --extra-experimental-features nix-command store ping
+
+ out=\$(nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > \$out"]; }')
+ [[ \$(cat \$out) = foobar ]]
+ EOF
+
+ echo "Done!"
+ touch $out
+ '';
+
+in
+
+builtins.mapAttrs (imageName: image:
+ { ${image.system} = builtins.mapAttrs (testName: test:
+ makeTest imageName testName
+ ) installScripts;
+ }
+) images
diff --git a/tests/installer/vagrant_insecure_key b/tests/installer/vagrant_insecure_key
new file mode 100644
index 000000000..7d6a08390
--- /dev/null
+++ b/tests/installer/vagrant_insecure_key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI
+w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP
+kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2
+hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO
+Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW
+yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd
+ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1
+Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf
+TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK
+iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A
+sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf
+4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP
+cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk
+EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN
+CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX
+3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG
+YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj
+3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+
+dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz
+6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC
+P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF
+llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ
+kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH
++vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ
+NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/lang.sh b/tests/lang.sh
index 61bb444ba..c0b0fc58c 100644
--- a/tests/lang.sh
+++ b/tests/lang.sh
@@ -4,6 +4,9 @@ export TEST_VAR=foo # for eval-okay-getenv.nix
export NIX_REMOTE=dummy://
nix-instantiate --eval -E 'builtins.trace "Hello" 123' 2>&1 | grep -q Hello
+nix-instantiate --eval -E 'builtins.addErrorContext "Hello" 123' 2>&1
+nix-instantiate --trace-verbose --eval -E 'builtins.traceVerbose "Hello" 123' 2>&1 | grep -q Hello
+(! nix-instantiate --eval -E 'builtins.traceVerbose "Hello" 123' 2>&1 | grep -q Hello)
(! nix-instantiate --show-trace --eval -E 'builtins.addErrorContext "Hello" 123' 2>&1 | grep -q Hello)
nix-instantiate --show-trace --eval -E 'builtins.addErrorContext "Hello" (throw "Foo")' 2>&1 | grep -q Hello
@@ -14,7 +17,7 @@ fail=0
for i in lang/parse-fail-*.nix; do
echo "parsing $i (should fail)";
i=$(basename $i .nix)
- if nix-instantiate --parse - < lang/$i.nix; then
+ if ! expect 1 nix-instantiate --parse - < lang/$i.nix; then
echo "FAIL: $i shouldn't parse"
fail=1
fi
@@ -23,7 +26,7 @@ done
for i in lang/parse-okay-*.nix; do
echo "parsing $i (should succeed)";
i=$(basename $i .nix)
- if ! nix-instantiate --parse - < lang/$i.nix > lang/$i.out; then
+ if ! expect 0 nix-instantiate --parse - < lang/$i.nix > lang/$i.out; then
echo "FAIL: $i should parse"
fail=1
fi
@@ -32,7 +35,7 @@ done
for i in lang/eval-fail-*.nix; do
echo "evaluating $i (should fail)";
i=$(basename $i .nix)
- if nix-instantiate --eval lang/$i.nix; then
+ if ! expect 1 nix-instantiate --eval lang/$i.nix; then
echo "FAIL: $i shouldn't evaluate"
fail=1
fi
@@ -47,7 +50,7 @@ for i in lang/eval-okay-*.nix; do
if test -e lang/$i.flags; then
flags=$(cat lang/$i.flags)
fi
- if ! NIX_PATH=lang/dir3:lang/dir4 nix-instantiate $flags --eval --strict lang/$i.nix > lang/$i.out; then
+ if ! expect 0 env NIX_PATH=lang/dir3:lang/dir4 nix-instantiate $flags --eval --strict lang/$i.nix > lang/$i.out; then
echo "FAIL: $i should evaluate"
fail=1
elif ! diff lang/$i.out lang/$i.exp; then
@@ -57,7 +60,7 @@ for i in lang/eval-okay-*.nix; do
fi
if test -e lang/$i.exp.xml; then
- if ! nix-instantiate --eval --xml --no-location --strict \
+ if ! expect 0 nix-instantiate --eval --xml --no-location --strict \
lang/$i.nix > lang/$i.out.xml; then
echo "FAIL: $i should evaluate"
fail=1
diff --git a/tests/lang/eval-okay-eq.exp b/tests/lang/eval-okay-eq.exp
new file mode 100644
index 000000000..27ba77dda
--- /dev/null
+++ b/tests/lang/eval-okay-eq.exp
@@ -0,0 +1 @@
+true
diff --git a/tests/lang/eval-okay-eq.exp.disabled b/tests/lang/eval-okay-eq.exp.disabled
deleted file mode 100644
index 2015847b6..000000000
--- a/tests/lang/eval-okay-eq.exp.disabled
+++ /dev/null
@@ -1 +0,0 @@
-Bool(True)
diff --git a/tests/lang/eval-okay-fromjson.nix b/tests/lang/eval-okay-fromjson.nix
index 102ee82b5..e1c0f86cc 100644
--- a/tests/lang/eval-okay-fromjson.nix
+++ b/tests/lang/eval-okay-fromjson.nix
@@ -1,36 +1,35 @@
-# RFC 7159, section 13.
builtins.fromJSON
''
{
- "Image": {
- "Width": 800,
- "Height": 600,
- "Title": "View from 15th Floor",
- "Thumbnail": {
- "Url": "http://www.example.com/image/481989943",
- "Height": 125,
- "Width": 100
+ "Video": {
+ "Title": "The Penguin Chronicles",
+ "Width": 1920,
+ "Height": 1080,
+ "EmbeddedData": [3.14159, 23493,null, true ,false, -10],
+ "Thumb": {
+ "Url": "http://www.example.com/video/5678931",
+ "Width": 200,
+ "Height": 250
},
- "Animated" : false,
- "IDs": [116, 943, 234, 38793, true ,false,null, -100],
- "Latitude": 37.7668,
- "Longitude": -122.3959
+ "Subtitle" : false,
+ "Latitude": 46.2051,
+ "Longitude": 6.0723
}
}
''
==
- { Image =
- { Width = 800;
- Height = 600;
- Title = "View from 15th Floor";
- Thumbnail =
- { Url = http://www.example.com/image/481989943;
- Height = 125;
- Width = 100;
+ { Video =
+ { Title = "The Penguin Chronicles";
+ Width = 1920;
+ Height = 1080;
+ EmbeddedData = [ 3.14159 23493 null true false (0-10) ];
+ Thumb =
+ { Url = "http://www.example.com/video/5678931";
+ Width = 200;
+ Height = 250;
};
- Animated = false;
- IDs = [ 116 943 234 38793 true false null (0-100) ];
- Latitude = 37.7668;
- Longitude = -122.3959;
+ Subtitle = false;
+ Latitude = 46.2051;
+ Longitude = 6.0723;
};
}
diff --git a/tests/lang/eval-okay-versions.nix b/tests/lang/eval-okay-versions.nix
index e63c36586..e9111f5f4 100644
--- a/tests/lang/eval-okay-versions.nix
+++ b/tests/lang/eval-okay-versions.nix
@@ -4,6 +4,7 @@ let
name2 = "hello";
name3 = "915resolution-0.5.2";
name4 = "xf86-video-i810-1.7.4";
+ name5 = "name-that-ends-with-dash--1.0";
eq = 0;
lt = builtins.sub 0 1;
@@ -23,6 +24,8 @@ let
((builtins.parseDrvName name3).version == "0.5.2")
((builtins.parseDrvName name4).name == "xf86-video-i810")
((builtins.parseDrvName name4).version == "1.7.4")
+ ((builtins.parseDrvName name5).name == "name-that-ends-with-dash")
+ ((builtins.parseDrvName name5).version == "-1.0")
(versionTest "1.0" "2.3" lt)
(versionTest "2.1" "2.3" lt)
(versionTest "2.3" "2.3" eq)
diff --git a/tests/lang/parse-fail-eof-in-string.nix b/tests/lang/parse-fail-eof-in-string.nix
new file mode 100644
index 000000000..19775d2ec
--- /dev/null
+++ b/tests/lang/parse-fail-eof-in-string.nix
@@ -0,0 +1,3 @@
+# https://github.com/NixOS/nix/issues/6562
+# Note that this file must not end with a newline.
+a 1"$ \ No newline at end of file
diff --git a/tests/local.mk b/tests/local.mk
index 53a9179a3..340817ec3 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -1,5 +1,12 @@
nix_tests = \
- flakes.sh \
+ flakes/flakes.sh \
+ flakes/run.sh \
+ flakes/mercurial.sh \
+ flakes/circular.sh \
+ flakes/init.sh \
+ flakes/follow-paths.sh \
+ flakes/bundle.sh \
+ flakes/check.sh \
ca/gc.sh \
gc.sh \
remote-store.sh \
@@ -21,6 +28,8 @@ nix_tests = \
tarball.sh \
fetchGit.sh \
fetchurl.sh \
+ fetchPath.sh \
+ fetchTree-file.sh \
simple.sh \
referrers.sh \
optimise-store.sh \
@@ -41,7 +50,7 @@ nix_tests = \
secure-drv-outputs.sh \
restricted.sh \
fetchGitSubmodules.sh \
- flake-searching.sh \
+ flakes/search-root.sh \
ca/duplicate-realisation-in-closure.sh \
readfile-context.sh \
nix-channel.sh \
@@ -52,6 +61,7 @@ nix_tests = \
build-remote-content-addressed-floating.sh \
nar-access.sh \
pure-eval.sh \
+ eval.sh \
ca/post-hook.sh \
repl.sh \
ca/repl.sh \
@@ -76,7 +86,8 @@ nix_tests = \
nix-copy-ssh.sh \
post-hook.sh \
function-trace.sh \
- flake-local-settings.sh \
+ flakes/config.sh \
+ fmt.sh \
eval-store.sh \
why-depends.sh \
import-derivation.sh \
@@ -88,11 +99,18 @@ nix_tests = \
plugins.sh \
build.sh \
ca/nix-run.sh \
+ selfref-gc.sh ca/selfref-gc.sh \
db-migration.sh \
- nix-profile.sh \
+ bash-profile.sh \
pass-as-file.sh \
describe-stores.sh \
- store-ping.sh
+ nix-profile.sh \
+ suggestions.sh \
+ store-ping.sh \
+ fetchClosure.sh \
+ completions.sh \
+ impure-derivations.sh \
+ path-from-hash-part.sh
ifeq ($(HAVE_LIBCPUID), 1)
nix_tests += compute-levels.sh
@@ -104,4 +122,8 @@ tests-environment = NIX_REMOTE= $(bash) -e
clean-files += $(d)/common.sh $(d)/config.nix $(d)/ca/config.nix
-test-deps += tests/common.sh tests/config.nix tests/ca/config.nix tests/plugins/libplugintest.$(SO_EXT)
+test-deps += tests/common.sh tests/config.nix tests/ca/config.nix
+
+ifeq ($(BUILD_SHARED_LIBS), 1)
+ test-deps += tests/plugins/libplugintest.$(SO_EXT)
+endif
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/multiple-outputs.nix b/tests/multiple-outputs.nix
index b915493f7..624a5dade 100644
--- a/tests/multiple-outputs.nix
+++ b/tests/multiple-outputs.nix
@@ -80,4 +80,11 @@ rec {
'';
}).a;
+ e = mkDerivation {
+ name = "multiple-outputs-e";
+ outputs = [ "a" "b" "c" ];
+ meta.outputsToInstall = [ "a" "b" ];
+ buildCommand = "mkdir $a $b $c";
+ };
+
}
diff --git a/tests/nix-copy-closure.nix b/tests/nix-copy-closure.nix
index 1b63a3fca..ba8b2cfc9 100644
--- a/tests/nix-copy-closure.nix
+++ b/tests/nix-copy-closure.nix
@@ -14,7 +14,7 @@ makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; pkgD = pk
{ client =
{ config, lib, pkgs, ... }:
{ virtualisation.writableStore = true;
- virtualisation.pathsInNixDB = [ pkgA pkgD.drvPath ];
+ virtualisation.additionalPaths = [ pkgA pkgD.drvPath ];
nix.binaryCaches = lib.mkForce [ ];
};
@@ -22,7 +22,7 @@ makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; pkgD = pk
{ config, pkgs, ... }:
{ services.openssh.enable = true;
virtualisation.writableStore = true;
- virtualisation.pathsInNixDB = [ pkgB pkgC ];
+ virtualisation.additionalPaths = [ pkgB pkgC ];
};
};
diff --git a/tests/nix-profile.sh b/tests/nix-profile.sh
index e2e0d1090..7ba3235fa 100644
--- a/tests/nix-profile.sh
+++ b/tests/nix-profile.sh
@@ -1,9 +1,140 @@
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"
+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}";
+ outputs = [ "out" "man" "dev" ];
+ 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
+ mkdir -p \$man/share/man
+ mkdir -p \$dev/include
+ '';
+ __contentAddressed = import ./ca.nix;
+ outputHashMode = "recursive";
+ outputHashAlgo = "sha256";
+ meta.outputsToInstall = [ "out" "man" ];
+ };
+ };
+}
+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" ]]
+[ -e $TEST_HOME/.nix-profile/share/man ]
+(! [ -e $TEST_HOME/.nix-profile/include ])
+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, 1.0-man -> 2.0, 2.0-man"
+
+# 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, 1.0-man -> 3.0, 3.0-man"
+
+# 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: ]]
+
+# Override the outputs.
+nix profile remove 0 1
+nix profile install "$flake1Dir^*"
+[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello Utrecht" ]]
+[ -e $TEST_HOME/.nix-profile/share/man ]
+[ -e $TEST_HOME/.nix-profile/include ]
+
+printf Nix > $flake1Dir/who
+nix profile upgrade 0
+[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello Nix" ]]
+[ -e $TEST_HOME/.nix-profile/share/man ]
+[ -e $TEST_HOME/.nix-profile/include ]
+
+nix profile remove 0
+nix profile install "$flake1Dir^man"
+(! [ -e $TEST_HOME/.nix-profile/bin/hello ])
+[ -e $TEST_HOME/.nix-profile/share/man ]
+(! [ -e $TEST_HOME/.nix-profile/include ])
+
+# test priority
+nix profile remove 0
+
+# Make another flake.
+flake2Dir=$TEST_ROOT/flake2
+printf World > $flake1Dir/who
+cp -r $flake1Dir $flake2Dir
+printf World2 > $flake2Dir/who
+
+nix profile install $flake1Dir
+[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
+nix profile install $flake2Dir --priority 100
+[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
+nix profile install $flake2Dir --priority 0
+[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World2" ]]
+# nix profile install $flake1Dir --priority 100
+# [[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
diff --git a/tests/nix-shell.sh b/tests/nix-shell.sh
index 3241d7a0f..f291c6f79 100644
--- a/tests/nix-shell.sh
+++ b/tests/nix-shell.sh
@@ -102,3 +102,11 @@ source <(nix print-dev-env -f "$shellDotNix" shellDrv)
[[ ${arr2[1]} = $'\n' ]]
[[ ${arr2[2]} = $'x\ny' ]]
[[ $(fun) = blabla ]]
+
+# Test nix-shell with ellipsis and no `inNixShell` argument (for backwards compat with old nixpkgs)
+cat >$TEST_ROOT/shell-ellipsis.nix <<EOF
+{ system ? "x86_64-linux", ... }@args:
+assert (!(args ? inNixShell));
+(import $shellDotNix { }).shellDrv
+EOF
+nix-shell $TEST_ROOT/shell-ellipsis.nix --run "true"
diff --git a/tests/nss-preload.nix b/tests/nss-preload.nix
index 2610d2b30..64b655ba2 100644
--- a/tests/nss-preload.nix
+++ b/tests/nss-preload.nix
@@ -5,6 +5,42 @@ with import (nixpkgs + "/nixos/lib/testing-python.nix") {
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
};
+let
+ 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" ];
+ }
+ '';
+in
+
makeTest (
rec {
@@ -68,40 +104,6 @@ rec {
};
};
- 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)
diff --git a/tests/path-from-hash-part.sh b/tests/path-from-hash-part.sh
new file mode 100644
index 000000000..bdd104434
--- /dev/null
+++ b/tests/path-from-hash-part.sh
@@ -0,0 +1,10 @@
+source common.sh
+
+path=$(nix build --no-link --print-out-paths -f simple.nix)
+
+hash_part=$(basename $path)
+hash_part=${hash_part:0:32}
+
+path2=$(nix store path-from-hash-part $hash_part)
+
+[[ $path = $path2 ]]
diff --git a/tests/plugins.sh b/tests/plugins.sh
index e22bf4408..6e278ad9d 100644
--- a/tests/plugins.sh
+++ b/tests/plugins.sh
@@ -2,6 +2,11 @@ source common.sh
set -o pipefail
+if [[ $BUILD_SHARED_LIBS != 1 ]]; then
+ echo "plugins are not supported"
+ exit 99
+fi
+
res=$(nix --option setting-set true --option plugin-files $PWD/plugins/libplugintest* eval --expr builtins.anotherNull)
[ "$res"x = "nullx" ]
diff --git a/tests/plugins/plugintest.cc b/tests/plugins/plugintest.cc
index cd7c9f8b1..04b791021 100644
--- a/tests/plugins/plugintest.cc
+++ b/tests/plugins/plugintest.cc
@@ -13,7 +13,7 @@ MySettings mySettings;
static GlobalConfig::Register rs(&mySettings);
-static void prim_anotherNull (EvalState & state, const Pos & pos, Value ** args, Value & v)
+static void prim_anotherNull (EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
if (mySettings.settingSet)
v.mkNull();
diff --git a/tests/post-hook.sh b/tests/post-hook.sh
index 049e40749..4eff5f511 100644
--- a/tests/post-hook.sh
+++ b/tests/post-hook.sh
@@ -9,12 +9,12 @@ echo 'require-sigs = false' >> $NIX_CONF_DIR/nix.conf
restartDaemon
-# Build the dependencies and push them to the remote store
+# Build the dependencies and push them to the remote store.
nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook $PWD/push-to-store.sh
clearStore
-# Ensure that we the remote store contains both the runtime and buildtime
-# closure of what we've just built
+# Ensure that the remote store contains both the runtime and build-time
+# closure of what we've just built.
nix copy --from "$REMOTE_STORE" --no-require-sigs -f dependencies.nix
nix copy --from "$REMOTE_STORE" --no-require-sigs -f dependencies.nix input1_drv
diff --git a/tests/pure-eval.sh b/tests/pure-eval.sh
index 1a4568ea6..b83ab8afe 100644
--- a/tests/pure-eval.sh
+++ b/tests/pure-eval.sh
@@ -30,3 +30,5 @@ nix eval --store dummy:// --write-to $TEST_ROOT/eval-out --expr '{ x = "foo" + "
rm -rf $TEST_ROOT/eval-out
(! nix eval --store dummy:// --write-to $TEST_ROOT/eval-out --expr '{ "." = "bla"; }')
+
+(! nix eval --expr '~/foo')
diff --git a/tests/push-to-store.sh b/tests/push-to-store.sh
index 25352c751..b1495c9e2 100755
--- a/tests/push-to-store.sh
+++ b/tests/push-to-store.sh
@@ -1,6 +1,10 @@
#!/bin/sh
set -x
+set -e
+
+[ -n "$OUT_PATHS" ]
+[ -n "$DRV_PATH" ]
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
diff --git a/tests/remote-builds.nix b/tests/remote-builds.nix
index b9e7352c0..7b2e6f708 100644
--- a/tests/remote-builds.nix
+++ b/tests/remote-builds.nix
@@ -61,7 +61,7 @@ in
}
];
virtualisation.writableStore = true;
- virtualisation.pathsInNixDB = [ config.system.build.extraUtils ];
+ virtualisation.additionalPaths = [ config.system.build.extraUtils ];
nix.binaryCaches = lib.mkForce [ ];
programs.ssh.extraConfig = "ConnectTimeout 30";
};
diff --git a/tests/repl.sh b/tests/repl.sh
index 6505f1741..c555560cc 100644
--- a/tests/repl.sh
+++ b/tests/repl.sh
@@ -1,29 +1,37 @@
source common.sh
+testDir="$PWD"
+cd "$TEST_ROOT"
+
replCmds="
simple = 1
-simple = import ./simple.nix
-:b simple
+simple = import $testDir/simple.nix
+:bl simple
:log simple
"
replFailingCmds="
-failing = import ./simple-failing.nix
+failing = import $testDir/simple-failing.nix
:b failing
:log failing
"
replUndefinedVariable="
-import ./undefined-variable.nix
+import $testDir/undefined-variable.nix
"
testRepl () {
local nixArgs=("$@")
+ rm -rf repl-result-out || true # cleanup from other runs backed by a foreign nix store
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"
+ [ "$(realpath ./repl-result-out)" == "$outPath" ] || fail "nix repl :bl doesn't make a symlink"
+ # run it again without checking the output to ensure the previously created symlink gets overwritten
+ nix repl "${nixArgs[@]}" <<< "$replCmds" || fail "nix repl does not work twice with the same inputs"
+
# 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)"
@@ -34,6 +42,11 @@ testRepl () {
echo "$replOutput"
echo "$replOutput" | grep -qs "while evaluating the file" \
|| fail "nix repl --show-trace doesn't show the trace"
+
+ nix repl "${nixArgs[@]}" --option pure-eval true 2>&1 <<< "builtins.currentSystem" \
+ | grep "attribute 'currentSystem' missing"
+ nix repl "${nixArgs[@]}" 2>&1 <<< "builtins.currentSystem" \
+ | grep "$(nix-instantiate --eval -E 'builtins.currentSystem')"
}
# Simple test, try building a drv
@@ -42,15 +55,17 @@ testRepl
testRepl --store "$TEST_ROOT/store?real=$NIX_STORE_DIR"
testReplResponse () {
- local response="$(nix repl <<< "$1")"
- echo "$response" | grep -qs "$2" \
+ local commands="$1"; shift
+ local expectedResponse="$1"; shift
+ local response="$(nix repl "$@" <<< "$commands")"
+ echo "$response" | grep -qs "$expectedResponse" \
|| fail "repl command set:
-$1
+$commands
does not respond with:
-$2
+$expectedResponse
but with:
@@ -63,3 +78,48 @@ testReplResponse '
:a { a = "2"; }
"result: ${a}"
' "result: 2"
+
+testReplResponse '
+drvPath
+' '".*-simple.drv"' \
+$testDir/simple.nix
+
+testReplResponse '
+drvPath
+' '".*-simple.drv"' \
+--file $testDir/simple.nix --experimental-features 'ca-derivations'
+
+testReplResponse '
+drvPath
+' '".*-simple.drv"' \
+--file $testDir/simple.nix --extra-experimental-features 'repl-flake ca-derivations'
+
+mkdir -p flake && cat <<EOF > flake/flake.nix
+{
+ outputs = { self }: {
+ foo = 1;
+ bar.baz = 2;
+
+ changingThing = "beforeChange";
+ };
+}
+EOF
+testReplResponse '
+foo + baz
+' "3" \
+ ./flake ./flake\#bar --experimental-features 'flakes repl-flake'
+
+# Test the `:reload` mechansim with flakes:
+# - Eval `./flake#changingThing`
+# - Modify the flake
+# - Re-eval it
+# - Check that the result has changed
+replResult=$( (
+echo "changingThing"
+sleep 1 # Leave the repl the time to eval 'foo'
+sed -i 's/beforeChange/afterChange/' flake/flake.nix
+echo ":reload"
+echo "changingThing"
+) | nix repl ./flake --experimental-features 'flakes repl-flake')
+echo "$replResult" | grep -qs beforeChange
+echo "$replResult" | grep -qs afterChange
diff --git a/tests/search.sh b/tests/search.sh
index 52e12f381..1a98f5b49 100644
--- a/tests/search.sh
+++ b/tests/search.sh
@@ -28,11 +28,19 @@ nix search -f search.nix '' |grep -q hello
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 ))
+(( $(nix search -f search.nix '' 'oo' 'foo' 'oo' | grep -c "$e\[32;1mfoo$e\\[0;1m") == 1 ))
+(( $(nix search -f search.nix '' 'broken b' 'en bar' | grep -c "$e\[32;1mbroken bar$e\\[0m") == 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 ))
+(( $(nix search -f search.nix '' 'o' | grep -Eoc "$e\[32;1mo{1,2}$e\[(0|0;1)m") == 3 ))
# Searching for 'b' should yield the 'b' in bar and the two 'b's in 'broken bar'
+# NOTE: This does not work with `grep -c` because it counts the two 'b's in 'broken bar' as one matched line
(( $(nix search -f search.nix '' 'b' | grep -Eo "$e\[32;1mb$e\[(0|0;1)m" | wc -l) == 3 ))
+
+## Tests for --exclude
+(( $(nix search -f search.nix -e hello | grep -c hello) == 0 ))
+
+(( $(nix search -f search.nix foo --exclude 'foo|bar' | grep -Ec 'foo|bar') == 0 ))
+(( $(nix search -f search.nix foo -e foo --exclude bar | grep -Ec 'foo|bar') == 0 ))
+[[ $(nix search -f search.nix -e bar --json | jq -c 'keys') == '["foo","hello"]' ]]
diff --git a/tests/selfref-gc.sh b/tests/selfref-gc.sh
new file mode 100644
index 000000000..3f1f50eea
--- /dev/null
+++ b/tests/selfref-gc.sh
@@ -0,0 +1,30 @@
+source common.sh
+
+requireDaemonNewerThan "2.6.0pre20211215"
+
+clearStore
+
+nix-build --no-out-link -E '
+ with import ./config.nix;
+
+ let d1 = mkDerivation {
+ name = "selfref-gc";
+ outputs = [ "out" ];
+ buildCommand = "
+ echo SELF_REF: $out > $out
+ ";
+ }; in
+
+ # the only change from d1 is d1 as an (unused) build input
+ # to get identical store path in CA.
+ mkDerivation {
+ name = "selfref-gc";
+ outputs = [ "out" ];
+ buildCommand = "
+ echo UNUSED: ${d1}
+ echo SELF_REF: $out > $out
+ ";
+ }
+'
+
+nix-collect-garbage
diff --git a/tests/setuid.nix b/tests/setuid.nix
index 35eb304ed..a83b1fc3a 100644
--- a/tests/setuid.nix
+++ b/tests/setuid.nix
@@ -10,12 +10,12 @@ with import (nixpkgs + "/nixos/lib/testing-python.nix") {
makeTest {
name = "setuid";
- machine =
+ nodes.machine =
{ config, lib, pkgs, ... }:
{ virtualisation.writableStore = true;
nix.binaryCaches = lib.mkForce [ ];
nix.nixPath = [ "nixpkgs=${lib.cleanSource pkgs.path}" ];
- virtualisation.pathsInNixDB = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ];
+ virtualisation.additionalPaths = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ];
};
testScript = { nodes }: ''
diff --git a/tests/shell-hello.nix b/tests/shell-hello.nix
index 77dcbd2a9..3fdd3501d 100644
--- a/tests/shell-hello.nix
+++ b/tests/shell-hello.nix
@@ -3,15 +3,24 @@ with import ./config.nix;
{
hello = mkDerivation {
name = "hello";
+ outputs = [ "out" "dev" ];
+ meta.outputsToInstall = [ "out" ];
buildCommand =
''
- mkdir -p $out/bin
+ mkdir -p $out/bin $dev/bin
+
cat > $out/bin/hello <<EOF
#! ${shell}
who=\$1
echo "Hello \''${who:-World} from $out/bin/hello"
EOF
chmod +x $out/bin/hello
+
+ cat > $dev/bin/hello2 <<EOF
+ #! ${shell}
+ echo "Hello2"
+ EOF
+ chmod +x $dev/bin/hello2
'';
};
}
diff --git a/tests/shell.sh b/tests/shell.sh
index 2b85bb337..6a80e8385 100644
--- a/tests/shell.sh
+++ b/tests/shell.sh
@@ -6,6 +6,10 @@ clearCache
nix shell -f shell-hello.nix hello -c hello | grep 'Hello World'
nix shell -f shell-hello.nix hello -c hello NixOS | grep 'Hello NixOS'
+# Test output selection.
+nix shell -f shell-hello.nix hello^dev -c hello2 | grep 'Hello2'
+nix shell -f shell-hello.nix 'hello^*' -c hello2 | grep 'Hello2'
+
if ! canUseSandbox; then exit 99; fi
chmod -R u+w $TEST_ROOT/store0 || true
diff --git a/tests/signing.sh b/tests/signing.sh
index 6aafbeb91..9b673c609 100644
--- a/tests/signing.sh
+++ b/tests/signing.sh
@@ -81,7 +81,7 @@ info=$(nix path-info --store file://$cacheDir --json $outPath2)
[[ $info =~ 'cache1.example.org' ]]
[[ $info =~ 'cache2.example.org' ]]
-# Copying to a diverted store should fail due to a lack of valid signatures.
+# Copying to a diverted store should fail due to a lack of signatures by trusted keys.
chmod -R u+w $TEST_ROOT/store0 || true
rm -rf $TEST_ROOT/store0
(! nix copy --to $TEST_ROOT/store0 $outPath)
diff --git a/tests/sourcehut-flakes.nix b/tests/sourcehut-flakes.nix
index d1d89d149..daa259dd6 100644
--- a/tests/sourcehut-flakes.nix
+++ b/tests/sourcehut-flakes.nix
@@ -59,7 +59,7 @@ let
echo 'ref: refs/heads/master' > $out/HEAD
mkdir -p $out/info
- echo '${nixpkgs.rev} refs/heads/master' > $out/info/refs
+ echo -e '${nixpkgs.rev}\trefs/heads/master\n${nixpkgs.rev}\trefs/tags/foo-bar' > $out/info/refs
'';
in
@@ -106,7 +106,7 @@ makeTest (
{
virtualisation.writableStore = true;
virtualisation.diskSize = 2048;
- virtualisation.pathsInNixDB = [ pkgs.hello pkgs.fuse ];
+ virtualisation.additionalPaths = [ pkgs.hello pkgs.fuse ];
virtualisation.memorySize = 4096;
nix.binaryCaches = lib.mkForce [ ];
nix.extraOptions = ''
@@ -132,6 +132,17 @@ makeTest (
client.succeed("curl -v https://git.sr.ht/ >&2")
client.succeed("nix registry list | grep nixpkgs")
+ # Test that it resolves HEAD
+ rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs --json | jq -r .revision")
+ assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
+ # Test that it resolves branches
+ rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs/master --json | jq -r .revision")
+ assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
+ # Test that it resolves tags
+ rev = client.succeed("nix flake info sourcehut:~NixOS/nixpkgs/foo-bar --json | jq -r .revision")
+ assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
+
+ # Registry and pinning test
rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision")
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
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