aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/binary-cache.sh26
-rw-r--r--tests/build-delete.sh2
-rw-r--r--tests/build-dry.sh2
-rw-r--r--tests/build-remote.sh35
-rw-r--r--tests/build.sh2
-rw-r--r--tests/ca/build.sh16
-rw-r--r--tests/ca/substitute.sh10
-rw-r--r--tests/check-refs.sh10
-rw-r--r--tests/check-reqs.sh4
-rw-r--r--tests/check.sh2
-rw-r--r--tests/common.sh2
-rw-r--r--tests/common/vars-and-functions.sh.in87
-rw-r--r--tests/compute-levels.sh2
-rw-r--r--tests/db-migration.sh10
-rw-r--r--tests/dependencies.sh6
-rw-r--r--tests/describe-stores.sh8
-rw-r--r--tests/eval-store.sh2
-rw-r--r--tests/experimental-features.sh23
-rw-r--r--tests/export-graph.sh2
-rw-r--r--tests/fetchClosure.sh4
-rw-r--r--tests/fetchGit.sh5
-rw-r--r--tests/fetchGitRefs.sh7
-rw-r--r--tests/fetchGitSubmodules.sh5
-rw-r--r--tests/fetchMercurial.sh5
-rw-r--r--tests/fetchTree-file.sh4
-rw-r--r--tests/fetchurl.sh2
-rw-r--r--tests/flakes/build-paths.sh2
-rw-r--r--tests/flakes/check.sh4
-rw-r--r--tests/flakes/common.sh9
-rw-r--r--tests/flakes/flake-in-submodule.sh52
-rw-r--r--tests/flakes/flakes.sh26
-rw-r--r--tests/flakes/follow-paths.sh2
-rw-r--r--tests/flakes/mercurial.sh5
-rw-r--r--tests/flakes/show.sh21
-rw-r--r--tests/fmt.sh2
-rwxr-xr-xtests/function-trace.sh10
-rw-r--r--tests/gc-runtime.sh2
-rw-r--r--tests/gc.sh17
-rw-r--r--tests/hash.sh32
-rw-r--r--tests/impure-derivations.sh2
-rwxr-xr-xtests/init.sh2
-rwxr-xr-xtests/install-darwin.sh2
-rw-r--r--tests/installer/default.nix22
-rw-r--r--tests/lang.sh10
-rw-r--r--tests/linux-sandbox.sh8
-rw-r--r--tests/local.mk8
-rw-r--r--tests/misc.sh12
-rw-r--r--tests/multiple-outputs.sh8
-rw-r--r--tests/nar-access.sh4
-rw-r--r--tests/nix-channel.sh14
-rw-r--r--tests/nix-profile.sh30
-rw-r--r--tests/nix-shell.sh43
-rw-r--r--tests/plugins.sh5
-rw-r--r--tests/post-hook.sh8
-rw-r--r--tests/pure-eval.sh2
-rwxr-xr-xtests/push-to-store-old.sh10
-rwxr-xr-xtests/push-to-store.sh2
-rw-r--r--tests/recursive.sh2
-rw-r--r--tests/repl.sh12
-rw-r--r--tests/restricted.sh2
-rw-r--r--tests/search.sh6
-rw-r--r--tests/shell.sh2
-rw-r--r--tests/tarball.sh4
-rw-r--r--tests/test-infra.sh85
-rw-r--r--tests/timeout.sh7
-rw-r--r--tests/user-envs-migration.sh2
-rw-r--r--tests/user-envs.sh50
-rw-r--r--tests/why-depends.sh10
68 files changed, 585 insertions, 256 deletions
diff --git a/tests/binary-cache.sh b/tests/binary-cache.sh
index 0361ac6a8..7c64a115c 100644
--- a/tests/binary-cache.sh
+++ b/tests/binary-cache.sh
@@ -15,15 +15,15 @@ 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'
+expect 1 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'
+expect 1 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 store copy-log --from file://$cacheDir $(nix-store -qd $outPath)^'*'
nix log $outPath | grep FOO
basicDownloadTests() {
@@ -78,8 +78,8 @@ mv $nar $nar.good
mkdir -p $TEST_ROOT/empty
nix-store --dump $TEST_ROOT/empty | xz > $nar
-nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
-grep -q "hash mismatch" $TEST_ROOT/log
+expect 1 nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
+grepQuiet "hash mismatch" $TEST_ROOT/log
mv $nar.good $nar
@@ -126,9 +126,9 @@ clearStore
rm -v $(grep -l "StorePath:.*dependencies-input-2" $cacheDir/*.narinfo)
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
-grep -q "copying path.*input-0" $TEST_ROOT/log
-grep -q "copying path.*input-2" $TEST_ROOT/log
-grep -q "copying path.*top" $TEST_ROOT/log
+grepQuiet "copying path.*input-0" $TEST_ROOT/log
+grepQuiet "copying path.*input-2" $TEST_ROOT/log
+grepQuiet "copying path.*top" $TEST_ROOT/log
# Idem, but without cached .narinfo.
@@ -136,11 +136,11 @@ clearStore
clearCacheCache
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
-grep -q "don't know how to build" $TEST_ROOT/log
-grep -q "building.*input-1" $TEST_ROOT/log
-grep -q "building.*input-2" $TEST_ROOT/log
-grep -q "copying path.*input-0" $TEST_ROOT/log
-grep -q "copying path.*top" $TEST_ROOT/log
+grepQuiet "don't know how to build" $TEST_ROOT/log
+grepQuiet "building.*input-1" $TEST_ROOT/log
+grepQuiet "building.*input-2" $TEST_ROOT/log
+grepQuiet "copying path.*input-0" $TEST_ROOT/log
+grepQuiet "copying path.*top" $TEST_ROOT/log
# Create a signed binary cache.
diff --git a/tests/build-delete.sh b/tests/build-delete.sh
index 636681f64..9c56b00e8 100644
--- a/tests/build-delete.sh
+++ b/tests/build-delete.sh
@@ -2,8 +2,6 @@ source common.sh
clearStore
-set -o pipefail
-
# https://github.com/NixOS/nix/issues/6572
issue_6572_independent_outputs() {
nix build -f multiple-outputs.nix --json independent --no-link > $TEST_ROOT/independent.json
diff --git a/tests/build-dry.sh b/tests/build-dry.sh
index 5f29239dc..6d1754af5 100644
--- a/tests/build-dry.sh
+++ b/tests/build-dry.sh
@@ -54,7 +54,7 @@ clearCache
RES=$(nix build -f dependencies.nix --dry-run --json)
-if [[ -z "$NIX_TESTS_CA_BY_DEFAULT" ]]; then
+if [[ -z "${NIX_TESTS_CA_BY_DEFAULT-}" ]]; then
echo "$RES" | jq '.[0] | [
(.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")),
(.outputs.out | test("'$NIX_STORE_DIR'"))
diff --git a/tests/build-remote.sh b/tests/build-remote.sh
index 25a482003..78e12b477 100644
--- a/tests/build-remote.sh
+++ b/tests/build-remote.sh
@@ -1,5 +1,5 @@
-if ! canUseSandbox; then exit 99; fi
-if ! [[ $busybox =~ busybox ]]; then exit 99; fi
+requireSandboxSupport
+[[ $busybox =~ busybox ]] || skipTest "no busybox"
unset NIX_STORE_DIR
unset NIX_STATE_DIR
@@ -7,7 +7,7 @@ unset NIX_STATE_DIR
function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }
EXTRA_SYSTEM_FEATURES=()
-if [[ -n "$CONTENT_ADDRESSED" ]]; then
+if [[ -n "${CONTENT_ADDRESSED-}" ]]; then
EXTRA_SYSTEM_FEATURES=("ca-derivations")
fi
@@ -42,25 +42,26 @@ testPrintOutPath=$(nix build -L -v -f $file --no-link --print-out-paths --max-jo
[[ $testPrintOutPath =~ store.*build-remote ]]
-set -o pipefail
-
# Ensure that input1 was built on store1 due to the required feature.
-nix path-info --store $TEST_ROOT/machine1 --all \
- | grep builder-build-remote-input-1.sh \
- | grep -v builder-build-remote-input-2.sh \
- | grep -v builder-build-remote-input-3.sh
+output=$(nix path-info --store $TEST_ROOT/machine1 --all)
+echo "$output" | grepQuiet builder-build-remote-input-1.sh
+echo "$output" | grepQuietInverse builder-build-remote-input-2.sh
+echo "$output" | grepQuietInverse builder-build-remote-input-3.sh
+unset output
# Ensure that input2 was built on store2 due to the required feature.
-nix path-info --store $TEST_ROOT/machine2 --all \
- | grep -v builder-build-remote-input-1.sh \
- | grep builder-build-remote-input-2.sh \
- | grep -v builder-build-remote-input-3.sh
+output=$(nix path-info --store $TEST_ROOT/machine2 --all)
+echo "$output" | grepQuietInverse builder-build-remote-input-1.sh
+echo "$output" | grepQuiet builder-build-remote-input-2.sh
+echo "$output" | grepQuietInverse builder-build-remote-input-3.sh
+unset output
# Ensure that input3 was built on store3 due to the required feature.
-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
+output=$(nix path-info --store $TEST_ROOT/machine3 --all)
+echo "$output" | grepQuietInverse builder-build-remote-input-1.sh
+echo "$output" | grepQuietInverse builder-build-remote-input-2.sh
+echo "$output" | grepQuiet builder-build-remote-input-3.sh
+unset output
for i in input1 input3; do
diff --git a/tests/build.sh b/tests/build.sh
index 2dfd43b65..b579fc374 100644
--- a/tests/build.sh
+++ b/tests/build.sh
@@ -2,8 +2,6 @@ source common.sh
clearStore
-set -o pipefail
-
# Make sure that 'nix build' returns all outputs by default.
nix build -f multiple-outputs.nix --json a b --no-link | jq --exit-status '
(.[0] |
diff --git a/tests/ca/build.sh b/tests/ca/build.sh
index cc225c6c8..98e1c5125 100644
--- a/tests/ca/build.sh
+++ b/tests/ca/build.sh
@@ -2,14 +2,14 @@
source common.sh
-drv=$(nix-instantiate --experimental-features ca-derivations ./content-addressed.nix -A rootCA --arg seed 1)
-nix --experimental-features 'nix-command ca-derivations' show-derivation "$drv" --arg seed 1
+drv=$(nix-instantiate ./content-addressed.nix -A rootCA --arg seed 1)
+nix show-derivation "$drv" --arg seed 1
buildAttr () {
local derivationPath=$1
local seedValue=$2
shift; shift
- local args=("--experimental-features" "ca-derivations" "./content-addressed.nix" "-A" "$derivationPath" --arg seed "$seedValue" "--no-out-link")
+ local args=("./content-addressed.nix" "-A" "$derivationPath" --arg seed "$seedValue" "--no-out-link")
args+=("$@")
nix-build "${args[@]}"
}
@@ -19,7 +19,7 @@ testRemoteCache () {
local outPath=$(buildAttr dependentNonCA 1)
nix copy --to file://$cacheDir $outPath
clearStore
- buildAttr dependentNonCA 1 --option substituters file://$cacheDir --no-require-sigs |& (! grep "building dependent-non-ca")
+ buildAttr dependentNonCA 1 --option substituters file://$cacheDir --no-require-sigs |& grepQuietInverse "building dependent-non-ca"
}
testDeterministicCA () {
@@ -46,17 +46,17 @@ testCutoff () {
}
testGC () {
- nix-instantiate --experimental-features ca-derivations ./content-addressed.nix -A rootCA --arg seed 5
- nix-collect-garbage --experimental-features ca-derivations --option keep-derivations true
+ nix-instantiate ./content-addressed.nix -A rootCA --arg seed 5
+ nix-collect-garbage --option keep-derivations true
clearStore
buildAttr rootCA 1 --out-link $TEST_ROOT/rootCA
- nix-collect-garbage --experimental-features ca-derivations
+ nix-collect-garbage
buildAttr rootCA 1 -j0
}
testNixCommand () {
clearStore
- nix build --experimental-features 'nix-command ca-derivations' --file ./content-addressed.nix --no-link
+ nix build --file ./content-addressed.nix --no-link
}
# Regression test for https://github.com/NixOS/nix/issues/4775
diff --git a/tests/ca/substitute.sh b/tests/ca/substitute.sh
index 819f3fd85..ea981adc4 100644
--- a/tests/ca/substitute.sh
+++ b/tests/ca/substitute.sh
@@ -28,6 +28,12 @@ nix realisation info --file ./content-addressed.nix transitivelyDependentCA
nix realisation info --file ./content-addressed.nix dependentCA
# nix realisation info --file ./content-addressed.nix rootCA --outputs out
+if isDaemonNewer "2.13"; then
+ pushToStore="../push-to-store.sh"
+else
+ pushToStore="../push-to-store-old.sh"
+fi
+
# Same thing, but
# 1. With non-ca derivations
# 2. Erasing the realisations on the remote store
@@ -37,7 +43,7 @@ nix realisation info --file ./content-addressed.nix dependentCA
#
# Regression test for #4725
clearStore
-nix build --file ../simple.nix -L --no-link --post-build-hook ../push-to-store.sh
+nix build --file ../simple.nix -L --no-link --post-build-hook "$pushToStore"
clearStore
rm -r "$REMOTE_STORE_DIR/realisations"
nix build --file ../simple.nix -L --no-link --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0
@@ -52,7 +58,7 @@ if [[ -z "$(ls "$REMOTE_STORE_DIR/realisations")" ]]; then
fi
# Test the local realisation disk cache
-buildDrvs --post-build-hook ../push-to-store.sh
+buildDrvs --post-build-hook "$pushToStore"
clearStore
# Add the realisations of rootCA to the cachecache
clearCacheCache
diff --git a/tests/check-refs.sh b/tests/check-refs.sh
index 65a72552a..2778e491d 100644
--- a/tests/check-refs.sh
+++ b/tests/check-refs.sh
@@ -8,14 +8,14 @@ dep=$(nix-build -o $RESULT check-refs.nix -A dep)
# test1 references dep, not itself.
test1=$(nix-build -o $RESULT check-refs.nix -A test1)
-(! nix-store -q --references $test1 | grep -q $test1)
-nix-store -q --references $test1 | grep -q $dep
+nix-store -q --references $test1 | grepQuietInverse $test1
+nix-store -q --references $test1 | grepQuiet $dep
# test2 references src, not itself nor dep.
test2=$(nix-build -o $RESULT check-refs.nix -A test2)
-(! nix-store -q --references $test2 | grep -q $test2)
-(! nix-store -q --references $test2 | grep -q $dep)
-nix-store -q --references $test2 | grep -q aux-ref
+nix-store -q --references $test2 | grepQuietInverse $test2
+nix-store -q --references $test2 | grepQuietInverse $dep
+nix-store -q --references $test2 | grepQuiet aux-ref
# test3 should fail (unallowed ref).
(! nix-build -o $RESULT check-refs.nix -A test3)
diff --git a/tests/check-reqs.sh b/tests/check-reqs.sh
index e9f65fc2a..856c94cec 100644
--- a/tests/check-reqs.sh
+++ b/tests/check-reqs.sh
@@ -8,8 +8,8 @@ nix-build -o $RESULT check-reqs.nix -A test1
(! nix-build -o $RESULT check-reqs.nix -A test2)
(! nix-build -o $RESULT check-reqs.nix -A test3)
-(! nix-build -o $RESULT check-reqs.nix -A test4) 2>&1 | grep -q 'check-reqs-dep1'
-(! nix-build -o $RESULT check-reqs.nix -A test4) 2>&1 | grep -q 'check-reqs-dep2'
+(! nix-build -o $RESULT check-reqs.nix -A test4) 2>&1 | grepQuiet 'check-reqs-dep1'
+(! nix-build -o $RESULT check-reqs.nix -A test4) 2>&1 | grepQuiet 'check-reqs-dep2'
(! nix-build -o $RESULT check-reqs.nix -A test5)
(! nix-build -o $RESULT check-reqs.nix -A test6)
diff --git a/tests/check.sh b/tests/check.sh
index e77c0405d..645b90222 100644
--- a/tests/check.sh
+++ b/tests/check.sh
@@ -37,7 +37,7 @@ checkBuildTempDirRemoved $TEST_ROOT/log
nix-build check.nix -A deterministic --argstr checkBuildId $checkBuildId \
--no-out-link --check --keep-failed 2> $TEST_ROOT/log
-if grep -q 'may not be deterministic' $TEST_ROOT/log; then false; fi
+if grepQuiet 'may not be deterministic' $TEST_ROOT/log; then false; fi
checkBuildTempDirRemoved $TEST_ROOT/log
nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \
diff --git a/tests/common.sh b/tests/common.sh
index 68b90a85f..8941671d6 100644
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -1,4 +1,4 @@
-set -e
+set -eu -o pipefail
if [[ -z "${COMMON_SH_SOURCED-}" ]]; then
diff --git a/tests/common/vars-and-functions.sh.in b/tests/common/vars-and-functions.sh.in
index 0deef4c1c..a9e6c802f 100644
--- a/tests/common/vars-and-functions.sh.in
+++ b/tests/common/vars-and-functions.sh.in
@@ -1,4 +1,4 @@
-set -e
+set -eu -o pipefail
if [[ -z "${COMMON_VARS_AND_FUNCTIONS_SH_SOURCED-}" ]]; then
@@ -152,31 +152,64 @@ isDaemonNewer () {
[[ $(nix eval --expr "builtins.compareVersions ''$daemonVersion'' ''$requiredVersion''") -ge 0 ]]
}
+skipTest () {
+ echo "$1, skipping this test..." >&2
+ exit 99
+}
+
requireDaemonNewerThan () {
- isDaemonNewer "$1" || exit 99
+ isDaemonNewer "$1" || skipTest "Daemon is too old"
}
canUseSandbox() {
- if [[ ! $_canUseSandbox ]]; then
- echo "Sandboxing not supported, skipping this test..."
- return 1
- fi
+ [[ ${_canUseSandbox-} ]]
+}
- return 0
+requireSandboxSupport () {
+ canUseSandbox || skipTest "Sandboxing not supported"
+}
+
+requireGit() {
+ [[ $(type -p git) ]] || skipTest "Git not installed"
}
fail() {
- echo "$1"
+ echo "$1" >&2
exit 1
}
+# Run a command failing if it didn't exit with the expected exit code.
+#
+# Has two advantages over the built-in `!`:
+#
+# 1. `!` conflates all non-0 codes. `expect` allows testing for an exact
+# code.
+#
+# 2. `!` unexpectedly negates `set -e`, and cannot be used on individual
+# pipeline stages with `set -o pipefail`. It only works on the entire
+# pipeline, which is useless if we want, say, `nix ...` invocation to
+# *fail*, but a grep on the error message it outputs to *succeed*.
expect() {
local expected res
expected="$1"
shift
- "$@" || res="$?"
+ "$@" && res=0 || res="$?"
if [[ $res -ne $expected ]]; then
- echo "Expected '$expected' but got '$res' while running '$*'"
+ echo "Expected '$expected' but got '$res' while running '${*@Q}'" >&2
+ return 1
+ fi
+ return 0
+}
+
+# Better than just doing `expect ... >&2` because the "Expected..."
+# message below will *not* be redirected.
+expectStderr() {
+ local expected res
+ expected="$1"
+ shift
+ "$@" 2>&1 && res=0 || res="$?"
+ if [[ $res -ne $expected ]]; then
+ echo "Expected '$expected' but got '$res' while running '${*@Q}'" >&2
return 1
fi
return 0
@@ -184,14 +217,13 @@ expect() {
needLocalStore() {
if [[ "$NIX_REMOTE" == "daemon" ]]; then
- echo "Can’t run through the daemon ($1), skipping this test..."
- return 99
+ skipTest "Can’t run through the daemon ($1)"
fi
}
# Just to make it easy to find which tests should be fixed
buggyNeedLocalStore() {
- needLocalStore
+ needLocalStore "$1"
}
enableFeatures() {
@@ -210,6 +242,35 @@ onError() {
done
}
+# `grep -v` doesn't work well for exit codes. We want `!(exist line l. l
+# matches)`. It gives us `exist line l. !(l matches)`.
+#
+# `!` normally doesn't work well with `set -e`, but when we wrap in a
+# function it *does*.
+grepInverse() {
+ ! grep "$@"
+}
+
+# A shorthand, `> /dev/null` is a bit noisy.
+#
+# `grep -q` would seem to do this, no function necessary, but it is a
+# bad fit with pipes and `set -o pipefail`: `-q` will exit after the
+# first match, and then subsequent writes will result in broken pipes.
+#
+# Note that reproducing the above is a bit tricky as it depends on
+# non-deterministic properties such as the timing between the match and
+# the closing of the pipe, the buffering of the pipe, and the speed of
+# the producer into the pipe. But rest assured we've seen it happen in
+# CI reliably.
+grepQuiet() {
+ grep "$@" > /dev/null
+}
+
+# The previous two, combined
+grepQuietInverse() {
+ ! grep "$@" > /dev/null
+}
+
trap onError ERR
fi # COMMON_VARS_AND_FUNCTIONS_SH_SOURCED
diff --git a/tests/compute-levels.sh b/tests/compute-levels.sh
index e4322dfa1..de3da2ebd 100644
--- a/tests/compute-levels.sh
+++ b/tests/compute-levels.sh
@@ -3,5 +3,5 @@ source common.sh
if [[ $(uname -ms) = "Linux x86_64" ]]; then
# x86_64 CPUs must always support the baseline
# microarchitecture level.
- nix -vv --version | grep -q "x86_64-v1-linux"
+ nix -vv --version | grepQuiet "x86_64-v1-linux"
fi
diff --git a/tests/db-migration.sh b/tests/db-migration.sh
index 92dd4f3ba..44cd16bc0 100644
--- a/tests/db-migration.sh
+++ b/tests/db-migration.sh
@@ -1,18 +1,18 @@
# Test that we can successfully migrate from an older db schema
+source common.sh
+
# Only run this if we have an older Nix available
# XXX: This assumes that the `daemon` package is older than the `client` one
-if [[ -z "$NIX_DAEMON_PACKAGE" ]]; then
- exit 99
+if [[ -z "${NIX_DAEMON_PACKAGE-}" ]]; then
+ skipTest "not using the Nix daemon"
fi
-source common.sh
-
killDaemon
# Fill the db using the older Nix
PATH_WITH_NEW_NIX="$PATH"
-export PATH="$NIX_DAEMON_PACKAGE/bin:$PATH"
+export PATH="${NIX_DAEMON_PACKAGE}/bin:$PATH"
clearStore
nix-build simple.nix --no-out-link
nix-store --generate-binary-cache-key cache1.example.org $TEST_ROOT/sk1 $TEST_ROOT/pk1
diff --git a/tests/dependencies.sh b/tests/dependencies.sh
index 092950aa7..f9da0c6bc 100644
--- a/tests/dependencies.sh
+++ b/tests/dependencies.sh
@@ -36,10 +36,10 @@ deps=$(nix-store -quR "$drvPath")
echo "output closure contains $deps"
# The output path should be in the closure.
-echo "$deps" | grep -q "$outPath"
+echo "$deps" | grepQuiet "$outPath"
# Input-1 is not retained.
-if echo "$deps" | grep -q "dependencies-input-1"; then exit 1; fi
+if echo "$deps" | grepQuiet "dependencies-input-1"; then exit 1; fi
# Input-2 is retained.
input2OutPath=$(echo "$deps" | grep "dependencies-input-2")
@@ -49,4 +49,4 @@ nix-store -q --referrers-closure "$input2OutPath" | grep "$outPath"
# Check that the derivers are set properly.
test $(nix-store -q --deriver "$outPath") = "$drvPath"
-nix-store -q --deriver "$input2OutPath" | grep -q -- "-input-2.drv"
+nix-store -q --deriver "$input2OutPath" | grepQuiet -- "-input-2.drv"
diff --git a/tests/describe-stores.sh b/tests/describe-stores.sh
deleted file mode 100644
index 3fea61483..000000000
--- a/tests/describe-stores.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-source common.sh
-
-# Query an arbitrary value in `nix describe-stores --json`'s output just to
-# check that it has the right structure
-[[ $(nix --experimental-features 'nix-command flakes' describe-stores --json | jq '.["SSH Store"]["compress"]["defaultValue"]') == false ]]
-
-# Ensure that the output of `nix describe-stores` isn't empty
-[[ -n $(nix --experimental-features 'nix-command flakes' describe-stores) ]]
diff --git a/tests/eval-store.sh b/tests/eval-store.sh
index 679da5741..8fc859730 100644
--- a/tests/eval-store.sh
+++ b/tests/eval-store.sh
@@ -2,7 +2,7 @@ source common.sh
# Using `--eval-store` with the daemon will eventually copy everything
# to the build store, invalidating most of the tests here
-needLocalStore
+needLocalStore "“--eval-store” doesn't achieve much with the daemon"
eval_store=$TEST_ROOT/eval-store
diff --git a/tests/experimental-features.sh b/tests/experimental-features.sh
new file mode 100644
index 000000000..3be77d5cc
--- /dev/null
+++ b/tests/experimental-features.sh
@@ -0,0 +1,23 @@
+source common.sh
+
+# Without flakes, flake options should not show up
+# With flakes, flake options should show up
+
+function both_ways {
+ nix --experimental-features 'nix-command' "$@" | grepQuietInverse flake
+ nix --experimental-features 'nix-command flakes' "$@" | grepQuiet flake
+
+ # Also, the order should not matter
+ nix "$@" --experimental-features 'nix-command' | grepQuietInverse flake
+ nix "$@" --experimental-features 'nix-command flakes' | grepQuiet flake
+}
+
+# Simple case, the configuration effects the running command
+both_ways show-config
+
+# Complicated case, earlier args effect later args
+
+both_ways store gc --help
+
+expect 1 nix --experimental-features 'nix-command' show-config --flake-registry 'https://no'
+nix --experimental-features 'nix-command flakes' show-config --flake-registry 'https://no'
diff --git a/tests/export-graph.sh b/tests/export-graph.sh
index 4954a6cbc..1f6232a40 100644
--- a/tests/export-graph.sh
+++ b/tests/export-graph.sh
@@ -4,7 +4,7 @@ clearStore
clearProfiles
checkRef() {
- nix-store -q --references $TEST_ROOT/result | grep -q "$1"'$' || fail "missing reference $1"
+ nix-store -q --references $TEST_ROOT/result | grepQuiet "$1"'$' || fail "missing reference $1"
}
# Test the export of the runtime dependency graph.
diff --git a/tests/fetchClosure.sh b/tests/fetchClosure.sh
index d88c55c3c..a207f647c 100644
--- a/tests/fetchClosure.sh
+++ b/tests/fetchClosure.sh
@@ -42,13 +42,13 @@ if [[ "$NIX_REMOTE" != "daemon" ]]; then
fi
# 'toPath' set to empty string should fail but print the expected path.
-nix eval -v --json --expr "
+expectStderr 1 nix eval -v --json --expr "
builtins.fetchClosure {
fromStore = \"file://$cacheDir\";
fromPath = $nonCaPath;
toPath = \"\";
}
-" 2>&1 | grep "error: rewriting.*$nonCaPath.*yielded.*$caPath"
+" | grep "error: rewriting.*$nonCaPath.*yielded.*$caPath"
# If fromPath is CA, then toPath isn't needed.
nix copy --to file://$cacheDir $caPath
diff --git a/tests/fetchGit.sh b/tests/fetchGit.sh
index a7a8df186..e2ccb0e97 100644
--- a/tests/fetchGit.sh
+++ b/tests/fetchGit.sh
@@ -1,9 +1,6 @@
source common.sh
-if [[ -z $(type -p git) ]]; then
- echo "Git not installed; skipping Git tests"
- exit 99
-fi
+requireGit
clearStore
diff --git a/tests/fetchGitRefs.sh b/tests/fetchGitRefs.sh
index 52926040b..d643fea04 100644
--- a/tests/fetchGitRefs.sh
+++ b/tests/fetchGitRefs.sh
@@ -1,9 +1,6 @@
source common.sh
-if [[ -z $(type -p git) ]]; then
- echo "Git not installed; skipping Git tests"
- exit 99
-fi
+requireGit
clearStore
@@ -56,7 +53,7 @@ invalid_ref() {
else
(! git check-ref-format --branch "$1" >/dev/null 2>&1)
fi
- nix --debug eval --raw --impure --expr "(builtins.fetchGit { url = $repo; ref = ''$1''; }).outPath" 2>&1 | grep 'invalid Git branch/tag name' >/dev/null
+ expect 1 nix --debug eval --raw --impure --expr "(builtins.fetchGit { url = $repo; ref = ''$1''; }).outPath" 2>&1 | grep 'invalid Git branch/tag name' >/dev/null
}
diff --git a/tests/fetchGitSubmodules.sh b/tests/fetchGitSubmodules.sh
index 08ccaa3cd..df81232e5 100644
--- a/tests/fetchGitSubmodules.sh
+++ b/tests/fetchGitSubmodules.sh
@@ -2,10 +2,7 @@ source common.sh
set -u
-if [[ -z $(type -p git) ]]; then
- echo "Git not installed; skipping Git submodule tests"
- exit 99
-fi
+requireGit
clearStore
diff --git a/tests/fetchMercurial.sh b/tests/fetchMercurial.sh
index 5c64ffd26..e6f8525c6 100644
--- a/tests/fetchMercurial.sh
+++ b/tests/fetchMercurial.sh
@@ -1,9 +1,6 @@
source common.sh
-if [[ -z $(type -p hg) ]]; then
- echo "Mercurial not installed; skipping Mercurial tests"
- exit 99
-fi
+[[ $(type -p hq) ]] || skipTest "Mercurial not installed"
clearStore
diff --git a/tests/fetchTree-file.sh b/tests/fetchTree-file.sh
index f0c530466..fe569cfb8 100644
--- a/tests/fetchTree-file.sh
+++ b/tests/fetchTree-file.sh
@@ -79,7 +79,7 @@ EOF
EOF
popd
- [[ -z "${NIX_DAEMON_PACKAGE}" ]] && return 0
+ [[ -z "${NIX_DAEMON_PACKAGE-}" ]] && return 0
# Ensure that a lockfile generated by the current Nix for tarball inputs
# can still be read by an older Nix
@@ -91,7 +91,7 @@ EOF
flake = false;
};
outputs = { self, tarball }: {
- foo = builtins.readFile "${tarball}/test_input_file";
+ foo = builtins.readFile "\${tarball}/test_input_file";
};
}
nix flake update
diff --git a/tests/fetchurl.sh b/tests/fetchurl.sh
index b41d8c4b7..8cd40c09f 100644
--- a/tests/fetchurl.sh
+++ b/tests/fetchurl.sh
@@ -62,7 +62,7 @@ hash=$(nix-hash --flat --type sha256 $nar)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file://$nar --argstr sha256 $hash \
--arg unpack true --argstr name xyzzy --no-out-link)
-echo $outPath | grep -q 'xyzzy'
+echo $outPath | grepQuiet 'xyzzy'
test -x $outPath/fetchurl.sh
test -L $outPath/symlink
diff --git a/tests/flakes/build-paths.sh b/tests/flakes/build-paths.sh
index 08b4d1763..b399a066e 100644
--- a/tests/flakes/build-paths.sh
+++ b/tests/flakes/build-paths.sh
@@ -35,7 +35,7 @@ cat > $flake1Dir/flake.nix <<EOF
a6 = flake2.outPath;
# FIXME
- a7 = "${flake2}/config.nix";
+ a7 = "\${flake2}/config.nix";
# This is only allowed in impure mode.
a8 = builtins.storePath $dep;
diff --git a/tests/flakes/check.sh b/tests/flakes/check.sh
index 278ac7fa4..865ca61b4 100644
--- a/tests/flakes/check.sh
+++ b/tests/flakes/check.sh
@@ -73,5 +73,5 @@ cat > $flakeDir/flake.nix <<EOF
EOF
checkRes=$(nix flake check --keep-going $flakeDir 2>&1 && fail "nix flake check should have failed" || true)
-echo "$checkRes" | grep -q "packages.system-1.default"
-echo "$checkRes" | grep -q "packages.system-2.default"
+echo "$checkRes" | grepQuiet "packages.system-1.default"
+echo "$checkRes" | grepQuiet "packages.system-2.default"
diff --git a/tests/flakes/common.sh b/tests/flakes/common.sh
index 9d79080cd..427abcdde 100644
--- a/tests/flakes/common.sh
+++ b/tests/flakes/common.sh
@@ -2,13 +2,6 @@ source ../common.sh
registry=$TEST_ROOT/registry.json
-requireGit() {
- if [[ -z $(type -p git) ]]; then
- echo "Git not installed; skipping flake tests"
- exit 99
- fi
-}
-
writeSimpleFlake() {
local flakeDir="$1"
cat > $flakeDir/flake.nix <<EOF
@@ -66,7 +59,7 @@ EOF
createGitRepo() {
local repo="$1"
- local extraArgs="$2"
+ local extraArgs="${2-}"
rm -rf $repo $repo.tmp
mkdir -p $repo
diff --git a/tests/flakes/flake-in-submodule.sh b/tests/flakes/flake-in-submodule.sh
new file mode 100644
index 000000000..21a4b52de
--- /dev/null
+++ b/tests/flakes/flake-in-submodule.sh
@@ -0,0 +1,52 @@
+source common.sh
+
+# Tests that:
+# - flake.nix may reside inside of a git submodule
+# - the flake can access content outside of the submodule
+#
+# rootRepo
+# ├── root.nix
+# └── submodule
+# ├── flake.nix
+# └── sub.nix
+
+
+requireGit
+
+clearStore
+
+# Submodules can't be fetched locally by default.
+# See fetchGitSubmodules.sh
+export XDG_CONFIG_HOME=$TEST_HOME/.config
+git config --global protocol.file.allow always
+
+
+rootRepo=$TEST_ROOT/rootRepo
+subRepo=$TEST_ROOT/submodule
+
+
+createGitRepo $subRepo
+cat > $subRepo/flake.nix <<EOF
+{
+ outputs = { self }: {
+ sub = import ./sub.nix;
+ root = import ../root.nix;
+ };
+}
+EOF
+echo '"expression in submodule"' > $subRepo/sub.nix
+git -C $subRepo add flake.nix sub.nix
+git -C $subRepo commit -m Initial
+
+createGitRepo $rootRepo
+
+git -C $rootRepo submodule init
+git -C $rootRepo submodule add $subRepo submodule
+echo '"expression in root repo"' > $rootRepo/root.nix
+git -C $rootRepo add root.nix
+git -C $rootRepo commit -m "Add root.nix"
+
+# Flake can live inside a submodule and can be accessed via ?dir=submodule
+[[ $(nix eval --json git+file://$rootRepo\?submodules=1\&dir=submodule#sub ) = '"expression in submodule"' ]]
+# The flake can access content outside of the submodule
+[[ $(nix eval --json git+file://$rootRepo\?submodules=1\&dir=submodule#root ) = '"expression in root repo"' ]]
diff --git a/tests/flakes/flakes.sh b/tests/flakes/flakes.sh
index 07f1e6698..5c922d7c5 100644
--- a/tests/flakes/flakes.sh
+++ b/tests/flakes/flakes.sh
@@ -76,17 +76,17 @@ nix registry add --registry $registry nixpkgs flake1
# Test 'nix registry list'.
[[ $(nix registry list | wc -l) == 5 ]]
-nix registry list | grep -q '^global'
-nix registry list | grep -q -v '^user' # nothing in user registry
+nix registry list | grep '^global'
+nix registry list | grepInverse '^user' # nothing in user registry
# Test 'nix flake metadata'.
nix flake metadata flake1
-nix flake metadata flake1 | grep -q 'Locked URL:.*flake1.*'
+nix flake metadata flake1 | grepQuiet 'Locked URL:.*flake1.*'
# Test 'nix flake metadata' on a local flake.
-(cd $flake1Dir && nix flake metadata) | grep -q 'URL:.*flake1.*'
-(cd $flake1Dir && nix flake metadata .) | grep -q 'URL:.*flake1.*'
-nix flake metadata $flake1Dir | grep -q 'URL:.*flake1.*'
+(cd $flake1Dir && nix flake metadata) | grepQuiet 'URL:.*flake1.*'
+(cd $flake1Dir && nix flake metadata .) | grepQuiet 'URL:.*flake1.*'
+nix flake metadata $flake1Dir | grepQuiet 'URL:.*flake1.*'
# Test 'nix flake metadata --json'.
json=$(nix flake metadata flake1 --json | jq .)
@@ -134,11 +134,11 @@ nix build -o $TEST_ROOT/result flake2#bar --impure --no-write-lock-file
nix eval --expr "builtins.getFlake \"$flake2Dir\"" --impure
# Building a local flake with an unlocked dependency should fail with --no-update-lock-file.
-nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
+expect 1 nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
# But it should succeed without that flag.
nix build -o $TEST_ROOT/result $flake2Dir#bar --no-write-lock-file
-nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
+expect 1 nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes'
nix build -o $TEST_ROOT/result $flake2Dir#bar --commit-lock-file
[[ -e $flake2Dir/flake.lock ]]
[[ -z $(git -C $flake2Dir diff main || echo failed) ]]
@@ -196,10 +196,10 @@ git -C $flake3Dir add flake.lock
git -C $flake3Dir commit -m 'Add lockfile'
# Test whether registry caching works.
-nix registry list --flake-registry file://$registry | grep -q flake3
+nix registry list --flake-registry file://$registry | grepQuiet flake3
mv $registry $registry.tmp
nix store gc
-nix registry list --flake-registry file://$registry --refresh | grep -q flake3
+nix registry list --flake-registry file://$registry --refresh | grepQuiet flake3
mv $registry.tmp $registry
# Test whether flakes are registered as GC roots for offline use.
@@ -346,8 +346,8 @@ nix registry remove flake1
nix registry add user-flake1 git+file://$flake1Dir
nix registry add user-flake2 git+file://$flake2Dir
[[ $(nix --flake-registry "" registry list | wc -l) == 2 ]]
-nix --flake-registry "" registry list | grep -q -v '^global' # nothing in global registry
-nix --flake-registry "" registry list | grep -q '^user'
+nix --flake-registry "" registry list | grepQuietInverse '^global' # nothing in global registry
+nix --flake-registry "" registry list | grepQuiet '^user'
nix registry remove user-flake1
nix registry remove user-flake2
[[ $(nix registry list | wc -l) == 5 ]]
@@ -454,7 +454,7 @@ url=$(nix flake metadata --json file://$TEST_ROOT/flake.tar.gz | jq -r .url)
nix build -o $TEST_ROOT/result $url
# Building with an incorrect SRI hash should fail.
-nix build -o $TEST_ROOT/result "file://$TEST_ROOT/flake.tar.gz?narHash=sha256-qQ2Zz4DNHViCUrp6gTS7EE4+RMqFQtUfWF2UNUtJKS0=" 2>&1 | grep 'NAR hash mismatch'
+expectStderr 102 nix build -o $TEST_ROOT/result "file://$TEST_ROOT/flake.tar.gz?narHash=sha256-qQ2Zz4DNHViCUrp6gTS7EE4+RMqFQtUfWF2UNUtJKS0=" | grep 'NAR hash mismatch'
# Test --override-input.
git -C $flake3Dir reset --hard
diff --git a/tests/flakes/follow-paths.sh b/tests/flakes/follow-paths.sh
index 19cc1bafa..fe9b51c65 100644
--- a/tests/flakes/follow-paths.sh
+++ b/tests/flakes/follow-paths.sh
@@ -128,7 +128,7 @@ EOF
git -C $flakeFollowsA add flake.nix
-nix flake lock $flakeFollowsA 2>&1 | grep 'points outside'
+expect 1 nix flake lock $flakeFollowsA 2>&1 | grep 'points outside'
# Non-existant follows should print a warning.
cat >$flakeFollowsA/flake.nix <<EOF
diff --git a/tests/flakes/mercurial.sh b/tests/flakes/mercurial.sh
index 2614006c8..0622c79b7 100644
--- a/tests/flakes/mercurial.sh
+++ b/tests/flakes/mercurial.sh
@@ -1,9 +1,6 @@
source ./common.sh
-if [[ -z $(type -p hg) ]]; then
- echo "Mercurial not installed; skipping"
- exit 99
-fi
+[[ $(type -p hq) ]] || skipTest "Mercurial not installed"
flake1Dir=$TEST_ROOT/flake-hg1
mkdir -p $flake1Dir
diff --git a/tests/flakes/show.sh b/tests/flakes/show.sh
index dd13264b9..a3d300552 100644
--- a/tests/flakes/show.sh
+++ b/tests/flakes/show.sh
@@ -64,3 +64,24 @@ in
assert show_output == { };
true
'
+
+# Test that attributes with errors are handled correctly.
+# nixpkgs.legacyPackages is a particularly prominent instance of this.
+cat >flake.nix <<EOF
+{
+ outputs = inputs: {
+ legacyPackages.$system = {
+ AAAAAASomeThingsFailToEvaluate = throw "nooo";
+ simple = import ./simple.nix;
+ };
+ };
+}
+EOF
+nix flake show --json --legacy --all-systems > show-output.json
+nix eval --impure --expr '
+let show_output = builtins.fromJSON (builtins.readFile ./show-output.json);
+in
+assert show_output.legacyPackages.${builtins.currentSystem}.AAAAAASomeThingsFailToEvaluate == { };
+assert show_output.legacyPackages.${builtins.currentSystem}.simple.name == "simple";
+true
+'
diff --git a/tests/fmt.sh b/tests/fmt.sh
index 254681ca2..3c1bd9989 100644
--- a/tests/fmt.sh
+++ b/tests/fmt.sh
@@ -1,7 +1,5 @@
source common.sh
-set -o pipefail
-
clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
diff --git a/tests/function-trace.sh b/tests/function-trace.sh
index b0d6c9d59..bd804bf18 100755
--- a/tests/function-trace.sh
+++ b/tests/function-trace.sh
@@ -10,17 +10,15 @@ expect_trace() {
--trace-function-calls \
--expr "$expr" 2>&1 \
| grep "function-trace" \
- | sed -e 's/ [0-9]*$//'
+ | sed -e 's/ [0-9]*$//' \
+ || true
)
echo -n "Tracing expression '$expr'"
- set +e
msg=$(diff -swB \
<(echo "$expect") \
<(echo "$actual")
- );
- result=$?
- set -e
+ ) && result=0 || result=$?
if [ $result -eq 0 ]; then
echo " ok."
else
@@ -67,5 +65,3 @@ expect_trace '1 2' "
function-trace entered «string»:1:1 at
function-trace exited «string»:1:1 at
"
-
-set -e
diff --git a/tests/gc-runtime.sh b/tests/gc-runtime.sh
index 6094959cb..dc1826a55 100644
--- a/tests/gc-runtime.sh
+++ b/tests/gc-runtime.sh
@@ -4,7 +4,7 @@ case $system in
*linux*)
;;
*)
- exit 99;
+ skipTest "Not running Linux";
esac
set -m # enable job control, needed for kill
diff --git a/tests/gc.sh b/tests/gc.sh
index ad09a8b39..98d6cb032 100644
--- a/tests/gc.sh
+++ b/tests/gc.sh
@@ -50,3 +50,20 @@ if test -e $outPath/foobar; then false; fi
# Check that the store is empty.
rmdir $NIX_STORE_DIR/.links
rmdir $NIX_STORE_DIR
+
+## Test `nix-collect-garbage -d`
+# `nix-env` doesn't work with CA derivations, so let's ignore that bit if we're
+# using them
+if [[ -z "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
+ clearProfiles
+ # Run two `nix-env` commands, should create two generations of
+ # the profile
+ nix-env -f ./user-envs.nix -i foo-1.0
+ nix-env -f ./user-envs.nix -i foo-2.0pre1
+ [[ $(nix-env --list-generations | wc -l) -eq 2 ]]
+
+ # Clear the profile history. There should be only one generation
+ # left
+ nix-collect-garbage -d
+ [[ $(nix-env --list-generations | wc -l) -eq 1 ]]
+fi
diff --git a/tests/hash.sh b/tests/hash.sh
index e5f75e2cf..34c1bb38a 100644
--- a/tests/hash.sh
+++ b/tests/hash.sh
@@ -2,13 +2,19 @@ source common.sh
try () {
printf "%s" "$2" > $TEST_ROOT/vector
- hash=$(nix hash file --base16 $EXTRA --type "$1" $TEST_ROOT/vector)
- if test "$hash" != "$3"; then
- echo "hash $1, expected $3, got $hash"
+ hash="$(nix-hash --flat ${FORMAT_FLAG-} --type "$1" "$TEST_ROOT/vector")"
+ if ! (( "${NO_TEST_CLASSIC-}" )) && test "$hash" != "$3"; then
+ echo "try nix-hash: hash $1, expected $3, got $hash"
+ exit 1
+ fi
+ hash="$(nix hash file ${FORMAT_FLAG-} --type "$1" "$TEST_ROOT/vector")"
+ if ! (( "${NO_TEST_NIX_COMMAND-}" )) && test "$hash" != "$3"; then
+ echo "try nix hash: hash $1, expected $3, got $hash"
exit 1
fi
}
+FORMAT_FLAG=--base16
try md5 "" "d41d8cd98f00b204e9800998ecf8427e"
try md5 "a" "0cc175b9c0f1b6a831c399e269772661"
try md5 "abc" "900150983cd24fb0d6963f7d28e17f72"
@@ -28,16 +34,24 @@ try sha256 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "248d6a61d
try sha512 "" "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
try sha512 "abc" "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
try sha512 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445"
+unset FORMAT_FLAG
-EXTRA=--base32
+FORMAT_FLAG=--base32
try sha256 "abc" "1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s"
-EXTRA=
+unset FORMAT_FLAG
-EXTRA=--sri
+FORMAT_FLAG=--sri
try sha512 "" "sha512-z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg=="
try sha512 "abc" "sha512-3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw=="
try sha512 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "sha512-IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ=="
try sha256 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" "sha256-JI1qYdIGOLjlwCaTDD5gOaM85Flk/yFn9uzt1BnbBsE="
+unset FORMAT_FLAG
+
+# nix-hash [--flat] defaults to the Base16 format
+NO_TEST_NIX_COMMAND=1 try sha512 "abc" "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
+
+# nix hash [file|path] defaults to the SRI format
+NO_TEST_CLASSIC=1 try sha512 "abc" "sha512-3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw=="
try2 () {
hash=$(nix-hash --type "$1" $TEST_ROOT/hash-path)
@@ -69,12 +83,18 @@ try2 md5 "f78b733a68f5edbdf9413899339eaa4a"
# Conversion.
try3() {
+ h64=$(nix-hash --type "$1" --to-base64 "$2")
+ [ "$h64" = "$4" ]
h64=$(nix hash to-base64 --type "$1" "$2")
[ "$h64" = "$4" ]
+ sri=$(nix-hash --type "$1" --to-sri "$2")
+ [ "$sri" = "$1-$4" ]
sri=$(nix hash to-sri --type "$1" "$2")
[ "$sri" = "$1-$4" ]
h32=$(nix-hash --type "$1" --to-base32 "$2")
[ "$h32" = "$3" ]
+ h32=$(nix hash to-base32 --type "$1" "$2")
+ [ "$h32" = "$3" ]
h16=$(nix-hash --type "$1" --to-base16 "$h32")
[ "$h16" = "$2" ]
h16=$(nix hash to-base16 --type "$1" "$h64")
diff --git a/tests/impure-derivations.sh b/tests/impure-derivations.sh
index 23a193833..7595fdd35 100644
--- a/tests/impure-derivations.sh
+++ b/tests/impure-derivations.sh
@@ -5,8 +5,6 @@ requireDaemonNewerThan "2.8pre20220311"
enableFeatures "ca-derivations impure-derivations"
restartDaemon
-set -o pipefail
-
clearStore
# Basic test of impure derivations: building one a second time should not use the previous result.
diff --git a/tests/init.sh b/tests/init.sh
index fea659516..c420e8c9f 100755
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -1,5 +1,3 @@
-set -eu -o pipefail
-
# Don't start the daemon
source common/vars-and-functions.sh
diff --git a/tests/install-darwin.sh b/tests/install-darwin.sh
index 7e44e54c4..ea2b75323 100755
--- a/tests/install-darwin.sh
+++ b/tests/install-darwin.sh
@@ -4,7 +4,7 @@ set -eux
cleanup() {
PLIST="/Library/LaunchDaemons/org.nixos.nix-daemon.plist"
- if sudo launchctl list | grep -q nix-daemon; then
+ if sudo launchctl list | grepQuiet nix-daemon; then
sudo launchctl unload "$PLIST"
fi
diff --git a/tests/installer/default.nix b/tests/installer/default.nix
index 31d83699d..8c9784eaf 100644
--- a/tests/installer/default.nix
+++ b/tests/installer/default.nix
@@ -30,6 +30,14 @@ let
};
};
+ mockChannel = pkgs:
+ pkgs.runCommandNoCC "mock-channel" {} ''
+ mkdir nixexprs
+ mkdir $out
+ echo -n 'someContent' > nixexprs/someFile
+ tar cvf - nixexprs | bzip2 > $out/nixexprs.tar.bz2
+ '';
+
disableSELinux = "sudo setenforce 0";
images = {
@@ -189,6 +197,9 @@ let
echo "Running installer..."
$ssh "set -eux; $installScript"
+ echo "Copying the mock channel"
+ scp -r -P 20022 $ssh_opts ${mockChannel pkgs} vagrant@localhost:channel
+
echo "Testing Nix installation..."
$ssh <<EOF
set -ex
@@ -204,6 +215,17 @@ let
out=\$(nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > \$out"]; }')
[[ \$(cat \$out) = foobar ]]
+
+ if pgrep nix-daemon; then
+ MAYBESUDO="sudo"
+ else
+ MAYBESUDO=""
+ fi
+
+
+ $MAYBESUDO \$(which nix-channel) --add file://\$HOME/channel myChannel
+ $MAYBESUDO \$(which nix-channel) --update
+ [[ \$(nix-instantiate --eval --expr 'builtins.readFile <myChannel/someFile>') = '"someContent"' ]]
EOF
echo "Done!"
diff --git a/tests/lang.sh b/tests/lang.sh
index 95e795e2e..cdb4174eb 100644
--- a/tests/lang.sh
+++ b/tests/lang.sh
@@ -4,12 +4,12 @@ export TEST_VAR=foo # for eval-okay-getenv.nix
export NIX_REMOTE=dummy://
export NIX_STORE_DIR=/nix/store
-nix-instantiate --eval -E 'builtins.trace "Hello" 123' 2>&1 | grep -q Hello
+nix-instantiate --eval -E 'builtins.trace "Hello" 123' 2>&1 | grepQuiet Hello
nix-instantiate --eval -E 'builtins.addErrorContext "Hello" 123' 2>&1
-nix-instantiate --trace-verbose --eval -E 'builtins.traceVerbose "Hello" 123' 2>&1 | grep -q Hello
-(! nix-instantiate --eval -E 'builtins.traceVerbose "Hello" 123' 2>&1 | grep -q Hello)
-(! nix-instantiate --show-trace --eval -E 'builtins.addErrorContext "Hello" 123' 2>&1 | grep -q Hello)
-nix-instantiate --show-trace --eval -E 'builtins.addErrorContext "Hello" (throw "Foo")' 2>&1 | grep -q Hello
+nix-instantiate --trace-verbose --eval -E 'builtins.traceVerbose "Hello" 123' 2>&1 | grepQuiet Hello
+nix-instantiate --eval -E 'builtins.traceVerbose "Hello" 123' 2>&1 | grepQuietInverse Hello
+nix-instantiate --show-trace --eval -E 'builtins.addErrorContext "Hello" 123' 2>&1 | grepQuietInverse Hello
+expectStderr 1 nix-instantiate --show-trace --eval -E 'builtins.addErrorContext "Hello" (throw "Foo")' | grepQuiet Hello
set +x
diff --git a/tests/linux-sandbox.sh b/tests/linux-sandbox.sh
index e62039567..5a2cf7abd 100644
--- a/tests/linux-sandbox.sh
+++ b/tests/linux-sandbox.sh
@@ -4,13 +4,13 @@ needLocalStore "the sandbox only runs on the builder side, so it makes no sense
clearStore
-if ! canUseSandbox; then exit 99; fi
+requireSandboxSupport
# Note: we need to bind-mount $SHELL into the chroot. Currently we
# only support the case where $SHELL is in the Nix store, because
# otherwise things get complicated (e.g. if it's in /bin, do we need
# /lib as well?).
-if [[ ! $SHELL =~ /nix/store ]]; then exit 99; fi
+if [[ ! $SHELL =~ /nix/store ]]; then skipTest "Shell is not from Nix store"; fi
chmod -R u+w $TEST_ROOT/store0 || true
rm -rf $TEST_ROOT/store0
@@ -35,8 +35,8 @@ nix-build dependencies.nix --no-out-link --check --sandbox-paths /nix/store
nix-build check.nix -A nondeterministic --sandbox-paths /nix/store --no-out-link
(! nix-build check.nix -A nondeterministic --sandbox-paths /nix/store --no-out-link --check -K 2> $TEST_ROOT/log)
-if grep -q 'error: renaming' $TEST_ROOT/log; then false; fi
-grep -q 'may not be deterministic' $TEST_ROOT/log
+if grepQuiet 'error: renaming' $TEST_ROOT/log; then false; fi
+grepQuiet 'may not be deterministic' $TEST_ROOT/log
# Test that sandboxed builds cannot write to /etc easily
(! nix-build -E 'with import ./config.nix; mkDerivation { name = "etc-write"; buildCommand = "echo > /etc/test"; }' --no-out-link --sandbox-paths /nix/store)
diff --git a/tests/local.mk b/tests/local.mk
index 4003d9447..5981177ed 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -1,4 +1,5 @@
nix_tests = \
+ test-infra.sh \
init.sh \
flakes/flakes.sh \
flakes/run.sh \
@@ -12,10 +13,12 @@ nix_tests = \
flakes/unlocked-override.sh \
flakes/absolute-paths.sh \
flakes/build-paths.sh \
+ flakes/flake-in-submodule.sh \
ca/gc.sh \
gc.sh \
remote-store.sh \
lang.sh \
+ experimental-features.sh \
fetchMercurial.sh \
gc-auto.sh \
user-envs.sh \
@@ -114,7 +117,6 @@ nix_tests = \
db-migration.sh \
bash-profile.sh \
pass-as-file.sh \
- describe-stores.sh \
nix-profile.sh \
suggestions.sh \
store-ping.sh \
@@ -131,9 +133,9 @@ endif
install-tests += $(foreach x, $(nix_tests), tests/$(x))
-clean-files += $(d)/tests/common/vars-and-functions.sh $(d)/config.nix $(d)/ca/config.nix
+clean-files += $(d)/common/vars-and-functions.sh $(d)/config.nix $(d)/ca/config.nix
-test-deps += tests/common/vars-and-functions.sh tests/config.nix tests/ca/config.nix tests/plugins/libplugintest.$(SO_EXT)
+test-deps += tests/common/vars-and-functions.sh tests/config.nix tests/ca/config.nix
ifeq ($(BUILD_SHARED_LIBS), 1)
test-deps += tests/plugins/libplugintest.$(SO_EXT)
diff --git a/tests/misc.sh b/tests/misc.sh
index 2830856ae..60d58310e 100644
--- a/tests/misc.sh
+++ b/tests/misc.sh
@@ -3,17 +3,17 @@ source common.sh
# Tests miscellaneous commands.
# Do all commands have help?
-#nix-env --help | grep -q install
-#nix-store --help | grep -q realise
-#nix-instantiate --help | grep -q eval
-#nix-hash --help | grep -q base32
+#nix-env --help | grepQuiet install
+#nix-store --help | grepQuiet realise
+#nix-instantiate --help | grepQuiet eval
+#nix-hash --help | grepQuiet base32
# Can we ask for the version number?
nix-env --version | grep "$version"
# Usage errors.
-nix-env --foo 2>&1 | grep "no operation"
-nix-env -q --foo 2>&1 | grep "unknown flag"
+expect 1 nix-env --foo 2>&1 | grep "no operation"
+expect 1 nix-env -q --foo 2>&1 | grep "unknown flag"
# Eval Errors.
eval_arg_res=$(nix-instantiate --eval -E 'let a = {} // a; in a.foo' 2>&1 || true)
diff --git a/tests/multiple-outputs.sh b/tests/multiple-outputs.sh
index 66be6fa64..330600d08 100644
--- a/tests/multiple-outputs.sh
+++ b/tests/multiple-outputs.sh
@@ -19,8 +19,8 @@ echo "evaluating c..."
# outputs.
drvPath=$(nix-instantiate multiple-outputs.nix -A c)
#[ "$drvPath" = "$drvPath2" ]
-grep -q 'multiple-outputs-a.drv",\["first","second"\]' $drvPath
-grep -q 'multiple-outputs-b.drv",\["out"\]' $drvPath
+grepQuiet 'multiple-outputs-a.drv",\["first","second"\]' $drvPath
+grepQuiet 'multiple-outputs-b.drv",\["out"\]' $drvPath
# While we're at it, test the ‘unsafeDiscardOutputDependency’ primop.
outPath=$(nix-build multiple-outputs.nix -A d --no-out-link)
@@ -84,5 +84,5 @@ nix-store --gc --print-roots
rm -rf $NIX_STORE_DIR/.links
rmdir $NIX_STORE_DIR
-nix build -f multiple-outputs.nix invalid-output-name-1 2>&1 | grep 'contains illegal character'
-nix build -f multiple-outputs.nix invalid-output-name-2 2>&1 | grep 'contains illegal character'
+expect 1 nix build -f multiple-outputs.nix invalid-output-name-1 2>&1 | grep 'contains illegal character'
+expect 1 nix build -f multiple-outputs.nix invalid-output-name-2 2>&1 | grep 'contains illegal character'
diff --git a/tests/nar-access.sh b/tests/nar-access.sh
index dcc2e8a36..d487d58d2 100644
--- a/tests/nar-access.sh
+++ b/tests/nar-access.sh
@@ -46,8 +46,8 @@ diff -u \
<(echo '{"type":"regular","size":0}' | jq -S)
# Test missing files.
-nix store ls --json -R $storePath/xyzzy 2>&1 | grep 'does not exist in NAR'
-nix store ls $storePath/xyzzy 2>&1 | grep 'does not exist'
+expect 1 nix store ls --json -R $storePath/xyzzy 2>&1 | grep 'does not exist in NAR'
+expect 1 nix store ls $storePath/xyzzy 2>&1 | grep 'does not exist'
# Test failure to dump.
if nix-store --dump $storePath >/dev/full ; then
diff --git a/tests/nix-channel.sh b/tests/nix-channel.sh
index b64283f48..dbb3114f1 100644
--- a/tests/nix-channel.sh
+++ b/tests/nix-channel.sh
@@ -6,7 +6,7 @@ rm -f $TEST_HOME/.nix-channels $TEST_HOME/.nix-profile
# Test add/list/remove.
nix-channel --add http://foo/bar xyzzy
-nix-channel --list | grep -q http://foo/bar
+nix-channel --list | grepQuiet http://foo/bar
nix-channel --remove xyzzy
[ -e $TEST_HOME/.nix-channels ]
@@ -17,7 +17,7 @@ nix-channel --remove xyzzy
export NIX_CONFIG="use-xdg-base-directories = true"
nix-channel --add http://foo/bar xyzzy
-nix-channel --list | grep -q http://foo/bar
+nix-channel --list | grepQuiet http://foo/bar
nix-channel --remove xyzzy
unset NIX_CONFIG
@@ -41,8 +41,8 @@ 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="foo".*name="dependencies-top"' $TEST_ROOT/meta.xml
+grepQuiet 'meta.*description.*Random test package' $TEST_ROOT/meta.xml
+grepQuiet 'item.*attrPath="foo".*name="dependencies-top"' $TEST_ROOT/meta.xml
# Do an install.
nix-env -i dependencies-top
@@ -54,9 +54,9 @@ 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
+grepQuiet 'meta.*description.*Random test package' $TEST_ROOT/meta.xml
+grepQuiet 'item.*attrPath="bar".*name="dependencies-top"' $TEST_ROOT/meta.xml
+grepQuiet 'item.*attrPath="foo".*name="dependencies-top"' $TEST_ROOT/meta.xml
# Do an install.
nix-env -i dependencies-top
diff --git a/tests/nix-profile.sh b/tests/nix-profile.sh
index 266dc9e49..652e8a8f2 100644
--- a/tests/nix-profile.sh
+++ b/tests/nix-profile.sh
@@ -140,6 +140,36 @@ printf World2 > $flake2Dir/who
nix profile install $flake1Dir
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
+expect 1 nix profile install $flake2Dir
+diff -u <(
+ nix --offline profile install $flake2Dir 2>&1 1> /dev/null \
+ | grep -vE "^warning: " \
+ || true
+) <(cat << EOF
+error: An existing package already provides the following file:
+
+ $(nix build --no-link --print-out-paths ${flake1Dir}"#default.out")/bin/hello
+
+ This is the conflicting file from the new package:
+
+ $(nix build --no-link --print-out-paths ${flake2Dir}"#default.out")/bin/hello
+
+ To remove the existing package:
+
+ nix profile remove path:${flake1Dir}
+
+ The new package can also be installed next to the existing one by assigning a different priority.
+ The conflicting packages have a priority of 5.
+ To prioritise the new package:
+
+ nix profile install path:${flake2Dir} --priority 4
+
+ To prioritise the existing package:
+
+ nix profile install path:${flake2Dir} --priority 6
+EOF
+)
+[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
nix profile install $flake2Dir --priority 100
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
nix profile install $flake2Dir --priority 0
diff --git a/tests/nix-shell.sh b/tests/nix-shell.sh
index f291c6f79..044b96d54 100644
--- a/tests/nix-shell.sh
+++ b/tests/nix-shell.sh
@@ -88,20 +88,43 @@ output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.rb abc ruby)
nix develop -f "$shellDotNix" shellDrv -c bash -c '[[ -n $stdenv ]]'
# Ensure `nix develop -c` preserves stdin
-echo foo | nix develop -f "$shellDotNix" shellDrv -c cat | grep -q foo
+echo foo | nix develop -f "$shellDotNix" shellDrv -c cat | grepQuiet foo
# Ensure `nix develop -c` actually executes the command if stdout isn't a terminal
-nix develop -f "$shellDotNix" shellDrv -c echo foo |& grep -q foo
+nix develop -f "$shellDotNix" shellDrv -c echo foo |& grepQuiet foo
# Test 'nix print-dev-env'.
-[[ $(nix print-dev-env -f "$shellDotNix" shellDrv --json | jq -r .variables.arr1.value[2]) = '3 4' ]]
-
-source <(nix print-dev-env -f "$shellDotNix" shellDrv)
-[[ -n $stdenv ]]
-[[ ${arr1[2]} = "3 4" ]]
-[[ ${arr2[1]} = $'\n' ]]
-[[ ${arr2[2]} = $'x\ny' ]]
-[[ $(fun) = blabla ]]
+
+nix print-dev-env -f "$shellDotNix" shellDrv > $TEST_ROOT/dev-env.sh
+nix print-dev-env -f "$shellDotNix" shellDrv --json > $TEST_ROOT/dev-env.json
+
+# Ensure `nix print-dev-env --json` contains variable assignments.
+[[ $(jq -r .variables.arr1.value[2] $TEST_ROOT/dev-env.json) = '3 4' ]]
+
+# Run tests involving `source <(nix print-dev-inv)` in subshells to avoid modifying the current
+# environment.
+
+set +u # FIXME: Make print-dev-env `set -u` compliant (issue #7951)
+
+# Ensure `source <(nix print-dev-env)` modifies the environment.
+(
+ path=$PATH
+ source $TEST_ROOT/dev-env.sh
+ [[ -n $stdenv ]]
+ [[ ${arr1[2]} = "3 4" ]]
+ [[ ${arr2[1]} = $'\n' ]]
+ [[ ${arr2[2]} = $'x\ny' ]]
+ [[ $(fun) = blabla ]]
+ [[ $PATH = $(jq -r .variables.PATH.value $TEST_ROOT/dev-env.json):$path ]]
+)
+
+# Ensure `source <(nix print-dev-env)` handles the case when PATH is empty.
+(
+ path=$PATH
+ PATH=
+ source $TEST_ROOT/dev-env.sh
+ [[ $PATH = $(PATH=$path jq -r .variables.PATH.value $TEST_ROOT/dev-env.json) ]]
+)
# Test nix-shell with ellipsis and no `inNixShell` argument (for backwards compat with old nixpkgs)
cat >$TEST_ROOT/shell-ellipsis.nix <<EOF
diff --git a/tests/plugins.sh b/tests/plugins.sh
index 6e278ad9d..baf71a362 100644
--- a/tests/plugins.sh
+++ b/tests/plugins.sh
@@ -1,10 +1,7 @@
source common.sh
-set -o pipefail
-
if [[ $BUILD_SHARED_LIBS != 1 ]]; then
- echo "plugins are not supported"
- exit 99
+ skipTest "Plugins are not supported"
fi
res=$(nix --option setting-set true --option plugin-files $PWD/plugins/libplugintest* eval --expr builtins.anotherNull)
diff --git a/tests/post-hook.sh b/tests/post-hook.sh
index 4eff5f511..0266eb15d 100644
--- a/tests/post-hook.sh
+++ b/tests/post-hook.sh
@@ -9,8 +9,14 @@ echo 'require-sigs = false' >> $NIX_CONF_DIR/nix.conf
restartDaemon
+if isDaemonNewer "2.13"; then
+ pushToStore="$PWD/push-to-store.sh"
+else
+ pushToStore="$PWD/push-to-store-old.sh"
+fi
+
# Build the dependencies and push them to the remote store.
-nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook $PWD/push-to-store.sh
+nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook "$pushToStore"
clearStore
diff --git a/tests/pure-eval.sh b/tests/pure-eval.sh
index b83ab8afe..5334bf28e 100644
--- a/tests/pure-eval.sh
+++ b/tests/pure-eval.sh
@@ -8,7 +8,7 @@ nix eval --expr 'assert 1 + 2 == 3; true'
missingImpureErrorMsg=$(! nix eval --expr 'builtins.readFile ./pure-eval.sh' 2>&1)
-echo "$missingImpureErrorMsg" | grep -q -- --impure || \
+echo "$missingImpureErrorMsg" | grepQuiet -- --impure || \
fail "The error message should mention the “--impure” flag to unblock users"
[[ $(nix eval --expr 'builtins.pathExists ./pure-eval.sh') == false ]] || \
diff --git a/tests/push-to-store-old.sh b/tests/push-to-store-old.sh
new file mode 100755
index 000000000..b1495c9e2
--- /dev/null
+++ b/tests/push-to-store-old.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -x
+set -e
+
+[ -n "$OUT_PATHS" ]
+[ -n "$DRV_PATH" ]
+
+echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
+printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
diff --git a/tests/push-to-store.sh b/tests/push-to-store.sh
index b1495c9e2..0b090e1b3 100755
--- a/tests/push-to-store.sh
+++ b/tests/push-to-store.sh
@@ -7,4 +7,4 @@ set -e
[ -n "$DRV_PATH" ]
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
-printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
+printf "%s" "$DRV_PATH"^'*' | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
diff --git a/tests/recursive.sh b/tests/recursive.sh
index 91518d67d..6335d44a5 100644
--- a/tests/recursive.sh
+++ b/tests/recursive.sh
@@ -4,7 +4,7 @@ sed -i 's/experimental-features .*/& recursive-nix/' "$NIX_CONF_DIR"/nix.conf
restartDaemon
# FIXME
-if [[ $(uname) != Linux ]]; then exit 99; fi
+if [[ $(uname) != Linux ]]; then skipTest "Not running Linux"; fi
clearStore
diff --git a/tests/repl.sh b/tests/repl.sh
index c555560cc..be8adb742 100644
--- a/tests/repl.sh
+++ b/tests/repl.sh
@@ -33,14 +33,14 @@ testRepl () {
nix repl "${nixArgs[@]}" <<< "$replCmds" || fail "nix repl does not work twice with the same inputs"
# simple.nix prints a PATH during build
- echo "$replOutput" | grep -qs 'PATH=' || fail "nix repl :log doesn't output logs"
+ echo "$replOutput" | grepQuiet -s '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' \
+ echo "$replOutput" | grepQuiet -s '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" \
+ echo "$replOutput" | grepQuiet -s "while evaluating the file" \
|| fail "nix repl --show-trace doesn't show the trace"
nix repl "${nixArgs[@]}" --option pure-eval true 2>&1 <<< "builtins.currentSystem" \
@@ -58,7 +58,7 @@ testReplResponse () {
local commands="$1"; shift
local expectedResponse="$1"; shift
local response="$(nix repl "$@" <<< "$commands")"
- echo "$response" | grep -qs "$expectedResponse" \
+ echo "$response" | grepQuiet -s "$expectedResponse" \
|| fail "repl command set:
$commands
@@ -121,5 +121,5 @@ sed -i 's/beforeChange/afterChange/' flake/flake.nix
echo ":reload"
echo "changingThing"
) | nix repl ./flake --experimental-features 'flakes repl-flake')
-echo "$replResult" | grep -qs beforeChange
-echo "$replResult" | grep -qs afterChange
+echo "$replResult" | grepQuiet -s beforeChange
+echo "$replResult" | grepQuiet -s afterChange
diff --git a/tests/restricted.sh b/tests/restricted.sh
index 9bd16cf51..776893a56 100644
--- a/tests/restricted.sh
+++ b/tests/restricted.sh
@@ -48,4 +48,4 @@ output="$(nix eval --raw --restrict-eval -I "$traverseDir" \
--expr "builtins.readFile \"$traverseDir/$goUp$(pwd)/restricted-innocent\"" \
2>&1 || :)"
echo "$output" | grep "is forbidden"
-! echo "$output" | grep -F restricted-secret
+echo "$output" | grepInverse -F restricted-secret
diff --git a/tests/search.sh b/tests/search.sh
index 1a98f5b49..8742f8736 100644
--- a/tests/search.sh
+++ b/tests/search.sh
@@ -20,9 +20,9 @@ clearCache
## Search expressions
# Check that empty search string matches all
-nix search -f search.nix '' |grep -q foo
-nix search -f search.nix '' |grep -q bar
-nix search -f search.nix '' |grep -q hello
+nix search -f search.nix '' |grepQuiet foo
+nix search -f search.nix '' |grepQuiet bar
+nix search -f search.nix '' |grepQuiet hello
## Tests for multiple regex/match highlighting
diff --git a/tests/shell.sh b/tests/shell.sh
index 6a80e8385..d2f7cf14e 100644
--- a/tests/shell.sh
+++ b/tests/shell.sh
@@ -10,7 +10,7 @@ nix shell -f shell-hello.nix hello -c hello NixOS | grep 'Hello NixOS'
nix shell -f shell-hello.nix hello^dev -c hello2 | grep 'Hello2'
nix shell -f shell-hello.nix 'hello^*' -c hello2 | grep 'Hello2'
-if ! canUseSandbox; then exit 99; fi
+requireSandboxSupport
chmod -R u+w $TEST_ROOT/store0 || true
rm -rf $TEST_ROOT/store0
diff --git a/tests/tarball.sh b/tests/tarball.sh
index d5cab879c..5f39658c9 100644
--- a/tests/tarball.sh
+++ b/tests/tarball.sh
@@ -19,7 +19,7 @@ test_tarball() {
tarball=$TEST_ROOT/tarball.tar$ext
(cd $TEST_ROOT && tar cf - tarball) | $compressor > $tarball
- nix-env -f file://$tarball -qa --out-path | grep -q dependencies
+ nix-env -f file://$tarball -qa --out-path | grepQuiet dependencies
nix-build -o $TEST_ROOT/result file://$tarball
@@ -34,7 +34,7 @@ test_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'
+ expectStderr 102 nix-build -o $TEST_ROOT/result -E "import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"sha256-xdKv2pq/IiwLSnBBJXW8hNowI4MrdZfW+SYqDQs7Tzc=\"; })" | grep 'NAR hash mismatch in input'
nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })) ? submodules)" >&2
nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })) ? submodules)" 2>&1 | grep 'true'
diff --git a/tests/test-infra.sh b/tests/test-infra.sh
new file mode 100644
index 000000000..54ae120e7
--- /dev/null
+++ b/tests/test-infra.sh
@@ -0,0 +1,85 @@
+# Test the functions for testing themselves!
+# Also test some assumptions on how bash works that they rely on.
+source common.sh
+
+# `true` should exit with 0
+expect 0 true
+
+# `false` should exit with 1
+expect 1 false
+
+# `expect` will fail when we get it wrong
+expect 1 expect 0 false
+
+noisyTrue () {
+ echo YAY! >&2
+ true
+}
+
+noisyFalse () {
+ echo NAY! >&2
+ false
+}
+
+# These should redirect standard error to standard output
+expectStderr 0 noisyTrue | grepQuiet YAY
+expectStderr 1 noisyFalse | grepQuiet NAY
+
+# `set -o pipefile` is enabled
+
+pipefailure () {
+ # shellcheck disable=SC2216
+ true | false | true
+}
+expect 1 pipefailure
+unset pipefailure
+
+pipefailure () {
+ # shellcheck disable=SC2216
+ false | true | true
+}
+expect 1 pipefailure
+unset pipefailure
+
+commandSubstitutionPipeFailure () {
+ # shellcheck disable=SC2216
+ res=$(set -eu -o pipefail; false | true | echo 0)
+}
+expect 1 commandSubstitutionPipeFailure
+
+# `set -u` is enabled
+
+# note (...), making function use subshell, as unbound variable errors
+# in the outer shell are *rightly* not recoverable.
+useUnbound () (
+ set -eu
+ # shellcheck disable=SC2154
+ echo "$thisVariableIsNotBound"
+)
+expect 1 useUnbound
+
+# ! alone unfortunately negates `set -e`, but it works in functions:
+# shellcheck disable=SC2251
+! true
+funBang () {
+ ! true
+}
+expect 1 funBang
+unset funBang
+
+# `grep -v -q` is not what we want for exit codes, but `grepInverse` is
+# Avoid `grep -v -q`. The following line proves the point, and if it fails,
+# we'll know that `grep` had a breaking change or `-v -q` may not be portable.
+{ echo foo; echo bar; } | grep -v -q foo
+{ echo foo; echo bar; } | expect 1 grepInverse foo
+
+# `grepQuiet` is quiet
+res=$(set -eu -o pipefail; echo foo | grepQuiet foo | wc -c)
+(( res == 0 ))
+unset res
+
+# `greqQietInverse` is both
+{ echo foo; echo bar; } | expect 1 grepQuietInverse foo
+res=$(set -eu -o pipefail; echo foo | expect 1 grepQuietInverse foo | wc -c)
+(( res == 0 ))
+unset res
diff --git a/tests/timeout.sh b/tests/timeout.sh
index e3fb3ebcc..b179b79a2 100644
--- a/tests/timeout.sh
+++ b/tests/timeout.sh
@@ -5,17 +5,14 @@ source common.sh
# XXX: This shouldn’t be, but #4813 cause this test to fail
needLocalStore "see #4813"
-set +e
-messages=$(nix-build -Q timeout.nix -A infiniteLoop --timeout 2 2>&1)
-status=$?
-set -e
+messages=$(nix-build -Q timeout.nix -A infiniteLoop --timeout 2 2>&1) && status=0 || status=$?
if [ $status -ne 101 ]; then
echo "error: 'nix-store' exited with '$status'; should have exited 101"
exit 1
fi
-if ! echo "$messages" | grep -q "timed out"; then
+if echo "$messages" | grepQuietInvert "timed out"; then
echo "error: build may have failed for reasons other than timeout; output:"
echo "$messages" >&2
exit 1
diff --git a/tests/user-envs-migration.sh b/tests/user-envs-migration.sh
index 467c28fbb..187372b16 100644
--- a/tests/user-envs-migration.sh
+++ b/tests/user-envs-migration.sh
@@ -4,7 +4,7 @@
source common.sh
if isDaemonNewer "2.4pre20211005"; then
- exit 99
+ skipTest "Daemon is too new"
fi
diff --git a/tests/user-envs.sh b/tests/user-envs.sh
index d63fe780a..d1260ba04 100644
--- a/tests/user-envs.sh
+++ b/tests/user-envs.sh
@@ -1,6 +1,6 @@
source common.sh
-if [ -z "$storeCleared" ]; then
+if [ -z "${storeCleared-}" ]; then
clearStore
fi
@@ -28,13 +28,13 @@ nix-env -f ./user-envs.nix -qa --json --out-path | jq -e '.[] | select(.name ==
] | all'
# Query descriptions.
-nix-env -f ./user-envs.nix -qa '*' --description | grep -q silly
+nix-env -f ./user-envs.nix -qa '*' --description | grepQuiet silly
rm -rf $HOME/.nix-defexpr
ln -s $(pwd)/user-envs.nix $HOME/.nix-defexpr
-nix-env -qa '*' --description | grep -q silly
+nix-env -qa '*' --description | grepQuiet silly
# Query the system.
-nix-env -qa '*' --system | grep -q $system
+nix-env -qa '*' --system | grepQuiet $system
# Install "foo-1.0".
nix-env -i foo-1.0
@@ -42,19 +42,19 @@ nix-env -i foo-1.0
# Query installed: should contain foo-1.0 now (which should be
# executable).
test "$(nix-env -q '*' | wc -l)" -eq 1
-nix-env -q '*' | grep -q foo-1.0
+nix-env -q '*' | grepQuiet foo-1.0
test "$($profiles/test/bin/foo)" = "foo-1.0"
# Test nix-env -qc to compare installed against available packages, and vice versa.
-nix-env -qc '*' | grep -q '< 2.0'
-nix-env -qac '*' | grep -q '> 1.0'
+nix-env -qc '*' | grepQuiet '< 2.0'
+nix-env -qac '*' | grepQuiet '> 1.0'
# Test the -b flag to filter out source-only packages.
[ "$(nix-env -qab | wc -l)" -eq 1 ]
# Test the -s flag to get package status.
-nix-env -qas | grep -q 'IP- foo-1.0'
-nix-env -qas | grep -q -- '--- bar-0.1'
+nix-env -qas | grepQuiet 'IP- foo-1.0'
+nix-env -qas | grepQuiet -- '--- bar-0.1'
# Disable foo.
nix-env --set-flag active false foo
@@ -74,15 +74,15 @@ nix-env -i foo-2.0pre1
# Query installed: should contain foo-2.0pre1 now.
test "$(nix-env -q '*' | wc -l)" -eq 1
-nix-env -q '*' | grep -q foo-2.0pre1
+nix-env -q '*' | grepQuiet foo-2.0pre1
test "$($profiles/test/bin/foo)" = "foo-2.0pre1"
# Upgrade "foo": should install foo-2.0.
-NIX_PATH=nixpkgs=./user-envs.nix:$NIX_PATH nix-env -f '<nixpkgs>' -u foo
+NIX_PATH=nixpkgs=./user-envs.nix:${NIX_PATH-} nix-env -f '<nixpkgs>' -u foo
# Query installed: should contain foo-2.0 now.
test "$(nix-env -q '*' | wc -l)" -eq 1
-nix-env -q '*' | grep -q foo-2.0
+nix-env -q '*' | grepQuiet foo-2.0
test "$($profiles/test/bin/foo)" = "foo-2.0"
# Store the path of foo-2.0.
@@ -94,20 +94,20 @@ nix-env -i bar-0.1
nix-env -e foo
# Query installed: should only contain bar-0.1 now.
-if nix-env -q '*' | grep -q foo; then false; fi
-nix-env -q '*' | grep -q bar
+if nix-env -q '*' | grepQuiet foo; then false; fi
+nix-env -q '*' | grepQuiet bar
# Rollback: should bring "foo" back.
oldGen="$(nix-store -q --resolve $profiles/test)"
nix-env --rollback
[ "$(nix-store -q --resolve $profiles/test)" != "$oldGen" ]
-nix-env -q '*' | grep -q foo-2.0
-nix-env -q '*' | grep -q bar
+nix-env -q '*' | grepQuiet foo-2.0
+nix-env -q '*' | grepQuiet bar
# Rollback again: should remove "bar".
nix-env --rollback
-nix-env -q '*' | grep -q foo-2.0
-if nix-env -q '*' | grep -q bar; then false; fi
+nix-env -q '*' | grepQuiet foo-2.0
+if nix-env -q '*' | grepQuiet bar; then false; fi
# Count generations.
nix-env --list-generations
@@ -129,7 +129,7 @@ nix-env --switch-generation 7
# Install foo-1.0, now using its store path.
nix-env -i "$outPath10"
-nix-env -q '*' | grep -q foo-1.0
+nix-env -q '*' | grepQuiet foo-1.0
nix-store -qR $profiles/test | grep "$outPath10"
nix-store -q --referrers-closure $profiles/test | grep "$(nix-store -q --resolve $profiles/test)"
[ "$(nix-store -q --deriver "$outPath10")" = $drvPath10 ]
@@ -137,12 +137,12 @@ nix-store -q --referrers-closure $profiles/test | grep "$(nix-store -q --resolve
# Uninstall foo-1.0, using a symlink to its store path.
ln -sfn $outPath10/bin/foo $TEST_ROOT/symlink
nix-env -e $TEST_ROOT/symlink
-if nix-env -q '*' | grep -q foo; then false; fi
-(! nix-store -qR $profiles/test | grep "$outPath10")
+if nix-env -q '*' | grepQuiet foo; then false; fi
+nix-store -qR $profiles/test | grepInverse "$outPath10"
# Install foo-1.0, now using a symlink to its store path.
nix-env -i $TEST_ROOT/symlink
-nix-env -q '*' | grep -q foo
+nix-env -q '*' | grepQuiet foo
# Delete all old generations.
nix-env --delete-generations old
@@ -160,7 +160,7 @@ test "$(nix-env -q '*' | wc -l)" -eq 0
# Installing "foo" should only install the newest foo.
nix-env -i foo
test "$(nix-env -q '*' | grep foo- | wc -l)" -eq 1
-nix-env -q '*' | grep -q foo-2.0
+nix-env -q '*' | grepQuiet foo-2.0
# On the other hand, this should install both (and should fail due to
# a collision).
@@ -171,8 +171,8 @@ nix-env -e '*'
nix-env -e '*'
nix-env -i '*'
test "$(nix-env -q '*' | wc -l)" -eq 2
-nix-env -q '*' | grep -q foo-2.0
-nix-env -q '*' | grep -q bar-0.1.1
+nix-env -q '*' | grepQuiet foo-2.0
+nix-env -q '*' | grepQuiet bar-0.1.1
# Test priorities: foo-0.1 has a lower priority than foo-1.0, so it
# should be possible to install both without a collision. Also test
diff --git a/tests/why-depends.sh b/tests/why-depends.sh
index a04d529b5..b35a0d1cf 100644
--- a/tests/why-depends.sh
+++ b/tests/why-depends.sh
@@ -16,9 +16,9 @@ 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
+echo "$FAST_WHY_DEPENDS_OUTPUT" | grepQuiet input-2
+echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grepQuiet 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
+# But only the “precise” one should refer to `reference-to-input-2`
+echo "$FAST_WHY_DEPENDS_OUTPUT" | grepQuietInverse reference-to-input-2
+echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grepQuiet reference-to-input-2