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