1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 06:31:14 +02:00

Merge remote-tracking branch 'origin/master' into no-flake-substitution

This commit is contained in:
Eelco Dolstra 2024-09-11 17:10:55 +02:00
commit aa41de7d82
1186 changed files with 33139 additions and 25194 deletions

1
tests/functional/.version Symbolic link
View file

@ -0,0 +1 @@
../../.version

18
tests/functional/add.sh Normal file → Executable file
View file

@ -1,10 +1,12 @@
#!/usr/bin/env bash
source common.sh
path1=$(nix-store --add ./dummy)
echo $path1
echo "$path1"
path2=$(nix-store --add-fixed sha256 --recursive ./dummy)
echo $path2
echo "$path2"
if test "$path1" != "$path2"; then
echo "nix-store --add and --add-fixed mismatch"
@ -12,24 +14,24 @@ if test "$path1" != "$path2"; then
fi
path3=$(nix-store --add-fixed sha256 ./dummy)
echo $path3
echo "$path3"
test "$path1" != "$path3" || exit 1
path4=$(nix-store --add-fixed sha1 --recursive ./dummy)
echo $path4
echo "$path4"
test "$path1" != "$path4" || exit 1
hash1=$(nix-store -q --hash $path1)
echo $hash1
hash1=$(nix-store -q --hash "$path1")
echo "$hash1"
hash2=$(nix-hash --type sha256 --base32 ./dummy)
echo $hash2
echo "$hash2"
test "$hash1" = "sha256:$hash2"
#### New style commands
clearStore
clearStoreIfPossible
(
path1=$(nix store add ./dummy)

8
tests/functional/bash-profile.sh Normal file → Executable file
View file

@ -1,9 +1,11 @@
#!/usr/bin/env bash
source common.sh
sed -e "s|@localstatedir@|$TEST_ROOT/profile-var|g" -e "s|@coreutils@|$coreutils|g" < ../../scripts/nix-profile.sh.in > $TEST_ROOT/nix-profile.sh
sed -e "s|@localstatedir@|$TEST_ROOT/profile-var|g" -e "s|@coreutils@|$coreutils|g" < ../../scripts/nix-profile.sh.in > "$TEST_ROOT"/nix-profile.sh
user=$(whoami)
rm -rf $TEST_HOME $TEST_ROOT/profile-var
mkdir -p $TEST_HOME
rm -rf "$TEST_HOME" "$TEST_ROOT/profile-var"
mkdir -p "$TEST_HOME"
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set"
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency

8
tests/functional/binary-cache-build-remote.sh Normal file → Executable file
View file

@ -1,6 +1,10 @@
#!/usr/bin/env bash
source common.sh
clearStore
TODO_NixOS
clearStoreIfPossible
clearCacheCache
# Fails without remote builders
@ -10,7 +14,7 @@ clearCacheCache
outPath=$(nix-build --store "file://$cacheDir" --builders 'auto - - 1 1' -j0 dependencies.nix)
# Test that the path exactly exists in the destination store.
nix path-info --store "file://$cacheDir" $outPath
nix path-info --store "file://$cacheDir" "$outPath"
# Succeeds without any build capability because no-op
nix-build --store "file://$cacheDir" -j0 dependencies.nix

167
tests/functional/binary-cache.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
needLocalStore "'--no-require-sigs' cant be used with the daemon"
# We can produce drvs directly into the binary cache
@ -12,9 +16,9 @@ clearStore
clearCache
outPath=$(nix-build dependencies.nix --no-out-link)
nix copy --to file://$cacheDir $outPath
nix copy --to "file://$cacheDir" "$outPath"
readarray -t paths < <(nix path-info --all --json --store file://$cacheDir | jq 'keys|sort|.[]' -r)
readarray -t paths < <(nix path-info --all --json --store "file://$cacheDir" | jq 'keys|sort|.[]' -r)
[[ "${#paths[@]}" -eq 3 ]]
for path in "${paths[@]}"; do
[[ "$path" =~ -dependencies-input-0$ ]] \
@ -23,16 +27,16 @@ for path in "${paths[@]}"; do
done
# Test copying build logs to the binary cache.
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
expect 1 nix log $outPath 2>&1 | grep 'is not available'
nix log --substituters file://$cacheDir $outPath | grep FOO
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"
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 log $outPath | grep FOO
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.
@ -44,15 +48,15 @@ basicDownloadTests() {
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "---"
nix-store --substituters "file://$cacheDir" --no-require-sigs -r $outPath
nix-store --substituters "file://$cacheDir" --no-require-sigs -r "$outPath"
[ -x $outPath/program ]
[ -x "$outPath/program" ]
# But with the right configuration, "nix-env -qas" should also work.
clearStore
clearCacheCache
echo "WantMassQuery: 1" >> $cacheDir/nix-cache-info
echo "WantMassQuery: 1" >> "$cacheDir/nix-cache-info"
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "--S"
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "--S"
@ -60,12 +64,12 @@ basicDownloadTests() {
x=$(nix-env -f dependencies.nix -qas \* --prebuilt-only)
[ -z "$x" ]
nix-store --substituters "file://$cacheDir" --no-require-sigs -r $outPath
nix-store --substituters "file://$cacheDir" --no-require-sigs -r "$outPath"
nix-store --check-validity $outPath
nix-store -qR $outPath | grep input-2
nix-store --check-validity "$outPath"
nix-store -qR "$outPath" | grep input-2
echo "WantMassQuery: 0" >> $cacheDir/nix-cache-info
echo "WantMassQuery: 0" >> "$cacheDir/nix-cache-info"
}
@ -81,22 +85,22 @@ basicDownloadTests
# Test whether Nix notices if the NAR doesn't match the hash in the NAR info.
clearStore
nar=$(ls $cacheDir/nar/*.nar.xz | head -n1)
mv $nar $nar.good
mkdir -p $TEST_ROOT/empty
nix-store --dump $TEST_ROOT/empty | xz > $nar
nar=$(find "$cacheDir/nar/" -type f -name "*.nar.xz" | head -n1)
mv "$nar" "$nar".good
mkdir -p "$TEST_ROOT/empty"
nix-store --dump "$TEST_ROOT/empty" | xz > "$nar"
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
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
mv "$nar".good "$nar"
# Test whether this unsigned cache is rejected if the user requires signed caches.
clearStore
clearCacheCache
if nix-store --substituters "file://$cacheDir" -r $outPath; then
if nix-store --substituters "file://$cacheDir" -r "$outPath"; then
echo "unsigned binary cache incorrectly accepted"
exit 1
fi
@ -105,131 +109,134 @@ fi
# Test whether fallback works if a NAR has disappeared. This does not require --fallback.
clearStore
mv $cacheDir/nar $cacheDir/nar2
mv "$cacheDir/nar" "$cacheDir/nar2"
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result"
mv $cacheDir/nar2 $cacheDir/nar
mv "$cacheDir/nar2" "$cacheDir/nar"
# Test whether fallback works if a NAR is corrupted. This does require --fallback.
clearStore
mv $cacheDir/nar $cacheDir/nar2
mkdir $cacheDir/nar
for i in $(cd $cacheDir/nar2 && echo *); do touch $cacheDir/nar/$i; done
mv "$cacheDir/nar" "$cacheDir/nar2"
mkdir "$cacheDir/nar"
for i in $(cd "$cacheDir/nar2" && echo *); do touch "$cacheDir"/nar/"$i"; done
(! nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result)
(! nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result")
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result --fallback
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" --fallback
rm -rf $cacheDir/nar
mv $cacheDir/nar2 $cacheDir/nar
rm -rf "$cacheDir/nar"
mv "$cacheDir/nar2" "$cacheDir/nar"
# Test whether building works if the binary cache contains an
# incomplete closure.
clearStore
rm -v $(grep -l "StorePath:.*dependencies-input-2" $cacheDir/*.narinfo)
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
grepQuiet "copying path.*input-0" $TEST_ROOT/log
grepQuiet "copying path.*input-2" $TEST_ROOT/log
grepQuiet "copying path.*top" $TEST_ROOT/log
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" 2>&1 | tee "$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.
clearStore
clearCacheCache
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $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
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" 2>&1 | tee "$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.
clearCache
clearCacheCache
nix key generate-secret --key-name test.nixos.org-1 > $TEST_ROOT/sk1
publicKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk1)
nix key generate-secret --key-name test.nixos.org-1 > "$TEST_ROOT/sk1"
publicKey=$(nix key convert-secret-to-public < "$TEST_ROOT/sk1")
nix key generate-secret --key-name test.nixos.org-1 > $TEST_ROOT/sk2
badKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk2)
nix key generate-secret --key-name test.nixos.org-1 > "$TEST_ROOT/sk2"
badKey=$(nix key convert-secret-to-public < "$TEST_ROOT/sk2")
nix key generate-secret --key-name foo.nixos.org-1 > $TEST_ROOT/sk3
otherKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk3)
nix key generate-secret --key-name foo.nixos.org-1 > "$TEST_ROOT/sk3"
otherKey=$(nix key convert-secret-to-public < "$TEST_ROOT/sk3")
_NIX_FORCE_HTTP= nix copy --to file://$cacheDir?secret-key=$TEST_ROOT/sk1 $outPath
_NIX_FORCE_HTTP='' nix copy --to "file://$cacheDir"?secret-key="$TEST_ROOT"/sk1 "$outPath"
# Downloading should fail if we don't provide a key.
clearStore
clearCacheCache
(! nix-store -r $outPath --substituters "file://$cacheDir")
(! nix-store -r "$outPath" --substituters "file://$cacheDir")
# And it should fail if we provide an incorrect key.
clearStore
clearCacheCache
(! nix-store -r $outPath --substituters "file://$cacheDir" --trusted-public-keys "$badKey")
(! nix-store -r "$outPath" --substituters "file://$cacheDir" --trusted-public-keys "$badKey")
# It should succeed if we provide the correct key.
nix-store -r $outPath --substituters "file://$cacheDir" --trusted-public-keys "$otherKey $publicKey"
nix-store -r "$outPath" --substituters "file://$cacheDir" --trusted-public-keys "$otherKey $publicKey"
# It should fail if we corrupt the .narinfo.
clearStore
cacheDir2=$TEST_ROOT/binary-cache-2
rm -rf $cacheDir2
cp -r $cacheDir $cacheDir2
rm -rf "$cacheDir2"
cp -r "$cacheDir" "$cacheDir2"
for i in $cacheDir2/*.narinfo; do
grep -v References $i > $i.tmp
mv $i.tmp $i
for i in "$cacheDir2"/*.narinfo; do
grep -v References "$i" > "$i".tmp
mv "$i".tmp "$i"
done
clearCacheCache
(! nix-store -r $outPath --substituters "file://$cacheDir2" --trusted-public-keys "$publicKey")
(! nix-store -r "$outPath" --substituters "file://$cacheDir2" --trusted-public-keys "$publicKey")
# If we provide a bad and a good binary cache, it should succeed.
nix-store -r $outPath --substituters "file://$cacheDir2 file://$cacheDir" --trusted-public-keys "$publicKey"
nix-store -r "$outPath" --substituters "file://$cacheDir2 file://$cacheDir" --trusted-public-keys "$publicKey"
unset _NIX_FORCE_HTTP
# Test 'nix verify --all' on a binary cache.
nix store verify -vvvvv --all --store file://$cacheDir --no-trust
nix store verify -vvvvv --all --store "file://$cacheDir" --no-trust
# Test local NAR caching.
narCache=$TEST_ROOT/nar-cache
rm -rf $narCache
mkdir $narCache
rm -rf "$narCache"
mkdir "$narCache"
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" $outPath/foobar) = FOOBAR ]]
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" "$outPath/foobar") = FOOBAR ]]
rm -rfv "$cacheDir/nar"
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" $outPath/foobar) = FOOBAR ]]
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" "$outPath/foobar") = FOOBAR ]]
(! nix store cat --store file://$cacheDir $outPath/foobar)
(! nix store cat --store "file://$cacheDir" "$outPath/foobar")
# Test NAR listing generation.
clearCache
# preserve quotes variables in the single-quoted string
# shellcheck disable=SC2016
outPath=$(nix-build --no-out-link -E '
with import ./config.nix;
mkDerivation {
@ -238,16 +245,18 @@ outPath=$(nix-build --no-out-link -E '
}
')
nix copy --to file://$cacheDir?write-nar-listing=1 $outPath
nix copy --to "file://$cacheDir"?write-nar-listing=1 "$outPath"
diff -u \
<(jq -S < $cacheDir/$(basename $outPath | cut -c1-32).ls) \
<(jq -S < "$cacheDir/$(basename "$outPath" | cut -c1-32).ls") \
<(echo '{"version":1,"root":{"type":"directory","entries":{"bar":{"type":"regular","size":4,"narOffset":232},"link":{"type":"symlink","target":"xyzzy"}}}}' | jq -S)
# Test debug info index generation.
clearCache
# preserve quotes variables in the single-quoted string
# shellcheck disable=SC2016
outPath=$(nix-build --no-out-link -E '
with import ./config.nix;
mkDerivation {
@ -256,14 +265,16 @@ outPath=$(nix-build --no-out-link -E '
}
')
nix copy --to "file://$cacheDir?index-debug-info=1&compression=none" $outPath
nix copy --to "file://$cacheDir?index-debug-info=1&compression=none" "$outPath"
diff -u \
<(cat $cacheDir/debuginfo/02623eda209c26a59b1a8638ff7752f6b945c26b.debug | jq -S) \
<(jq -S < "$cacheDir"/debuginfo/02623eda209c26a59b1a8638ff7752f6b945c26b.debug) \
<(echo '{"archive":"../nar/100vxs724qr46phz8m24iswmg9p3785hsyagz0kchf6q6gf06sw6.nar","member":"lib/debug/.build-id/02/623eda209c26a59b1a8638ff7752f6b945c26b.debug"}' | jq -S)
# Test against issue https://github.com/NixOS/nix/issues/3964
#
# preserve quotes variables in the single-quoted string
# shellcheck disable=SC2016
expr='
with import ./config.nix;
mkDerivation {
@ -273,22 +284,22 @@ expr='
}
'
outPath=$(nix-build --no-out-link -E "$expr")
docPath=$(nix-store -q --references $outPath)
docPath=$(nix-store -q --references "$outPath")
# $ nix-store -q --tree $outPath
# ...-multi-output
# +---...-multi-output-doc
nix copy --to "file://$cacheDir" $outPath
nix copy --to "file://$cacheDir" "$outPath"
hashpart() {
basename "$1" | cut -c1-32
}
# break the closure of out by removing doc
rm $cacheDir/$(hashpart $docPath).narinfo
rm "$cacheDir/$(hashpart "$docPath")".narinfo
nix-store --delete $outPath $docPath
nix-store --delete "$outPath" "$docPath"
# -vvv is the level that logs during the loop
timeout 60 nix-build --no-out-link -E "$expr" --option substituters "file://$cacheDir" \
--option trusted-binary-caches "file://$cacheDir" --no-require-sigs

14
tests/functional/brotli.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
clearCache
@ -7,15 +11,15 @@ cacheURI="file://$cacheDir?compression=br"
outPath=$(nix-build dependencies.nix --no-out-link)
nix copy --to $cacheURI $outPath
nix copy --to "$cacheURI" "$outPath"
HASH=$(nix hash path $outPath)
HASH=$(nix hash path "$outPath")
clearStore
clearCacheCache
nix copy --from $cacheURI $outPath --no-check-sigs
nix copy --from "$cacheURI" "$outPath" --no-check-sigs
HASH2=$(nix hash path $outPath)
HASH2=$(nix hash path "$outPath")
[[ $HASH = $HASH2 ]]
[[ $HASH == "$HASH2" ]]

20
tests/functional/build-delete.sh Normal file → Executable file
View file

@ -1,28 +1,30 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
# 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
nix build -f multiple-outputs.nix --json independent --no-link > "$TEST_ROOT"/independent.json
# Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
nix-store --delete "$p" # Clean up for next test
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
nix-store --delete "$(jq -r <$TEST_ROOT/independent.json .[0].outputs.first)"
nix-store --delete "$(jq -r <"$TEST_ROOT"/independent.json .[0].outputs.first)"
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
cmp $p <<EOF
cmp "$p" <<EOF
first
second
EOF
nix-store --delete "$p" # Clean up for next test
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
nix-store --delete "$(jq -r <$TEST_ROOT/independent.json .[0].outputs.second)"
nix-store --delete "$(jq -r <"$TEST_ROOT"/independent.json .[0].outputs.second)"
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
cmp $p <<EOF
cmp "$p" <<EOF
first
second
EOF
@ -34,16 +36,16 @@ issue_6572_independent_outputs
# https://github.com/NixOS/nix/issues/6572
issue_6572_dependent_outputs() {
nix build -f multiple-outputs.nix --json a --no-link > $TEST_ROOT/a.json
nix build -f multiple-outputs.nix --json a --no-link > "$TEST_ROOT"/a.json
# # Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
nix-store --delete "$p" # Clean up for next test
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
nix-store --delete "$(jq -r <$TEST_ROOT/a.json .[0].outputs.second)"
nix-store --delete "$(jq -r <"$TEST_ROOT"/a.json .[0].outputs.second)"
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
cmp $p <<EOF
cmp "$p" <<EOF
first
second
EOF

18
tests/functional/build-dry.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
###################################################
# Check that --dry-run isn't confused with read-only mode
# https://github.com/NixOS/nix/issues/1795
@ -33,17 +37,17 @@ clearStore
clearCache
RESULT=$TEST_ROOT/result-link
rm -f $RESULT
rm -f "$RESULT"
nix-build dependencies.nix -o $RESULT --dry-run
nix-build dependencies.nix -o "$RESULT" --dry-run
[[ ! -h $RESULT ]] || fail "nix-build --dry-run created output link"
nix build -f dependencies.nix -o $RESULT --dry-run
nix build -f dependencies.nix -o "$RESULT" --dry-run
[[ ! -h $RESULT ]] || fail "nix build --dry-run created output link"
nix build -f dependencies.nix -o $RESULT
nix build -f dependencies.nix -o "$RESULT"
[[ -h $RESULT ]]
@ -56,12 +60,12 @@ RES=$(nix build -f dependencies.nix --dry-run --json)
if [[ -z "${NIX_TESTS_CA_BY_DEFAULT-}" ]]; then
echo "$RES" | jq '.[0] | [
(.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")),
(.outputs.out | test("'$NIX_STORE_DIR'"))
(.drvPath | test("'"$NIX_STORE_DIR"'.*\\.drv")),
(.outputs.out | test("'"$NIX_STORE_DIR"'"))
] | all'
else
echo "$RES" | jq '.[0] | [
(.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")),
(.drvPath | test("'"$NIX_STORE_DIR"'.*\\.drv")),
.outputs.out == null
] | all'
fi

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
file=build-hook-ca-fixed.nix

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
file=build-hook-ca-floating.nix

12
tests/functional/build-remote-input-addressed.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
file=build-hook.nix
@ -11,17 +13,17 @@ registerBuildHook () {
# Dummy post-build-hook just to ensure that it's executed correctly.
# (we can't reuse the one from `$PWD/push-to-store.sh` because of
# https://github.com/NixOS/nix/issues/4341)
cat <<EOF > $TEST_ROOT/post-build-hook.sh
cat <<EOF > "$TEST_ROOT/post-build-hook.sh"
#!/bin/sh
echo "Post hook ran successfully"
# Add an empty line to a counter file, just to check that this hook ran properly
echo "" >> $TEST_ROOT/post-hook-counter
EOF
chmod +x $TEST_ROOT/post-build-hook.sh
rm -f $TEST_ROOT/post-hook-counter
chmod +x "$TEST_ROOT/post-build-hook.sh"
rm -f "$TEST_ROOT/post-hook-counter"
echo "post-build-hook = $TEST_ROOT/post-build-hook.sh" >> $NIX_CONF_DIR/nix.conf
echo "post-build-hook = $TEST_ROOT/post-build-hook.sh" >> "$test_nix_conf"
}
registerBuildHook
@ -30,4 +32,4 @@ source build-remote.sh
# `build-hook.nix` has four derivations to build, and the hook runs twice for
# each derivation (once on the builder and once on the host), so the counter
# should contain eight lines now
[[ $(cat $TEST_ROOT/post-hook-counter | wc -l) -eq 8 ]]
[[ $(wc -l < "$TEST_ROOT/post-hook-counter") -eq 8 ]]

View file

@ -1,2 +1,7 @@
outPath=$(readlink -f $TEST_ROOT/result)
grep 'FOO BAR BAZ' ${remoteDir}/${outPath}
# shellcheck shell=bash
# Variables must be defined by caller, so
# shellcheck disable=SC2154
outPath=$(readlink -f "$TEST_ROOT/result")
grep 'FOO BAR BAZ' "${remoteDir}/${outPath}"

View file

@ -1,7 +1,10 @@
#!/usr/bin/env bash
source common.sh
enableFeatures "daemon-trust-override"
TODO_NixOS
restartDaemon
requireSandboxSupport
@ -22,8 +25,12 @@ nix-build build-hook.nix -A passthru.input2 \
# copy our already-build `input2` to the remote store. That store object
# is input-addressed, so this will fail.
# For script below
# shellcheck disable=SC2034
file=build-hook.nix
# shellcheck disable=SC2034
prog=$(readlink -e ./nix-daemon-untrusting.sh)
# shellcheck disable=SC2034
proto=ssh-ng
expectStderr 1 source build-remote-trustless.sh \

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
# Remote trusts us

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
# Remote trusts us

View file

@ -1,7 +1,11 @@
#!/usr/bin/env bash
source common.sh
enableFeatures "daemon-trust-override"
TODO_NixOS
restartDaemon
# Remote doesn't trust us

View file

@ -1,7 +1,10 @@
#!/usr/bin/env bash
source common.sh
enableFeatures "daemon-trust-override"
TODO_NixOS
restartDaemon
# Remote doesn't trusts us, but this is fine because we are only

View file

@ -1,5 +1,11 @@
# shellcheck shell=bash
# All variables should be defined externally by the scripts that source
# this, `set -u` will catch any that are forgotten.
# shellcheck disable=SC2154
requireSandboxSupport
[[ $busybox =~ busybox ]] || skipTest "no busybox"
[[ "$busybox" =~ busybox ]] || skipTest "no busybox"
unset NIX_STORE_DIR
unset NIX_STATE_DIR
@ -8,7 +14,7 @@ remoteDir=$TEST_ROOT/remote
# Note: ssh{-ng}://localhost bypasses ssh. See tests/functional/build-remote.sh for
# more details.
nix-build $file -o $TEST_ROOT/result --max-jobs 0 \
--arg busybox $busybox \
--store $TEST_ROOT/local \
nix-build "$file" -o "$TEST_ROOT/result" --max-jobs 0 \
--arg busybox "$busybox" \
--store "$TEST_ROOT/local" \
--builders "$proto://localhost?remote-program=$prog&remote-store=${remoteDir}%3Fsystem-features=foo%20bar%20baz - - 1 1 foo,bar,baz"

14
tests/functional/build-remote-with-mounted-ssh-ng.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
requireSandboxSupport
@ -6,17 +8,17 @@ requireSandboxSupport
enableFeatures mounted-ssh-store
nix build -Lvf simple.nix \
--arg busybox $busybox \
--out-link $TEST_ROOT/result-from-remote \
--arg busybox "$busybox" \
--out-link "$TEST_ROOT/result-from-remote" \
--store mounted-ssh-ng://localhost
nix build -Lvf simple.nix \
--arg busybox $busybox \
--out-link $TEST_ROOT/result-from-remote-new-cli \
--arg busybox "$busybox" \
--out-link "$TEST_ROOT/result-from-remote-new-cli" \
--store 'mounted-ssh-ng://localhost?remote-program=nix daemon'
# This verifies that the out link was actually created and valid. The ability
# to create out links (permanent gc roots) is the distinguishing feature of
# the mounted-ssh-ng store.
cat $TEST_ROOT/result-from-remote/hello | grepQuiet 'Hello World!'
cat $TEST_ROOT/result-from-remote-new-cli/hello | grepQuiet 'Hello World!'
grepQuiet 'Hello World!' < "$TEST_ROOT/result-from-remote/hello"
grepQuiet 'Hello World!' < "$TEST_ROOT/result-from-remote-new-cli/hello"

View file

@ -1,5 +1,9 @@
# shellcheck shell=bash
: "${file?must be defined by caller (remote building test case using this)}"
requireSandboxSupport
[[ $busybox =~ busybox ]] || skipTest "no busybox"
[[ "${busybox-}" =~ busybox ]] || skipTest "no busybox"
# Avoid store dir being inside sandbox build-dir
unset NIX_STORE_DIR
@ -15,50 +19,50 @@ fi
builders=(
# system-features will automatically be added to the outer URL, but not inner
# remote-store URL.
"ssh://localhost?remote-store=$TEST_ROOT/machine1?system-features=$(join_by "%20" foo ${EXTRA_SYSTEM_FEATURES[@]}) - - 1 1 $(join_by "," foo ${EXTRA_SYSTEM_FEATURES[@]})"
"$TEST_ROOT/machine2 - - 1 1 $(join_by "," bar ${EXTRA_SYSTEM_FEATURES[@]})"
"ssh-ng://localhost?remote-store=$TEST_ROOT/machine3?system-features=$(join_by "%20" baz ${EXTRA_SYSTEM_FEATURES[@]}) - - 1 1 $(join_by "," baz ${EXTRA_SYSTEM_FEATURES[@]})"
"ssh://localhost?remote-store=$TEST_ROOT/machine1?system-features=$(join_by "%20" foo "${EXTRA_SYSTEM_FEATURES[@]}") - - 1 1 $(join_by "," foo "${EXTRA_SYSTEM_FEATURES[@]}")"
"$TEST_ROOT/machine2 - - 1 1 $(join_by "," bar "${EXTRA_SYSTEM_FEATURES[@]}")"
"ssh-ng://localhost?remote-store=$TEST_ROOT/machine3?system-features=$(join_by "%20" baz "${EXTRA_SYSTEM_FEATURES[@]}") - - 1 1 $(join_by "," baz "${EXTRA_SYSTEM_FEATURES[@]}")"
)
chmod -R +w $TEST_ROOT/machine* || true
rm -rf $TEST_ROOT/machine* || true
chmod -R +w "$TEST_ROOT/machine"* || true
rm -rf "$TEST_ROOT/machine"* || true
# Note: ssh://localhost bypasses ssh, directly invoking nix-store as a
# child process. This allows us to test LegacySSHStore::buildDerivation().
# ssh-ng://... likewise allows us to test RemoteStore::buildDerivation().
nix build -L -v -f $file -o $TEST_ROOT/result --max-jobs 0 \
--arg busybox $busybox \
--store $TEST_ROOT/machine0 \
nix build -L -v -f "$file" -o "$TEST_ROOT/result" --max-jobs 0 \
--arg busybox "$busybox" \
--store "$TEST_ROOT/machine0" \
--builders "$(join_by '; ' "${builders[@]}")"
outPath=$(readlink -f $TEST_ROOT/result)
outPath=$(readlink -f "$TEST_ROOT/result")
grep 'FOO BAR BAZ' $TEST_ROOT/machine0/$outPath
grep 'FOO BAR BAZ' "$TEST_ROOT/machine0/$outPath"
testPrintOutPath=$(nix build -L -v -f $file --no-link --print-out-paths --max-jobs 0 \
--arg busybox $busybox \
--store $TEST_ROOT/machine0 \
testPrintOutPath=$(nix build -L -v -f "$file" --no-link --print-out-paths --max-jobs 0 \
--arg busybox "$busybox" \
--store "$TEST_ROOT/machine0" \
--builders "$(join_by '; ' "${builders[@]}")"
)
[[ $testPrintOutPath =~ store.*build-remote ]]
# Ensure that input1 was built on store1 due to the required feature.
output=$(nix path-info --store $TEST_ROOT/machine1 --all)
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.
output=$(nix path-info --store $TEST_ROOT/machine2 --all)
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.
output=$(nix path-info --store $TEST_ROOT/machine3 --all)
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
@ -66,7 +70,7 @@ unset output
for i in input1 input3; do
nix log --store $TEST_ROOT/machine0 --file "$file" --arg busybox $busybox passthru."$i" | grep hi-$i
nix log --store "$TEST_ROOT/machine0" --file "$file" --arg busybox "$busybox" "passthru.$i" | grep hi-$i
done
# Behavior of keep-failed
@ -74,9 +78,9 @@ out="$(nix-build 2>&1 failing.nix \
--no-out-link \
--builders "$(join_by '; ' "${builders[@]}")" \
--keep-failed \
--store $TEST_ROOT/machine0 \
--store "$TEST_ROOT/machine0" \
-j0 \
--arg busybox $busybox)" || true
--arg busybox "$busybox")" || true
[[ "$out" =~ .*"note: keeping build directory".* ]]

56
tests/functional/build.sh Normal file → Executable file
View file

@ -1,6 +1,8 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
# Make sure that 'nix build' returns all outputs by default.
nix build -f multiple-outputs.nix --json a b --no-link | jq --exit-status '
@ -43,6 +45,14 @@ nix build -f multiple-outputs.nix --json e --no-link | jq --exit-status '
(.outputs | keys == ["a_a", "b"]))
'
# Tests that we can handle empty 'outputsToInstall' (assuming that default
# output "out" exists).
nix build -f multiple-outputs.nix --json nothing-to-install --no-link | jq --exit-status '
(.[0] |
(.drvPath | match(".*nothing-to-install.drv")) and
(.outputs | keys == ["out"]))
'
# But not when it's overriden.
nix build -f multiple-outputs.nix --json e^a_a --no-link
nix build -f multiple-outputs.nix --json e^a_a --no-link | jq --exit-status '
@ -130,6 +140,50 @@ nix build --impure -f multiple-outputs.nix --json e --no-link | jq --exit-status
(.outputs | keys == ["a_a", "b"]))
'
# Make sure that the 3 types of aliases work
# BaseSettings<T>, BaseSettings<bool>, and BaseSettings<SandboxMode>.
nix build --impure -f multiple-outputs.nix --json e --no-link \
--build-max-jobs 3 \
--gc-keep-outputs \
--build-use-sandbox | \
jq --exit-status '
(.[0] |
(.drvPath | match(".*multiple-outputs-e.drv")) and
(.outputs | keys == ["a_a", "b"]))
'
# Make sure that `--stdin` works and does not apply any defaults
printf "" | nix build --no-link --stdin --json | jq --exit-status '. == []'
printf "%s\n" "$drv^*" | nix build --no-link --stdin --json | jq --exit-status '.[0]|has("drvPath")'
# --keep-going and FOD
out="$(nix build -f fod-failing.nix -L 2>&1)" && status=0 || status=$?
test "$status" = 1
# one "hash mismatch" error, one "build of ... failed"
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
<<<"$out" grepQuiet -E "error: build of '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out' failed"
out="$(nix build -f fod-failing.nix -L x1 x2 x3 --keep-going 2>&1)" && status=0 || status=$?
test "$status" = 1
# three "hash mismatch" errors - for each failing fod, one "build of ... failed"
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 4
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
<<<"$out" grepQuiet -E "error: build of '.*-x[1-3]\\.drv\\^out', '.*-x[1-3]\\.drv\\^out', '.*-x[1-3]\\.drv\\^out' failed"
out="$(nix build -f fod-failing.nix -L x4 2>&1)" && status=0 || status=$?
test "$status" = 1
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2
<<<"$out" grepQuiet -E "error: 1 dependencies of derivation '.*-x4\\.drv' failed to build"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
out="$(nix build -f fod-failing.nix -L x4 --keep-going 2>&1)" && status=0 || status=$?
test "$status" = 1
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 3
<<<"$out" grepQuiet -E "error: 2 dependencies of derivation '.*-x4\\.drv' failed to build"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'"

View file

@ -26,7 +26,8 @@ copyAttr () {
# Note: to copy CA derivations, we need to copy the realisations, which
# currently requires naming the installables, not just the derivation output
# path.
nix copy --to file://$cacheDir "${args[@]}"
nix copy --to "file://$cacheDir" "${args[@]}"
}
testRemoteCacheFor () {
@ -35,7 +36,7 @@ testRemoteCacheFor () {
copyAttr "$derivationPath" 1
clearStore
# Check nothing gets built.
buildAttr "$derivationPath" 1 --option substituters file://$cacheDir --no-require-sigs |& grepQuietInverse " will be built:"
buildAttr "$derivationPath" 1 --option substituters "file://$cacheDir" --no-require-sigs |& grepQuietInverse " will be built:"
}
testRemoteCache () {
@ -48,4 +49,4 @@ testRemoteCache () {
}
clearStore
testRemoteCache
testRemoteCache

View file

@ -20,11 +20,11 @@ testDeterministicCA () {
testCutoffFor () {
local out1 out2
out1=$(buildAttr $1 1)
out1=$(buildAttr "$1" 1)
# The seed only changes the root derivation, and not it's output, so the
# dependent derivations should only need to be built once.
buildAttr rootCA 2
out2=$(buildAttr $1 2 -j0)
out2=$(buildAttr "$1" 2 -j0)
test "$out1" == "$out2"
}
@ -41,7 +41,7 @@ testGC () {
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
buildAttr rootCA 1 --out-link "$TEST_ROOT"/rootCA
nix-collect-garbage
buildAttr rootCA 1 -j0
}
@ -55,7 +55,7 @@ testNixCommand () {
testNormalization () {
clearStore
outPath=$(buildAttr rootCA 1)
test "$(stat -c %Y $outPath)" -eq 1
test "$(stat -c %Y "$outPath")" -eq 1
}
clearStore

View file

@ -2,4 +2,6 @@ source ../common.sh
enableFeatures "ca-derivations"
TODO_NixOS
restartDaemon

View file

@ -1,29 +1,31 @@
#!/usr/bin/env bash
#
source common.sh
export NIX_TESTS_CA_BY_DEFAULT=1
drvPath=$(nix-instantiate ../simple.nix)
nix derivation show $drvPath | jq .[] > $TEST_HOME/simple.json
nix derivation show "$drvPath" | jq .[] > "$TEST_HOME"/simple.json
drvPath2=$(nix derivation add < $TEST_HOME/simple.json)
drvPath2=$(nix derivation add < "$TEST_HOME"/simple.json)
[[ "$drvPath" = "$drvPath2" ]]
# Content-addressed derivations can be renamed.
jq '.name = "foo"' < $TEST_HOME/simple.json > $TEST_HOME/foo.json
drvPath3=$(nix derivation add --dry-run < $TEST_HOME/foo.json)
jq '.name = "foo"' < "$TEST_HOME"/simple.json > "$TEST_HOME"/foo.json
drvPath3=$(nix derivation add --dry-run < "$TEST_HOME"/foo.json)
# With --dry-run nothing is actually written
[[ ! -e "$drvPath3" ]]
# But the JSON is rejected without the experimental feature
expectStderr 1 nix derivation add < $TEST_HOME/foo.json --experimental-features nix-command | grepQuiet "experimental Nix feature 'ca-derivations' is disabled"
expectStderr 1 nix derivation add < "$TEST_HOME"/foo.json --experimental-features nix-command | grepQuiet "experimental Nix feature 'ca-derivations' is disabled"
# Without --dry-run it is actually written
drvPath4=$(nix derivation add < $TEST_HOME/foo.json)
drvPath4=$(nix derivation add < "$TEST_HOME"/foo.json)
[[ "$drvPath4" = "$drvPath3" ]]
[[ -e "$drvPath3" ]]
# The modified derivation read back as JSON matches
nix derivation show $drvPath3 | jq .[] > $TEST_HOME/foo-read.json
diff $TEST_HOME/foo.json $TEST_HOME/foo-read.json
nix derivation show "$drvPath3" | jq .[] > "$TEST_HOME"/foo-read.json
diff "$TEST_HOME"/foo.json "$TEST_HOME"/foo-read.json

View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source ./common.sh
requireDaemonNewerThan "2.4pre20210625"
@ -5,7 +7,7 @@ requireDaemonNewerThan "2.4pre20210625"
export REMOTE_STORE_DIR="$TEST_ROOT/remote_store"
export REMOTE_STORE="file://$REMOTE_STORE_DIR"
rm -rf $REMOTE_STORE_DIR
rm -rf "$REMOTE_STORE_DIR"
clearStore
# Build dep1 and push that to the binary cache.

View file

@ -0,0 +1,33 @@
configure_file(
input : 'config.nix.in',
output : 'config.nix',
configuration : test_confdata,
)
suites += {
'name': 'ca',
'deps': [],
'tests': [
'build-with-garbage-path.sh',
'build.sh',
'build-cache.sh',
'concurrent-builds.sh',
'derivation-json.sh',
'duplicate-realisation-in-closure.sh',
'eval-store.sh',
'gc.sh',
'import-derivation.sh',
'new-build-cmd.sh',
'nix-copy.sh',
'nix-run.sh',
'nix-shell.sh',
'post-hook.sh',
'recursive.sh',
'repl.sh',
'selfref-gc.sh',
'signatures.sh',
'substitute.sh',
'why-depends.sh',
],
'workdir': meson.current_build_dir(),
}

View file

@ -15,13 +15,13 @@ testOneCopy () {
rm -rf "$REMOTE_STORE_DIR"
attrPath="$1"
nix copy --to $REMOTE_STORE "$attrPath" --file ./content-addressed.nix
nix copy --to "$REMOTE_STORE" "$attrPath" --file ./content-addressed.nix
ensureCorrectlyCopied "$attrPath"
# Ensure that we can copy back what we put in the store
clearStore
nix copy --from $REMOTE_STORE \
nix copy --from "$REMOTE_STORE" \
--file ./content-addressed.nix "$attrPath" \
--no-check-sigs
}

View file

@ -4,4 +4,4 @@ source common.sh
FLAKE_PATH=path:$PWD
nix run --no-write-lock-file $FLAKE_PATH#runnable
nix run --no-write-lock-file "$FLAKE_PATH#runnable"

View file

@ -1,10 +1,12 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearCache
nix-store --generate-binary-cache-key cache1.example.org $TEST_ROOT/sk1 $TEST_ROOT/pk1
pk1=$(cat $TEST_ROOT/pk1)
nix-store --generate-binary-cache-key cache1.example.org "$TEST_ROOT/sk1" "$TEST_ROOT/pk1"
pk1=$(cat "$TEST_ROOT/pk1")
export REMOTE_STORE_DIR="$TEST_ROOT/remote_store"
export REMOTE_STORE="file://$REMOTE_STORE_DIR"
@ -19,16 +21,16 @@ testOneCopy () {
rm -rf "$REMOTE_STORE_DIR"
attrPath="$1"
nix copy -vvvv --to $REMOTE_STORE "$attrPath" --file ./content-addressed.nix \
nix copy -vvvv --to "$REMOTE_STORE" "$attrPath" --file ./content-addressed.nix \
--secret-key-files "$TEST_ROOT/sk1" --show-trace
ensureCorrectlyCopied "$attrPath"
# Ensure that we can copy back what we put in the store
clearStore
nix copy --from $REMOTE_STORE \
nix copy --from "$REMOTE_STORE" \
--file ./content-addressed.nix "$attrPath" \
--trusted-public-keys $pk1
--trusted-public-keys "$pk1"
}
for attrPath in rootCA dependentCA transitivelyDependentCA dependentNonCA dependentFixedOutput; do

View file

@ -4,9 +4,10 @@
source common.sh
# shellcheck disable=SC1111
needLocalStore "“--no-require-sigs” cant be used with the daemon"
rm -rf $TEST_ROOT/binary_cache
rm -rf "$TEST_ROOT/binary_cache"
export REMOTE_STORE_DIR=$TEST_ROOT/binary_cache
export REMOTE_STORE=file://$REMOTE_STORE_DIR
@ -17,11 +18,11 @@ buildDrvs () {
# Populate the remote cache
clearStore
nix copy --to $REMOTE_STORE --file ./content-addressed.nix
nix copy --to "$REMOTE_STORE" --file ./content-addressed.nix
# Restart the build on an empty store, ensuring that we don't build
clearStore
buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0 transitivelyDependentCA
buildDrvs --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0 transitivelyDependentCA
# Check that the thing weve just substituted has its realisation stored
nix realisation info --file ./content-addressed.nix transitivelyDependentCA
# Check that its dependencies have it too
@ -63,9 +64,9 @@ clearStore
# Add the realisations of rootCA to the cachecache
clearCacheCache
export _NIX_FORCE_HTTP=1
buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0
buildDrvs --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0
# Try rebuilding, but remove the realisations from the remote cache to force
# using the cachecache
clearStore
rm $REMOTE_STORE_DIR/realisations/*
buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0
rm "$REMOTE_STORE_DIR"/realisations/*
buildDrvs --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0

Binary file not shown.

View file

@ -1,19 +0,0 @@
source common.sh
clearStore
rm -rf $TEST_ROOT/case
opts="--option use-case-hack true"
# Check whether restoring and dumping a NAR that contains case
# collisions is round-tripping, even on a case-insensitive system.
nix-store $opts --restore $TEST_ROOT/case < case.nar
nix-store $opts --dump $TEST_ROOT/case > $TEST_ROOT/case.nar
cmp case.nar $TEST_ROOT/case.nar
[ "$(nix-hash $opts --type sha256 $TEST_ROOT/case)" = "$(nix-hash --flat --type sha256 case.nar)" ]
# Check whether we detect true collisions (e.g. those remaining after
# removal of the suffix).
touch "$TEST_ROOT/case/xt_CONNMARK.h~nix~case~hack~3"
(! nix-store $opts --dump $TEST_ROOT/case > /dev/null)

View file

@ -1,7 +1,9 @@
#!/usr/bin/env bash
# Test the function for lang.sh
source common.sh
source lang/framework.sh
source characterisation/framework.sh
# We are testing this, so don't want outside world to affect us.
unset _NIX_TEST_ACCEPT

View file

@ -0,0 +1,77 @@
# shellcheck shell=bash
# Golden test support
#
# Test that the output of the given test matches what is expected. If
# `_NIX_TEST_ACCEPT` is non-empty also update the expected output so
# that next time the test succeeds.
function diffAndAcceptInner() {
local -r testName=$1
local -r got="$2"
local -r expected="$3"
# Absence of expected file indicates empty output expected.
if test -e "$expected"; then
local -r expectedOrEmpty="$expected"
else
local -r expectedOrEmpty=characterisation/empty
fi
# Diff so we get a nice message
if ! diff --color=always --unified "$expectedOrEmpty" "$got"; then
echo "FAIL: evaluation result of $testName not as expected"
# shellcheck disable=SC2034
badDiff=1
fi
# Update expected if `_NIX_TEST_ACCEPT` is non-empty.
if test -n "${_NIX_TEST_ACCEPT-}"; then
cp "$got" "$expected"
# Delete empty expected files to avoid bloating the repo with
# empty files.
if ! test -s "$expected"; then
rm "$expected"
fi
fi
}
function characterisationTestExit() {
# Make sure shellcheck knows all these will be defined by the caller
: "${badDiff?} ${badExitCode?}"
if test -n "${_NIX_TEST_ACCEPT-}"; then
if (( "$badDiff" )); then
set +x
echo 'Output did mot match, but accepted output as the persisted expected output.'
echo 'That means the next time the tests are run, they should pass.'
set -x
else
set +x
echo 'NOTE: Environment variable _NIX_TEST_ACCEPT is defined,'
echo 'indicating the unexpected output should be accepted as the expected output going forward,'
echo 'but no tests had unexpected output so there was no expected output to update.'
set -x
fi
if (( "$badExitCode" )); then
exit "$badExitCode"
else
skipTest "regenerating golden masters"
fi
else
if (( "$badDiff" )); then
set +x
echo ''
echo 'You can rerun this test with:'
echo ''
echo " _NIX_TEST_ACCEPT=1 make tests/functional/${TEST_NAME}.sh.test"
echo ''
echo 'to regenerate the files containing the expected output,'
echo 'and then view the git diff to decide whether a change is'
echo 'good/intentional or bad/unintentional.'
echo 'If the diff contains arbitrary or impure information,'
echo 'please improve the normalization that the test applies to the output.'
set -x
fi
exit $(( "$badExitCode" + "$badDiff" ))
fi
}

55
tests/functional/check-refs.sh Normal file → Executable file
View file

@ -1,53 +1,62 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
RESULT=$TEST_ROOT/result
dep=$(nix-build -o $RESULT check-refs.nix -A dep)
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 | grepQuietInverse $test1
nix-store -q --references $test1 | grepQuiet $dep
test1=$(nix-build -o "$RESULT" check-refs.nix -A test1)
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 | grepQuietInverse $test2
nix-store -q --references $test2 | grepQuietInverse $dep
nix-store -q --references $test2 | grepQuiet aux-ref
test2=$(nix-build -o "$RESULT" check-refs.nix -A test2)
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)
(! nix-build -o "$RESULT" check-refs.nix -A test3)
# test4 should succeed.
nix-build -o $RESULT check-refs.nix -A test4
nix-build -o "$RESULT" check-refs.nix -A test4
# test5 should succeed.
nix-build -o $RESULT check-refs.nix -A test5
nix-build -o "$RESULT" check-refs.nix -A test5
# test6 should fail (unallowed self-ref).
(! nix-build -o $RESULT check-refs.nix -A test6)
(! nix-build -o "$RESULT" check-refs.nix -A test6)
# test7 should succeed (allowed self-ref).
nix-build -o $RESULT check-refs.nix -A test7
nix-build -o "$RESULT" check-refs.nix -A test7
# test8 should fail (toFile depending on derivation output).
(! nix-build -o $RESULT check-refs.nix -A test8)
(! nix-build -o "$RESULT" check-refs.nix -A test8)
# test9 should fail (disallowed reference).
(! nix-build -o $RESULT check-refs.nix -A test9)
(! nix-build -o "$RESULT" check-refs.nix -A test9)
# test10 should succeed (no disallowed references).
nix-build -o $RESULT check-refs.nix -A test10
nix-build -o "$RESULT" check-refs.nix -A test10
if isDaemonNewer 2.12pre20230103; then
if ! isDaemonNewer 2.16.0; then
enableFeatures discard-references
restartDaemon
if ! isTestOnNixOS; then
# If we have full control over our store, we can test some more things.
if isDaemonNewer 2.12pre20230103; then
if ! isDaemonNewer 2.16.0; then
enableFeatures discard-references
restartDaemon
fi
# test11 should succeed.
test11=$(nix-build -o "$RESULT" check-refs.nix -A test11)
[[ -z $(nix-store -q --references "$test11") ]]
fi
# test11 should succeed.
test11=$(nix-build -o $RESULT check-refs.nix -A test11)
[[ -z $(nix-store -q --references "$test11") ]]
fi

20
tests/functional/check-reqs.sh Normal file → Executable file
View file

@ -1,16 +1,18 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
RESULT=$TEST_ROOT/result
nix-build -o $RESULT check-reqs.nix -A test1
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 | 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)
(! 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 | 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)
nix-build -o $RESULT check-reqs.nix -A test7
nix-build -o "$RESULT" check-reqs.nix -A test7

11
tests/functional/check.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
# XXX: This shouldnt be, but #4813 cause this test to fail
@ -13,6 +15,8 @@ checkBuildTempDirRemoved ()
# written to build temp directories to verify created by this instance
checkBuildId=$(date +%s%N)
TODO_NixOS
clearStore
nix-build dependencies.nix --no-out-link
@ -44,7 +48,10 @@ test_custom_build_dir() {
--no-out-link --keep-failed --option build-dir "$TEST_ROOT/custom-build-dir" 2> $TEST_ROOT/log || status=$?
[ "$status" = "100" ]
[[ 1 == "$(count "$customBuildDir/nix-build-"*)" ]]
local buildDir="$customBuildDir/nix-build-"*
local buildDir="$customBuildDir/nix-build-"*""
if [[ -e $buildDir/build ]]; then
buildDir=$buildDir/build
fi
grep $checkBuildId $buildDir/checkBuildId
}
test_custom_build_dir
@ -74,6 +81,8 @@ grep 'may not be deterministic' $TEST_ROOT/log
[ "$status" = "104" ]
if checkBuildTempDirRemoved $TEST_ROOT/log; then false; fi
TODO_NixOS
clearStore
path=$(nix-build check.nix -A fetchurl --no-out-link)

35
tests/functional/chroot-store.sh Normal file → Executable file
View file

@ -1,33 +1,35 @@
#!/usr/bin/env bash
source common.sh
echo example > $TEST_ROOT/example.txt
mkdir -p $TEST_ROOT/x
echo example > "$TEST_ROOT"/example.txt
mkdir -p "$TEST_ROOT/x"
export NIX_STORE_DIR=/nix2/store
CORRECT_PATH=$(cd $TEST_ROOT && nix-store --store ./x --add example.txt)
CORRECT_PATH=$(cd "$TEST_ROOT" && nix-store --store ./x --add example.txt)
[[ $CORRECT_PATH =~ ^/nix2/store/.*-example.txt$ ]]
PATH1=$(cd $TEST_ROOT && nix path-info --store ./x $CORRECT_PATH)
[ $CORRECT_PATH == $PATH1 ]
PATH1=$(cd "$TEST_ROOT" && nix path-info --store ./x "$CORRECT_PATH")
[ "$CORRECT_PATH" == "$PATH1" ]
PATH2=$(nix path-info --store "$TEST_ROOT/x" $CORRECT_PATH)
[ $CORRECT_PATH == $PATH2 ]
PATH2=$(nix path-info --store "$TEST_ROOT/x" "$CORRECT_PATH")
[ "$CORRECT_PATH" == "$PATH2" ]
PATH3=$(nix path-info --store "local?root=$TEST_ROOT/x" $CORRECT_PATH)
[ $CORRECT_PATH == $PATH3 ]
PATH3=$(nix path-info --store "local?root=$TEST_ROOT/x" "$CORRECT_PATH")
[ "$CORRECT_PATH" == "$PATH3" ]
# Ensure store info trusted works with local store
nix --store $TEST_ROOT/x store info --json | jq -e '.trusted'
nix --store "$TEST_ROOT/x" store info --json | jq -e '.trusted'
# Test building in a chroot store.
if canUseSandbox; then
flakeDir=$TEST_ROOT/flake
mkdir -p $flakeDir
mkdir -p "$flakeDir"
cat > $flakeDir/flake.nix <<EOF
cat > "$flakeDir"/flake.nix <<EOF
{
outputs = inputs: rec {
packages.$system.default = import ./simple.nix;
@ -35,11 +37,14 @@ if canUseSandbox; then
}
EOF
cp simple.nix shell.nix simple.builder.sh config.nix $flakeDir/
cp simple.nix shell.nix simple.builder.sh config.nix "$flakeDir/"
outPath=$(nix build --print-out-paths --no-link --sandbox-paths '/nix? /bin? /lib? /lib64? /usr?' --store $TEST_ROOT/x path:$flakeDir)
TODO_NixOS
outPath=$(nix build --print-out-paths --no-link --sandbox-paths '/nix? /bin? /lib? /lib64? /usr?' --store "$TEST_ROOT/x" path:"$flakeDir")
[[ $outPath =~ ^/nix2/store/.*-simple$ ]]
[[ $(cat $TEST_ROOT/x/nix/store/$(basename $outPath)/hello) = 'Hello World!' ]]
base=$(basename "$outPath")
[[ $(cat "$TEST_ROOT"/x/nix/store/"$base"/hello) = 'Hello World!' ]]
fi

View file

@ -1,10 +1,17 @@
# shellcheck shell=bash
set -eu -o pipefail
if [[ -z "${COMMON_SH_SOURCED-}" ]]; then
COMMON_SH_SOURCED=1
source "$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")/common/vars-and-functions.sh"
functionalTestsDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
source "$functionalTestsDir/common/vars.sh"
source "$functionalTestsDir/common/functions.sh"
source "$functionalTestsDir/common/init.sh"
if [[ -n "${NIX_DAEMON_PACKAGE:-}" ]]; then
startDaemon
fi

View file

@ -0,0 +1,348 @@
# shellcheck shell=bash
set -eu -o pipefail
if [[ -z "${COMMON_FUNCTIONS_SH_SOURCED-}" ]]; then
COMMON_FUNCTIONS_SH_SOURCED=1
isTestOnNixOS() {
[[ "${isTestOnNixOS:-}" == 1 ]]
}
die() {
echo "unexpected fatal error: $*" >&2
exit 1
}
readLink() {
# TODO fix this
# shellcheck disable=SC2012
ls -l "$1" | sed 's/.*->\ //'
}
clearProfiles() {
profiles="$HOME/.local/state/nix/profiles"
rm -rf "$profiles"
}
# Clear the store, but do not fail if we're in an environment where we can't.
# This allows the test to run in a NixOS test environment, where we use the system store.
# See doc/manual/src/contributing/testing.md / Running functional tests on NixOS.
clearStoreIfPossible() {
if isTestOnNixOS; then
echo "clearStoreIfPossible: Not clearing store, because we're on NixOS. Moving on."
else
doClearStore
fi
}
clearStore() {
if isTestOnNixOS; then
die "clearStore: not supported when testing on NixOS. If not essential, call clearStoreIfPossible. If really needed, add conditionals; e.g. if ! isTestOnNixOS; then ..."
fi
doClearStore
}
doClearStore() {
echo "clearing store..."
chmod -R +w "$NIX_STORE_DIR"
rm -rf "$NIX_STORE_DIR"
mkdir "$NIX_STORE_DIR"
rm -rf "$NIX_STATE_DIR"
mkdir "$NIX_STATE_DIR"
clearProfiles
}
clearCache() {
rm -rf "${cacheDir?}"
}
clearCacheCache() {
rm -f "$TEST_HOME/.cache/nix/binary-cache"*
}
startDaemon() {
if isTestOnNixOS; then
die "startDaemon: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
fi
# Dont start the daemon twice, as this would just make it loop indefinitely
if [[ "${_NIX_TEST_DAEMON_PID-}" != '' ]]; then
return
fi
# Start the daemon, wait for the socket to appear.
rm -f "$NIX_DAEMON_SOCKET_PATH"
PATH=$DAEMON_PATH nix --extra-experimental-features 'nix-command' daemon &
_NIX_TEST_DAEMON_PID=$!
export _NIX_TEST_DAEMON_PID
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 "Didnt manage to start the daemon"
fi
trap "killDaemon" EXIT
# Save for if daemon is killed
NIX_REMOTE_OLD=$NIX_REMOTE
export NIX_REMOTE=daemon
}
killDaemon() {
if isTestOnNixOS; then
die "killDaemon: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
fi
# Dont fail trying to stop a non-existant daemon twice
if [[ "${_NIX_TEST_DAEMON_PID-}" == '' ]]; then
return
fi
kill "$_NIX_TEST_DAEMON_PID"
for i in {0..100}; do
kill -0 "$_NIX_TEST_DAEMON_PID" 2> /dev/null || break
sleep 0.1
done
kill -9 "$_NIX_TEST_DAEMON_PID" 2> /dev/null || true
wait "$_NIX_TEST_DAEMON_PID" || true
rm -f "$NIX_DAEMON_SOCKET_PATH"
# Indicate daemon is stopped
unset _NIX_TEST_DAEMON_PID
# Restore old nix remote
NIX_REMOTE=$NIX_REMOTE_OLD
trap "" EXIT
}
restartDaemon() {
if isTestOnNixOS; then
die "restartDaemon: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
fi
[[ -z "${_NIX_TEST_DAEMON_PID:-}" ]] && return 0
killDaemon
startDaemon
}
isDaemonNewer () {
[[ -n "${NIX_DAEMON_PACKAGE:-}" ]] || return 0
local requiredVersion="$1"
local daemonVersion
daemonVersion=$("$NIX_DAEMON_PACKAGE/bin/nix" daemon --version | cut -d' ' -f3)
[[ $(nix eval --expr "builtins.compareVersions ''$daemonVersion'' ''$requiredVersion''") -ge 0 ]]
}
skipTest () {
echo "$1, skipping this test..." >&2
exit 77
}
TODO_NixOS() {
if isTestOnNixOS; then
skipTest "This test has not been adapted for NixOS yet"
fi
}
requireDaemonNewerThan () {
isDaemonNewer "$1" || skipTest "Daemon is too old"
}
canUseSandbox() {
[[ ${_canUseSandbox-} ]]
}
requireSandboxSupport () {
canUseSandbox || skipTest "Sandboxing not supported"
}
requireGit() {
[[ $(type -p git) ]] || skipTest "Git not installed"
}
fail() {
echo "test failed: $*" >&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=0 || res="$?"
# also match "negative" codes, which wrap around to >127
if [[ $res -ne $expected && $res -ne $((256 + expected)) ]]; then
echo "Expected exit code '$expected' but got '$res' from command ${*@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="$?"
# also match "negative" codes, which wrap around to >127
if [[ $res -ne $expected && $res -ne $((256 + expected)) ]]; then
echo "Expected exit code '$expected' but got '$res' from command ${*@Q}" >&2
return 1
fi
return 0
}
# Run a command and check whether the stderr matches stdin.
# Show a diff when output does not match.
# Usage:
#
# assertStderr nix profile remove nothing << EOF
# error: This error is expected
# EOF
assertStderr() {
diff -u /dev/stdin <("$@" 2>/dev/null 2>&1)
}
needLocalStore() {
if [[ "$NIX_REMOTE" == "daemon" ]]; then
skipTest "Cant run through the daemon ($1)"
fi
}
# Just to make it easy to find which tests should be fixed
buggyNeedLocalStore() {
needLocalStore "$1"
}
enableFeatures() {
local features="$1"
sed -i 's/experimental-features .*/& '"$features"'/' "${test_nix_conf?}"
}
onError() {
set +x
echo "$0: test failed at:" >&2
for ((i = 1; i < ${#BASH_SOURCE[@]}; i++)); do
if [[ -z ${BASH_SOURCE[i]} ]]; then break; fi
echo " ${FUNCNAME[i]} in ${BASH_SOURCE[i]}:${BASH_LINENO[i-1]}" >&2
done
}
# Prints an error message prefix referring to the last call into this file.
# Ignores `expect` and `expectStderr` calls.
# Set a special exit code when test suite functions are misused, so that
# functions like expectStderr won't mistake them for expected Nix CLI errors.
# Suggestion: -101 (negative to indicate very abnormal, and beyond the normal
# range of signals)
# Example (showns as string): 'repl.sh:123: in call to grepQuiet: '
# This function is inefficient, so it should only be used in error messages.
callerPrefix() {
# Find the closest caller that's not from this file
# using the bash `caller` builtin.
local i file line fn savedFn
# Use `caller`
for i in $(seq 0 100); do
caller "$i" > /dev/null || {
if [[ -n "${file:-}" ]]; then
echo "$file:$line: ${savedFn+in call to $savedFn: }"
fi
break
}
line="$(caller "$i" | cut -d' ' -f1)"
fn="$(caller "$i" | cut -d' ' -f2)"
file="$(caller "$i" | cut -d' ' -f3)"
if [[ $file != "${BASH_SOURCE[0]}" ]]; then
echo "$file:$line: ${savedFn+in call to $savedFn: }"
return
fi
case "$fn" in
# Ignore higher order functions that don't report any misuse of themselves
# This way a misuse of a foo in `expectStderr 1 foo` will be reported as
# calling foo, not expectStderr.
expect|expectStderr|callerPrefix)
;;
*)
savedFn="$fn"
;;
esac
done
}
checkGrepArgs() {
local arg
for arg in "$@"; do
if [[ "$arg" != "${arg//$'\n'/_}" ]]; then
echo "$(callerPrefix)newline not allowed in arguments; grep would try each line individually as if connected by an OR operator" >&2
return 155 # = -101 mod 256
fi
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*.
#
# `command grep` lets us avoid re-checking the args by going directly to the
# executable.
grepInverse() {
checkGrepArgs "$@" && \
! command 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.
#
# `command grep` lets us avoid re-checking the args by going directly to the
# executable.
grepQuiet() {
checkGrepArgs "$@" && \
command grep "$@" > /dev/null
}
# The previous two, combined
grepQuietInverse() {
checkGrepArgs "$@" && \
! command grep "$@" > /dev/null
}
# Wrap grep to remove its newline footgun; see checkGrepArgs.
# Note that we keep the checkGrepArgs calls in the other helpers, because some
# of them are negated and that would defeat this check.
grep() {
checkGrepArgs "$@" && \
command grep "$@"
}
# Return the number of arguments
count() {
echo $#
}
trap onError ERR
fi # COMMON_FUNCTIONS_SH_SOURCED

71
tests/functional/common/init.sh Executable file
View file

@ -0,0 +1,71 @@
# shellcheck shell=bash
# for shellcheck
: "${test_nix_conf_dir?}" "${test_nix_conf?}"
if isTestOnNixOS; then
mkdir -p "$test_nix_conf_dir" "$TEST_HOME"
export NIX_USER_CONF_FILES="$test_nix_conf"
mkdir -p "$test_nix_conf_dir" "$TEST_HOME"
! test -e "$test_nix_conf"
cat > "$test_nix_conf" <<EOF
# TODO: this is not needed for all tests and prevents stable commands from be tested in isolation
experimental-features = nix-command flakes
flake-registry = $TEST_ROOT/registry.json
show-trace = true
EOF
# When we're doing everything in the same store, we need to bring
# dependencies into context.
sed -i "$(dirname "${BASH_SOURCE[0]}")"/../config.nix \
-e 's^\(shell\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
-e 's^\(path\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
;
else
test -n "$TEST_ROOT"
# We would delete any daemon socket, so let's stop the daemon first.
killDaemon
# Destroy the test directory that may have persisted from previous runs
if [[ -e "$TEST_ROOT" ]]; then
chmod -R u+w "$TEST_ROOT"
rm -rf "$TEST_ROOT"
fi
mkdir -p "$TEST_ROOT"
mkdir "$TEST_HOME"
mkdir "$NIX_STORE_DIR"
mkdir "$NIX_LOCALSTATE_DIR"
mkdir -p "$NIX_LOG_DIR/drvs"
mkdir "$NIX_STATE_DIR"
mkdir "$NIX_CONF_DIR"
cat > "$NIX_CONF_DIR"/nix.conf <<EOF
build-users-group =
keep-derivations = false
sandbox = false
experimental-features = nix-command
gc-reserved-space = 0
substituters =
flake-registry = $TEST_ROOT/registry.json
show-trace = true
include nix.conf.extra
trusted-users = $(whoami)
EOF
cat > "$NIX_CONF_DIR"/nix.conf.extra <<EOF
fsync-metadata = false
extra-experimental-features = flakes
!include nix.conf.extra.not-there
EOF
# Initialise the database.
# The flag itself does nothing, but running the command touches the store
nix-store --init
# Sanity check
test -e "$NIX_STATE_DIR"/db/db.sqlite
fi # !isTestOnNixOS

View file

@ -0,0 +1,5 @@
configure_file(
input : 'subst-vars.sh.in',
output : 'subst-vars.sh',
configuration : test_confdata,
)

View file

@ -0,0 +1,33 @@
# shellcheck shell=bash
set -eu -o pipefail
if [[ -z "${COMMON_PATHS_SH_SOURCED-}" ]]; then
COMMON_PATHS_SH_SOURCED=1
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
# Since these are generated files
# shellcheck disable=SC1091
source "$commonDir/functions.sh"
# shellcheck disable=SC1091
source "$commonDir/subst-vars.sh"
# Make sure shellcheck knows this will be defined by the above generated snippet
: "${bash?}" "${bindir?}"
if ! isTestOnNixOS; then
export SHELL="$bash"
export PATH="$bindir:$PATH"
fi
if [[ -n "${NIX_CLIENT_PACKAGE:-}" ]]; then
export PATH="$NIX_CLIENT_PACKAGE/bin":$PATH
fi
DAEMON_PATH="$PATH"
if [[ -n "${NIX_DAEMON_PACKAGE:-}" ]]; then
DAEMON_PATH="${NIX_DAEMON_PACKAGE}/bin:$DAEMON_PATH"
fi
fi # COMMON_PATHS_SH_SOURCED

View file

@ -0,0 +1,17 @@
# NOTE: instances of @variable@ are substituted as defined in /mk/templates.mk
if [[ -z "${COMMON_SUBST_VARS_SH_SOURCED-}" ]]; then
COMMON_SUBST_VARS_SH_SOURCED=1
bash=@bash@
bindir=@bindir@
coreutils=@coreutils@
dot=@dot@
busybox="@sandbox_shell@"
version=@PACKAGE_VERSION@
system=@system@
fi

View file

@ -0,0 +1,4 @@
# shellcheck shell=bash
TEST_ROOT=$(realpath "${TMPDIR:-/tmp}/nix-test")/${TEST_NAME:-default/tests\/functional//}
export TEST_ROOT

View file

@ -1,293 +0,0 @@
set -eu -o pipefail
if [[ -z "${COMMON_VARS_AND_FUNCTIONS_SH_SOURCED-}" ]]; then
COMMON_VARS_AND_FUNCTIONS_SH_SOURCED=1
set +x
export TEST_ROOT=$(realpath ${TMPDIR:-/tmp}/nix-test)/${TEST_NAME:-default/tests\/functional//}
export NIX_STORE_DIR
if ! NIX_STORE_DIR=$(readlink -f $TEST_ROOT/store 2> /dev/null); then
# Maybe the build directory is symlinked.
export NIX_IGNORE_SYMLINK_STORE=1
NIX_STORE_DIR=$TEST_ROOT/store
fi
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_DAEMON_SOCKET_PATH=$TEST_ROOT/dSocket
unset NIX_USER_CONF_FILES
export _NIX_TEST_SHARED=$TEST_ROOT/shared
if [[ -n $NIX_STORE ]]; then
export _NIX_TEST_NO_SANDBOX=1
fi
export _NIX_IN_TEST=$TEST_ROOT/shared
export _NIX_TEST_NO_LSOF=1
export NIX_REMOTE=${NIX_REMOTE_-}
unset NIX_PATH
export TEST_HOME=$TEST_ROOT/test-home
export HOME=$TEST_HOME
unset XDG_STATE_HOME
unset XDG_DATA_HOME
unset XDG_CONFIG_HOME
unset XDG_CONFIG_DIRS
unset XDG_CACHE_HOME
mkdir -p $TEST_HOME
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
DAEMON_PATH="${NIX_DAEMON_PACKAGE}/bin:$DAEMON_PATH"
fi
coreutils=@coreutils@
lsof=@lsof@
export dot=@dot@
export SHELL="@bash@"
export PAGER=cat
export busybox="@sandbox_shell@"
export version=@PACKAGE_VERSION@
export system=@system@
export BUILD_SHARED_LIBS=@BUILD_SHARED_LIBS@
export IMPURE_VAR1=foo
export IMPURE_VAR2=bar
cacheDir=$TEST_ROOT/binary-cache
readLink() {
ls -l "$1" | sed 's/.*->\ //'
}
clearProfiles() {
profiles="$HOME"/.local/state/nix/profiles
rm -rf "$profiles"
}
clearStore() {
echo "clearing store..."
chmod -R +w "$NIX_STORE_DIR"
rm -rf "$NIX_STORE_DIR"
mkdir "$NIX_STORE_DIR"
rm -rf "$NIX_STATE_DIR"
mkdir "$NIX_STATE_DIR"
clearProfiles
}
clearCache() {
rm -rf "$cacheDir"
}
clearCacheCache() {
rm -f $TEST_HOME/.cache/nix/binary-cache*
}
startDaemon() {
# Dont start the daemon twice, as this would just make it loop indefinitely
if [[ "${_NIX_TEST_DAEMON_PID-}" != '' ]]; then
return
fi
# Start the daemon, wait for the socket to appear.
rm -f $NIX_DAEMON_SOCKET_PATH
PATH=$DAEMON_PATH nix --extra-experimental-features 'nix-command' daemon &
_NIX_TEST_DAEMON_PID=$!
export _NIX_TEST_DAEMON_PID
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 "Didnt manage to start the daemon"
fi
trap "killDaemon" EXIT
# Save for if daemon is killed
NIX_REMOTE_OLD=$NIX_REMOTE
export NIX_REMOTE=daemon
}
killDaemon() {
# Dont fail trying to stop a non-existant daemon twice
if [[ "${_NIX_TEST_DAEMON_PID-}" == '' ]]; then
return
fi
kill $_NIX_TEST_DAEMON_PID
for i in {0..100}; do
kill -0 $_NIX_TEST_DAEMON_PID 2> /dev/null || break
sleep 0.1
done
kill -9 $_NIX_TEST_DAEMON_PID 2> /dev/null || true
wait $_NIX_TEST_DAEMON_PID || true
rm -f $NIX_DAEMON_SOCKET_PATH
# Indicate daemon is stopped
unset _NIX_TEST_DAEMON_PID
# Restore old nix remote
NIX_REMOTE=$NIX_REMOTE_OLD
trap "" EXIT
}
restartDaemon() {
[[ -z "${_NIX_TEST_DAEMON_PID:-}" ]] && return 0
killDaemon
startDaemon
}
if [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true; then
_canUseSandbox=1
fi
isDaemonNewer () {
[[ -n "${NIX_DAEMON_PACKAGE:-}" ]] || return 0
local requiredVersion="$1"
local daemonVersion=$($NIX_DAEMON_PACKAGE/bin/nix daemon --version | cut -d' ' -f3)
[[ $(nix eval --expr "builtins.compareVersions ''$daemonVersion'' ''$requiredVersion''") -ge 0 ]]
}
skipTest () {
echo "$1, skipping this test..." >&2
exit 99
}
requireDaemonNewerThan () {
isDaemonNewer "$1" || skipTest "Daemon is too old"
}
canUseSandbox() {
[[ ${_canUseSandbox-} ]]
}
requireSandboxSupport () {
canUseSandbox || skipTest "Sandboxing not supported"
}
requireGit() {
[[ $(type -p git) ]] || skipTest "Git not installed"
}
fail() {
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=0 || res="$?"
if [[ $res -ne $expected ]]; then
echo "Expected exit code '$expected' but got '$res' from command ${*@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 exit code '$expected' but got '$res' from command ${*@Q}" >&2
return 1
fi
return 0
}
# Run a command and check whether the stderr matches stdin.
# Show a diff when output does not match.
# Usage:
#
# assertStderr nix profile remove nothing << EOF
# error: This error is expected
# EOF
assertStderr() {
diff -u /dev/stdin <($@ 2>/dev/null 2>&1)
}
needLocalStore() {
if [[ "$NIX_REMOTE" == "daemon" ]]; then
skipTest "Cant run through the daemon ($1)"
fi
}
# Just to make it easy to find which tests should be fixed
buggyNeedLocalStore() {
needLocalStore "$1"
}
enableFeatures() {
local features="$1"
sed -i 's/experimental-features .*/& '"$features"'/' "$NIX_CONF_DIR"/nix.conf
}
set -x
onError() {
set +x
echo "$0: test failed at:" >&2
for ((i = 1; i < ${#BASH_SOURCE[@]}; i++)); do
if [[ -z ${BASH_SOURCE[i]} ]]; then break; fi
echo " ${FUNCNAME[i]} in ${BASH_SOURCE[i]}:${BASH_LINENO[i-1]}" >&2
done
}
# `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
}
# Return the number of arguments
count() {
echo $#
}
trap onError ERR
fi # COMMON_VARS_AND_FUNCTIONS_SH_SOURCED

View file

@ -0,0 +1,72 @@
# shellcheck shell=bash
set -eu -o pipefail
if [[ -z "${COMMON_VARS_SH_SOURCED-}" ]]; then
COMMON_VARS_SH_SOURCED=1
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
# Since this is a generated file
# shellcheck disable=SC1091
source "$commonDir/subst-vars.sh"
# Make sure shellcheck knows all these will be defined by the above generated snippet
: "${bindir?} ${coreutils?} ${dot?} ${SHELL?} ${busybox?} ${version?} ${system?}"
export coreutils dot busybox version system
export PAGER=cat
source "$commonDir/paths.sh"
source "$commonDir/test-root.sh"
test_nix_conf_dir=$TEST_ROOT/etc
# Used in other files
# shellcheck disable=SC2034
test_nix_conf=$test_nix_conf_dir/nix.conf
export TEST_HOME=$TEST_ROOT/test-home
if ! isTestOnNixOS; then
export NIX_STORE_DIR
if ! NIX_STORE_DIR=$(readlink -f "$TEST_ROOT/store" 2> /dev/null); then
# Maybe the build directory is symlinked.
export NIX_IGNORE_SYMLINK_STORE=1
NIX_STORE_DIR=$TEST_ROOT/store
fi
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_CONF_DIR=$test_nix_conf_dir
export NIX_DAEMON_SOCKET_PATH=$TEST_ROOT/dSocket
unset NIX_USER_CONF_FILES
export _NIX_TEST_SHARED=$TEST_ROOT/shared
if [[ -n $NIX_STORE ]]; then
export _NIX_TEST_NO_SANDBOX=1
fi
export _NIX_IN_TEST=$TEST_ROOT/shared
export _NIX_TEST_NO_LSOF=1
export NIX_REMOTE=${NIX_REMOTE_-}
fi # ! isTestOnNixOS
unset NIX_PATH
export HOME=$TEST_HOME
unset XDG_STATE_HOME
unset XDG_DATA_HOME
unset XDG_CONFIG_HOME
unset XDG_CONFIG_DIRS
unset XDG_CACHE_HOME
export IMPURE_VAR1=foo
export IMPURE_VAR2=bar
# Used in other files
# shellcheck disable=SC2034
cacheDir=$TEST_ROOT/binary-cache
if [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true; then
_canUseSandbox=1
fi
fi # COMMON_VARS_SH_SOURCED

2
tests/functional/completions.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
cd "$TEST_ROOT"

12
tests/functional/compression-levels.sh Normal file → Executable file
View file

@ -1,22 +1,24 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
clearCache
outPath=$(nix-build dependencies.nix --no-out-link)
cacheURI="file://$cacheDir?compression=xz&compression-level=0"
nix copy --to $cacheURI $outPath
nix copy --to "$cacheURI" "$outPath"
FILESIZES=$(cat ${cacheDir}/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
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
nix copy --to "$cacheURI" "$outPath"
FILESIZES2=$(cat ${cacheDir}/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
FILESIZES2=$(cat "${cacheDir}"/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
[[ $FILESIZES -gt $FILESIZES2 ]]

2
tests/functional/compute-levels.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
if [[ $(uname -ms) = "Linux x86_64" ]]; then

11
tests/functional/config.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
# Isolate the home for this test.
@ -26,6 +28,8 @@ nix registry remove userhome-with-xdg
# Assert the .config folder hasn't been created.
[ ! -e "$HOME/.config" ]
TODO_NixOS # Very specific test setup not compatible with the NixOS test environment?
# Test that files are loaded from XDG by default
export XDG_CONFIG_HOME=$TEST_ROOT/confighome
export XDG_CONFIG_DIRS=$TEST_ROOT/dir1:$TEST_ROOT/dir2
@ -66,4 +70,9 @@ exp_features=$(nix config show | grep '^experimental-features' | cut -d '=' -f 2
# Test that it's possible to retrieve a single setting's value
val=$(nix config show | grep '^warn-dirty' | cut -d '=' -f 2 | xargs)
val2=$(nix config show warn-dirty)
[[ $val == $val2 ]]
[[ $val == $val2 ]]
# Test unit prefixes.
[[ $(nix config show --min-free 64K min-free) = 65536 ]]
[[ $(nix config show --min-free 1M min-free) = 1048576 ]]
[[ $(nix config show --min-free 2G min-free) = 2147483648 ]]

4
tests/functional/db-migration.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
# Test that we can successfully migrate from an older db schema
source common.sh
@ -8,6 +10,8 @@ if [[ -z "${NIX_DAEMON_PACKAGE-}" ]]; then
skipTest "not using the Nix daemon"
fi
TODO_NixOS
killDaemon
# Fill the db using the older Nix

4
tests/functional/debugger.sh Normal file → Executable file
View file

@ -1,6 +1,8 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
# regression #9932
echo ":env" | expect 1 nix eval --debugger --expr '(_: throw "oh snap") 42'

8
tests/functional/dependencies.sh Normal file → Executable file
View file

@ -1,6 +1,8 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
drvPath=$(nix-instantiate dependencies.nix)
@ -31,7 +33,7 @@ nix-store -q --tree "$outPath" | grep '───.*dependencies-input-2'
echo "output path is $outPath"
text=$(cat "$outPath"/foobar)
text=$(cat "$outPath/foobar")
if test "$text" != "FOOBAR"; then exit 1; fi
deps=$(nix-store -quR "$drvPath")
@ -63,6 +65,8 @@ drvPath2=$(nix-instantiate dependencies.nix --argstr hashInvalidator yay)
# now --valid-derivers returns both
test "$(nix-store -q --valid-derivers "$outPath" | sort)" = "$(sort <<< "$drvPath"$'\n'"$drvPath2")"
TODO_NixOS # The following --delete fails, because it seems to be still alive. This might be caused by a different test using the same path. We should try make the derivations unique, e.g. naming after tests, and adding a timestamp that's constant for that test script run.
# check that nix-store --valid-derivers only returns existing drv
nix-store --delete "$drvPath"
test "$(nix-store -q --valid-derivers "$outPath")" = "$drvPath2"

View file

@ -0,0 +1,23 @@
#!/usr/bin/env bash
source common/test-root.sh
source common/paths.sh
set -eu -o pipefail
source characterisation/framework.sh
badDiff=0
badExitCode=0
store="$TEST_ROOT/store"
for nixFile in derivation/*.nix; do
drvPath=$(nix-instantiate --store "$store" --pure-eval --expr "$(< "$nixFile")")
testName=$(basename "$nixFile" .nix)
got="${store}${drvPath}"
expected="derivation/$testName.drv"
diffAndAcceptInner "$testName" "$got" "$expected"
done
characterisationTestExit

8
tests/functional/derivation-json.sh Normal file → Executable file
View file

@ -1,12 +1,14 @@
#!/usr/bin/env bash
source common.sh
drvPath=$(nix-instantiate simple.nix)
nix derivation show $drvPath | jq .[] > $TEST_HOME/simple.json
nix derivation show "$drvPath" | jq .[] > "$TEST_HOME"/simple.json
drvPath2=$(nix derivation add < $TEST_HOME/simple.json)
drvPath2=$(nix derivation add < "$TEST_HOME"/simple.json)
[[ "$drvPath" = "$drvPath2" ]]
# Input addressed derivations cannot be renamed.
jq '.name = "foo"' < $TEST_HOME/simple.json | expectStderr 1 nix derivation add | grepQuiet "has incorrect output"
jq '.name = "foo"' < "$TEST_HOME"/simple.json | expectStderr 1 nix derivation add | grepQuiet "has incorrect output"

View file

@ -0,0 +1 @@
Derive([("out","/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults","","")],[],[],"my-system","/bin/bash",["-c","echo hello > $out"],[("builder","/bin/bash"),("name","advanced-attributes-defaults"),("out","/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults"),("system","my-system")])

View file

@ -0,0 +1,6 @@
derivation {
name = "advanced-attributes-defaults";
system = "my-system";
builder = "/bin/bash";
args = [ "-c" "echo hello > $out" ];
}

View file

@ -0,0 +1 @@
Derive([("dev","/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev","",""),("out","/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults","","")],[],[],"my-system","/bin/bash",["-c","echo hello > $out"],[("__json","{\"builder\":\"/bin/bash\",\"name\":\"advanced-attributes-structured-attrs-defaults\",\"outputs\":[\"out\",\"dev\"],\"system\":\"my-system\"}"),("dev","/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev"),("out","/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults")])

View file

@ -0,0 +1,8 @@
derivation {
name = "advanced-attributes-structured-attrs-defaults";
system = "my-system";
builder = "/bin/bash";
args = [ "-c" "echo hello > $out" ];
outputs = [ "out" "dev" ];
__structuredAttrs = true;
}

View file

@ -0,0 +1 @@
Derive([("bin","/nix/store/pbzb48v0ycf80jgligcp4n8z0rblna4n-advanced-attributes-structured-attrs-bin","",""),("dev","/nix/store/7xapi8jv7flcz1qq8jhw55ar8ag8hldh-advanced-attributes-structured-attrs-dev","",""),("out","/nix/store/mpq3l1l1qc2yr50q520g08kprprwv79f-advanced-attributes-structured-attrs","","")],[("/nix/store/4xm4wccqsvagz9gjksn24s7rip2fdy7v-foo.drv",["out"]),("/nix/store/plsq5jbr5nhgqwcgb2qxw7jchc09dnl8-bar.drv",["out"])],[],"my-system","/bin/bash",["-c","echo hello > $out"],[("__json","{\"__darwinAllowLocalNetworking\":true,\"__impureHostDeps\":[\"/usr/bin/ditto\"],\"__noChroot\":true,\"__sandboxProfile\":\"sandcastle\",\"allowSubstitutes\":false,\"builder\":\"/bin/bash\",\"impureEnvVars\":[\"UNICORN\"],\"name\":\"advanced-attributes-structured-attrs\",\"outputChecks\":{\"bin\":{\"disallowedReferences\":[\"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar\"],\"disallowedRequisites\":[\"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar\"]},\"dev\":{\"maxClosureSize\":5909,\"maxSize\":789},\"out\":{\"allowedReferences\":[\"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo\"],\"allowedRequisites\":[\"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo\"]}},\"outputs\":[\"out\",\"bin\",\"dev\"],\"preferLocalBuild\":true,\"requiredSystemFeatures\":[\"rainbow\",\"uid-range\"],\"system\":\"my-system\"}"),("bin","/nix/store/pbzb48v0ycf80jgligcp4n8z0rblna4n-advanced-attributes-structured-attrs-bin"),("dev","/nix/store/7xapi8jv7flcz1qq8jhw55ar8ag8hldh-advanced-attributes-structured-attrs-dev"),("out","/nix/store/mpq3l1l1qc2yr50q520g08kprprwv79f-advanced-attributes-structured-attrs")])

View file

@ -0,0 +1,45 @@
let
system = "my-system";
foo = derivation {
inherit system;
name = "foo";
builder = "/bin/bash";
args = ["-c" "echo foo > $out"];
};
bar = derivation {
inherit system;
name = "bar";
builder = "/bin/bash";
args = ["-c" "echo bar > $out"];
};
in
derivation {
inherit system;
name = "advanced-attributes-structured-attrs";
builder = "/bin/bash";
args = [ "-c" "echo hello > $out" ];
__sandboxProfile = "sandcastle";
__noChroot = true;
__impureHostDeps = ["/usr/bin/ditto"];
impureEnvVars = ["UNICORN"];
__darwinAllowLocalNetworking = true;
outputs = [ "out" "bin" "dev" ];
__structuredAttrs = true;
outputChecks = {
out = {
allowedReferences = [foo];
allowedRequisites = [foo];
};
bin = {
disallowedReferences = [bar];
disallowedRequisites = [bar];
};
dev = {
maxSize = 789;
maxClosureSize = 5909;
};
};
requiredSystemFeatures = ["rainbow" "uid-range"];
preferLocalBuild = true;
allowSubstitutes = false;
}

View file

@ -0,0 +1 @@
Derive([("out","/nix/store/33a6fdmn8q9ih9d7npbnrxn2q56a4l8q-advanced-attributes","","")],[("/nix/store/4xm4wccqsvagz9gjksn24s7rip2fdy7v-foo.drv",["out"]),("/nix/store/plsq5jbr5nhgqwcgb2qxw7jchc09dnl8-bar.drv",["out"])],[],"my-system","/bin/bash",["-c","echo hello > $out"],[("__darwinAllowLocalNetworking","1"),("__impureHostDeps","/usr/bin/ditto"),("__noChroot","1"),("__sandboxProfile","sandcastle"),("allowSubstitutes",""),("allowedReferences","/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"),("allowedRequisites","/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"),("builder","/bin/bash"),("disallowedReferences","/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"),("disallowedRequisites","/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"),("impureEnvVars","UNICORN"),("name","advanced-attributes"),("out","/nix/store/33a6fdmn8q9ih9d7npbnrxn2q56a4l8q-advanced-attributes"),("preferLocalBuild","1"),("requiredSystemFeatures","rainbow uid-range"),("system","my-system")])

View file

@ -0,0 +1,33 @@
let
system = "my-system";
foo = derivation {
inherit system;
name = "foo";
builder = "/bin/bash";
args = ["-c" "echo foo > $out"];
};
bar = derivation {
inherit system;
name = "bar";
builder = "/bin/bash";
args = ["-c" "echo bar > $out"];
};
in
derivation {
inherit system;
name = "advanced-attributes";
builder = "/bin/bash";
args = [ "-c" "echo hello > $out" ];
__sandboxProfile = "sandcastle";
__noChroot = true;
__impureHostDeps = ["/usr/bin/ditto"];
impureEnvVars = ["UNICORN"];
__darwinAllowLocalNetworking = true;
allowedReferences = [foo];
allowedRequisites = [foo];
disallowedReferences = [bar];
disallowedRequisites = [bar];
requiredSystemFeatures = ["rainbow" "uid-range"];
preferLocalBuild = true;
allowSubstitutes = false;
}

4
tests/functional/dump-db.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
needLocalStore "--dump-db requires a local store"
clearStore

Binary file not shown.

View file

@ -5,4 +5,6 @@ requireDaemonNewerThan "2.16.0pre20230419"
enableFeatures "ca-derivations dynamic-derivations"
TODO_NixOS
restartDaemon

View file

@ -0,0 +1,19 @@
configure_file(
input : 'config.nix.in',
output : 'config.nix',
configuration : test_confdata,
)
suites += {
'name': 'dyn-drv',
'deps': [],
'tests': [
'text-hashed-output.sh',
'recursive-mod-json.sh',
'build-built-drv.sh',
'eval-outputOf.sh',
'dep-built-drv.sh',
'old-daemon-error-hack.sh',
],
'workdir': meson.current_build_dir(),
}

View file

@ -20,7 +20,7 @@ nix show-derivation "$drvProducingDrv"
out1=$(nix-build ./text-hashed-output.nix -A producingDrv --no-out-link)
nix path-info $drv --derivation --json | jq
nix path-info $out1 --derivation --json | jq
nix path-info "$drv" --derivation --json | jq
nix path-info "$out1" --derivation --json | jq
test $out1 == $drv
test "$out1" == "$drv"

4
tests/functional/eval-store.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
# Using `--eval-store` with the daemon will eventually copy everything
# to the build store, invalidating most of the tests here
needLocalStore "“--eval-store” doesn't achieve much with the daemon"

12
tests/functional/eval.sh Normal file → Executable file
View file

@ -1,6 +1,8 @@
#!/usr/bin/env bash
source common.sh
clearStore
clearStoreIfPossible
testStdinHeredoc=$(nix eval -f - <<EOF
{
@ -52,3 +54,11 @@ fi
# Test --arg-from-stdin.
[[ "$(echo bla | nix eval --raw --arg-from-stdin foo --expr '{ foo }: { inherit foo; }' foo)" = bla ]]
# Test that unknown settings are warned about
out="$(expectStderr 0 nix eval --option foobar baz --expr '""' --raw)"
[[ "$(echo "$out" | grep foobar | wc -l)" = 1 ]]
# Test flag alias
out="$(nix eval --expr '{}' --build-cores 1)"
[[ "$(echo "$out" | wc -l)" = 1 ]]

30
tests/functional/experimental-features.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
# Skipping these two for now, because we actually *do* want flags and
@ -31,35 +33,35 @@ source common.sh
NIX_CONFIG='
experimental-features = nix-command
accept-flake-config = true
' expect 1 nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
[[ $(cat $TEST_ROOT/stdout) = '' ]]
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
grepQuiet "error: could not find setting 'accept-flake-config'" $TEST_ROOT/stderr
' expect 1 nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
[[ $(cat "$TEST_ROOT/stdout") = '' ]]
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" "$TEST_ROOT/stderr"
grepQuiet "error: could not find setting 'accept-flake-config'" "$TEST_ROOT/stderr"
# 'flakes' experimental-feature is disabled after, ignore and warn
NIX_CONFIG='
accept-flake-config = true
experimental-features = nix-command
' expect 1 nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
[[ $(cat $TEST_ROOT/stdout) = '' ]]
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
grepQuiet "error: could not find setting 'accept-flake-config'" $TEST_ROOT/stderr
' expect 1 nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
[[ $(cat "$TEST_ROOT/stdout") = '' ]]
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" "$TEST_ROOT/stderr"
grepQuiet "error: could not find setting 'accept-flake-config'" "$TEST_ROOT/stderr"
# 'flakes' experimental-feature is enabled before, process
NIX_CONFIG='
experimental-features = nix-command flakes
accept-flake-config = true
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
grepQuiet "true" $TEST_ROOT/stdout
grepQuietInverse "Ignoring setting 'accept-flake-config'" $TEST_ROOT/stderr
' nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
grepQuiet "true" "$TEST_ROOT/stdout"
grepQuietInverse "Ignoring setting 'accept-flake-config'" "$TEST_ROOT/stderr"
# 'flakes' experimental-feature is enabled after, process
NIX_CONFIG='
accept-flake-config = true
experimental-features = nix-command flakes
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
grepQuiet "true" $TEST_ROOT/stdout
grepQuietInverse "Ignoring setting 'accept-flake-config'" $TEST_ROOT/stderr
' nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
grepQuiet "true" "$TEST_ROOT/stdout"
grepQuietInverse "Ignoring setting 'accept-flake-config'" "$TEST_ROOT/stderr"
function exit_code_both_ways {
expect 1 nix --experimental-features 'nix-command' "$@" 1>/dev/null

4
tests/functional/export-graph.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
clearProfiles

4
tests/functional/export.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
outPath=$(nix-build dependencies.nix --no-out-link)

View file

@ -0,0 +1,19 @@
{ destFile, seed }:
with import ./config.nix;
mkDerivation {
name = "simple";
__sandboxProfile = ''
# Allow writing any file in the filesystem
(allow file*)
'';
inherit seed;
buildCommand = ''
(
set -x
touch ${destFile}
touch $out
)
'';
}

View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
source common.sh
if [[ $(uname) != Darwin ]]; then skipTest "Need Darwin"; fi
DEST_FILE="${TEST_ROOT}/foo"
testSandboxProfile () (
set -e
sandboxMode="$1"
rm -f "${DEST_FILE}"
nix-build --no-out-link ./extra-sandbox-profile.nix \
--option sandbox "$sandboxMode" \
--argstr seed "$RANDOM" \
--argstr destFile "${DEST_FILE}"
ls -l "${DEST_FILE}"
)
testSandboxProfile "false"
expectStderr 2 testSandboxProfile "true"
testSandboxProfile "relaxed"

4
tests/functional/fetchClosure.sh Normal file → Executable file
View file

@ -1,7 +1,11 @@
#!/usr/bin/env bash
source common.sh
enableFeatures "fetch-closure"
TODO_NixOS
clearStore
clearCacheCache

4
tests/functional/fetchGit.sh Normal file → Executable file
View file

@ -1,8 +1,10 @@
#!/usr/bin/env bash
source common.sh
requireGit
clearStore
clearStoreIfPossible
# Intentionally not in a canonical form
# See https://github.com/NixOS/nix/issues/6195

6
tests/functional/fetchGitRefs.sh Normal file → Executable file
View file

@ -1,8 +1,10 @@
#!/usr/bin/env bash
source common.sh
requireGit
clearStore
clearStoreIfPossible
repo="$TEST_ROOT/git"
@ -12,7 +14,7 @@ git init "$repo"
git -C "$repo" config user.email "foobar@example.com"
git -C "$repo" config user.name "Foobar"
echo utrecht > "$repo"/hello
echo utrecht > "$repo/hello"
git -C "$repo" add hello
git -C "$repo" commit -m 'Bla1'

4
tests/functional/fetchGitSubmodules.sh Normal file → Executable file
View file

@ -1,10 +1,12 @@
#!/usr/bin/env bash
source common.sh
set -u
requireGit
clearStore
clearStoreIfPossible
rootRepo=$TEST_ROOT/gitSubmodulesRoot
subRepo=$TEST_ROOT/gitSubmodulesSub

4
tests/functional/fetchGitVerification.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
requireGit
@ -5,7 +7,7 @@ requireGit
enableFeatures "verified-fetches"
clearStore
clearStoreIfPossible
repo="$TEST_ROOT/git"

5
tests/functional/fetchMercurial.sh Normal file → Executable file
View file

@ -1,7 +1,11 @@
#!/usr/bin/env bash
source common.sh
[[ $(type -p hg) ]] || skipTest "Mercurial not installed"
TODO_NixOS
clearStore
# Intentionally not in a canonical form
@ -101,6 +105,7 @@ path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchMercurial file:
[[ $path2 = $path4 ]]
echo paris > $repo/hello
# Passing a `name` argument should be reflected in the output path
path5=$(nix eval -vvvvv --impure --refresh --raw --expr "(builtins.fetchMercurial { url = \"file://$repo\"; name = \"foo\"; } ).outPath")
[[ $path5 =~ -foo$ ]]

4
tests/functional/fetchPath.sh Normal file → Executable file
View file

@ -1,6 +1,8 @@
#!/usr/bin/env bash
source common.sh
touch $TEST_ROOT/foo -t 202211111111
touch "$TEST_ROOT/foo" -t 202211111111
# We only check whether 2022-11-1* **:**:** is the last modified date since
# `lastModified` is transformed into UTC in `builtins.fetchTarball`.
[[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]]

6
tests/functional/fetchTree-file.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
cd "$TEST_ROOT"
@ -88,7 +92,7 @@ EOF
EOF
# Test tarball URLs on the command line.
[[ $(nix flake metadata --json file://$PWD/test_input_no_ext | jq -r .resolved.type) = tarball ]]
[[ $(nix flake metadata --json "file://$PWD/test_input_no_ext" | jq -r .resolved.type) = tarball ]]
popd

4
tests/functional/fetchurl.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
# Test fetching a flat file.

38
tests/functional/filter-source.sh Normal file → Executable file
View file

@ -1,25 +1,27 @@
#!/usr/bin/env bash
source common.sh
rm -rf $TEST_ROOT/filterin
mkdir $TEST_ROOT/filterin
mkdir $TEST_ROOT/filterin/foo
touch $TEST_ROOT/filterin/foo/bar
touch $TEST_ROOT/filterin/xyzzy
touch $TEST_ROOT/filterin/b
touch $TEST_ROOT/filterin/bak
touch $TEST_ROOT/filterin/bla.c.bak
ln -s xyzzy $TEST_ROOT/filterin/link
rm -rf "$TEST_ROOT/filterin"
mkdir "$TEST_ROOT/filterin"
mkdir "$TEST_ROOT/filterin/foo"
touch "$TEST_ROOT/filterin/foo/bar"
touch "$TEST_ROOT/filterin/xyzzy"
touch "$TEST_ROOT/filterin/b"
touch "$TEST_ROOT/filterin/bak"
touch "$TEST_ROOT"/filterin/bla.c.bak
ln -s xyzzy "$TEST_ROOT/filterin/link"
checkFilter() {
test ! -e $1/foo/bar
test -e $1/xyzzy
test -e $1/bak
test ! -e $1/bla.c.bak
test ! -L $1/link
test ! -e "$1/foo/bar"
test -e "$1/xyzzy"
test -e "$1/bak"
test ! -e "$1"/bla.c.bak
test ! -L "$1/link"
}
nix-build ./filter-source.nix -o $TEST_ROOT/filterout1
checkFilter $TEST_ROOT/filterout1
nix-build ./filter-source.nix -o "$TEST_ROOT/filterout1"
checkFilter "$TEST_ROOT/filterout1"
nix-build ./path.nix -o $TEST_ROOT/filterout2
checkFilter $TEST_ROOT/filterout2
nix-build ./path.nix -o "$TEST_ROOT/filterout2"
checkFilter "$TEST_ROOT/filterout2"

4
tests/functional/fixed.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source common.sh
TODO_NixOS
clearStore
path=$(nix-store -q $(nix-instantiate fixed.nix -A good.0))

12
tests/functional/flakes/absolute-attr-paths.sh Normal file → Executable file
View file

@ -1,9 +1,11 @@
#!/usr/bin/env bash
source ./common.sh
flake1Dir=$TEST_ROOT/flake1
mkdir -p $flake1Dir
cat > $flake1Dir/flake.nix <<EOF
mkdir -p "$flake1Dir"
cat > "$flake1Dir"/flake.nix <<EOF
{
outputs = { self }: {
x = 1;
@ -12,6 +14,6 @@ cat > $flake1Dir/flake.nix <<EOF
}
EOF
[ "$(nix eval --impure --json $flake1Dir#.x)" -eq 1 ]
[ "$(nix eval --impure --json $flake1Dir#x)" -eq 2 ]
[ "$(nix eval --impure --json $flake1Dir#.packages.$system.x)" -eq 2 ]
[ "$(nix eval --impure --json "$flake1Dir"#.x)" -eq 1 ]
[ "$(nix eval --impure --json "$flake1Dir#x")" -eq 2 ]
[ "$(nix eval --impure --json "$flake1Dir"#.packages."$system".x)" -eq 2 ]

2
tests/functional/flakes/absolute-paths.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source ./common.sh
requireGit

46
tests/functional/flakes/build-paths.sh Normal file → Executable file
View file

@ -1,17 +1,19 @@
#!/usr/bin/env bash
source ./common.sh
flake1Dir=$TEST_ROOT/flake1
flake2Dir=$TEST_ROOT/flake2
mkdir -p $flake1Dir $flake2Dir
mkdir -p "$flake1Dir" "$flake2Dir"
writeSimpleFlake $flake2Dir
tar cfz $TEST_ROOT/flake.tar.gz -C $TEST_ROOT flake2
hash=$(nix hash path $flake2Dir)
writeSimpleFlake "$flake2Dir"
tar cfz "$TEST_ROOT"/flake.tar.gz -C "$TEST_ROOT" flake2
hash=$(nix hash path "$flake2Dir")
dep=$(nix store add-path ./common.sh)
cat > $flake1Dir/flake.nix <<EOF
cat > "$flake1Dir"/flake.nix <<EOF
{
inputs.flake2.url = "file://$TEST_ROOT/flake.tar.gz";
@ -77,43 +79,43 @@ cat > $flake1Dir/flake.nix <<EOF
}
EOF
cp ../simple.nix ../simple.builder.sh ../config.nix $flake1Dir/
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
echo bar > $flake1Dir/foo
echo bar > "$flake1Dir/foo"
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a1
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a1"
[[ -e $TEST_ROOT/result/simple.nix ]]
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a2
[[ $(cat $TEST_ROOT/result) = bar ]]
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a2"
[[ $(cat "$TEST_ROOT/result") = bar ]]
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a3
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a3"
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a4
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a4"
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a6
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a6"
[[ -e $TEST_ROOT/result/simple.nix ]]
nix build --impure --json --out-link $TEST_ROOT/result $flake1Dir#a8
diff common.sh $TEST_ROOT/result
nix build --impure --json --out-link "$TEST_ROOT/result" "$flake1Dir#a8"
diff common.sh "$TEST_ROOT/result"
expectStderr 1 nix build --impure --json --out-link $TEST_ROOT/result $flake1Dir#a9 \
expectStderr 1 nix build --impure --json --out-link "$TEST_ROOT/result" "$flake1Dir#a9" \
| grepQuiet "has 0 entries in its context. It should only have exactly one entry"
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a10
[[ $(readlink -e $TEST_ROOT/result) = *simple.drv ]]
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir"#a10
[[ $(readlink -e "$TEST_ROOT/result") = *simple.drv ]]
expectStderr 1 nix build --json --out-link $TEST_ROOT/result $flake1Dir#a11 \
expectStderr 1 nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a11" \
| grepQuiet "has a context which refers to a complete source and binary closure"
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a12
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a12"
[[ -e $TEST_ROOT/result/hello ]]
expectStderr 1 nix build --impure --json --out-link $TEST_ROOT/result $flake1Dir#a13 \
expectStderr 1 nix build --impure --json --out-link "$TEST_ROOT/result" "$flake1Dir#a13" \
| grepQuiet "has 2 entries in its context. It should only have exactly one entry"
# Test accessing output in installables with `.` (foobarbaz.<output>)
nix build --json --no-link $flake1Dir#a14.foo | jq --exit-status '
nix build --json --no-link "$flake1Dir"#a14.foo | jq --exit-status '
(.[0] |
(.drvPath | match(".*dot-installable.drv")) and
(.outputs | keys == ["foo"]))

14
tests/functional/flakes/bundle.sh Normal file → Executable file
View file

@ -1,8 +1,10 @@
#!/usr/bin/env bash
source common.sh
cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
cp ../simple.nix ../simple.builder.sh ../config.nix "$TEST_HOME"
cd $TEST_HOME
cd "$TEST_HOME"
cat <<EOF > flake.nix
{
@ -25,8 +27,8 @@ 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 .#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
nix bundle --bundler .#bundlers."$system".default .#apps."$system".default
nix bundle --bundler .#bundlers."$system".simple .#apps."$system".default

46
tests/functional/flakes/check.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
flakeDir=$TEST_ROOT/flake3
@ -89,3 +91,47 @@ nix flake check $flakeDir
checkRes=$(nix flake check --all-systems --keep-going $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
echo "$checkRes" | grepQuiet "packages.system-1.default"
echo "$checkRes" | grepQuiet "packages.system-2.default"
cat > $flakeDir/flake.nix <<EOF
{
outputs = { self }: {
apps.system-1.default = {
type = "app";
program = "foo";
};
apps.system-2.default = {
type = "app";
program = "bar";
meta.description = "baz";
};
};
}
EOF
nix flake check --all-systems $flakeDir
cat > $flakeDir/flake.nix <<EOF
{
outputs = { self }: {
apps.system-1.default = {
type = "app";
program = "foo";
unknown-attr = "bar";
};
};
}
EOF
checkRes=$(nix flake check --all-systems $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
echo "$checkRes" | grepQuiet "unknown-attr"
cat > $flakeDir/flake.nix <<EOF
{
outputs = { self }: {
formatter.system-1 = "foo";
};
}
EOF
checkRes=$(nix flake check --all-systems $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
echo "$checkRes" | grepQuiet "formatter.system-1"

30
tests/functional/flakes/circular.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
# Test circular flake dependencies.
source ./common.sh
@ -6,10 +8,10 @@ requireGit
flakeA=$TEST_ROOT/flakeA
flakeB=$TEST_ROOT/flakeB
createGitRepo $flakeA
createGitRepo $flakeB
createGitRepo "$flakeA"
createGitRepo "$flakeB"
cat > $flakeA/flake.nix <<EOF
cat > "$flakeA"/flake.nix <<EOF
{
inputs.b.url = git+file://$flakeB;
inputs.b.inputs.a.follows = "/";
@ -21,9 +23,9 @@ cat > $flakeA/flake.nix <<EOF
}
EOF
git -C $flakeA add flake.nix
git -C "$flakeA" add flake.nix
cat > $flakeB/flake.nix <<EOF
cat > "$flakeB"/flake.nix <<EOF
{
inputs.a.url = git+file://$flakeA;
@ -33,18 +35,18 @@ cat > $flakeB/flake.nix <<EOF
}
EOF
git -C $flakeB add flake.nix
git -C $flakeB commit -a -m 'Foo'
git -C "$flakeB" add flake.nix
git -C "$flakeB" commit -a -m 'Foo'
[[ $(nix eval $flakeA#foo) = 1579 ]]
[[ $(nix eval $flakeA#foo) = 1579 ]]
[[ $(nix eval "$flakeA#foo") = 1579 ]]
[[ $(nix eval "$flakeA#foo") = 1579 ]]
sed -i $flakeB/flake.nix -e 's/456/789/'
git -C $flakeB commit -a -m 'Foo'
sed -i "$flakeB"/flake.nix -e 's/456/789/'
git -C "$flakeB" commit -a -m 'Foo'
nix flake update b --flake $flakeA
[[ $(nix eval $flakeA#foo) = 1912 ]]
nix flake update b --flake "$flakeA"
[[ $(nix eval "$flakeA#foo") = 1912 ]]
# Test list-inputs with circular dependencies
nix flake metadata $flakeA
nix flake metadata "$flakeA"

View file

@ -21,6 +21,12 @@ writeSimpleFlake() {
# To test "nix flake init".
legacyPackages.$system.hello = import ./simple.nix;
parent = builtins.dirOf ./.;
baseName = builtins.baseNameOf ./.;
root = ./.;
};
}
EOF

3
tests/functional/flakes/config.sh Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source common.sh
cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
@ -26,6 +28,7 @@ EOF
# Without --accept-flake-config, the post hook should not run.
nix build < /dev/null
(! [[ -f post-hook-ran ]])
TODO_NixOS
clearStore
nix build --accept-flake-config

4
tests/functional/flakes/develop.sh Normal file → Executable file
View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
source ../common.sh
TODO_NixOS
clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local

13
tests/functional/flakes/edit.sh Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env bash
source ./common.sh
requireGit
flake1Dir=$TEST_ROOT/flake1
createGitRepo "$flake1Dir"
createSimpleGitFlake "$flake1Dir"
export EDITOR=cat
nix edit "$flake1Dir#" | grepQuiet simple.builder.sh

View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
source ./common.sh
requireGit
flake1Dir="$TEST_ROOT/eval-cache-flake"
createGitRepo "$flake1Dir" ""
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
git -C "$flake1Dir" add simple.nix simple.builder.sh config.nix
git -C "$flake1Dir" commit -m "config.nix"
cat >"$flake1Dir/flake.nix" <<EOF
{
description = "Fnord";
outputs = { self }: let inherit (import ./config.nix) mkDerivation; in {
foo.bar = throw "breaks";
drv = mkDerivation {
name = "build";
buildCommand = ''
echo true > \$out
'';
};
ifd = assert (import self.drv); self.drv;
};
}
EOF
git -C "$flake1Dir" add flake.nix
git -C "$flake1Dir" commit -m "Init"
expect 1 nix build "$flake1Dir#foo.bar" 2>&1 | grepQuiet 'error: breaks'
expect 1 nix build "$flake1Dir#foo.bar" 2>&1 | grepQuiet 'error: breaks'
# Conditional error should not be cached
expect 1 nix build "$flake1Dir#ifd" --option allow-import-from-derivation false 2>&1 \
| grepQuiet 'error: cannot build .* during evaluation because the option '\''allow-import-from-derivation'\'' is disabled'
nix build --no-link "$flake1Dir#ifd"

Some files were not shown because too many files have changed in this diff Show more