mirror of
https://github.com/NixOS/nix
synced 2025-07-07 18:31:49 +02:00
Merge remote-tracking branch 'origin/master' into profile-names-instead-of-index
This commit is contained in:
commit
9d9d9ff0de
501 changed files with 10352 additions and 4635 deletions
|
@ -26,3 +26,20 @@ hash2=$(nix-hash --type sha256 --base32 ./dummy)
|
|||
echo $hash2
|
||||
|
||||
test "$hash1" = "sha256:$hash2"
|
||||
|
||||
#### New style commands
|
||||
|
||||
clearStore
|
||||
|
||||
(
|
||||
path1=$(nix store add ./dummy)
|
||||
path2=$(nix store add --mode nar ./dummy)
|
||||
path3=$(nix store add-path ./dummy)
|
||||
[[ "$path1" == "$path2" ]]
|
||||
[[ "$path1" == "$path3" ]]
|
||||
)
|
||||
(
|
||||
path1=$(nix store add --mode flat ./dummy)
|
||||
path2=$(nix store add-file ./dummy)
|
||||
[[ "$path1" == "$path2" ]]
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ enableFeatures "daemon-trust-override"
|
|||
|
||||
restartDaemon
|
||||
|
||||
requireSandboxSupport
|
||||
[[ $busybox =~ busybox ]] || skipTest "no busybox"
|
||||
|
||||
unset NIX_STORE_DIR
|
||||
|
|
22
tests/functional/build-remote-with-mounted-ssh-ng.sh
Normal file
22
tests/functional/build-remote-with-mounted-ssh-ng.sh
Normal file
|
@ -0,0 +1,22 @@
|
|||
source common.sh
|
||||
|
||||
requireSandboxSupport
|
||||
[[ $busybox =~ busybox ]] || skipTest "no busybox"
|
||||
|
||||
enableFeatures mounted-ssh-store
|
||||
|
||||
nix build -Lvf simple.nix \
|
||||
--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 \
|
||||
--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!'
|
10
tests/functional/ca/eval-store.sh
Normal file
10
tests/functional/ca/eval-store.sh
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Ensure that garbage collection works properly with ca derivations
|
||||
|
||||
source common.sh
|
||||
|
||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||
|
||||
cd ..
|
||||
source eval-store.sh
|
|
@ -5,6 +5,7 @@ ca-tests := \
|
|||
$(d)/concurrent-builds.sh \
|
||||
$(d)/derivation-json.sh \
|
||||
$(d)/duplicate-realisation-in-closure.sh \
|
||||
$(d)/eval-store.sh \
|
||||
$(d)/gc.sh \
|
||||
$(d)/import-derivation.sh \
|
||||
$(d)/new-build-cmd.sh \
|
||||
|
|
|
@ -4,7 +4,7 @@ if [[ -z "${COMMON_VARS_AND_FUNCTIONS_SH_SOURCED-}" ]]; then
|
|||
|
||||
COMMON_VARS_AND_FUNCTIONS_SH_SOURCED=1
|
||||
|
||||
export PS4='+(${BASH_SOURCE[0]-$0}:$LINENO) '
|
||||
set +x
|
||||
|
||||
export TEST_ROOT=$(realpath ${TMPDIR:-/tmp}/nix-test)/${TEST_NAME:-default/tests\/functional//}
|
||||
export NIX_STORE_DIR
|
||||
|
|
|
@ -40,19 +40,20 @@ files=$(nix-build --verbose --version | grep "User config" | cut -d ':' -f2- | x
|
|||
# Test that it's possible to load the config from a custom location
|
||||
here=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
|
||||
export NIX_USER_CONF_FILES=$here/config/nix-with-substituters.conf
|
||||
var=$(nix show-config | grep '^substituters =' | cut -d '=' -f 2 | xargs)
|
||||
var=$(nix config show | grep '^substituters =' | cut -d '=' -f 2 | xargs)
|
||||
[[ $var == https://example.com ]]
|
||||
|
||||
# Test that it's possible to load config from the environment
|
||||
prev=$(nix show-config | grep '^cores' | cut -d '=' -f 2 | xargs)
|
||||
prev=$(nix config show | grep '^cores' | cut -d '=' -f 2 | xargs)
|
||||
export NIX_CONFIG="cores = 4242"$'\n'"experimental-features = nix-command flakes"
|
||||
exp_cores=$(nix show-config | grep '^cores' | cut -d '=' -f 2 | xargs)
|
||||
exp_features=$(nix show-config | grep '^experimental-features' | cut -d '=' -f 2 | xargs)
|
||||
exp_cores=$(nix config show | grep '^cores' | cut -d '=' -f 2 | xargs)
|
||||
exp_features=$(nix config show | grep '^experimental-features' | cut -d '=' -f 2 | xargs)
|
||||
[[ $prev != $exp_cores ]]
|
||||
[[ $exp_cores == "4242" ]]
|
||||
[[ $exp_features == "flakes nix-command" ]]
|
||||
# flakes implies fetch-tree
|
||||
[[ $exp_features == "fetch-tree flakes nix-command" ]]
|
||||
|
||||
# Test that it's possible to retrieve a single setting's value
|
||||
val=$(nix show-config | grep '^warn-dirty' | cut -d '=' -f 2 | xargs)
|
||||
val2=$(nix show-config warn-dirty)
|
||||
val=$(nix config show | grep '^warn-dirty' | cut -d '=' -f 2 | xargs)
|
||||
val2=$(nix config show warn-dirty)
|
||||
[[ $val == $val2 ]]
|
||||
|
|
|
@ -11,7 +11,16 @@ rm -rf "$eval_store"
|
|||
|
||||
nix build -f dependencies.nix --eval-store "$eval_store" -o "$TEST_ROOT/result"
|
||||
[[ -e $TEST_ROOT/result/foobar ]]
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
if [[ ! -n "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
||||
# Resolved CA derivations are written to store for building
|
||||
#
|
||||
# TODO when we something more systematic
|
||||
# (https://github.com/NixOS/nix/issues/5025) that distinguishes
|
||||
# between scratch storage for building and the final destination
|
||||
# store, we'll be able to make this unconditional again -- resolved
|
||||
# derivations should only appear in the scratch store.
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
fi
|
||||
ls $eval_store/nix/store/*.drv
|
||||
|
||||
clearStore
|
||||
|
@ -26,5 +35,8 @@ rm -rf "$eval_store"
|
|||
|
||||
nix-build dependencies.nix --eval-store "$eval_store" -o "$TEST_ROOT/result"
|
||||
[[ -e $TEST_ROOT/result/foobar ]]
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
if [[ ! -n "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then
|
||||
# See above
|
||||
(! ls $NIX_STORE_DIR/*.drv)
|
||||
fi
|
||||
ls $eval_store/nix/store/*.drv
|
||||
|
|
|
@ -31,7 +31,7 @@ source common.sh
|
|||
NIX_CONFIG='
|
||||
experimental-features = nix-command
|
||||
accept-flake-config = true
|
||||
' nix show-config accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
||||
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
||||
grepQuiet "false" $TEST_ROOT/stdout
|
||||
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
||||
|
||||
|
@ -39,7 +39,7 @@ grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature '
|
|||
NIX_CONFIG='
|
||||
accept-flake-config = true
|
||||
experimental-features = nix-command
|
||||
' nix show-config accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
||||
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
||||
grepQuiet "false" $TEST_ROOT/stdout
|
||||
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
||||
|
||||
|
@ -47,7 +47,7 @@ grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature '
|
|||
NIX_CONFIG='
|
||||
experimental-features = nix-command flakes
|
||||
accept-flake-config = true
|
||||
' nix show-config accept-flake-config 1>$TEST_ROOT/stdout 2>$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
|
||||
|
||||
|
@ -55,7 +55,7 @@ grepQuietInverse "Ignoring setting 'accept-flake-config'" $TEST_ROOT/stderr
|
|||
NIX_CONFIG='
|
||||
accept-flake-config = true
|
||||
experimental-features = nix-command flakes
|
||||
' nix show-config accept-flake-config 1>$TEST_ROOT/stdout 2>$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
|
||||
|
||||
|
|
|
@ -51,9 +51,7 @@ git -C $repo add differentbranch
|
|||
git -C $repo commit -m 'Test2'
|
||||
git -C $repo checkout master
|
||||
devrev=$(git -C $repo rev-parse devtest)
|
||||
out=$(nix eval --impure --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; }" 2>&1) || status=$?
|
||||
[[ $status == 1 ]]
|
||||
[[ $out =~ 'Cannot find Git revision' ]]
|
||||
nix eval --impure --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; }"
|
||||
|
||||
[[ $(nix eval --raw --expr "builtins.readFile (builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; allRefs = true; } + \"/differentbranch\")") = 'different file' ]]
|
||||
|
||||
|
@ -185,11 +183,7 @@ path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref =
|
|||
# Nuke the cache
|
||||
rm -rf $TEST_HOME/.cache/nix
|
||||
|
||||
# Try again, but without 'git' on PATH. This should fail.
|
||||
NIX=$(command -v nix)
|
||||
(! PATH= $NIX eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outPath" )
|
||||
|
||||
# Try again, with 'git' available. This should work.
|
||||
# Try again. This should work.
|
||||
path5=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outPath")
|
||||
[[ $path3 = $path5 ]]
|
||||
|
||||
|
@ -241,6 +235,7 @@ rm -rf $repo/.git
|
|||
|
||||
# should succeed for a repo without commits
|
||||
git init $repo
|
||||
git -C $repo add hello # need to add at least one file to cause the root of the repo to be visible
|
||||
path10=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")
|
||||
|
||||
# should succeed for a path with a space
|
||||
|
|
|
@ -118,11 +118,3 @@ cloneRepo=$TEST_ROOT/a/b/gitSubmodulesClone # NB /a/b to make the relative path
|
|||
git clone $rootRepo $cloneRepo
|
||||
pathIndirect=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$cloneRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
||||
[[ $pathIndirect = $pathWithRelative ]]
|
||||
|
||||
# Test that if the clone has the submodule already, we're not fetching
|
||||
# it again.
|
||||
git -C $cloneRepo submodule update --init
|
||||
rm $TEST_HOME/.cache/nix/fetcher-cache*
|
||||
rm -rf $subRepo
|
||||
pathSubmoduleGone=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$cloneRepo; rev = \"$rev2\"; submodules = true; }).outPath")
|
||||
[[ $pathSubmoduleGone = $pathWithRelative ]]
|
||||
|
|
|
@ -34,6 +34,12 @@ out=$(nix eval --impure --raw --expr "builtins.fetchGit { url = \"file://$repo\"
|
|||
[[ $(nix eval --impure --raw --expr "builtins.readFile (builtins.fetchGit { url = \"file://$repo\"; publicKey = \"$publicKey1\"; } + \"/text\")") = 'hello' ]]
|
||||
|
||||
echo 'hello world' > $repo/text
|
||||
|
||||
# Verification on a dirty repo should fail.
|
||||
out=$(nix eval --impure --raw --expr "builtins.fetchGit { url = \"file://$repo\"; keytype = \"ssh-rsa\"; publicKey = \"$publicKey2\"; }" 2>&1) || status=$?
|
||||
[[ $status == 1 ]]
|
||||
[[ $out =~ 'dirty' ]]
|
||||
|
||||
git -C $repo add text
|
||||
git -C $repo -c "user.signingkey=$key2File" commit -S -m 'second commit'
|
||||
|
||||
|
@ -73,4 +79,4 @@ cat > "$flakeDir/flake.nix" <<EOF
|
|||
EOF
|
||||
out=$(nix build "$flakeDir#test" 2>&1) || status=$?
|
||||
[[ $status == 1 ]]
|
||||
[[ $out =~ 'No principal matched.' ]]
|
||||
[[ $out =~ 'No principal matched.' ]]
|
||||
|
|
|
@ -11,6 +11,7 @@ writeSimpleFlake() {
|
|||
outputs = inputs: rec {
|
||||
packages.$system = rec {
|
||||
foo = import ./simple.nix;
|
||||
fooScript = (import ./shell.nix {}).foo;
|
||||
default = foo;
|
||||
};
|
||||
packages.someOtherSystem = rec {
|
||||
|
@ -24,13 +25,13 @@ writeSimpleFlake() {
|
|||
}
|
||||
EOF
|
||||
|
||||
cp ../simple.nix ../simple.builder.sh ../config.nix $flakeDir/
|
||||
cp ../simple.nix ../shell.nix ../simple.builder.sh ../config.nix $flakeDir/
|
||||
}
|
||||
|
||||
createSimpleGitFlake() {
|
||||
local flakeDir="$1"
|
||||
writeSimpleFlake $flakeDir
|
||||
git -C $flakeDir add flake.nix simple.nix simple.builder.sh config.nix
|
||||
git -C $flakeDir add flake.nix simple.nix shell.nix simple.builder.sh config.nix
|
||||
git -C $flakeDir commit -m 'Initial'
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,16 @@ echo '"expression in root repo"' > $rootRepo/root.nix
|
|||
git -C $rootRepo add root.nix
|
||||
git -C $rootRepo commit -m "Add root.nix"
|
||||
|
||||
flakeref=git+file://$rootRepo\?submodules=1\&dir=submodule
|
||||
|
||||
# Flake can live inside a submodule and can be accessed via ?dir=submodule
|
||||
[[ $(nix eval --json git+file://$rootRepo\?submodules=1\&dir=submodule#sub ) = '"expression in submodule"' ]]
|
||||
[[ $(nix eval --json $flakeref#sub ) = '"expression in submodule"' ]]
|
||||
|
||||
# The flake can access content outside of the submodule
|
||||
[[ $(nix eval --json git+file://$rootRepo\?submodules=1\&dir=submodule#root ) = '"expression in root repo"' ]]
|
||||
[[ $(nix eval --json $flakeref#root ) = '"expression in root repo"' ]]
|
||||
|
||||
# Check that dirtying a submodule makes the entire thing dirty.
|
||||
[[ $(nix flake metadata --json $flakeref | jq -r .locked.rev) != null ]]
|
||||
echo '"foo"' > $rootRepo/submodule/sub.nix
|
||||
[[ $(nix eval --json $flakeref#sub ) = '"foo"' ]]
|
||||
[[ $(nix flake metadata --json $flakeref | jq -r .locked.rev) = null ]]
|
||||
|
|
|
@ -66,9 +66,82 @@ cat > "$nonFlakeDir/README.md" <<EOF
|
|||
FNORD
|
||||
EOF
|
||||
|
||||
git -C "$nonFlakeDir" add README.md
|
||||
cat > "$nonFlakeDir/shebang.sh" <<EOF
|
||||
#! $(type -P env) nix
|
||||
#! nix --offline shell
|
||||
#! nix flake1#fooScript
|
||||
#! nix --no-write-lock-file --command bash
|
||||
set -ex
|
||||
foo
|
||||
echo "\$@"
|
||||
EOF
|
||||
chmod +x "$nonFlakeDir/shebang.sh"
|
||||
|
||||
git -C "$nonFlakeDir" add README.md shebang.sh
|
||||
git -C "$nonFlakeDir" commit -m 'Initial'
|
||||
|
||||
# this also tests a fairly trivial double backtick quoted string, ``--command``
|
||||
cat > $nonFlakeDir/shebang-comments.sh <<EOF
|
||||
#! $(type -P env) nix
|
||||
# some comments
|
||||
# some comments
|
||||
# some comments
|
||||
#! nix --offline shell
|
||||
#! nix flake1#fooScript
|
||||
#! nix --no-write-lock-file ``--command`` bash
|
||||
foo
|
||||
EOF
|
||||
chmod +x $nonFlakeDir/shebang-comments.sh
|
||||
|
||||
cat > $nonFlakeDir/shebang-reject.sh <<EOF
|
||||
#! $(type -P env) nix
|
||||
# some comments
|
||||
# some comments
|
||||
# some comments
|
||||
#! nix --offline shell *
|
||||
#! nix flake1#fooScript
|
||||
#! nix --no-write-lock-file --command bash
|
||||
foo
|
||||
EOF
|
||||
chmod +x $nonFlakeDir/shebang-reject.sh
|
||||
|
||||
cat > $nonFlakeDir/shebang-inline-expr.sh <<EOF
|
||||
#! $(type -P env) nix
|
||||
EOF
|
||||
cat >> $nonFlakeDir/shebang-inline-expr.sh <<"EOF"
|
||||
#! nix --offline shell
|
||||
#! nix --impure --expr ``
|
||||
#! nix let flake = (builtins.getFlake (toString ../flake1)).packages;
|
||||
#! nix fooScript = flake.${builtins.currentSystem}.fooScript;
|
||||
#! nix /* just a comment !@#$%^&*()__+ # */
|
||||
#! nix in fooScript
|
||||
#! nix ``
|
||||
#! nix --no-write-lock-file --command bash
|
||||
set -ex
|
||||
foo
|
||||
echo "$@"
|
||||
EOF
|
||||
chmod +x $nonFlakeDir/shebang-inline-expr.sh
|
||||
|
||||
cat > $nonFlakeDir/fooScript.nix <<"EOF"
|
||||
let flake = (builtins.getFlake (toString ../flake1)).packages;
|
||||
fooScript = flake.${builtins.currentSystem}.fooScript;
|
||||
in fooScript
|
||||
EOF
|
||||
|
||||
cat > $nonFlakeDir/shebang-file.sh <<EOF
|
||||
#! $(type -P env) nix
|
||||
EOF
|
||||
cat >> $nonFlakeDir/shebang-file.sh <<"EOF"
|
||||
#! nix --offline shell
|
||||
#! nix --impure --file ./fooScript.nix
|
||||
#! nix --no-write-lock-file --command bash
|
||||
set -ex
|
||||
foo
|
||||
echo "$@"
|
||||
EOF
|
||||
chmod +x $nonFlakeDir/shebang-file.sh
|
||||
|
||||
# Construct a custom registry, additionally test the --registry flag
|
||||
nix registry add --registry "$registry" flake1 "git+file://$flake1Dir"
|
||||
nix registry add --registry "$registry" flake2 "git+file://$percentEncodedFlake2Dir"
|
||||
|
@ -120,6 +193,14 @@ nix build -o "$TEST_ROOT/result" flake1
|
|||
nix build -o "$TEST_ROOT/result" "$flake1Dir"
|
||||
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir"
|
||||
|
||||
# Test explicit packages.default.
|
||||
nix build -o "$TEST_ROOT/result" "$flake1Dir#default"
|
||||
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir#default"
|
||||
|
||||
# Test explicit packages.default with query.
|
||||
nix build -o "$TEST_ROOT/result" "$flake1Dir?ref=HEAD#default"
|
||||
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir?ref=HEAD#default"
|
||||
|
||||
# Check that store symlinks inside a flake are not interpreted as flakes.
|
||||
nix build -o "$flake1Dir/result" "git+file://$flake1Dir"
|
||||
nix path-info "$flake1Dir/result"
|
||||
|
@ -511,3 +592,11 @@ nix flake metadata "$flake2Dir" --reference-lock-file $TEST_ROOT/flake2-overridd
|
|||
|
||||
# reference-lock-file can only be used if allow-dirty is set.
|
||||
expectStderr 1 nix flake metadata "$flake2Dir" --no-allow-dirty --reference-lock-file $TEST_ROOT/flake2-overridden.lock
|
||||
|
||||
# Test shebang
|
||||
[[ $($nonFlakeDir/shebang.sh) = "foo" ]]
|
||||
[[ $($nonFlakeDir/shebang.sh "bar") = "foo"$'\n'"bar" ]]
|
||||
[[ $($nonFlakeDir/shebang-comments.sh ) = "foo" ]]
|
||||
[[ $($nonFlakeDir/shebang-inline-expr.sh baz) = "foo"$'\n'"baz" ]]
|
||||
[[ $($nonFlakeDir/shebang-file.sh baz) = "foo"$'\n'"baz" ]]
|
||||
expect 1 $nonFlakeDir/shebang-reject.sh 2>&1 | grepQuiet -F 'error: unsupported unquoted character in nix shebang: *. Use double backticks to escape?'
|
||||
|
|
|
@ -260,3 +260,79 @@ EOF
|
|||
|
||||
checkRes=$(nix flake lock "$flakeFollowCycle" 2>&1 && fail "nix flake lock should have failed." || true)
|
||||
echo $checkRes | grep -F "error: follow cycle detected: [baz -> foo -> bar -> baz]"
|
||||
|
||||
|
||||
# Test transitive input url locking
|
||||
# This tests the following lockfile issue: https://github.com/NixOS/nix/issues/9143
|
||||
#
|
||||
# We construct the following graph, where p->q means p has input q.
|
||||
#
|
||||
# A -> B -> C
|
||||
#
|
||||
# And override B/C to flake D, first in A's flake.nix and then with --override-input.
|
||||
#
|
||||
# A -> B -> D
|
||||
flakeFollowsCustomUrlA="$TEST_ROOT/follows/custom-url/flakeA"
|
||||
flakeFollowsCustomUrlB="$TEST_ROOT/follows/custom-url/flakeA/flakeB"
|
||||
flakeFollowsCustomUrlC="$TEST_ROOT/follows/custom-url/flakeA/flakeB/flakeC"
|
||||
flakeFollowsCustomUrlD="$TEST_ROOT/follows/custom-url/flakeA/flakeB/flakeD"
|
||||
|
||||
|
||||
createGitRepo "$flakeFollowsCustomUrlA"
|
||||
mkdir -p "$flakeFollowsCustomUrlB"
|
||||
mkdir -p "$flakeFollowsCustomUrlC"
|
||||
mkdir -p "$flakeFollowsCustomUrlD"
|
||||
|
||||
cat > "$flakeFollowsCustomUrlD/flake.nix" <<EOF
|
||||
{
|
||||
description = "Flake D";
|
||||
inputs = {};
|
||||
outputs = { ... }: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
cat > "$flakeFollowsCustomUrlC/flake.nix" <<EOF
|
||||
{
|
||||
description = "Flake C";
|
||||
inputs = {};
|
||||
outputs = { ... }: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
cat > "$flakeFollowsCustomUrlB/flake.nix" <<EOF
|
||||
{
|
||||
description = "Flake B";
|
||||
inputs = {
|
||||
C = {
|
||||
url = "path:./flakeC";
|
||||
};
|
||||
};
|
||||
outputs = { ... }: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
cat > "$flakeFollowsCustomUrlA/flake.nix" <<EOF
|
||||
{
|
||||
description = "Flake A";
|
||||
inputs = {
|
||||
B = {
|
||||
url = "path:./flakeB";
|
||||
inputs.C.url = "path:./flakeB/flakeD";
|
||||
};
|
||||
};
|
||||
outputs = { ... }: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
git -C "$flakeFollowsCustomUrlA" add flake.nix flakeB/flake.nix \
|
||||
flakeB/flakeC/flake.nix flakeB/flakeD/flake.nix
|
||||
|
||||
# lock "original" entry should contain overridden url
|
||||
json=$(nix flake metadata "$flakeFollowsCustomUrlA" --json)
|
||||
[[ $(echo "$json" | jq -r .locks.nodes.C.original.path) = './flakeB/flakeD' ]]
|
||||
rm "$flakeFollowsCustomUrlA"/flake.lock
|
||||
|
||||
# if override-input is specified, lock "original" entry should contain original url
|
||||
json=$(nix flake metadata "$flakeFollowsCustomUrlA" --override-input B/C "path:./flakeB/flakeD" --json)
|
||||
echo "$json" | jq .locks.nodes.C.original
|
||||
[[ $(echo "$json" | jq -r .locks.nodes.C.original.path) = './flakeC' ]]
|
||||
|
|
|
@ -81,27 +81,106 @@ rm $TEST_ROOT/hash-path/hello
|
|||
ln -s x $TEST_ROOT/hash-path/hello
|
||||
try2 md5 "f78b733a68f5edbdf9413899339eaa4a"
|
||||
|
||||
# Conversion.
|
||||
# Conversion with `nix hash` `nix-hash` and `nix hash convert`
|
||||
try3() {
|
||||
# $1 = hash algo
|
||||
# $2 = expected hash in base16
|
||||
# $3 = expected hash in base32
|
||||
# $4 = expected hash in base64
|
||||
h64=$(nix hash convert --algo "$1" --to base64 "$2")
|
||||
[ "$h64" = "$4" ]
|
||||
h64=$(nix-hash --type "$1" --to-base64 "$2")
|
||||
[ "$h64" = "$4" ]
|
||||
# Deprecated experiment
|
||||
h64=$(nix hash to-base64 --type "$1" "$2")
|
||||
[ "$h64" = "$4" ]
|
||||
|
||||
sri=$(nix hash convert --algo "$1" --to sri "$2")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix-hash --type "$1" --to-sri "$2")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash to-sri --type "$1" "$2")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
h32=$(nix hash convert --algo "$1" --to base32 "$2")
|
||||
[ "$h32" = "$3" ]
|
||||
h32=$(nix-hash --type "$1" --to-base32 "$2")
|
||||
[ "$h32" = "$3" ]
|
||||
h32=$(nix hash to-base32 --type "$1" "$2")
|
||||
[ "$h32" = "$3" ]
|
||||
h16=$(nix-hash --type "$1" --to-base16 "$h32")
|
||||
[ "$h16" = "$2" ]
|
||||
|
||||
h16=$(nix hash convert --algo "$1" --to base16 "$h64")
|
||||
[ "$h16" = "$2" ]
|
||||
h16=$(nix hash to-base16 --type "$1" "$h64")
|
||||
[ "$h16" = "$2" ]
|
||||
h16=$(nix hash convert --to base16 "$sri")
|
||||
[ "$h16" = "$2" ]
|
||||
h16=$(nix hash to-base16 "$sri")
|
||||
[ "$h16" = "$2" ]
|
||||
|
||||
#
|
||||
# Converting from SRI
|
||||
#
|
||||
|
||||
# Input hash algo auto-detected from SRI and output defaults to SRI as well.
|
||||
sri=$(nix hash convert "$1-$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
sri=$(nix hash convert --from sri "$1-$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
sri=$(nix hash convert --to sri "$1-$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
sri=$(nix hash convert --from sri --to sri "$1-$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
sri=$(nix hash convert --to base64 "$1-$4")
|
||||
[ "$sri" = "$4" ]
|
||||
|
||||
#
|
||||
# Auto-detecting the input from algo and length.
|
||||
#
|
||||
|
||||
sri=$(nix hash convert --algo "$1" "$2")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash convert --algo "$1" "$3")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash convert --algo "$1" "$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
sri=$(nix hash convert --algo "$1" "$2")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash convert --algo "$1" "$3")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash convert --algo "$1" "$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
#
|
||||
# Asserting input format succeeds.
|
||||
#
|
||||
|
||||
sri=$(nix hash convert --algo "$1" --from base16 "$2")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash convert --algo "$1" --from nix32 "$3")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
sri=$(nix hash convert --algo "$1" --from base64 "$4")
|
||||
[ "$sri" = "$1-$4" ]
|
||||
|
||||
#
|
||||
# Asserting input format fails.
|
||||
#
|
||||
|
||||
fail=$(nix hash convert --algo "$1" --from nix32 "$2" 2>&1 || echo "exit: $?")
|
||||
[[ "$fail" == *"error: input hash"*"exit: 1" ]]
|
||||
fail=$(nix hash convert --algo "$1" --from base16 "$3" 2>&1 || echo "exit: $?")
|
||||
[[ "$fail" == *"error: input hash"*"exit: 1" ]]
|
||||
fail=$(nix hash convert --algo "$1" --from nix32 "$4" 2>&1 || echo "exit: $?")
|
||||
[[ "$fail" == *"error: input hash"*"exit: 1" ]]
|
||||
|
||||
}
|
||||
|
||||
try3 sha1 "800d59cfcd3c05e900cb4e214be48f6b886a08df" "vw46m23bizj4n8afrc0fj19wrp7mj3c0" "gA1Zz808BekAy04hS+SPa4hqCN8="
|
||||
try3 sha256 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" "1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s" "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="
|
||||
try3 sha512 "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" "12k9jiq29iyqm03swfsgiw5mlqs173qazm3n7daz43infy12pyrcdf30fkk3qwv4yl2ick8yipc2mqnlh48xsvvxl60lbx8vp38yji0" "IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ=="
|
||||
|
|
35
tests/functional/impure-eval.sh
Normal file
35
tests/functional/impure-eval.sh
Normal file
|
@ -0,0 +1,35 @@
|
|||
source common.sh
|
||||
|
||||
export REMOTE_STORE="dummy://"
|
||||
|
||||
simpleTest () {
|
||||
local expr=$1; shift
|
||||
local result=$1; shift
|
||||
# rest, extra args
|
||||
|
||||
[[ "$(nix eval --impure --raw "$@" --expr "$expr")" == "$result" ]]
|
||||
}
|
||||
|
||||
# `builtins.storeDir`
|
||||
|
||||
## Store dir follows `store` store setting
|
||||
simpleTest 'builtins.storeDir' '/foo' --store "$REMOTE_STORE?store=/foo"
|
||||
simpleTest 'builtins.storeDir' '/bar' --store "$REMOTE_STORE?store=/bar"
|
||||
|
||||
# `builtins.currentSystem`
|
||||
|
||||
## `system` alone affects by default
|
||||
simpleTest 'builtins.currentSystem' 'foo' --system 'foo'
|
||||
simpleTest 'builtins.currentSystem' 'bar' --system 'bar'
|
||||
|
||||
## `system` affects if `eval-system` is an empty string
|
||||
simpleTest 'builtins.currentSystem' 'foo' --system 'foo' --eval-system ''
|
||||
simpleTest 'builtins.currentSystem' 'bar' --system 'bar' --eval-system ''
|
||||
|
||||
## `eval-system` alone affects
|
||||
simpleTest 'builtins.currentSystem' 'foo' --eval-system 'foo'
|
||||
simpleTest 'builtins.currentSystem' 'bar' --eval-system 'bar'
|
||||
|
||||
## `eval-system` overrides `system`
|
||||
simpleTest 'builtins.currentSystem' 'bar' --system 'foo' --eval-system 'bar'
|
||||
simpleTest 'builtins.currentSystem' 'baz' --system 'foo' --eval-system 'baz'
|
|
@ -20,7 +20,7 @@ cat > "$NIX_CONF_DIR"/nix.conf <<EOF
|
|||
build-users-group =
|
||||
keep-derivations = false
|
||||
sandbox = false
|
||||
experimental-features = nix-command flakes
|
||||
experimental-features = nix-command
|
||||
gc-reserved-space = 0
|
||||
substituters =
|
||||
flake-registry = $TEST_ROOT/registry.json
|
||||
|
@ -31,6 +31,7 @@ EOF
|
|||
|
||||
cat > "$NIX_CONF_DIR"/nix.conf.extra <<EOF
|
||||
fsync-metadata = false
|
||||
extra-experimental-features = flakes
|
||||
!include nix.conf.extra.not-there
|
||||
EOF
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'abort' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-abort.nix:1:14:
|
||||
|
||||
1| if true then abort "this should fail" else 1
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'addDrvOutputDependencies' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-addDrvOutputDependencies-empty-context.nix:1:1:
|
||||
|
||||
1| builtins.addDrvOutputDependencies ""
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'addDrvOutputDependencies' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix:18:4:
|
||||
|
||||
17|
|
||||
18| in builtins.addDrvOutputDependencies combo-path
|
||||
| ^
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'addDrvOutputDependencies' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix:9:4:
|
||||
|
||||
8|
|
||||
9| in builtins.addDrvOutputDependencies drv.outPath
|
||||
| ^
|
||||
|
|
|
@ -1,35 +1,27 @@
|
|||
error:
|
||||
… while evaluating the attribute 'body'
|
||||
|
||||
at /pwd/lang/eval-fail-assert.nix:4:3:
|
||||
|
||||
3|
|
||||
4| body = x "x";
|
||||
| ^
|
||||
5| }
|
||||
|
||||
… from call site
|
||||
|
||||
at /pwd/lang/eval-fail-assert.nix:4:10:
|
||||
|
||||
3|
|
||||
4| body = x "x";
|
||||
| ^
|
||||
5| }
|
||||
|
||||
… while calling 'x'
|
||||
|
||||
at /pwd/lang/eval-fail-assert.nix:2:7:
|
||||
|
||||
1| let {
|
||||
2| x = arg: assert arg == "y"; 123;
|
||||
| ^
|
||||
3|
|
||||
|
||||
error: assertion '(arg == "y")' failed
|
||||
|
||||
at /pwd/lang/eval-fail-assert.nix:2:12:
|
||||
|
||||
1| let {
|
||||
2| x = arg: assert arg == "y"; 123;
|
||||
| ^
|
||||
|
|
16
tests/functional/lang/eval-fail-attr-name-type.err.exp
Normal file
16
tests/functional/lang/eval-fail-attr-name-type.err.exp
Normal file
|
@ -0,0 +1,16 @@
|
|||
error:
|
||||
… while evaluating the attribute 'puppy."${key}"'
|
||||
at /pwd/lang/eval-fail-attr-name-type.nix:3:5:
|
||||
2| attrs = {
|
||||
3| puppy.doggy = {};
|
||||
| ^
|
||||
4| };
|
||||
|
||||
… while evaluating an attribute name
|
||||
at /pwd/lang/eval-fail-attr-name-type.nix:7:17:
|
||||
6| in
|
||||
7| attrs.puppy.${key}
|
||||
| ^
|
||||
8|
|
||||
|
||||
error: value is an integer while a string was expected
|
7
tests/functional/lang/eval-fail-attr-name-type.nix
Normal file
7
tests/functional/lang/eval-fail-attr-name-type.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
let
|
||||
attrs = {
|
||||
puppy.doggy = {};
|
||||
};
|
||||
key = 1;
|
||||
in
|
||||
attrs.puppy.${key}
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while evaluating a path segment
|
||||
|
||||
at /pwd/lang/eval-fail-bad-string-interpolation-1.nix:1:2:
|
||||
|
||||
1| "${x: x}"
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while evaluating a path segment
|
||||
|
||||
at /pwd/lang/eval-fail-bad-string-interpolation-3.nix:1:3:
|
||||
|
||||
1| ''${x: x}''
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
error:
|
||||
… while evaluating a path segment
|
||||
at /pwd/lang/eval-fail-bad-string-interpolation-4.nix:9:3:
|
||||
8| # The error message should not be too long.
|
||||
9| ''${pkgs}''
|
||||
| ^
|
||||
10|
|
||||
|
||||
error: cannot coerce a set to a string
|
|
@ -0,0 +1,9 @@
|
|||
let
|
||||
# Basically a "billion laughs" attack, but toned down to simulated `pkgs`.
|
||||
ha = x: y: { a = x y; b = x y; c = x y; d = x y; e = x y; f = x y; g = x y; h = x y; j = x y; };
|
||||
has = ha (ha (ha (ha (x: x)))) "ha";
|
||||
# A large structure that has already been evaluated.
|
||||
pkgs = builtins.deepSeq has has;
|
||||
in
|
||||
# The error message should not be too long.
|
||||
''${pkgs}''
|
|
@ -1,17 +1,13 @@
|
|||
error:
|
||||
… while evaluating the attribute 'body'
|
||||
|
||||
at /pwd/lang/eval-fail-blackhole.nix:2:3:
|
||||
|
||||
1| let {
|
||||
2| body = x;
|
||||
| ^
|
||||
3| x = y;
|
||||
|
||||
error: infinite recursion encountered
|
||||
|
||||
at /pwd/lang/eval-fail-blackhole.nix:3:7:
|
||||
|
||||
2| body = x;
|
||||
3| x = y;
|
||||
| ^
|
||||
|
|
10
tests/functional/lang/eval-fail-call-primop.err.exp
Normal file
10
tests/functional/lang/eval-fail-call-primop.err.exp
Normal file
|
@ -0,0 +1,10 @@
|
|||
error:
|
||||
… while calling the 'length' builtin
|
||||
at /pwd/lang/eval-fail-call-primop.nix:1:1:
|
||||
1| builtins.length 1
|
||||
| ^
|
||||
2|
|
||||
|
||||
… while evaluating the first argument passed to builtins.length
|
||||
|
||||
error: value is an integer while a list was expected
|
1
tests/functional/lang/eval-fail-call-primop.nix
Normal file
1
tests/functional/lang/eval-fail-call-primop.nix
Normal file
|
@ -0,0 +1 @@
|
|||
builtins.length 1
|
|
@ -1,24 +1,18 @@
|
|||
error:
|
||||
… while calling the 'deepSeq' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-deepseq.nix:1:1:
|
||||
|
||||
1| builtins.deepSeq { x = abort "foo"; } 456
|
||||
| ^
|
||||
2|
|
||||
|
||||
… while evaluating the attribute 'x'
|
||||
|
||||
at /pwd/lang/eval-fail-deepseq.nix:1:20:
|
||||
|
||||
1| builtins.deepSeq { x = abort "foo"; } 456
|
||||
| ^
|
||||
2|
|
||||
|
||||
… while calling the 'abort' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-deepseq.nix:1:24:
|
||||
|
||||
1| builtins.deepSeq { x = abort "foo"; } 456
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
error:
|
||||
… while evaluating the attribute 'set'
|
||||
|
||||
at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:2:3:
|
||||
|
||||
1| {
|
||||
2| set = { "${"" + "b"}" = 1; };
|
||||
| ^
|
||||
3| set = { "${"b" + ""}" = 2; };
|
||||
|
||||
error: dynamic attribute 'b' already defined at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:2:11
|
||||
|
||||
at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:3:11:
|
||||
|
||||
2| set = { "${"" + "b"}" = 1; };
|
||||
3| set = { "${"b" + ""}" = 2; };
|
||||
| ^
|
||||
|
|
|
@ -1,35 +1,27 @@
|
|||
error:
|
||||
… while calling the 'foldl'' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:1:
|
||||
|
||||
1| # Tests that the result of applying op is forced even if the value is never used
|
||||
2| builtins.foldl'
|
||||
| ^
|
||||
3| (_: f: f null)
|
||||
|
||||
… while calling anonymous lambda
|
||||
|
||||
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:7:
|
||||
|
||||
2| builtins.foldl'
|
||||
3| (_: f: f null)
|
||||
| ^
|
||||
4| null
|
||||
|
||||
… from call site
|
||||
|
||||
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:10:
|
||||
|
||||
2| builtins.foldl'
|
||||
3| (_: f: f null)
|
||||
| ^
|
||||
4| null
|
||||
|
||||
… while calling anonymous lambda
|
||||
|
||||
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:5:6:
|
||||
|
||||
4| null
|
||||
5| [ (_: throw "Not the final value, but is still forced!") (_: 23) ]
|
||||
| ^
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'fromTOML' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-fromTOML-timestamps.nix:1:1:
|
||||
|
||||
1| builtins.fromTOML ''
|
||||
| ^
|
||||
2| key = "value"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'toString' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-hashfile-missing.nix:4:3:
|
||||
|
||||
3| in
|
||||
4| toString (builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"]))
|
||||
| ^
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while evaluating one of the elements to concatenate
|
||||
|
||||
at /pwd/lang/eval-fail-list.nix:1:2:
|
||||
|
||||
1| 8++1
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
error:
|
||||
… from call site
|
||||
|
||||
at /pwd/lang/eval-fail-missing-arg.nix:1:1:
|
||||
|
||||
1| ({x, y, z}: x + y + z) {x = "foo"; z = "bar";}
|
||||
| ^
|
||||
2|
|
||||
|
||||
error: function 'anonymous lambda' called without required argument 'y'
|
||||
|
||||
at /pwd/lang/eval-fail-missing-arg.nix:1:2:
|
||||
|
||||
1| ({x, y, z}: x + y + z) {x = "foo"; z = "bar";}
|
||||
| ^
|
||||
2|
|
||||
|
|
14
tests/functional/lang/eval-fail-not-throws.err.exp
Normal file
14
tests/functional/lang/eval-fail-not-throws.err.exp
Normal file
|
@ -0,0 +1,14 @@
|
|||
error:
|
||||
… in the argument of the not operator
|
||||
at /pwd/lang/eval-fail-not-throws.nix:1:4:
|
||||
1| ! (throw "uh oh!")
|
||||
| ^
|
||||
2|
|
||||
|
||||
… while calling the 'throw' builtin
|
||||
at /pwd/lang/eval-fail-not-throws.nix:1:4:
|
||||
1| ! (throw "uh oh!")
|
||||
| ^
|
||||
2|
|
||||
|
||||
error: uh oh!
|
1
tests/functional/lang/eval-fail-not-throws.nix
Normal file
1
tests/functional/lang/eval-fail-not-throws.nix
Normal file
|
@ -0,0 +1 @@
|
|||
! (throw "uh oh!")
|
|
@ -1,7 +1,5 @@
|
|||
error: path has a trailing slash
|
||||
|
||||
at /pwd/lang/eval-fail-path-slash.nix:6:12:
|
||||
|
||||
5| # and https://nixos.org/nix-dev/2016-June/020829.html
|
||||
6| /nix/store/
|
||||
| ^
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
error:
|
||||
… in the right operand of the update (//) operator
|
||||
|
||||
at /pwd/lang/eval-fail-recursion.nix:1:12:
|
||||
|
||||
1| let a = {} // a; in a.foo
|
||||
| ^
|
||||
2|
|
||||
|
||||
error: infinite recursion encountered
|
||||
|
||||
at /pwd/lang/eval-fail-recursion.nix:1:15:
|
||||
|
||||
1| let a = {} // a; in a.foo
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
error:
|
||||
… while evaluating the attribute 'body'
|
||||
|
||||
at /pwd/lang/eval-fail-remove.nix:4:3:
|
||||
|
||||
3|
|
||||
4| body = (removeAttrs attrs ["x"]).x;
|
||||
| ^
|
||||
5| }
|
||||
|
||||
error: attribute 'x' missing
|
||||
|
||||
at /pwd/lang/eval-fail-remove.nix:4:10:
|
||||
|
||||
3|
|
||||
4| body = (removeAttrs attrs ["x"]).x;
|
||||
| ^
|
||||
|
|
|
@ -1,35 +1,27 @@
|
|||
error:
|
||||
… while evaluating the attribute 'body'
|
||||
|
||||
at /pwd/lang/eval-fail-scope-5.nix:8:3:
|
||||
|
||||
7|
|
||||
8| body = f {};
|
||||
| ^
|
||||
9|
|
||||
|
||||
… from call site
|
||||
|
||||
at /pwd/lang/eval-fail-scope-5.nix:8:10:
|
||||
|
||||
7|
|
||||
8| body = f {};
|
||||
| ^
|
||||
9|
|
||||
|
||||
… while calling 'f'
|
||||
|
||||
at /pwd/lang/eval-fail-scope-5.nix:6:7:
|
||||
|
||||
5|
|
||||
6| f = {x ? y, y ? x}: x + y;
|
||||
| ^
|
||||
7|
|
||||
|
||||
error: infinite recursion encountered
|
||||
|
||||
at /pwd/lang/eval-fail-scope-5.nix:6:12:
|
||||
|
||||
5|
|
||||
6| f = {x ? y, y ? x}: x + y;
|
||||
| ^
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
error:
|
||||
… while calling the 'seq' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-seq.nix:1:1:
|
||||
|
||||
1| builtins.seq (abort "foo") 2
|
||||
| ^
|
||||
2|
|
||||
|
||||
… while calling the 'abort' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-seq.nix:1:15:
|
||||
|
||||
1| builtins.seq (abort "foo") 2
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: undefined variable 'x'
|
||||
|
||||
at /pwd/lang/eval-fail-set.nix:1:3:
|
||||
|
||||
1| 8.x
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'substring' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-substring.nix:1:1:
|
||||
|
||||
1| builtins.substring (builtins.sub 0 1) 1 "x"
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
error:
|
||||
… while calling the 'toPath' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-to-path.nix:1:1:
|
||||
|
||||
1| builtins.toPath "foo/bar"
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,25 +1,19 @@
|
|||
error:
|
||||
… while calling the 'toJSON' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-toJSON.nix:1:1:
|
||||
|
||||
1| builtins.toJSON {
|
||||
| ^
|
||||
2| a.b = [
|
||||
|
||||
… while evaluating attribute 'a'
|
||||
|
||||
at /pwd/lang/eval-fail-toJSON.nix:2:3:
|
||||
|
||||
1| builtins.toJSON {
|
||||
2| a.b = [
|
||||
| ^
|
||||
3| true
|
||||
|
||||
… while evaluating attribute 'b'
|
||||
|
||||
at /pwd/lang/eval-fail-toJSON.nix:2:3:
|
||||
|
||||
1| builtins.toJSON {
|
||||
2| a.b = [
|
||||
| ^
|
||||
|
@ -28,27 +22,21 @@ error:
|
|||
… while evaluating list element at index 3
|
||||
|
||||
… while evaluating attribute 'c'
|
||||
|
||||
at /pwd/lang/eval-fail-toJSON.nix:7:7:
|
||||
|
||||
6| {
|
||||
7| c.d = throw "hah no";
|
||||
| ^
|
||||
8| }
|
||||
|
||||
… while evaluating attribute 'd'
|
||||
|
||||
at /pwd/lang/eval-fail-toJSON.nix:7:7:
|
||||
|
||||
6| {
|
||||
7| c.d = throw "hah no";
|
||||
| ^
|
||||
8| }
|
||||
|
||||
… while calling the 'throw' builtin
|
||||
|
||||
at /pwd/lang/eval-fail-toJSON.nix:7:13:
|
||||
|
||||
6| {
|
||||
7| c.d = throw "hah no";
|
||||
| ^
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
error:
|
||||
… from call site
|
||||
|
||||
at /pwd/lang/eval-fail-undeclared-arg.nix:1:1:
|
||||
|
||||
1| ({x, z}: x + z) {x = "foo"; y = "bla"; z = "bar";}
|
||||
| ^
|
||||
2|
|
||||
|
||||
error: function 'anonymous lambda' called with unexpected argument 'y'
|
||||
|
||||
at /pwd/lang/eval-fail-undeclared-arg.nix:1:2:
|
||||
|
||||
1| ({x, z}: x + z) {x = "foo"; y = "bla"; z = "bar";}
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
error:
|
||||
… while evaluating an attribute name
|
||||
at /pwd/lang/eval-fail-using-set-as-attr-name.nix:5:10:
|
||||
4| in
|
||||
5| attr.${key}
|
||||
| ^
|
||||
6|
|
||||
|
||||
error: value is a set while a string was expected
|
|
@ -0,0 +1,5 @@
|
|||
let
|
||||
attr = {foo = "bar";};
|
||||
key = {};
|
||||
in
|
||||
attr.${key}
|
108
tests/functional/lang/eval-okay-convertHash.err.exp
Normal file
108
tests/functional/lang/eval-okay-convertHash.err.exp
Normal file
|
@ -0,0 +1,108 @@
|
|||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
||||
warning: "base32" is a deprecated alias for hash format "nix32".
|
|
@ -1 +1 @@
|
|||
{ hashesBase16 = [ "d41d8cd98f00b204e9800998ecf8427e" "6c69ee7f211c640419d5366cc076ae46" "bb3438fbabd460ea6dbd27d153e2233b" "da39a3ee5e6b4b0d3255bfef95601890afd80709" "cd54e8568c1b37cf1e5badb0779bcbf382212189" "6d12e10b1d331dad210e47fd25d4f260802b7e77" "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" "900a4469df00ccbfd0c145c6d1e4b7953dd0afafadd7534e3a4019e8d38fc663" "ad0387b3bd8652f730ca46d25f9c170af0fd589f42e7f23f5a9e6412d97d7e56" "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" "9d0886f8c6b389398a16257bc79780fab9831c7fc11c8ab07fa732cb7b348feade382f92617c9c5305fefba0af02ab5fd39a587d330997ff5bd0db19f7666653" "21644b72aa259e5a588cd3afbafb1d4310f4889680f6c83b9d531596a5a284f34dbebff409d23bcc86aee6bad10c891606f075c6f4755cb536da27db5693f3a7" ]; hashesBase32 = [ "3y8bwfr609h3lh9ch0izcqq7fl" "26mrvc0v1nslch8r0w45zywsbc" "1v4gi57l97pmnylq6lmgxkhd5v" "143xibwh31h9bvxzalr0sjvbbvpa6ffs" "i4hj30pkrfdpgc5dbcgcydqviibfhm6d" "fxz2p030yba2bza71qhss79k3l5y24kd" "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73" "0qy6iz9yh6a079757mxdmypx0gcmnzjd3ij5q78bzk00vxll82lh" "0mkygpci4r4yb8zz5rs2kxcgvw0a2yf5zlj6r8qgfll6pnrqf0xd" "0zdl9zrg8r3i9c1g90lgg9ip5ijzv3yhz91i0zzn3r8ap9ws784gkp9dk9j3aglhgf1amqb0pj21mh7h1nxcl18akqvvf7ggqsy30yg" "19ncrpp37dx0nzzjw4k6zaqkb9mzaq2myhgpzh5aff7qqcj5wwdxslg6ixwncm7gyq8l761gwf87fgsh2bwfyr52s53k2dkqvw8c24x" "2kz74snvckxldmmbisz9ikmy031d28cs6xfdbl6rhxx42glpyz4vww4lajrc5akklxwixl0js4g84233pxvmbykiic5m7i5m9r4nr11" ]; hashesBase64 = [ "1B2M2Y8AsgTpgAmY7PhCfg==" "bGnufyEcZAQZ1TZswHauRg==" "uzQ4+6vUYOptvSfRU+IjOw==" "2jmj7l5rSw0yVb/vlWAYkK/YBwk=" "zVToVowbN88eW62wd5vL84IhIYk=" "bRLhCx0zHa0hDkf9JdTyYIArfnc=" "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" "kApEad8AzL/QwUXG0eS3lT3Qr6+t11NOOkAZ6NOPxmM=" "rQOHs72GUvcwykbSX5wXCvD9WJ9C5/I/Wp5kEtl9flY=" "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==" "nQiG+MaziTmKFiV7x5eA+rmDHH/BHIqwf6cyy3s0j+reOC+SYXycUwX++6CvAqtf05pYfTMJl/9b0NsZ92ZmUw==" "IWRLcqolnlpYjNOvuvsdQxD0iJaA9sg7nVMVlqWihPNNvr/0CdI7zIau5rrRDIkWBvB1xvR1XLU22ifbVpPzpw==" ]; hashesSRI = [ "md5-1B2M2Y8AsgTpgAmY7PhCfg==" "md5-bGnufyEcZAQZ1TZswHauRg==" "md5-uzQ4+6vUYOptvSfRU+IjOw==" "sha1-2jmj7l5rSw0yVb/vlWAYkK/YBwk=" "sha1-zVToVowbN88eW62wd5vL84IhIYk=" "sha1-bRLhCx0zHa0hDkf9JdTyYIArfnc=" "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" "sha256-kApEad8AzL/QwUXG0eS3lT3Qr6+t11NOOkAZ6NOPxmM=" "sha256-rQOHs72GUvcwykbSX5wXCvD9WJ9C5/I/Wp5kEtl9flY=" "sha512-z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==" "sha512-nQiG+MaziTmKFiV7x5eA+rmDHH/BHIqwf6cyy3s0j+reOC+SYXycUwX++6CvAqtf05pYfTMJl/9b0NsZ92ZmUw==" "sha512-IWRLcqolnlpYjNOvuvsdQxD0iJaA9sg7nVMVlqWihPNNvr/0CdI7zIau5rrRDIkWBvB1xvR1XLU22ifbVpPzpw==" ]; }
|
||||
{ hashesBase16 = [ "d41d8cd98f00b204e9800998ecf8427e" "6c69ee7f211c640419d5366cc076ae46" "bb3438fbabd460ea6dbd27d153e2233b" "da39a3ee5e6b4b0d3255bfef95601890afd80709" "cd54e8568c1b37cf1e5badb0779bcbf382212189" "6d12e10b1d331dad210e47fd25d4f260802b7e77" "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" "900a4469df00ccbfd0c145c6d1e4b7953dd0afafadd7534e3a4019e8d38fc663" "ad0387b3bd8652f730ca46d25f9c170af0fd589f42e7f23f5a9e6412d97d7e56" "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" "9d0886f8c6b389398a16257bc79780fab9831c7fc11c8ab07fa732cb7b348feade382f92617c9c5305fefba0af02ab5fd39a587d330997ff5bd0db19f7666653" "21644b72aa259e5a588cd3afbafb1d4310f4889680f6c83b9d531596a5a284f34dbebff409d23bcc86aee6bad10c891606f075c6f4755cb536da27db5693f3a7" ]; hashesBase32 = [ "3y8bwfr609h3lh9ch0izcqq7fl" "26mrvc0v1nslch8r0w45zywsbc" "1v4gi57l97pmnylq6lmgxkhd5v" "143xibwh31h9bvxzalr0sjvbbvpa6ffs" "i4hj30pkrfdpgc5dbcgcydqviibfhm6d" "fxz2p030yba2bza71qhss79k3l5y24kd" "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73" "0qy6iz9yh6a079757mxdmypx0gcmnzjd3ij5q78bzk00vxll82lh" "0mkygpci4r4yb8zz5rs2kxcgvw0a2yf5zlj6r8qgfll6pnrqf0xd" "0zdl9zrg8r3i9c1g90lgg9ip5ijzv3yhz91i0zzn3r8ap9ws784gkp9dk9j3aglhgf1amqb0pj21mh7h1nxcl18akqvvf7ggqsy30yg" "19ncrpp37dx0nzzjw4k6zaqkb9mzaq2myhgpzh5aff7qqcj5wwdxslg6ixwncm7gyq8l761gwf87fgsh2bwfyr52s53k2dkqvw8c24x" "2kz74snvckxldmmbisz9ikmy031d28cs6xfdbl6rhxx42glpyz4vww4lajrc5akklxwixl0js4g84233pxvmbykiic5m7i5m9r4nr11" ]; hashesBase64 = [ "1B2M2Y8AsgTpgAmY7PhCfg==" "bGnufyEcZAQZ1TZswHauRg==" "uzQ4+6vUYOptvSfRU+IjOw==" "2jmj7l5rSw0yVb/vlWAYkK/YBwk=" "zVToVowbN88eW62wd5vL84IhIYk=" "bRLhCx0zHa0hDkf9JdTyYIArfnc=" "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" "kApEad8AzL/QwUXG0eS3lT3Qr6+t11NOOkAZ6NOPxmM=" "rQOHs72GUvcwykbSX5wXCvD9WJ9C5/I/Wp5kEtl9flY=" "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==" "nQiG+MaziTmKFiV7x5eA+rmDHH/BHIqwf6cyy3s0j+reOC+SYXycUwX++6CvAqtf05pYfTMJl/9b0NsZ92ZmUw==" "IWRLcqolnlpYjNOvuvsdQxD0iJaA9sg7nVMVlqWihPNNvr/0CdI7zIau5rrRDIkWBvB1xvR1XLU22ifbVpPzpw==" ]; hashesNix32 = [ "3y8bwfr609h3lh9ch0izcqq7fl" "26mrvc0v1nslch8r0w45zywsbc" "1v4gi57l97pmnylq6lmgxkhd5v" "143xibwh31h9bvxzalr0sjvbbvpa6ffs" "i4hj30pkrfdpgc5dbcgcydqviibfhm6d" "fxz2p030yba2bza71qhss79k3l5y24kd" "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73" "0qy6iz9yh6a079757mxdmypx0gcmnzjd3ij5q78bzk00vxll82lh" "0mkygpci4r4yb8zz5rs2kxcgvw0a2yf5zlj6r8qgfll6pnrqf0xd" "0zdl9zrg8r3i9c1g90lgg9ip5ijzv3yhz91i0zzn3r8ap9ws784gkp9dk9j3aglhgf1amqb0pj21mh7h1nxcl18akqvvf7ggqsy30yg" "19ncrpp37dx0nzzjw4k6zaqkb9mzaq2myhgpzh5aff7qqcj5wwdxslg6ixwncm7gyq8l761gwf87fgsh2bwfyr52s53k2dkqvw8c24x" "2kz74snvckxldmmbisz9ikmy031d28cs6xfdbl6rhxx42glpyz4vww4lajrc5akklxwixl0js4g84233pxvmbykiic5m7i5m9r4nr11" ]; hashesSRI = [ "md5-1B2M2Y8AsgTpgAmY7PhCfg==" "md5-bGnufyEcZAQZ1TZswHauRg==" "md5-uzQ4+6vUYOptvSfRU+IjOw==" "sha1-2jmj7l5rSw0yVb/vlWAYkK/YBwk=" "sha1-zVToVowbN88eW62wd5vL84IhIYk=" "sha1-bRLhCx0zHa0hDkf9JdTyYIArfnc=" "sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" "sha256-kApEad8AzL/QwUXG0eS3lT3Qr6+t11NOOkAZ6NOPxmM=" "sha256-rQOHs72GUvcwykbSX5wXCvD9WJ9C5/I/Wp5kEtl9flY=" "sha512-z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==" "sha512-nQiG+MaziTmKFiV7x5eA+rmDHH/BHIqwf6cyy3s0j+reOC+SYXycUwX++6CvAqtf05pYfTMJl/9b0NsZ92ZmUw==" "sha512-IWRLcqolnlpYjNOvuvsdQxD0iJaA9sg7nVMVlqWihPNNvr/0CdI7zIau5rrRDIkWBvB1xvR1XLU22ifbVpPzpw==" ]; }
|
||||
|
|
|
@ -5,12 +5,14 @@ let
|
|||
map2' = f: fsts: snds: map2 f { inherit fsts snds; };
|
||||
getOutputHashes = hashes: {
|
||||
hashesBase16 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base16";}) hashAlgos hashes;
|
||||
hashesNix32 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "nix32";}) hashAlgos hashes;
|
||||
hashesBase32 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base32";}) hashAlgos hashes;
|
||||
hashesBase64 = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base64";}) hashAlgos hashes;
|
||||
hashesSRI = map2' (hashAlgo: hash: builtins.convertHash { inherit hash hashAlgo; toHashFormat = "sri" ;}) hashAlgos hashes;
|
||||
};
|
||||
getOutputHashesColon = hashes: {
|
||||
hashesBase16 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "base16";}) hashAlgos hashes;
|
||||
hashesNix32 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "nix32";}) hashAlgos hashes;
|
||||
hashesBase32 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "base32";}) hashAlgos hashes;
|
||||
hashesBase64 = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "base64";}) hashAlgos hashes;
|
||||
hashesSRI = map2' (hashAlgo: hashBody: builtins.convertHash { hash = hashAlgo + ":" + hashBody; toHashFormat = "sri" ;}) hashAlgos hashes;
|
||||
|
|
1
tests/functional/lang/eval-okay-symlink-resolution.exp
Normal file
1
tests/functional/lang/eval-okay-symlink-resolution.exp
Normal file
|
@ -0,0 +1 @@
|
|||
"test"
|
1
tests/functional/lang/eval-okay-symlink-resolution.nix
Normal file
1
tests/functional/lang/eval-okay-symlink-resolution.nix
Normal file
|
@ -0,0 +1 @@
|
|||
import symlink-resolution/foo/overlays/overlay.nix
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'x' already defined at «stdin»:1:3
|
||||
|
||||
at «stdin»:3:3:
|
||||
|
||||
2| y = 456;
|
||||
3| x = 789;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'x' already defined at «stdin»:9:5
|
||||
|
||||
at «stdin»:10:17:
|
||||
|
||||
9| x = 789;
|
||||
10| inherit (as) x;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'x' already defined at «stdin»:9:5
|
||||
|
||||
at «stdin»:10:17:
|
||||
|
||||
9| x = 789;
|
||||
10| inherit (as) x;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'services.ssh.port' already defined at «stdin»:2:3
|
||||
|
||||
at «stdin»:3:3:
|
||||
|
||||
2| services.ssh.port = 22;
|
||||
3| services.ssh.port = 23;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'x' already defined at «stdin»:6:12
|
||||
|
||||
at «stdin»:7:12:
|
||||
|
||||
6| inherit x;
|
||||
7| inherit x;
|
||||
| ^
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
error: duplicate formal function argument 'x'
|
||||
|
||||
at «stdin»:1:8:
|
||||
|
||||
1| {x, y, x}: x
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: syntax error, unexpected end of file, expecting '"'
|
||||
|
||||
at «stdin»:3:5:
|
||||
|
||||
2| # Note that this file must not end with a newline.
|
||||
3| a 1"$
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'z' already defined at «stdin»:3:16
|
||||
|
||||
at «stdin»:2:3:
|
||||
|
||||
1| {
|
||||
2| x.z = 3;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: attribute 'y' already defined at «stdin»:3:9
|
||||
|
||||
at «stdin»:2:3:
|
||||
|
||||
1| {
|
||||
2| x.y.y = 3;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: duplicate formal function argument 'args'
|
||||
|
||||
at «stdin»:1:1:
|
||||
|
||||
1| args@{args, x, y, z}: x
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: undefined variable 'gcc'
|
||||
|
||||
at «stdin»:8:12:
|
||||
|
||||
7|
|
||||
8| body = ({
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: syntax error, unexpected ':', expecting '}'
|
||||
|
||||
at «stdin»:3:13:
|
||||
|
||||
2|
|
||||
3| f = {x, y :
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
error: undefined variable 'y'
|
||||
|
||||
at «stdin»:1:4:
|
||||
|
||||
1| x: y
|
||||
| ^
|
||||
2|
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
error: syntax error, unexpected invalid token, expecting end of file
|
||||
|
||||
at «stdin»:1:5:
|
||||
|
||||
1| 123 Ã
|
||||
| ^
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"test"
|
1
tests/functional/lang/symlink-resolution/foo/overlays
Symbolic link
1
tests/functional/lang/symlink-resolution/foo/overlays
Symbolic link
|
@ -0,0 +1 @@
|
|||
../overlays
|
|
@ -0,0 +1 @@
|
|||
import ../lib
|
|
@ -69,7 +69,9 @@ nix_tests = \
|
|||
build-remote-trustless-should-pass-2.sh \
|
||||
build-remote-trustless-should-pass-3.sh \
|
||||
build-remote-trustless-should-fail-0.sh \
|
||||
build-remote-with-mounted-ssh-ng.sh \
|
||||
nar-access.sh \
|
||||
impure-eval.sh \
|
||||
pure-eval.sh \
|
||||
eval.sh \
|
||||
repl.sh \
|
||||
|
@ -139,9 +141,9 @@ ifeq ($(ENABLE_BUILD), yes)
|
|||
endif
|
||||
|
||||
$(d)/test-libstoreconsumer.sh.test $(d)/test-libstoreconsumer.sh.test-debug: \
|
||||
$(d)/test-libstoreconsumer/test-libstoreconsumer
|
||||
$(buildprefix)$(d)/test-libstoreconsumer/test-libstoreconsumer
|
||||
$(d)/plugins.sh.test $(d)/plugins.sh.test-debug: \
|
||||
$(d)/plugins/libplugintest.$(SO_EXT)
|
||||
$(buildprefix)$(d)/plugins/libplugintest.$(SO_EXT)
|
||||
|
||||
install-tests += $(foreach x, $(nix_tests), $(d)/$(x))
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ nix-build dependencies.nix --no-out-link --compress-build-log
|
|||
[ "$(nix-store -l $path)" = FOO ]
|
||||
|
||||
# test whether empty logs work fine with `nix log`.
|
||||
builder="$(mktemp)"
|
||||
builder="$(realpath "$(mktemp)")"
|
||||
echo -e "#!/bin/sh\nmkdir \$out" > "$builder"
|
||||
outp="$(nix-build -E \
|
||||
'with import ./config.nix; mkDerivation { name = "fnord"; builder = '"$builder"'; }' \
|
||||
|
|
70
tests/functional/nix-copy-ssh-common.sh
Normal file
70
tests/functional/nix-copy-ssh-common.sh
Normal file
|
@ -0,0 +1,70 @@
|
|||
proto=$1
|
||||
shift
|
||||
(( $# == 0 ))
|
||||
|
||||
clearStore
|
||||
clearCache
|
||||
|
||||
mkdir -p $TEST_ROOT/stores
|
||||
|
||||
# Create path to copy back and forth
|
||||
outPath=$(nix-build --no-out-link dependencies.nix)
|
||||
|
||||
storeQueryParam="store=${NIX_STORE_DIR}"
|
||||
|
||||
realQueryParam () {
|
||||
echo "real=$1$NIX_STORE_DIR"
|
||||
}
|
||||
|
||||
remoteRoot="$TEST_ROOT/stores/$proto"
|
||||
|
||||
clearRemoteStore () {
|
||||
chmod -R u+w "$remoteRoot" || true
|
||||
rm -rf "$remoteRoot"
|
||||
}
|
||||
|
||||
clearRemoteStore
|
||||
|
||||
remoteStore="${proto}://localhost?${storeQueryParam}&remote-store=${remoteRoot}%3f${storeQueryParam}%26$(realQueryParam "$remoteRoot")"
|
||||
|
||||
# Copy to store
|
||||
|
||||
args=()
|
||||
if [[ "$proto" == "ssh-ng" ]]; then
|
||||
# TODO investigate discrepancy
|
||||
args+=(--no-check-sigs)
|
||||
fi
|
||||
|
||||
[ ! -f ${remoteRoot}${outPath}/foobar ]
|
||||
nix copy "${args[@]}" --to "$remoteStore" $outPath
|
||||
[ -f ${remoteRoot}${outPath}/foobar ]
|
||||
|
||||
# Copy back from store
|
||||
|
||||
clearStore
|
||||
|
||||
[ ! -f $outPath/foobar ]
|
||||
nix copy --no-check-sigs --from "$remoteStore" $outPath
|
||||
[ -f $outPath/foobar ]
|
||||
|
||||
# Check --substitute-on-destination, avoid corrupted store
|
||||
|
||||
clearRemoteStore
|
||||
|
||||
corruptedRoot=$TEST_ROOT/stores/corrupted
|
||||
corruptedStore="${corruptedRoot}?${storeQueryParam}&$(realQueryParam "$corruptedRoot")"
|
||||
|
||||
# Copy it to the corrupted store
|
||||
nix copy --no-check-sigs "$outPath" --to "$corruptedStore"
|
||||
|
||||
# Corrupt it in there
|
||||
corruptPath="${corruptedRoot}${outPath}"
|
||||
chmod +w "$corruptPath"
|
||||
echo "not supposed to be here" > "$corruptPath/foobarbaz"
|
||||
chmod -w "$corruptPath"
|
||||
|
||||
# Copy from the corrupted store with the regular store as a
|
||||
# substituter. It must use the substituter not the source store in
|
||||
# order to avoid errors.
|
||||
NIX_CONFIG=$(echo -e "substituters = local\nrequire-sigs = false") \
|
||||
nix copy --no-check-sigs --from "$corruptedStore" --to "$remoteStore" --substitute-on-destination "$outPath"
|
|
@ -1,18 +1,14 @@
|
|||
source common.sh
|
||||
|
||||
clearStore
|
||||
clearCache
|
||||
source nix-copy-ssh-common.sh "ssh-ng"
|
||||
|
||||
remoteRoot=$TEST_ROOT/store2
|
||||
chmod -R u+w "$remoteRoot" || true
|
||||
rm -rf "$remoteRoot"
|
||||
clearStore
|
||||
clearRemoteStore
|
||||
|
||||
outPath=$(nix-build --no-out-link dependencies.nix)
|
||||
|
||||
nix store info --store "ssh-ng://localhost?store=$NIX_STORE_DIR&remote-store=$remoteRoot%3fstore=$NIX_STORE_DIR%26real=$remoteRoot$NIX_STORE_DIR"
|
||||
nix store info --store "$remoteStore"
|
||||
|
||||
# Regression test for https://github.com/NixOS/nix/issues/6253
|
||||
nix copy --to "ssh-ng://localhost?store=$NIX_STORE_DIR&remote-store=$remoteRoot%3fstore=$NIX_STORE_DIR%26real=$remoteRoot$NIX_STORE_DIR" $outPath --no-check-sigs &
|
||||
nix copy --to "ssh-ng://localhost?store=$NIX_STORE_DIR&remote-store=$remoteRoot%3fstore=$NIX_STORE_DIR%26real=$remoteRoot$NIX_STORE_DIR" $outPath --no-check-sigs
|
||||
|
||||
[ -f $remoteRoot$outPath/foobar ]
|
||||
nix copy --to "$remoteStore" $outPath --no-check-sigs &
|
||||
nix copy --to "$remoteStore" $outPath --no-check-sigs
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
source common.sh
|
||||
|
||||
clearStore
|
||||
clearCache
|
||||
|
||||
remoteRoot=$TEST_ROOT/store2
|
||||
chmod -R u+w "$remoteRoot" || true
|
||||
rm -rf "$remoteRoot"
|
||||
|
||||
outPath=$(nix-build --no-out-link dependencies.nix)
|
||||
|
||||
nix copy --to "ssh://localhost?store=$NIX_STORE_DIR&remote-store=$remoteRoot%3fstore=$NIX_STORE_DIR%26real=$remoteRoot$NIX_STORE_DIR" $outPath
|
||||
|
||||
[ -f $remoteRoot$outPath/foobar ]
|
||||
|
||||
clearStore
|
||||
|
||||
nix copy --no-check-sigs --from "ssh://localhost?store=$NIX_STORE_DIR&remote-store=$remoteRoot%3fstore=$NIX_STORE_DIR%26real=$remoteRoot$NIX_STORE_DIR" $outPath
|
||||
|
||||
[ -f $outPath/foobar ]
|
||||
source nix-copy-ssh-common.sh "ssh"
|
||||
|
|
|
@ -14,8 +14,8 @@ nix-instantiate --restrict-eval --eval -E 'builtins.readFile ./simple.nix' -I sr
|
|||
(! nix-instantiate --restrict-eval --eval -E 'builtins.readDir ../../src/nix-channel')
|
||||
nix-instantiate --restrict-eval --eval -E 'builtins.readDir ../../src/nix-channel' -I src=../../src
|
||||
|
||||
(! nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in <foo>')
|
||||
nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in <foo>' -I src=.
|
||||
expectStderr 1 nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile <foo/simple.nix>' | grepQuiet "forbidden in restricted mode"
|
||||
nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile <foo/simple.nix>' -I src=.
|
||||
|
||||
p=$(nix eval --raw --expr "builtins.fetchurl file://$(pwd)/restricted.sh" --impure --restrict-eval --allowed-uris "file://$(pwd)")
|
||||
cmp $p restricted.sh
|
||||
|
@ -39,6 +39,18 @@ nix-instantiate --eval --restrict-eval $TEST_ROOT/restricted.nix -I $TEST_ROOT -
|
|||
|
||||
[[ $(nix eval --raw --impure --restrict-eval -I . --expr 'builtins.readFile "${import ./simple.nix}/hello"') == 'Hello World!' ]]
|
||||
|
||||
# Check that we can't follow a symlink outside of the allowed paths.
|
||||
mkdir -p $TEST_ROOT/tunnel.d $TEST_ROOT/foo2
|
||||
ln -sfn .. $TEST_ROOT/tunnel.d/tunnel
|
||||
echo foo > $TEST_ROOT/bar
|
||||
|
||||
expectStderr 1 nix-instantiate --restrict-eval --eval -E "let __nixPath = [ { prefix = \"foo\"; path = $TEST_ROOT/tunnel.d; } ]; in builtins.readFile <foo/tunnel/bar>" -I $TEST_ROOT/tunnel.d | grepQuiet "forbidden in restricted mode"
|
||||
|
||||
expectStderr 1 nix-instantiate --restrict-eval --eval -E "let __nixPath = [ { prefix = \"foo\"; path = $TEST_ROOT/tunnel.d; } ]; in builtins.readDir <foo/tunnel/foo2>" -I $TEST_ROOT/tunnel.d | grepQuiet "forbidden in restricted mode"
|
||||
|
||||
# Reading the parents of allowed paths should show only the ancestors of the allowed paths.
|
||||
[[ $(nix-instantiate --restrict-eval --eval -E "let __nixPath = [ { prefix = \"foo\"; path = $TEST_ROOT/tunnel.d; } ]; in builtins.readDir <foo/tunnel>" -I $TEST_ROOT/tunnel.d) == '{ "tunnel.d" = "directory"; }' ]]
|
||||
|
||||
# Check whether we can leak symlink information through directory traversal.
|
||||
traverseDir="$(pwd)/restricted-traverse-me"
|
||||
ln -sfn "$(pwd)/restricted-secret" "$(pwd)/restricted-innocent"
|
||||
|
|
|
@ -26,6 +26,7 @@ nix-env -f ./user-envs.nix -qa --json --out-path | jq -e '.[] | select(.name ==
|
|||
.outputName == "out",
|
||||
(.outputs.out | test("'$NIX_STORE_DIR'.*-0\\.1"))
|
||||
] | all'
|
||||
nix-env -f ./user-envs.nix -qa --json --drv-path | jq -e '.[] | select(.name == "bar-0.1") | (.drvPath | test("'$NIX_STORE_DIR'.*-0\\.1\\.drv"))'
|
||||
|
||||
# Query descriptions.
|
||||
nix-env -f ./user-envs.nix -qa '*' --description | grepQuiet silly
|
||||
|
|
|
@ -10,6 +10,7 @@ let
|
|||
hostPkgs = nixpkgsFor.${system}.native;
|
||||
defaults = {
|
||||
nixpkgs.pkgs = nixpkgsFor.${system}.native;
|
||||
nix.checkAllErrors = false;
|
||||
};
|
||||
_module.args.nixpkgs = nixpkgs;
|
||||
};
|
||||
|
@ -21,6 +22,8 @@ in
|
|||
|
||||
remoteBuilds = runNixOSTestFor "x86_64-linux" ./remote-builds.nix;
|
||||
|
||||
remoteBuildsSshNg = runNixOSTestFor "x86_64-linux" ./remote-builds-ssh-ng.nix;
|
||||
|
||||
nix-copy-closure = runNixOSTestFor "x86_64-linux" ./nix-copy-closure.nix;
|
||||
|
||||
nix-copy = runNixOSTestFor "x86_64-linux" ./nix-copy.nix;
|
||||
|
|
|
@ -144,7 +144,7 @@ in
|
|||
virtualisation.memorySize = 4096;
|
||||
nix.settings.substituters = lib.mkForce [ ];
|
||||
nix.extraOptions = "experimental-features = nix-command flakes";
|
||||
networking.hosts.${(builtins.head nodes.github.config.networking.interfaces.eth1.ipv4.addresses).address} =
|
||||
networking.hosts.${(builtins.head nodes.github.networking.interfaces.eth1.ipv4.addresses).address} =
|
||||
[ "channels.nixos.org" "api.github.com" "github.com" ];
|
||||
security.pki.certificateFiles = [ "${cert}/ca.crt" ];
|
||||
};
|
||||
|
|
|
@ -36,7 +36,7 @@ in {
|
|||
server =
|
||||
{ config, pkgs, ... }:
|
||||
{ services.openssh.enable = true;
|
||||
services.openssh.permitRootLogin = "yes";
|
||||
services.openssh.settings.PermitRootLogin = "yes";
|
||||
users.users.root.password = "foobar";
|
||||
virtualisation.writableStore = true;
|
||||
virtualisation.additionalPaths = [ pkgB pkgC ];
|
||||
|
|
|
@ -84,8 +84,8 @@ in
|
|||
client = { lib, nodes, pkgs, ... }: {
|
||||
networking.useDHCP = false;
|
||||
networking.nameservers = [
|
||||
(lib.head nodes.http_dns.config.networking.interfaces.eth1.ipv6.addresses).address
|
||||
(lib.head nodes.http_dns.config.networking.interfaces.eth1.ipv4.addresses).address
|
||||
(lib.head nodes.http_dns.networking.interfaces.eth1.ipv6.addresses).address
|
||||
(lib.head nodes.http_dns.networking.interfaces.eth1.ipv4.addresses).address
|
||||
];
|
||||
networking.interfaces.eth1.ipv6.addresses = [
|
||||
{ address = "fd21::10"; prefixLength = 64; }
|
||||
|
|
108
tests/nixos/remote-builds-ssh-ng.nix
Normal file
108
tests/nixos/remote-builds-ssh-ng.nix
Normal file
|
@ -0,0 +1,108 @@
|
|||
{ config, lib, hostPkgs, ... }:
|
||||
|
||||
let
|
||||
pkgs = config.nodes.client.nixpkgs.pkgs;
|
||||
|
||||
# Trivial Nix expression to build remotely.
|
||||
expr = config: nr: pkgs.writeText "expr.nix"
|
||||
''
|
||||
let utils = builtins.storePath ${config.system.build.extraUtils}; in
|
||||
derivation {
|
||||
name = "hello-${toString nr}";
|
||||
system = "i686-linux";
|
||||
PATH = "''${utils}/bin";
|
||||
builder = "''${utils}/bin/sh";
|
||||
args = [ "-c" "${
|
||||
lib.concatStringsSep "; " [
|
||||
''if [[ -n $NIX_LOG_FD ]]''
|
||||
''then echo '@nix {\"action\":\"setPhase\",\"phase\":\"buildPhase\"}' >&''$NIX_LOG_FD''
|
||||
"fi"
|
||||
"echo Hello"
|
||||
"mkdir $out"
|
||||
"cat /proc/sys/kernel/hostname > $out/host"
|
||||
]
|
||||
}" ];
|
||||
outputs = [ "out" ];
|
||||
}
|
||||
'';
|
||||
in
|
||||
|
||||
{
|
||||
name = "remote-builds-ssh-ng";
|
||||
|
||||
nodes =
|
||||
{ builder =
|
||||
{ config, pkgs, ... }:
|
||||
{ services.openssh.enable = true;
|
||||
virtualisation.writableStore = true;
|
||||
nix.settings.sandbox = true;
|
||||
nix.settings.substituters = lib.mkForce [ ];
|
||||
};
|
||||
|
||||
client =
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ nix.settings.max-jobs = 0; # force remote building
|
||||
nix.distributedBuilds = true;
|
||||
nix.buildMachines =
|
||||
[ { hostName = "builder";
|
||||
sshUser = "root";
|
||||
sshKey = "/root/.ssh/id_ed25519";
|
||||
system = "i686-linux";
|
||||
maxJobs = 1;
|
||||
protocol = "ssh-ng";
|
||||
}
|
||||
];
|
||||
virtualisation.writableStore = true;
|
||||
virtualisation.additionalPaths = [ config.system.build.extraUtils ];
|
||||
nix.settings.substituters = lib.mkForce [ ];
|
||||
programs.ssh.extraConfig = "ConnectTimeout 30";
|
||||
};
|
||||
};
|
||||
|
||||
testScript = { nodes }: ''
|
||||
# fmt: off
|
||||
import subprocess
|
||||
|
||||
start_all()
|
||||
|
||||
# Create an SSH key on the client.
|
||||
subprocess.run([
|
||||
"${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", ""
|
||||
], capture_output=True, check=True)
|
||||
client.succeed("mkdir -p -m 700 /root/.ssh")
|
||||
client.copy_from_host("key", "/root/.ssh/id_ed25519")
|
||||
client.succeed("chmod 600 /root/.ssh/id_ed25519")
|
||||
|
||||
# Install the SSH key on the builder.
|
||||
client.wait_for_unit("network.target")
|
||||
builder.succeed("mkdir -p -m 700 /root/.ssh")
|
||||
builder.copy_from_host("key.pub", "/root/.ssh/authorized_keys")
|
||||
builder.wait_for_unit("sshd")
|
||||
client.succeed(f"ssh -o StrictHostKeyChecking=no {builder.name} 'echo hello world'")
|
||||
|
||||
# Perform a build
|
||||
out = client.succeed("nix-build ${expr nodes.client 1} 2> build-output")
|
||||
|
||||
# Verify that the build was done on the builder
|
||||
builder.succeed(f"test -e {out.strip()}")
|
||||
|
||||
# Print the build log, prefix the log lines to avoid nix intercepting lines starting with @nix
|
||||
buildOutput = client.succeed("sed -e 's/^/build-output:/' build-output")
|
||||
print(buildOutput)
|
||||
|
||||
# Make sure that we get the expected build output
|
||||
client.succeed("grep -qF Hello build-output")
|
||||
|
||||
# We don't want phase reporting in the build output
|
||||
client.fail("grep -qF '@nix' build-output")
|
||||
|
||||
# Get the log file
|
||||
client.succeed(f"nix-store --read-log {out.strip()} > log-output")
|
||||
# Prefix the log lines to avoid nix intercepting lines starting with @nix
|
||||
logOutput = client.succeed("sed -e 's/^/log-file:/' log-output")
|
||||
print(logOutput)
|
||||
|
||||
# Check that we get phase reporting in the log file
|
||||
client.succeed("grep -q '@nix {\"action\":\"setPhase\",\"phase\":\"buildPhase\"}' log-output")
|
||||
'';
|
||||
}
|
|
@ -90,22 +90,22 @@ in
|
|||
|
||||
# Perform a build and check that it was performed on the builder.
|
||||
out = client.succeed(
|
||||
"nix-build ${expr nodes.client.config 1} 2> build-output",
|
||||
"nix-build ${expr nodes.client 1} 2> build-output",
|
||||
"grep -q Hello build-output"
|
||||
)
|
||||
builder1.succeed(f"test -e {out}")
|
||||
|
||||
# And a parallel build.
|
||||
paths = client.succeed(r'nix-store -r $(nix-instantiate ${expr nodes.client.config 2})\!out $(nix-instantiate ${expr nodes.client.config 3})\!out')
|
||||
paths = client.succeed(r'nix-store -r $(nix-instantiate ${expr nodes.client 2})\!out $(nix-instantiate ${expr nodes.client 3})\!out')
|
||||
out1, out2 = paths.split()
|
||||
builder1.succeed(f"test -e {out1} -o -e {out2}")
|
||||
builder2.succeed(f"test -e {out1} -o -e {out2}")
|
||||
|
||||
# And a failing build.
|
||||
client.fail("nix-build ${expr nodes.client.config 5}")
|
||||
client.fail("nix-build ${expr nodes.client 5}")
|
||||
|
||||
# Test whether the build hook automatically skips unavailable builders.
|
||||
builder1.block()
|
||||
client.succeed("nix-build ${expr nodes.client.config 4}")
|
||||
client.succeed("nix-build ${expr nodes.client 4}")
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ in
|
|||
flake-registry = https://git.sr.ht/~NixOS/flake-registry/blob/master/flake-registry.json
|
||||
'';
|
||||
environment.systemPackages = [ pkgs.jq ];
|
||||
networking.hosts.${(builtins.head nodes.sourcehut.config.networking.interfaces.eth1.ipv4.addresses).address} =
|
||||
networking.hosts.${(builtins.head nodes.sourcehut.networking.interfaces.eth1.ipv4.addresses).address} =
|
||||
[ "git.sr.ht" ];
|
||||
security.pki.certificateFiles = [ "${cert}/ca.crt" ];
|
||||
};
|
||||
|
|
23
tests/unit/libexpr-support/local.mk
Normal file
23
tests/unit/libexpr-support/local.mk
Normal file
|
@ -0,0 +1,23 @@
|
|||
libraries += libexpr-test-support
|
||||
|
||||
libexpr-test-support_NAME = libnixexpr-test-support
|
||||
|
||||
libexpr-test-support_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libexpr-test-support_INSTALL_DIR := $(checklibdir)
|
||||
else
|
||||
libexpr-test-support_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libexpr-test-support_SOURCES := \
|
||||
$(wildcard $(d)/tests/*.cc) \
|
||||
$(wildcard $(d)/tests/value/*.cc)
|
||||
|
||||
libexpr-test-support_CXXFLAGS += $(libexpr-tests_EXTRA_INCLUDES)
|
||||
|
||||
libexpr-test-support_LIBS = \
|
||||
libstore-test-support libutil-test-support \
|
||||
libexpr libstore libutil
|
||||
|
||||
libexpr-test-support_LDFLAGS := -pthread -lrapidcheck
|
145
tests/unit/libexpr-support/tests/libexpr.hh
Normal file
145
tests/unit/libexpr-support/tests/libexpr.hh
Normal file
|
@ -0,0 +1,145 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "value.hh"
|
||||
#include "nixexpr.hh"
|
||||
#include "eval.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
#include "tests/libstore.hh"
|
||||
|
||||
namespace nix {
|
||||
class LibExprTest : public LibStoreTest {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
LibStoreTest::SetUpTestSuite();
|
||||
initGC();
|
||||
evalSettings.nixPath = {};
|
||||
}
|
||||
|
||||
protected:
|
||||
LibExprTest()
|
||||
: LibStoreTest()
|
||||
, state({}, store)
|
||||
{
|
||||
}
|
||||
Value eval(std::string input, bool forceValue = true) {
|
||||
Value v;
|
||||
Expr * e = state.parseExprFromString(input, state.rootPath(CanonPath::root));
|
||||
assert(e);
|
||||
state.eval(e, v);
|
||||
if (forceValue)
|
||||
state.forceValue(v, noPos);
|
||||
return v;
|
||||
}
|
||||
|
||||
Symbol createSymbol(const char * value) {
|
||||
return state.symbols.create(value);
|
||||
}
|
||||
|
||||
EvalState state;
|
||||
};
|
||||
|
||||
MATCHER(IsListType, "") {
|
||||
return arg != nList;
|
||||
}
|
||||
|
||||
MATCHER(IsList, "") {
|
||||
return arg.type() == nList;
|
||||
}
|
||||
|
||||
MATCHER(IsString, "") {
|
||||
return arg.type() == nString;
|
||||
}
|
||||
|
||||
MATCHER(IsNull, "") {
|
||||
return arg.type() == nNull;
|
||||
}
|
||||
|
||||
MATCHER(IsThunk, "") {
|
||||
return arg.type() == nThunk;
|
||||
}
|
||||
|
||||
MATCHER(IsAttrs, "") {
|
||||
return arg.type() == nAttrs;
|
||||
}
|
||||
|
||||
MATCHER_P(IsStringEq, s, fmt("The string is equal to \"%1%\"", s)) {
|
||||
if (arg.type() != nString) {
|
||||
return false;
|
||||
}
|
||||
return std::string_view(arg.c_str()) == s;
|
||||
}
|
||||
|
||||
MATCHER_P(IsIntEq, v, fmt("The string is equal to \"%1%\"", v)) {
|
||||
if (arg.type() != nInt) {
|
||||
return false;
|
||||
}
|
||||
return arg.integer == v;
|
||||
}
|
||||
|
||||
MATCHER_P(IsFloatEq, v, fmt("The float is equal to \"%1%\"", v)) {
|
||||
if (arg.type() != nFloat) {
|
||||
return false;
|
||||
}
|
||||
return arg.fpoint == v;
|
||||
}
|
||||
|
||||
MATCHER(IsTrue, "") {
|
||||
if (arg.type() != nBool) {
|
||||
return false;
|
||||
}
|
||||
return arg.boolean == true;
|
||||
}
|
||||
|
||||
MATCHER(IsFalse, "") {
|
||||
if (arg.type() != nBool) {
|
||||
return false;
|
||||
}
|
||||
return arg.boolean == false;
|
||||
}
|
||||
|
||||
MATCHER_P(IsPathEq, p, fmt("Is a path equal to \"%1%\"", p)) {
|
||||
if (arg.type() != nPath) {
|
||||
*result_listener << "Expected a path got " << arg.type();
|
||||
return false;
|
||||
} else {
|
||||
auto path = arg.path();
|
||||
if (path.path != CanonPath(p)) {
|
||||
*result_listener << "Expected a path that equals \"" << p << "\" but got: " << path.path;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
MATCHER_P(IsListOfSize, n, fmt("Is a list of size [%1%]", n)) {
|
||||
if (arg.type() != nList) {
|
||||
*result_listener << "Expected list got " << arg.type();
|
||||
return false;
|
||||
} else if (arg.listSize() != (size_t)n) {
|
||||
*result_listener << "Expected as list of size " << n << " got " << arg.listSize();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MATCHER_P(IsAttrsOfSize, n, fmt("Is a set of size [%1%]", n)) {
|
||||
if (arg.type() != nAttrs) {
|
||||
*result_listener << "Expected set got " << arg.type();
|
||||
return false;
|
||||
} else if (arg.attrs->size() != (size_t)n) {
|
||||
*result_listener << "Expected a set with " << n << " attributes but got " << arg.attrs->size();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace nix */
|
30
tests/unit/libexpr-support/tests/value/context.cc
Normal file
30
tests/unit/libexpr-support/tests/value/context.cc
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <rapidcheck.h>
|
||||
|
||||
#include "tests/path.hh"
|
||||
#include "tests/value/context.hh"
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
Gen<NixStringContextElem::DrvDeep> Arbitrary<NixStringContextElem::DrvDeep>::arbitrary()
|
||||
{
|
||||
return gen::just(NixStringContextElem::DrvDeep {
|
||||
.drvPath = *gen::arbitrary<StorePath>(),
|
||||
});
|
||||
}
|
||||
|
||||
Gen<NixStringContextElem> Arbitrary<NixStringContextElem>::arbitrary()
|
||||
{
|
||||
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<NixStringContextElem::Raw>)) {
|
||||
case 0:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Opaque>());
|
||||
case 1:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::DrvDeep>());
|
||||
case 2:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Built>());
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
31
tests/unit/libexpr-support/tests/value/context.hh
Normal file
31
tests/unit/libexpr-support/tests/value/context.hh
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <rapidcheck/gen/Arbitrary.h>
|
||||
|
||||
#include "value/context.hh"
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
template<>
|
||||
struct Arbitrary<NixStringContextElem::Opaque> {
|
||||
static Gen<NixStringContextElem::Opaque> arbitrary();
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Arbitrary<NixStringContextElem::Built> {
|
||||
static Gen<NixStringContextElem::Built> arbitrary();
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Arbitrary<NixStringContextElem::DrvDeep> {
|
||||
static Gen<NixStringContextElem::DrvDeep> arbitrary();
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Arbitrary<NixStringContextElem> {
|
||||
static Gen<NixStringContextElem> arbitrary();
|
||||
};
|
||||
|
||||
}
|
68
tests/unit/libexpr/derived-path.cc
Normal file
68
tests/unit/libexpr/derived-path.cc
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <rapidcheck/gtest.h>
|
||||
|
||||
#include "tests/derived-path.hh"
|
||||
#include "tests/libexpr.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
// Testing of trivial expressions
|
||||
class DerivedPathExpressionTest : public LibExprTest {};
|
||||
|
||||
// FIXME: `RC_GTEST_FIXTURE_PROP` isn't calling `SetUpTestSuite` because it is
|
||||
// no a real fixture.
|
||||
//
|
||||
// See https://github.com/emil-e/rapidcheck/blob/master/doc/gtest.md#rc_gtest_fixture_propfixture-name-args
|
||||
TEST_F(DerivedPathExpressionTest, force_init)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef COVERAGE
|
||||
|
||||
RC_GTEST_FIXTURE_PROP(
|
||||
DerivedPathExpressionTest,
|
||||
prop_opaque_path_round_trip,
|
||||
(const SingleDerivedPath::Opaque & o))
|
||||
{
|
||||
auto * v = state.allocValue();
|
||||
state.mkStorePathString(o.path, *v);
|
||||
auto d = state.coerceToSingleDerivedPath(noPos, *v, "");
|
||||
RC_ASSERT(SingleDerivedPath { o } == d);
|
||||
}
|
||||
|
||||
// TODO use DerivedPath::Built for parameter once it supports a single output
|
||||
// path only.
|
||||
|
||||
RC_GTEST_FIXTURE_PROP(
|
||||
DerivedPathExpressionTest,
|
||||
prop_derived_path_built_placeholder_round_trip,
|
||||
(const SingleDerivedPath::Built & b))
|
||||
{
|
||||
/**
|
||||
* We set these in tests rather than the regular globals so we don't have
|
||||
* to worry about race conditions if the tests run concurrently.
|
||||
*/
|
||||
ExperimentalFeatureSettings mockXpSettings;
|
||||
mockXpSettings.set("experimental-features", "ca-derivations");
|
||||
|
||||
auto * v = state.allocValue();
|
||||
state.mkOutputString(*v, b, std::nullopt, mockXpSettings);
|
||||
auto [d, _] = state.coerceToSingleDerivedPathUnchecked(noPos, *v, "");
|
||||
RC_ASSERT(SingleDerivedPath { b } == d);
|
||||
}
|
||||
|
||||
RC_GTEST_FIXTURE_PROP(
|
||||
DerivedPathExpressionTest,
|
||||
prop_derived_path_built_out_path_round_trip,
|
||||
(const SingleDerivedPath::Built & b, const StorePath & outPath))
|
||||
{
|
||||
auto * v = state.allocValue();
|
||||
state.mkOutputString(*v, b, outPath);
|
||||
auto [d, _] = state.coerceToSingleDerivedPathUnchecked(noPos, *v, "");
|
||||
RC_ASSERT(SingleDerivedPath { b } == d);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} /* namespace nix */
|
1298
tests/unit/libexpr/error_traces.cc
Normal file
1298
tests/unit/libexpr/error_traces.cc
Normal file
File diff suppressed because it is too large
Load diff
141
tests/unit/libexpr/eval.cc
Normal file
141
tests/unit/libexpr/eval.cc
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "eval.hh"
|
||||
#include "tests/libexpr.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(nix_isAllowedURI, http_example_com) {
|
||||
Strings allowed;
|
||||
allowed.push_back("http://example.com");
|
||||
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com/foo", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com/foo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.co", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.como", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.org", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.org/foo", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, http_example_com_foo) {
|
||||
Strings allowed;
|
||||
allowed.push_back("http://example.com/foo");
|
||||
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com/foo", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com/foo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/foo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.como", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.org/foo", allowed));
|
||||
// Broken?
|
||||
// ASSERT_TRUE(isAllowedURI("http://example.com/foo?ok=1", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, http) {
|
||||
Strings allowed;
|
||||
allowed.push_back("http://");
|
||||
|
||||
ASSERT_TRUE(isAllowedURI("http://", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com/foo", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com/foo/", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("http://example.com", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("https://", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http:foo", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, https) {
|
||||
Strings allowed;
|
||||
allowed.push_back("https://");
|
||||
|
||||
ASSERT_TRUE(isAllowedURI("https://example.com", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("https://example.com/foo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com/https:", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, absolute_path) {
|
||||
Strings allowed;
|
||||
allowed.push_back("/var/evil"); // bad idea
|
||||
|
||||
ASSERT_TRUE(isAllowedURI("/var/evil", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("/var/evil/", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("/var/evil/foo", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("/var/evil/foo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evi", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evilo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evilo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evilo/foo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com/var/evil", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com//var/evil", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com//var/evil/foo", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, file_url) {
|
||||
Strings allowed;
|
||||
allowed.push_back("file:///var/evil"); // bad idea
|
||||
|
||||
ASSERT_TRUE(isAllowedURI("file:///var/evil", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("file:///var/evil/", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("file:///var/evil/foo", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("file:///var/evil/foo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evi", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evilo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evilo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("/var/evilo/foo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com/var/evil", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com//var/evil", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://example.com//var/evil/foo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://var/evil", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http:///var/evil", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("http://var/evil/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///var/evi", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///var/evilo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///var/evilo/", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///var/evilo/foo", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file://", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, github_all) {
|
||||
Strings allowed;
|
||||
allowed.push_back("github:");
|
||||
ASSERT_TRUE(isAllowedURI("github:", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github:foo/bar", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github:foo/bar/feat-multi-bar", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github:foo/bar?ref=refs/heads/feat-multi-bar", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github://foo/bar", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("https://github:443/foo/bar/archive/master.tar.gz", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file://github:foo/bar/archive/master.tar.gz", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///github:foo/bar/archive/master.tar.gz", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("github", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, github_org) {
|
||||
Strings allowed;
|
||||
allowed.push_back("github:foo");
|
||||
ASSERT_FALSE(isAllowedURI("github:", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github:foo/bar", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github:foo/bar/feat-multi-bar", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("github:foo/bar?ref=refs/heads/feat-multi-bar", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("github://foo/bar", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("https://github:443/foo/bar/archive/master.tar.gz", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file://github:foo/bar/archive/master.tar.gz", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("file:///github:foo/bar/archive/master.tar.gz", allowed));
|
||||
}
|
||||
|
||||
TEST(nix_isAllowedURI, non_scheme_colon) {
|
||||
Strings allowed;
|
||||
allowed.push_back("https://foo/bar:");
|
||||
ASSERT_TRUE(isAllowedURI("https://foo/bar:", allowed));
|
||||
ASSERT_TRUE(isAllowedURI("https://foo/bar:/baz", allowed));
|
||||
ASSERT_FALSE(isAllowedURI("https://foo/bar:baz", allowed));
|
||||
}
|
||||
|
||||
} // namespace nix
|
22
tests/unit/libexpr/flakeref.cc
Normal file
22
tests/unit/libexpr/flakeref.cc
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "flake/flakeref.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
/* ----------- tests for flake/flakeref.hh --------------------------------------------------*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* to_string
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(to_string, doesntReencodeUrl) {
|
||||
auto s = "http://localhost:8181/test/+3d.tar.gz";
|
||||
auto flakeref = parseFlakeRef(s);
|
||||
auto parsed = flakeref.to_string();
|
||||
auto expected = "http://localhost:8181/test/%2B3d.tar.gz";
|
||||
|
||||
ASSERT_EQ(parsed, expected);
|
||||
}
|
||||
|
||||
}
|
68
tests/unit/libexpr/json.cc
Normal file
68
tests/unit/libexpr/json.cc
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "tests/libexpr.hh"
|
||||
#include "value-to-json.hh"
|
||||
|
||||
namespace nix {
|
||||
// Testing the conversion to JSON
|
||||
|
||||
class JSONValueTest : public LibExprTest {
|
||||
protected:
|
||||
std::string getJSONValue(Value& value) {
|
||||
std::stringstream ss;
|
||||
NixStringContext ps;
|
||||
printValueAsJSON(state, true, value, noPos, ss, ps);
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(JSONValueTest, null) {
|
||||
Value v;
|
||||
v.mkNull();
|
||||
ASSERT_EQ(getJSONValue(v), "null");
|
||||
}
|
||||
|
||||
TEST_F(JSONValueTest, BoolFalse) {
|
||||
Value v;
|
||||
v.mkBool(false);
|
||||
ASSERT_EQ(getJSONValue(v),"false");
|
||||
}
|
||||
|
||||
TEST_F(JSONValueTest, BoolTrue) {
|
||||
Value v;
|
||||
v.mkBool(true);
|
||||
ASSERT_EQ(getJSONValue(v), "true");
|
||||
}
|
||||
|
||||
TEST_F(JSONValueTest, IntPositive) {
|
||||
Value v;
|
||||
v.mkInt(100);
|
||||
ASSERT_EQ(getJSONValue(v), "100");
|
||||
}
|
||||
|
||||
TEST_F(JSONValueTest, IntNegative) {
|
||||
Value v;
|
||||
v.mkInt(-100);
|
||||
ASSERT_EQ(getJSONValue(v), "-100");
|
||||
}
|
||||
|
||||
TEST_F(JSONValueTest, String) {
|
||||
Value v;
|
||||
v.mkString("test");
|
||||
ASSERT_EQ(getJSONValue(v), "\"test\"");
|
||||
}
|
||||
|
||||
TEST_F(JSONValueTest, StringQuotes) {
|
||||
Value v;
|
||||
|
||||
v.mkString("test\"");
|
||||
ASSERT_EQ(getJSONValue(v), "\"test\\\"\"");
|
||||
}
|
||||
|
||||
// The dummy store doesn't support writing files. Fails with this exception message:
|
||||
// C++ exception with description "error: operation 'addToStoreFromDump' is
|
||||
// not supported by store 'dummy'" thrown in the test body.
|
||||
TEST_F(JSONValueTest, DISABLED_Path) {
|
||||
Value v;
|
||||
v.mkPath(state.rootPath(CanonPath("/test")));
|
||||
ASSERT_EQ(getJSONValue(v), "\"/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x\"");
|
||||
}
|
||||
} /* namespace nix */
|
36
tests/unit/libexpr/local.mk
Normal file
36
tests/unit/libexpr/local.mk
Normal file
|
@ -0,0 +1,36 @@
|
|||
check: libexpr-tests_RUN
|
||||
|
||||
programs += libexpr-tests
|
||||
|
||||
libexpr-tests_NAME := libnixexpr-tests
|
||||
|
||||
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
||||
|
||||
libexpr-tests_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libexpr-tests_INSTALL_DIR := $(checkbindir)
|
||||
else
|
||||
libexpr-tests_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libexpr-tests_SOURCES := \
|
||||
$(wildcard $(d)/*.cc) \
|
||||
$(wildcard $(d)/value/*.cc)
|
||||
|
||||
libexpr-tests_EXTRA_INCLUDES = \
|
||||
-I tests/unit/libexpr-support \
|
||||
-I tests/unit/libstore-support \
|
||||
-I tests/unit/libutil-support \
|
||||
-I src/libexpr \
|
||||
-I src/libfetchers \
|
||||
-I src/libstore \
|
||||
-I src/libutil
|
||||
|
||||
libexpr-tests_CXXFLAGS += $(libexpr-tests_EXTRA_INCLUDES)
|
||||
|
||||
libexpr-tests_LIBS = \
|
||||
libexpr-test-support libstore-test-support libutils-test-support \
|
||||
libexpr libfetchers libstore libutil
|
||||
|
||||
libexpr-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue