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