mirror of
https://github.com/NixOS/nix
synced 2025-07-10 04:43:53 +02:00
Merge commit 'b24757f08a
' into sync-2.24.2
This commit is contained in:
commit
c1d27763c6
330 changed files with 4907 additions and 1814 deletions
|
@ -140,6 +140,18 @@ nix build --impure -f multiple-outputs.nix --json e --no-link | jq --exit-status
|
|||
(.outputs | keys == ["a_a", "b"]))
|
||||
'
|
||||
|
||||
# Make sure that the 3 types of aliases work
|
||||
# BaseSettings<T>, BaseSettings<bool>, and BaseSettings<SandboxMode>.
|
||||
nix build --impure -f multiple-outputs.nix --json e --no-link \
|
||||
--build-max-jobs 3 \
|
||||
--gc-keep-outputs \
|
||||
--build-use-sandbox | \
|
||||
jq --exit-status '
|
||||
(.[0] |
|
||||
(.drvPath | match(".*multiple-outputs-e.drv")) and
|
||||
(.outputs | keys == ["a_a", "b"]))
|
||||
'
|
||||
|
||||
# Make sure that `--stdin` works and does not apply any defaults
|
||||
printf "" | nix build --no-link --stdin --json | jq --exit-status '. == []'
|
||||
printf "%s\n" "$drv^*" | nix build --no-link --stdin --json | jq --exit-status '.[0]|has("drvPath")'
|
||||
|
|
|
@ -190,7 +190,7 @@ isDaemonNewer () {
|
|||
|
||||
skipTest () {
|
||||
echo "$1, skipping this test..." >&2
|
||||
exit 99
|
||||
exit 77
|
||||
}
|
||||
|
||||
TODO_NixOS() {
|
||||
|
@ -236,7 +236,8 @@ expect() {
|
|||
expected="$1"
|
||||
shift
|
||||
"$@" && res=0 || res="$?"
|
||||
if [[ $res -ne $expected ]]; then
|
||||
# also match "negative" codes, which wrap around to >127
|
||||
if [[ $res -ne $expected && $res -ne $[256 + expected] ]]; then
|
||||
echo "Expected exit code '$expected' but got '$res' from command ${*@Q}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
@ -250,7 +251,8 @@ expectStderr() {
|
|||
expected="$1"
|
||||
shift
|
||||
"$@" 2>&1 && res=0 || res="$?"
|
||||
if [[ $res -ne $expected ]]; then
|
||||
# also match "negative" codes, which wrap around to >127
|
||||
if [[ $res -ne $expected && $res -ne $[256 + expected] ]]; then
|
||||
echo "Expected exit code '$expected' but got '$res' from command ${*@Q}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
@ -295,13 +297,67 @@ onError() {
|
|||
done
|
||||
}
|
||||
|
||||
# Prints an error message prefix referring to the last call into this file.
|
||||
# Ignores `expect` and `expectStderr` calls.
|
||||
# Set a special exit code when test suite functions are misused, so that
|
||||
# functions like expectStderr won't mistake them for expected Nix CLI errors.
|
||||
# Suggestion: -101 (negative to indicate very abnormal, and beyond the normal
|
||||
# range of signals)
|
||||
# Example (showns as string): 'repl.sh:123: in call to grepQuiet: '
|
||||
# This function is inefficient, so it should only be used in error messages.
|
||||
callerPrefix() {
|
||||
# Find the closest caller that's not from this file
|
||||
# using the bash `caller` builtin.
|
||||
local i file line fn savedFn
|
||||
# Use `caller`
|
||||
for i in $(seq 0 100); do
|
||||
caller $i > /dev/null || {
|
||||
if [[ -n "${file:-}" ]]; then
|
||||
echo "$file:$line: ${savedFn+in call to $savedFn: }"
|
||||
fi
|
||||
break
|
||||
}
|
||||
line="$(caller $i | cut -d' ' -f1)"
|
||||
fn="$(caller $i | cut -d' ' -f2)"
|
||||
file="$(caller $i | cut -d' ' -f3)"
|
||||
if [[ $file != "${BASH_SOURCE[0]}" ]]; then
|
||||
echo "$file:$line: ${savedFn+in call to $savedFn: }"
|
||||
return
|
||||
fi
|
||||
case "$fn" in
|
||||
# Ignore higher order functions that don't report any misuse of themselves
|
||||
# This way a misuse of a foo in `expectStderr 1 foo` will be reported as
|
||||
# calling foo, not expectStderr.
|
||||
expect|expectStderr|callerPrefix)
|
||||
;;
|
||||
*)
|
||||
savedFn="$fn"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
checkGrepArgs() {
|
||||
local arg
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" != "${arg//$'\n'/_}" ]]; then
|
||||
echo "$(callerPrefix)newline not allowed in arguments; grep would try each line individually as if connected by an OR operator" >&2
|
||||
return -101
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# `grep -v` doesn't work well for exit codes. We want `!(exist line l. l
|
||||
# matches)`. It gives us `exist line l. !(l matches)`.
|
||||
#
|
||||
# `!` normally doesn't work well with `set -e`, but when we wrap in a
|
||||
# function it *does*.
|
||||
#
|
||||
# `command grep` lets us avoid re-checking the args by going directly to the
|
||||
# executable.
|
||||
grepInverse() {
|
||||
! grep "$@"
|
||||
checkGrepArgs "$@" && \
|
||||
! command grep "$@"
|
||||
}
|
||||
|
||||
# A shorthand, `> /dev/null` is a bit noisy.
|
||||
|
@ -315,13 +371,26 @@ grepInverse() {
|
|||
# the closing of the pipe, the buffering of the pipe, and the speed of
|
||||
# the producer into the pipe. But rest assured we've seen it happen in
|
||||
# CI reliably.
|
||||
#
|
||||
# `command grep` lets us avoid re-checking the args by going directly to the
|
||||
# executable.
|
||||
grepQuiet() {
|
||||
grep "$@" > /dev/null
|
||||
checkGrepArgs "$@" && \
|
||||
command grep "$@" > /dev/null
|
||||
}
|
||||
|
||||
# The previous two, combined
|
||||
grepQuietInverse() {
|
||||
! grep "$@" > /dev/null
|
||||
checkGrepArgs "$@" && \
|
||||
! command grep "$@" > /dev/null
|
||||
}
|
||||
|
||||
# Wrap grep to remove its newline footgun; see checkGrepArgs.
|
||||
# Note that we keep the checkGrepArgs calls in the other helpers, because some
|
||||
# of them are negated and that would defeat this check.
|
||||
grep() {
|
||||
checkGrepArgs "$@" && \
|
||||
command grep "$@"
|
||||
}
|
||||
|
||||
# Return the number of arguments
|
||||
|
|
|
@ -58,3 +58,7 @@ fi
|
|||
# Test that unknown settings are warned about
|
||||
out="$(expectStderr 0 nix eval --option foobar baz --expr '""' --raw)"
|
||||
[[ "$(echo "$out" | grep foobar | wc -l)" = 1 ]]
|
||||
|
||||
# Test flag alias
|
||||
out="$(nix eval --expr '{}' --build-cores 1)"
|
||||
[[ "$(echo "$out" | wc -l)" = 1 ]]
|
||||
|
|
24
tests/functional/flakes/local.mk
Normal file
24
tests/functional/flakes/local.mk
Normal file
|
@ -0,0 +1,24 @@
|
|||
flake-tests := \
|
||||
$(d)/flakes.sh \
|
||||
$(d)/develop.sh \
|
||||
$(d)/edit.sh \
|
||||
$(d)/run.sh \
|
||||
$(d)/mercurial.sh \
|
||||
$(d)/circular.sh \
|
||||
$(d)/init.sh \
|
||||
$(d)/inputs.sh \
|
||||
$(d)/follow-paths.sh \
|
||||
$(d)/bundle.sh \
|
||||
$(d)/check.sh \
|
||||
$(d)/unlocked-override.sh \
|
||||
$(d)/absolute-paths.sh \
|
||||
$(d)/absolute-attr-paths.sh \
|
||||
$(d)/build-paths.sh \
|
||||
$(d)/flake-in-submodule.sh \
|
||||
$(d)/prefetch.sh \
|
||||
$(d)/eval-cache.sh \
|
||||
$(d)/search-root.sh \
|
||||
$(d)/config.sh \
|
||||
$(d)/show.sh
|
||||
|
||||
install-tests-groups += flake
|
|
@ -29,5 +29,26 @@ nix run --no-write-lock-file .#pkgAsPkg
|
|||
! nix run --no-write-lock-file .#pkgAsApp || fail "'nix run' shouldn’t accept an 'app' defined under 'packages'"
|
||||
! nix run --no-write-lock-file .#appAsPkg || fail "elements of 'apps' should be of type 'app'"
|
||||
|
||||
# Test that we're not setting any more environment variables than necessary.
|
||||
# For instance, we might set an environment variable temporarily to affect some
|
||||
# initialization or whatnot, but this must not leak into the environment of the
|
||||
# command being run.
|
||||
env > $TEST_ROOT/expected-env
|
||||
nix run -f shell-hello.nix env > $TEST_ROOT/actual-env
|
||||
# Remove/reset variables we expect to be different.
|
||||
# - PATH is modified by nix shell
|
||||
# - _ is set by bash and is expected to differ because it contains the original command
|
||||
# - __CF_USER_TEXT_ENCODING is set by macOS and is beyond our control
|
||||
sed -i \
|
||||
-e 's/PATH=.*/PATH=.../' \
|
||||
-e 's/_=.*/_=.../' \
|
||||
-e '/^__CF_USER_TEXT_ENCODING=.*$/d' \
|
||||
$TEST_ROOT/expected-env $TEST_ROOT/actual-env
|
||||
sort $TEST_ROOT/expected-env | uniq > $TEST_ROOT/expected-env.sorted
|
||||
# nix run appears to clear _. I don't understand why. Is this ok?
|
||||
echo "_=..." >> $TEST_ROOT/actual-env
|
||||
sort $TEST_ROOT/actual-env | uniq > $TEST_ROOT/actual-env.sorted
|
||||
diff $TEST_ROOT/expected-env.sorted $TEST_ROOT/actual-env.sorted
|
||||
|
||||
clearStore
|
||||
|
||||
|
|
36
tests/functional/lang-gc.sh
Normal file
36
tests/functional/lang-gc.sh
Normal file
|
@ -0,0 +1,36 @@
|
|||
# shellcheck shell=bash
|
||||
|
||||
# Regression tests for the evaluator
|
||||
# These are not in lang.sh because they generally only need to run in CI,
|
||||
# whereas lang.sh is often run locally during development
|
||||
|
||||
|
||||
source common.sh
|
||||
|
||||
set -o pipefail
|
||||
|
||||
skipTest "Too memory instensive for CI. Attempt to reduce memory usage was unsuccessful, because it made detection of the bug unreliable."
|
||||
|
||||
# Regression test for #11141. The stack pointer corrector assigned the base
|
||||
# instead of the top (which resides at the low end of the stack). Sounds confusing?
|
||||
# Stacks grow downwards, so that's why this mistake happened.
|
||||
# My manual testing did not uncover this, because it didn't rely on the stack enough.
|
||||
# https://github.com/NixOS/nix/issues/11141
|
||||
test_issue_11141() {
|
||||
mkdir -p "$TEST_ROOT/issue-11141/src"
|
||||
cp lang-gc/issue-11141-gc-coroutine-test.nix "$TEST_ROOT/issue-11141/"
|
||||
(
|
||||
set +x;
|
||||
n=10
|
||||
echo "populating $TEST_ROOT/issue-11141/src with $((n*100)) files..."
|
||||
for i in $(seq 0 $n); do
|
||||
touch "$TEST_ROOT/issue-11141/src/file-$i"{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
|
||||
done
|
||||
)
|
||||
|
||||
GC_INITIAL_HEAP_SIZE=$((1024 * 1024)) \
|
||||
NIX_SHOW_STATS=1 \
|
||||
nix eval -vvv\
|
||||
-f "$TEST_ROOT/issue-11141/issue-11141-gc-coroutine-test.nix"
|
||||
}
|
||||
test_issue_11141
|
65
tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix
Normal file
65
tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
# Run:
|
||||
# GC_INITIAL_HEAP_SIZE=$[1024 * 1024] NIX_SHOW_STATS=1 nix eval -f gc-coroutine-test.nix -vvvv
|
||||
|
||||
let
|
||||
inherit (builtins)
|
||||
foldl'
|
||||
isList
|
||||
;
|
||||
|
||||
# Generate a tree of numbers, n deep, such that the numbers add up to (1 + salt) * 10^n.
|
||||
# The salting makes the numbers all different, increasing the likelihood of catching
|
||||
# any memory corruptions that might be caused by the GC or otherwise.
|
||||
garbage = salt: n:
|
||||
if n == 0
|
||||
then [(1 + salt)]
|
||||
else [
|
||||
(garbage (10 * salt + 1) (n - 1))
|
||||
(garbage (10 * salt - 1) (n - 1))
|
||||
(garbage (10 * salt + 2) (n - 1))
|
||||
(garbage (10 * salt - 2) (n - 1))
|
||||
(garbage (10 * salt + 3) (n - 1))
|
||||
(garbage (10 * salt - 3) (n - 1))
|
||||
(garbage (10 * salt + 4) (n - 1))
|
||||
(garbage (10 * salt - 4) (n - 1))
|
||||
(garbage (10 * salt + 5) (n - 1))
|
||||
(garbage (10 * salt - 5) (n - 1))
|
||||
];
|
||||
|
||||
pow = base: n:
|
||||
if n == 0
|
||||
then 1
|
||||
else base * (pow base (n - 1));
|
||||
|
||||
sumNestedLists = l:
|
||||
if isList l
|
||||
then foldl' (a: b: a + sumNestedLists b) 0 l
|
||||
else l;
|
||||
|
||||
in
|
||||
assert sumNestedLists (garbage 0 3) == pow 10 3;
|
||||
assert sumNestedLists (garbage 0 6) == pow 10 6;
|
||||
builtins.foldl'
|
||||
(a: b:
|
||||
assert
|
||||
"${
|
||||
builtins.path {
|
||||
path = ./src;
|
||||
filter = path: type:
|
||||
# We're not doing common subexpression elimination, so this reallocates
|
||||
# the fairly big tree over and over, producing a lot of garbage during
|
||||
# source filtering, whose filter runs in a coroutine.
|
||||
assert sumNestedLists (garbage 0 3) == pow 10 3;
|
||||
true;
|
||||
}
|
||||
}"
|
||||
== "${./src}";
|
||||
|
||||
# These asserts don't seem necessary, as the lambda value get corrupted first
|
||||
assert a.okay;
|
||||
assert b.okay;
|
||||
{ okay = true; }
|
||||
)
|
||||
{ okay = true; }
|
||||
[ { okay = true; } { okay = true; } { okay = true; } ]
|
|
@ -50,11 +50,25 @@ set +x
|
|||
badDiff=0
|
||||
badExitCode=0
|
||||
|
||||
# Extra post-processing that's specific to each test case
|
||||
postprocess() {
|
||||
if [[ -e "lang/$1.postprocess" ]]; then
|
||||
(
|
||||
# We could allow arbitrary interpreters in .postprocess, but that
|
||||
# just exposes us to the complexity of not having /usr/bin/env in
|
||||
# the sandbox. So let's just hardcode bash for now.
|
||||
set -x;
|
||||
bash "lang/$1.postprocess" "lang/$1"
|
||||
)
|
||||
fi
|
||||
}
|
||||
|
||||
for i in lang/parse-fail-*.nix; do
|
||||
echo "parsing $i (should fail)";
|
||||
i=$(basename "$i" .nix)
|
||||
if expectStderr 1 nix-instantiate --parse - < "lang/$i.nix" > "lang/$i.err"
|
||||
then
|
||||
postprocess "$i"
|
||||
diffAndAccept "$i" err err.exp
|
||||
else
|
||||
echo "FAIL: $i shouldn't parse"
|
||||
|
@ -71,6 +85,7 @@ for i in lang/parse-okay-*.nix; do
|
|||
2> "lang/$i.err"
|
||||
then
|
||||
sed "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err"
|
||||
postprocess "$i"
|
||||
diffAndAccept "$i" out exp
|
||||
diffAndAccept "$i" err err.exp
|
||||
else
|
||||
|
@ -94,6 +109,7 @@ for i in lang/eval-fail-*.nix; do
|
|||
expectStderr 1 nix-instantiate $flags "lang/$i.nix" \
|
||||
| sed "s!$(pwd)!/pwd!g" > "lang/$i.err"
|
||||
then
|
||||
postprocess "$i"
|
||||
diffAndAccept "$i" err err.exp
|
||||
else
|
||||
echo "FAIL: $i shouldn't evaluate"
|
||||
|
@ -109,6 +125,7 @@ for i in lang/eval-okay-*.nix; do
|
|||
if expect 0 nix-instantiate --eval --xml --no-location --strict \
|
||||
"lang/$i.nix" > "lang/$i.out.xml"
|
||||
then
|
||||
postprocess "$i"
|
||||
diffAndAccept "$i" out.xml exp.xml
|
||||
else
|
||||
echo "FAIL: $i should evaluate"
|
||||
|
@ -129,6 +146,7 @@ for i in lang/eval-okay-*.nix; do
|
|||
2> "lang/$i.err"
|
||||
then
|
||||
sed -i "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err"
|
||||
postprocess "$i"
|
||||
diffAndAccept "$i" out exp
|
||||
diffAndAccept "$i" err err.exp
|
||||
else
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ a = true; } == { a = true; b = true; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-attrs-names-2.nix:1:1:
|
||||
1| assert { a = true; } == { a = true; b = true; };
|
||||
| ^
|
||||
2| throw "unreachable"
|
||||
|
||||
error: attribute names of attribute set '{ a = true; }' differs from attribute set '{ a = true; b = true; }'
|
|
@ -0,0 +1,2 @@
|
|||
assert { a = true; } == { a = true; b = true; };
|
||||
throw "unreachable"
|
|
@ -0,0 +1,8 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ a = true; b = true; } == { a = true; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-attrs-names.nix:1:1:
|
||||
1| assert { a = true; b = true; } == { a = true; };
|
||||
| ^
|
||||
2| throw "unreachable"
|
||||
|
||||
error: attribute names of attribute set '{ a = true; b = true; }' differs from attribute set '{ a = true; }'
|
|
@ -0,0 +1,2 @@
|
|||
assert { a = true; b = true; } == { a = true; };
|
||||
throw "unreachable"
|
|
@ -0,0 +1,26 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ foo = { outPath = "/nix/store/0"; type = "derivation"; }; } == { foo = { devious = true; outPath = "/nix/store/1"; type = "derivation"; }; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:1:1:
|
||||
1| assert
|
||||
| ^
|
||||
2| { foo = { type = "derivation"; outPath = "/nix/store/0"; }; }
|
||||
|
||||
… while comparing attribute 'foo'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:2:5:
|
||||
1| assert
|
||||
2| { foo = { type = "derivation"; outPath = "/nix/store/0"; }; }
|
||||
| ^
|
||||
3| ==
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:4:5:
|
||||
3| ==
|
||||
4| { foo = { type = "derivation"; outPath = "/nix/store/1"; devious = true; }; };
|
||||
| ^
|
||||
5| throw "unreachable"
|
||||
|
||||
… while comparing a derivation by its 'outPath' attribute
|
||||
|
||||
error: string '"/nix/store/0"' is not equal to string '"/nix/store/1"'
|
|
@ -0,0 +1,5 @@
|
|||
assert
|
||||
{ foo = { type = "derivation"; outPath = "/nix/store/0"; }; }
|
||||
==
|
||||
{ foo = { type = "derivation"; outPath = "/nix/store/1"; devious = true; }; };
|
||||
throw "unreachable"
|
|
@ -0,0 +1,26 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ foo = { ignored = (abort "not ignored"); outPath = "/nix/store/0"; type = "derivation"; }; } == { foo = { ignored = (abort "not ignored"); outPath = "/nix/store/1"; type = "derivation"; }; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-derivations.nix:1:1:
|
||||
1| assert
|
||||
| ^
|
||||
2| { foo = { type = "derivation"; outPath = "/nix/store/0"; ignored = abort "not ignored"; }; }
|
||||
|
||||
… while comparing attribute 'foo'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-derivations.nix:2:5:
|
||||
1| assert
|
||||
2| { foo = { type = "derivation"; outPath = "/nix/store/0"; ignored = abort "not ignored"; }; }
|
||||
| ^
|
||||
3| ==
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-derivations.nix:4:5:
|
||||
3| ==
|
||||
4| { foo = { type = "derivation"; outPath = "/nix/store/1"; ignored = abort "not ignored"; }; };
|
||||
| ^
|
||||
5| throw "unreachable"
|
||||
|
||||
… while comparing a derivation by its 'outPath' attribute
|
||||
|
||||
error: string '"/nix/store/0"' is not equal to string '"/nix/store/1"'
|
|
@ -0,0 +1,5 @@
|
|||
assert
|
||||
{ foo = { type = "derivation"; outPath = "/nix/store/0"; ignored = abort "not ignored"; }; }
|
||||
==
|
||||
{ foo = { type = "derivation"; outPath = "/nix/store/1"; ignored = abort "not ignored"; }; };
|
||||
throw "unreachable"
|
22
tests/functional/lang/eval-fail-assert-equal-floats.err.exp
Normal file
22
tests/functional/lang/eval-fail-assert-equal-floats.err.exp
Normal file
|
@ -0,0 +1,22 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ b = 1; } == { b = 1.01; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-floats.nix:1:1:
|
||||
1| assert { b = 1.0; } == { b = 1.01; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
… while comparing attribute 'b'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-floats.nix:1:10:
|
||||
1| assert { b = 1.0; } == { b = 1.01; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-floats.nix:1:26:
|
||||
1| assert { b = 1.0; } == { b = 1.01; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
error: a float with value '1' is not equal to a float with value '1.01'
|
2
tests/functional/lang/eval-fail-assert-equal-floats.nix
Normal file
2
tests/functional/lang/eval-fail-assert-equal-floats.nix
Normal file
|
@ -0,0 +1,2 @@
|
|||
assert { b = 1.0; } == { b = 1.01; };
|
||||
abort "unreachable"
|
|
@ -0,0 +1,9 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '((x: x) == (x: x))'
|
||||
at /pwd/lang/eval-fail-assert-equal-function-direct.nix:3:1:
|
||||
2| # This only compares a direct comparison and makes no claims about functions in nested structures.
|
||||
3| assert
|
||||
| ^
|
||||
4| (x: x)
|
||||
|
||||
error: distinct functions and immediate comparisons of identical functions compare as unequal
|
|
@ -0,0 +1,7 @@
|
|||
# Note: functions in nested structures, e.g. attributes, may be optimized away by pointer identity optimization.
|
||||
# This only compares a direct comparison and makes no claims about functions in nested structures.
|
||||
assert
|
||||
(x: x)
|
||||
==
|
||||
(x: x);
|
||||
abort "unreachable"
|
|
@ -0,0 +1,8 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '(1 == 1.1)'
|
||||
at /pwd/lang/eval-fail-assert-equal-int-float.nix:1:1:
|
||||
1| assert 1 == 1.1;
|
||||
| ^
|
||||
2| throw "unreachable"
|
||||
|
||||
error: an integer with value '1' is not equal to a float with value '1.1'
|
|
@ -0,0 +1,2 @@
|
|||
assert 1 == 1.1;
|
||||
throw "unreachable"
|
22
tests/functional/lang/eval-fail-assert-equal-ints.err.exp
Normal file
22
tests/functional/lang/eval-fail-assert-equal-ints.err.exp
Normal file
|
@ -0,0 +1,22 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ b = 1; } == { b = 2; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-ints.nix:1:1:
|
||||
1| assert { b = 1; } == { b = 2; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
… while comparing attribute 'b'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-ints.nix:1:10:
|
||||
1| assert { b = 1; } == { b = 2; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-ints.nix:1:24:
|
||||
1| assert { b = 1; } == { b = 2; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
error: an integer with value '1' is not equal to an integer with value '2'
|
2
tests/functional/lang/eval-fail-assert-equal-ints.nix
Normal file
2
tests/functional/lang/eval-fail-assert-equal-ints.nix
Normal file
|
@ -0,0 +1,2 @@
|
|||
assert { b = 1; } == { b = 2; };
|
||||
abort "unreachable"
|
|
@ -0,0 +1,8 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '([ (1) (0) ] == [ (10) ])'
|
||||
at /pwd/lang/eval-fail-assert-equal-list-length.nix:1:1:
|
||||
1| assert [ 1 0 ] == [ 10 ];
|
||||
| ^
|
||||
2| throw "unreachable"
|
||||
|
||||
error: list of size '2' is not equal to list of size '1', left hand side is '[ 1 0 ]', right hand side is '[ 10 ]'
|
|
@ -0,0 +1,2 @@
|
|||
assert [ 1 0 ] == [ 10 ];
|
||||
throw "unreachable"
|
|
@ -0,0 +1,8 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '(/pwd/lang/foo == /pwd/lang/bar)'
|
||||
at /pwd/lang/eval-fail-assert-equal-paths.nix:1:1:
|
||||
1| assert ./foo == ./bar;
|
||||
| ^
|
||||
2| throw "unreachable"
|
||||
|
||||
error: path '/pwd/lang/foo' is not equal to path '/pwd/lang/bar'
|
2
tests/functional/lang/eval-fail-assert-equal-paths.nix
Normal file
2
tests/functional/lang/eval-fail-assert-equal-paths.nix
Normal file
|
@ -0,0 +1,2 @@
|
|||
assert ./foo == ./bar;
|
||||
throw "unreachable"
|
|
@ -0,0 +1,22 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ ding = false; } == { ding = null; })'
|
||||
at /pwd/lang/eval-fail-assert-equal-type-nested.nix:1:1:
|
||||
1| assert { ding = false; } == { ding = null; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
… while comparing attribute 'ding'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-type-nested.nix:1:10:
|
||||
1| assert { ding = false; } == { ding = null; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-equal-type-nested.nix:1:31:
|
||||
1| assert { ding = false; } == { ding = null; };
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
error: a Boolean of value 'false' is not equal to null of value 'null'
|
|
@ -0,0 +1,2 @@
|
|||
assert { ding = false; } == { ding = null; };
|
||||
abort "unreachable"
|
|
@ -0,0 +1,8 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '(false == null)'
|
||||
at /pwd/lang/eval-fail-assert-equal-type.nix:1:1:
|
||||
1| assert false == null;
|
||||
| ^
|
||||
2| abort "unreachable"
|
||||
|
||||
error: a Boolean of value 'false' is not equal to null of value 'null'
|
2
tests/functional/lang/eval-fail-assert-equal-type.nix
Normal file
2
tests/functional/lang/eval-fail-assert-equal-type.nix
Normal file
|
@ -0,0 +1,2 @@
|
|||
assert false == null;
|
||||
abort "unreachable"
|
74
tests/functional/lang/eval-fail-assert-nested-bool.err.exp
Normal file
74
tests/functional/lang/eval-fail-assert-nested-bool.err.exp
Normal file
|
@ -0,0 +1,74 @@
|
|||
error:
|
||||
… while evaluating the condition of the assertion '({ a = { b = [ ({ c = { d = true; }; }) ]; }; } == { a = { b = [ ({ c = { d = false; }; }) ]; }; })'
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:1:
|
||||
1| assert
|
||||
| ^
|
||||
2| { a.b = [ { c.d = true; } ]; }
|
||||
|
||||
… while comparing attribute 'a'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:2:5:
|
||||
1| assert
|
||||
2| { a.b = [ { c.d = true; } ]; }
|
||||
| ^
|
||||
3| ==
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:4:5:
|
||||
3| ==
|
||||
4| { a.b = [ { c.d = false; } ]; };
|
||||
| ^
|
||||
5|
|
||||
|
||||
… while comparing attribute 'b'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:2:5:
|
||||
1| assert
|
||||
2| { a.b = [ { c.d = true; } ]; }
|
||||
| ^
|
||||
3| ==
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:4:5:
|
||||
3| ==
|
||||
4| { a.b = [ { c.d = false; } ]; };
|
||||
| ^
|
||||
5|
|
||||
|
||||
… while comparing list element 0
|
||||
|
||||
… while comparing attribute 'c'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:2:15:
|
||||
1| assert
|
||||
2| { a.b = [ { c.d = true; } ]; }
|
||||
| ^
|
||||
3| ==
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:4:15:
|
||||
3| ==
|
||||
4| { a.b = [ { c.d = false; } ]; };
|
||||
| ^
|
||||
5|
|
||||
|
||||
… while comparing attribute 'd'
|
||||
|
||||
… where left hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:2:15:
|
||||
1| assert
|
||||
2| { a.b = [ { c.d = true; } ]; }
|
||||
| ^
|
||||
3| ==
|
||||
|
||||
… where right hand side is
|
||||
at /pwd/lang/eval-fail-assert-nested-bool.nix:4:15:
|
||||
3| ==
|
||||
4| { a.b = [ { c.d = false; } ]; };
|
||||
| ^
|
||||
5|
|
||||
|
||||
error: boolean 'true' is not equal to boolean 'false'
|
6
tests/functional/lang/eval-fail-assert-nested-bool.nix
Normal file
6
tests/functional/lang/eval-fail-assert-nested-bool.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
assert
|
||||
{ a.b = [ { c.d = true; } ]; }
|
||||
==
|
||||
{ a.b = [ { c.d = false; } ]; };
|
||||
|
||||
abort "unreachable"
|
|
@ -20,9 +20,11 @@ error:
|
|||
| ^
|
||||
3|
|
||||
|
||||
error: assertion '(arg == "y")' failed
|
||||
at /pwd/lang/eval-fail-assert.nix:2:12:
|
||||
… while evaluating the condition of the assertion '(arg == "y")'
|
||||
at /pwd/lang/eval-fail-assert.nix:2:12:
|
||||
1| let {
|
||||
2| x = arg: assert arg == "y"; 123;
|
||||
| ^
|
||||
3|
|
||||
|
||||
error: string '"x"' is not equal to string '"y"'
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
error:
|
||||
… while evaluating the attribute 'outPath'
|
||||
at <nix/derivation-internal.nix>:19:9:
|
||||
18| value = commonAttrs // {
|
||||
19| outPath = builtins.getAttr outputName strict;
|
||||
at <nix/derivation-internal.nix>:<number>:<number>:
|
||||
<number>| value = commonAttrs // {
|
||||
<number>| outPath = builtins.getAttr outputName strict;
|
||||
| ^
|
||||
20| drvPath = strict.drvPath;
|
||||
<number>| drvPath = strict.drvPath;
|
||||
|
||||
… while calling the 'getAttr' builtin
|
||||
at <nix/derivation-internal.nix>:19:19:
|
||||
18| value = commonAttrs // {
|
||||
19| outPath = builtins.getAttr outputName strict;
|
||||
at <nix/derivation-internal.nix>:<number>:<number>:
|
||||
<number>| value = commonAttrs // {
|
||||
<number>| outPath = builtins.getAttr outputName strict;
|
||||
| ^
|
||||
20| drvPath = strict.drvPath;
|
||||
<number>| drvPath = strict.drvPath;
|
||||
|
||||
… while calling the 'derivationStrict' builtin
|
||||
at <nix/derivation-internal.nix>:9:12:
|
||||
8|
|
||||
9| strict = derivationStrict drvAttrs;
|
||||
at <nix/derivation-internal.nix>:<number>:<number>:
|
||||
<number>|
|
||||
<number>| strict = derivationStrict drvAttrs;
|
||||
| ^
|
||||
10|
|
||||
<number>|
|
||||
|
||||
… while evaluating derivation '~jiggle~'
|
||||
whose name attribute is located at /pwd/lang/eval-fail-derivation-name.nix:2:3
|
||||
whose name attribute is located at /pwd/lang/eval-fail-derivation-name.nix:<number>:<number>
|
||||
|
||||
error: invalid derivation name: name '~jiggle~' contains illegal character '~'. Please pass a different 'name'.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# shellcheck shell=bash
|
||||
set -euo pipefail
|
||||
testcaseBasename=$1
|
||||
|
||||
# Line numbers change when derivation.nix docs are updated.
|
||||
sed -i "$testcaseBasename.err" \
|
||||
-e 's/[0-9 ][0-9 ][0-9 ][0-9 ][0-9 ][0-9 ][0-9 ][0-9]\([^0-9]\)/<number>\1/g' \
|
||||
-e 's/[0-9][0-9]*/<number>/g' \
|
||||
;
|
5
tests/functional/lang/eval-fail-pipe-operators.err.exp
Normal file
5
tests/functional/lang/eval-fail-pipe-operators.err.exp
Normal file
|
@ -0,0 +1,5 @@
|
|||
error: experimental Nix feature 'pipe-operators' is disabled; add '--extra-experimental-features pipe-operators' to enable it
|
||||
at /pwd/lang/eval-fail-pipe-operators.nix:1:3:
|
||||
1| 1 |> 2
|
||||
| ^
|
||||
2|
|
1
tests/functional/lang/eval-fail-pipe-operators.nix
Normal file
1
tests/functional/lang/eval-fail-pipe-operators.nix
Normal file
|
@ -0,0 +1 @@
|
|||
1 |> 2
|
1
tests/functional/lang/parse-okay-ind-string.exp
Normal file
1
tests/functional/lang/parse-okay-ind-string.exp
Normal file
|
@ -0,0 +1 @@
|
|||
(let string = "str"; in [ (/some/path) ((/some/path)) ((/some/path)) ((/some/path + "\n end")) (string) ((string)) ((string)) ((string + "\n end")) ("") ("") ("end") ])
|
31
tests/functional/lang/parse-okay-ind-string.nix
Normal file
31
tests/functional/lang/parse-okay-ind-string.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
let
|
||||
string = "str";
|
||||
in [
|
||||
/some/path
|
||||
|
||||
''${/some/path}''
|
||||
|
||||
''
|
||||
${/some/path}''
|
||||
|
||||
''${/some/path}
|
||||
end''
|
||||
|
||||
string
|
||||
|
||||
''${string}''
|
||||
|
||||
''
|
||||
${string}''
|
||||
|
||||
''${string}
|
||||
end''
|
||||
|
||||
''''
|
||||
|
||||
''
|
||||
''
|
||||
|
||||
''
|
||||
end''
|
||||
]
|
|
@ -1,28 +1,11 @@
|
|||
nix_tests = \
|
||||
test-infra.sh \
|
||||
flakes/flakes.sh \
|
||||
flakes/develop.sh \
|
||||
flakes/edit.sh \
|
||||
flakes/run.sh \
|
||||
flakes/mercurial.sh \
|
||||
flakes/circular.sh \
|
||||
flakes/init.sh \
|
||||
flakes/inputs.sh \
|
||||
flakes/follow-paths.sh \
|
||||
flakes/bundle.sh \
|
||||
flakes/check.sh \
|
||||
flakes/unlocked-override.sh \
|
||||
flakes/absolute-paths.sh \
|
||||
flakes/absolute-attr-paths.sh \
|
||||
flakes/build-paths.sh \
|
||||
flakes/flake-in-submodule.sh \
|
||||
flakes/prefetch.sh \
|
||||
flakes/eval-cache.sh \
|
||||
gc.sh \
|
||||
nix-collect-garbage-d.sh \
|
||||
remote-store.sh \
|
||||
legacy-ssh-store.sh \
|
||||
lang.sh \
|
||||
lang-gc.sh \
|
||||
characterisation-test-infra.sh \
|
||||
experimental-features.sh \
|
||||
fetchMercurial.sh \
|
||||
|
@ -60,7 +43,6 @@ nix_tests = \
|
|||
restricted.sh \
|
||||
fetchGitSubmodules.sh \
|
||||
fetchGitVerification.sh \
|
||||
flakes/search-root.sh \
|
||||
readfile-context.sh \
|
||||
nix-channel.sh \
|
||||
recursive.sh \
|
||||
|
@ -101,7 +83,6 @@ nix_tests = \
|
|||
nix-copy-ssh-ng.sh \
|
||||
post-hook.sh \
|
||||
function-trace.sh \
|
||||
flakes/config.sh \
|
||||
fmt.sh \
|
||||
eval-store.sh \
|
||||
why-depends.sh \
|
||||
|
@ -124,7 +105,6 @@ nix_tests = \
|
|||
store-info.sh \
|
||||
fetchClosure.sh \
|
||||
completions.sh \
|
||||
flakes/show.sh \
|
||||
impure-derivations.sh \
|
||||
path-from-hash-part.sh \
|
||||
path-info.sh \
|
||||
|
|
|
@ -65,6 +65,25 @@ chmod a+rx $TEST_ROOT/shell.shebang.sh
|
|||
output=$($TEST_ROOT/shell.shebang.sh abc def)
|
||||
[ "$output" = "foo bar abc def" ]
|
||||
|
||||
# Test nix-shell shebang mode with an alternate working directory
|
||||
sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.expr > $TEST_ROOT/shell.shebang.expr
|
||||
chmod a+rx $TEST_ROOT/shell.shebang.expr
|
||||
# Should fail due to expressions using relative path
|
||||
! $TEST_ROOT/shell.shebang.expr bar
|
||||
cp shell.nix config.nix $TEST_ROOT
|
||||
# Should succeed
|
||||
echo "cwd: $PWD"
|
||||
output=$($TEST_ROOT/shell.shebang.expr bar)
|
||||
[ "$output" = foo ]
|
||||
|
||||
# Test nix-shell shebang mode with an alternate working directory
|
||||
sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.legacy.expr > $TEST_ROOT/shell.shebang.legacy.expr
|
||||
chmod a+rx $TEST_ROOT/shell.shebang.legacy.expr
|
||||
# Should fail due to expressions using relative path
|
||||
mkdir -p "$TEST_ROOT/somewhere-unrelated"
|
||||
output="$(cd "$TEST_ROOT/somewhere-unrelated"; $TEST_ROOT/shell.shebang.legacy.expr bar;)"
|
||||
[[ $(realpath "$output") = $(realpath "$TEST_ROOT/somewhere-unrelated") ]]
|
||||
|
||||
# Test nix-shell shebang mode again with metacharacters in the filename.
|
||||
# First word of filename is chosen to not match any file in the test root.
|
||||
sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.sh > $TEST_ROOT/spaced\ \\\'\"shell.shebang.sh
|
||||
|
|
|
@ -14,3 +14,75 @@ nix-instantiate --eval -E '<by-relative-path/simple.nix>' --restrict-eval
|
|||
|
||||
[[ $(nix-instantiate --find-file by-absolute-path/simple.nix) = $PWD/simple.nix ]]
|
||||
[[ $(nix-instantiate --find-file by-relative-path/simple.nix) = $PWD/simple.nix ]]
|
||||
|
||||
# this is the human-readable specification for the following test cases of interactions between various ways of specifying NIX_PATH.
|
||||
# TODO: the actual tests are incomplete and too manual.
|
||||
# there should be 43 of them, since the table has 9 rows and columns, and 2 interactions are meaningless
|
||||
# ideally they would work off the table programmatically.
|
||||
#
|
||||
# | precedence | hard-coded | nix-path in file | extra-nix-path in file | nix-path in env | extra-nix-path in env | NIX_PATH | nix-path | extra-nix-path | -I |
|
||||
# |------------------------|------------|------------------|------------------------|-----------------|-----------------------|-----------|-----------|-----------------|-----------------|
|
||||
# | hard-coded | x | ^override | ^append | ^override | ^append | ^override | ^override | ^append | ^prepend |
|
||||
# | nix-path in file | | last wins | ^append | ^override | ^append | ^override | ^override | ^append | ^prepend |
|
||||
# | extra-nix-path in file | | | append in order | ^override | ^append | ^override | ^override | ^append | ^prepend |
|
||||
# | nix-path in env | | | | last wins | ^append | ^override | ^override | ^append | ^prepend |
|
||||
# | extra-nix-path in env | | | | | append in order | ^override | ^override | ^append | ^prepend |
|
||||
# | NIX_PATH | | | | | | x | ^override | ^append | ^prepend |
|
||||
# | nix-path | | | | | | | last wins | ^append | ^prepend |
|
||||
# | extra-nix-path | | | | | | | | append in order | append in order |
|
||||
# | -I | | | | | | | | | append in order |
|
||||
|
||||
unset NIX_PATH
|
||||
|
||||
mkdir -p $TEST_ROOT/{from-nix-path-file,from-NIX_PATH,from-nix-path,from-extra-nix-path,from-I}
|
||||
for i in from-nix-path-file from-NIX_PATH from-nix-path from-extra-nix-path from-I; do
|
||||
touch $TEST_ROOT/$i/only-$i.nix
|
||||
done
|
||||
|
||||
# finding something that's not in any of the default paths fails
|
||||
( ! $(nix-instantiate --find-file test) )
|
||||
|
||||
echo "nix-path = test=$TEST_ROOT/from-nix-path-file" >> "$test_nix_conf"
|
||||
|
||||
# Use nix.conf in absence of NIX_PATH
|
||||
[[ $(nix-instantiate --find-file test) = $TEST_ROOT/from-nix-path-file ]]
|
||||
|
||||
# NIX_PATH overrides nix.conf
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate --find-file test) = $TEST_ROOT/from-NIX_PATH ]]
|
||||
# if NIX_PATH does not have the desired entry, it fails
|
||||
(! NIX_PATH=test=$TEST_ROOT nix-instantiate --find-file test/only-from-nix-path-file.nix)
|
||||
|
||||
# -I extends nix.conf
|
||||
[[ $(nix-instantiate -I test=$TEST_ROOT/from-I --find-file test/only-from-I.nix) = $TEST_ROOT/from-I/only-from-I.nix ]]
|
||||
# if -I does not have the desired entry, the value from nix.conf is used
|
||||
[[ $(nix-instantiate -I test=$TEST_ROOT/from-I --find-file test/only-from-nix-path-file.nix) = $TEST_ROOT/from-nix-path-file/only-from-nix-path-file.nix ]]
|
||||
|
||||
# -I extends NIX_PATH
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate -I test=$TEST_ROOT/from-I --find-file test/only-from-I.nix) = $TEST_ROOT/from-I/only-from-I.nix ]]
|
||||
# -I takes precedence over NIX_PATH
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate -I test=$TEST_ROOT/from-I --find-file test) = $TEST_ROOT/from-I ]]
|
||||
# if -I does not have the desired entry, the value from NIX_PATH is used
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate -I test=$TEST_ROOT/from-I --find-file test/only-from-NIX_PATH.nix) = $TEST_ROOT/from-NIX_PATH/only-from-NIX_PATH.nix ]]
|
||||
|
||||
# --extra-nix-path extends NIX_PATH
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate --extra-nix-path test=$TEST_ROOT/from-extra-nix-path --find-file test/only-from-extra-nix-path.nix) = $TEST_ROOT/from-extra-nix-path/only-from-extra-nix-path.nix ]]
|
||||
# if --extra-nix-path does not have the desired entry, the value from NIX_PATH is used
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate --extra-nix-path test=$TEST_ROOT/from-extra-nix-path --find-file test/only-from-NIX_PATH.nix) = $TEST_ROOT/from-NIX_PATH/only-from-NIX_PATH.nix ]]
|
||||
|
||||
# --nix-path overrides NIX_PATH
|
||||
[[ $(NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate --nix-path test=$TEST_ROOT/from-nix-path --find-file test) = $TEST_ROOT/from-nix-path ]]
|
||||
# if --nix-path does not have the desired entry, it fails
|
||||
(! NIX_PATH=test=$TEST_ROOT/from-NIX_PATH nix-instantiate --nix-path test=$TEST_ROOT/from-nix-path --find-file test/only-from-NIX_PATH.nix)
|
||||
|
||||
# --nix-path overrides nix.conf
|
||||
[[ $(nix-instantiate --nix-path test=$TEST_ROOT/from-nix-path --find-file test) = $TEST_ROOT/from-nix-path ]]
|
||||
(! nix-instantiate --nix-path test=$TEST_ROOT/from-nix-path --find-file test/only-from-nix-path-file.nix)
|
||||
|
||||
# --extra-nix-path extends nix.conf
|
||||
[[ $(nix-instantiate --extra-nix-path test=$TEST_ROOT/from-extra-nix-path --find-file test/only-from-extra-nix-path.nix) = $TEST_ROOT/from-extra-nix-path/only-from-extra-nix-path.nix ]]
|
||||
# if --extra-nix-path does not have the desired entry, it is taken from nix.conf
|
||||
[[ $(nix-instantiate --extra-nix-path test=$TEST_ROOT/from-extra-nix-path --find-file test) = $TEST_ROOT/from-nix-path-file ]]
|
||||
|
||||
# -I extends --nix-path
|
||||
[[ $(nix-instantiate --nix-path test=$TEST_ROOT/from-nix-path -I test=$TEST_ROOT/from-I --find-file test/only-from-I.nix) = $TEST_ROOT/from-I/only-from-I.nix ]]
|
||||
[[ $(nix-instantiate --nix-path test=$TEST_ROOT/from-nix-path -I test=$TEST_ROOT/from-I --find-file test/only-from-nix-path.nix) = $TEST_ROOT/from-nix-path/only-from-nix-path.nix ]]
|
||||
|
|
|
@ -262,6 +262,23 @@ badExitCode=0
|
|||
|
||||
nixVersion="$(nix eval --impure --raw --expr 'builtins.nixVersion' --extra-experimental-features nix-command)"
|
||||
|
||||
# TODO: write a repl interacter for testing. Papering over the differences between readline / editline and between platforms is a pain.
|
||||
|
||||
# I couldn't get readline and editline to agree on the newline before the prompt,
|
||||
# so let's just force it to be one empty line.
|
||||
stripEmptyLinesBeforePrompt() {
|
||||
# --null-data: treat input as NUL-terminated instead of newline-terminated
|
||||
sed --null-data 's/\n\n*nix-repl>/\n\nnix-repl>/g'
|
||||
}
|
||||
|
||||
# We don't get a final prompt on darwin, so we strip this as well.
|
||||
stripFinalPrompt() {
|
||||
# Strip the final prompt and/or any trailing spaces
|
||||
sed --null-data \
|
||||
-e 's/\(.*[^\n]\)\n\n*nix-repl>[ \n]*$/\1/' \
|
||||
-e 's/[ \n]*$/\n/'
|
||||
}
|
||||
|
||||
runRepl () {
|
||||
|
||||
# That is right, we are also filtering out the testdir _without underscores_.
|
||||
|
@ -273,8 +290,13 @@ runRepl () {
|
|||
testDirNoUnderscores="${testDir//_/}"
|
||||
|
||||
# TODO: pass arguments to nix repl; see lang.sh
|
||||
_NIX_TEST_RAW_MARKDOWN=1 \
|
||||
_NIX_TEST_REPL_ECHO=1 \
|
||||
nix repl 2>&1 \
|
||||
| stripColors \
|
||||
| tr -d '\0' \
|
||||
| stripEmptyLinesBeforePrompt \
|
||||
| stripFinalPrompt \
|
||||
| sed \
|
||||
-e "s@$testDir@/path/to/tests/functional@g" \
|
||||
-e "s@$testDirNoUnderscores@/path/to/tests/functional@g" \
|
||||
|
@ -289,7 +311,10 @@ for test in $(cd "$testDir/repl"; echo *.in); do
|
|||
in="$testDir/repl/$test.in"
|
||||
actual="$testDir/repl/$test.actual"
|
||||
expected="$testDir/repl/$test.expected"
|
||||
(cd "$testDir/repl"; set +x; runRepl 2>&1) < "$in" > "$actual"
|
||||
(cd "$testDir/repl"; set +x; runRepl 2>&1) < "$in" > "$actual" || {
|
||||
echo "FAIL: $test (exit code $?)" >&2
|
||||
badExitCode=1
|
||||
}
|
||||
diffAndAcceptInner "$test" "$actual" "$expected"
|
||||
done
|
||||
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function curriedArgs
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:48:5
|
||||
nix-repl> :doc curriedArgs
|
||||
Function `curriedArgs`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:48:5
|
||||
|
||||
A documented function.
|
||||
A documented function.
|
||||
|
||||
nix-repl> x = curriedArgs 1
|
||||
|
||||
nix-repl> "Note that users may not expect this to behave as it currently does"
|
||||
"Note that users may not expect this to behave as it currently does"
|
||||
|
||||
Function curriedArgs
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:50:5
|
||||
nix-repl> :doc x
|
||||
Function `curriedArgs`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:50:5
|
||||
|
||||
The function returned by applying once
|
||||
The function returned by applying once
|
||||
|
||||
"This won't produce documentation, because we can't actually document arbitrary values"
|
||||
nix-repl> "This won't produce docs; no support for arbitrary values"
|
||||
"This won't produce docs; no support for arbitrary values"
|
||||
|
||||
nix-repl> :doc x 2
|
||||
error: value does not have documentation
|
||||
|
||||
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
x = curriedArgs 1
|
||||
"Note that users may not expect this to behave as it currently does"
|
||||
:doc x
|
||||
"This won't produce documentation, because we can't actually document arbitrary values"
|
||||
"This won't produce docs; no support for arbitrary values"
|
||||
:doc x 2
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
nix-repl> "Note that this is not yet complete"
|
||||
"Note that this is not yet complete"
|
||||
|
||||
Function documentedFormals
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:57:5
|
||||
|
||||
Finds x
|
||||
|
||||
nix-repl> :doc documentedFormals
|
||||
Function `documentedFormals`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:57:5
|
||||
|
||||
Finds x
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
Function defined at
|
||||
/path/to/tests/functional/repl/doc-comment-function.nix:2:1
|
||||
|
||||
A doc comment for a file that only contains a function
|
||||
|
||||
nix-repl> :doc import ./doc-comment-function.nix
|
||||
Function defined at /path/to/tests/functional/repl/doc-comment-function.nix:2:1
|
||||
|
||||
A doc comment for a file that only contains a function
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function compact
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:18:20
|
||||
|
||||
boom
|
||||
|
||||
nix-repl> :doc compact
|
||||
Function `compact`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:18:20
|
||||
|
||||
boom
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
nix-repl> :doc constant
|
||||
error: value does not have documentation
|
||||
|
||||
Attribute version
|
||||
nix-repl> :doc lib.version
|
||||
Attribute `version`
|
||||
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:30:3
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:30:3
|
||||
|
||||
Immovably fixed.
|
||||
Immovably fixed.
|
||||
|
||||
Attribute empty
|
||||
nix-repl> :doc lib.attr.empty
|
||||
Attribute `empty`
|
||||
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:33:3
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:33:3
|
||||
|
||||
Unchangeably constant.
|
||||
Unchangeably constant.
|
||||
|
||||
nix-repl> :doc lib.attr.undocument
|
||||
error:
|
||||
… while evaluating the attribute 'attr.undocument'
|
||||
at /path/to/tests/functional/repl/doc-comments.nix:33:3:
|
||||
|
@ -32,59 +36,65 @@ error:
|
|||
| ^
|
||||
Did you mean undocumented?
|
||||
|
||||
Attribute constant
|
||||
nix-repl> :doc (import ./doc-comments.nix).constant
|
||||
Attribute `constant`
|
||||
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:27:3
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:27:3
|
||||
|
||||
Firmly rigid.
|
||||
Firmly rigid.
|
||||
|
||||
Attribute version
|
||||
nix-repl> :doc (import ./doc-comments.nix).lib.version
|
||||
Attribute `version`
|
||||
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:30:3
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:30:3
|
||||
|
||||
Immovably fixed.
|
||||
Immovably fixed.
|
||||
|
||||
Attribute empty
|
||||
nix-repl> :doc (import ./doc-comments.nix).lib.attr.empty
|
||||
Attribute `empty`
|
||||
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:33:3
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:33:3
|
||||
|
||||
Unchangeably constant.
|
||||
Unchangeably constant.
|
||||
|
||||
Attribute undocumented
|
||||
nix-repl> :doc (import ./doc-comments.nix).lib.attr.undocumented
|
||||
Attribute `undocumented`
|
||||
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:35:3
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:35:3
|
||||
|
||||
No documentation found.
|
||||
No documentation found.
|
||||
|
||||
nix-repl> :doc missing
|
||||
error: undefined variable 'missing'
|
||||
at «string»:1:1:
|
||||
1| missing
|
||||
| ^
|
||||
|
||||
nix-repl> :doc constanz
|
||||
error: undefined variable 'constanz'
|
||||
at «string»:1:1:
|
||||
1| constanz
|
||||
| ^
|
||||
|
||||
nix-repl> :doc missing.attr
|
||||
error: undefined variable 'missing'
|
||||
at «string»:1:1:
|
||||
1| missing.attr
|
||||
| ^
|
||||
|
||||
nix-repl> :doc lib.missing
|
||||
error: attribute 'missing' missing
|
||||
at «string»:1:1:
|
||||
1| lib.missing
|
||||
| ^
|
||||
|
||||
nix-repl> :doc lib.missing.attr
|
||||
error: attribute 'missing' missing
|
||||
at «string»:1:1:
|
||||
1| lib.missing.attr
|
||||
| ^
|
||||
|
||||
nix-repl> :doc lib.attr.undocumental
|
||||
error:
|
||||
… while evaluating the attribute 'attr.undocumental'
|
||||
at /path/to/tests/functional/repl/doc-comments.nix:33:3:
|
||||
|
@ -98,5 +108,3 @@ error:
|
|||
1| lib.attr.undocumental
|
||||
| ^
|
||||
Did you mean undocumented?
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function floatedIn
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:16:5
|
||||
|
||||
This also works.
|
||||
|
||||
nix-repl> :doc floatedIn
|
||||
Function `floatedIn`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:16:5
|
||||
|
||||
This also works.
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function nonStrict
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:37:70
|
||||
nix-repl> :doc nonStrict
|
||||
Function `nonStrict`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:37:70
|
||||
|
||||
My syntax is not strict, but I'm strict anyway.
|
||||
My syntax is not strict, but I'm strict anyway.
|
||||
|
||||
Function strict
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:38:63
|
||||
nix-repl> :doc strict
|
||||
Function `strict`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:38:63
|
||||
|
||||
I don't have to be strict, but I am anyway.
|
||||
I don't have to be strict, but I am anyway.
|
||||
|
||||
Function strictPre
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:40:48
|
||||
nix-repl> :doc strictPre
|
||||
Function `strictPre`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:40:48
|
||||
|
||||
Here's one way to do this
|
||||
|
||||
Function strictPost
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:41:53
|
||||
|
||||
Here's another way to do this
|
||||
Here's one way to do this
|
||||
|
||||
nix-repl> :doc strictPost
|
||||
Function `strictPost`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:41:53
|
||||
|
||||
Here's another way to do this
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function measurement
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:13:17
|
||||
|
||||
👈 precisely this wide 👉
|
||||
|
||||
nix-repl> :doc measurement
|
||||
Function `measurement`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:13:17
|
||||
|
||||
👈 precisely this wide 👉
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function multiply
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:10:14
|
||||
|
||||
Perform arithmetic multiplication. It's kind of like
|
||||
repeated addition, very neat.
|
||||
|
||||
| multiply 2 3
|
||||
| => 6
|
||||
nix-repl> :doc multiply
|
||||
Function `multiply`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:10:14
|
||||
|
||||
|
||||
Perform *arithmetic* multiplication. It's kind of like repeated **addition**, very neat.
|
||||
|
||||
```nix
|
||||
multiply 2 3
|
||||
=> 6
|
||||
```
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l doc-comments.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
Function unambiguous
|
||||
… defined at
|
||||
/path/to/tests/functional/repl/doc-comments.nix:24:5
|
||||
|
||||
Very close
|
||||
|
||||
nix-repl> :doc unambiguous
|
||||
Function `unambiguous`\
|
||||
… defined at /path/to/tests/functional/repl/doc-comments.nix:24:5
|
||||
|
||||
Very close
|
||||
|
|
37
tests/functional/repl/pretty-print-idempotent.expected
Normal file
37
tests/functional/repl/pretty-print-idempotent.expected
Normal file
|
@ -0,0 +1,37 @@
|
|||
Nix <nix version>
|
||||
Type :? for help.
|
||||
|
||||
nix-repl> :l pretty-print-idempotent.nix
|
||||
Added <number omitted> variables.
|
||||
|
||||
nix-repl> oneDeep
|
||||
{ homepage = "https://example.com"; }
|
||||
|
||||
nix-repl> oneDeep
|
||||
{ homepage = "https://example.com"; }
|
||||
|
||||
nix-repl> twoDeep
|
||||
{
|
||||
layerOne = { ... };
|
||||
}
|
||||
|
||||
nix-repl> twoDeep
|
||||
{
|
||||
layerOne = { ... };
|
||||
}
|
||||
|
||||
nix-repl> oneDeepList
|
||||
[ "https://example.com" ]
|
||||
|
||||
nix-repl> oneDeepList
|
||||
[ "https://example.com" ]
|
||||
|
||||
nix-repl> twoDeepList
|
||||
[
|
||||
[ ... ]
|
||||
]
|
||||
|
||||
nix-repl> twoDeepList
|
||||
[
|
||||
[ ... ]
|
||||
]
|
9
tests/functional/repl/pretty-print-idempotent.in
Normal file
9
tests/functional/repl/pretty-print-idempotent.in
Normal file
|
@ -0,0 +1,9 @@
|
|||
:l pretty-print-idempotent.nix
|
||||
oneDeep
|
||||
oneDeep
|
||||
twoDeep
|
||||
twoDeep
|
||||
oneDeepList
|
||||
oneDeepList
|
||||
twoDeepList
|
||||
twoDeepList
|
19
tests/functional/repl/pretty-print-idempotent.nix
Normal file
19
tests/functional/repl/pretty-print-idempotent.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
oneDeep = {
|
||||
homepage = "https://" + "example.com";
|
||||
};
|
||||
twoDeep = {
|
||||
layerOne = {
|
||||
homepage = "https://" + "example.com";
|
||||
};
|
||||
};
|
||||
|
||||
oneDeepList = [
|
||||
("https://" + "example.com")
|
||||
];
|
||||
twoDeepList = [
|
||||
[
|
||||
("https://" + "example.com")
|
||||
]
|
||||
];
|
||||
}
|
|
@ -10,6 +10,9 @@ nix-instantiate --restrict-eval --eval -E '1 + 2'
|
|||
nix-instantiate --restrict-eval ./simple.nix -I src=.
|
||||
nix-instantiate --restrict-eval ./simple.nix -I src1=simple.nix -I src2=config.nix -I src3=./simple.builder.sh
|
||||
|
||||
# no default NIX_PATH
|
||||
(unset NIX_PATH; ! nix-instantiate --restrict-eval --find-file .)
|
||||
|
||||
(! nix-instantiate --restrict-eval --eval -E 'builtins.readFile ./simple.nix')
|
||||
nix-instantiate --restrict-eval --eval -E 'builtins.readFile ./simple.nix' -I src=../..
|
||||
|
||||
|
|
|
@ -55,4 +55,26 @@ rec {
|
|||
chmod +x $out/bin/hello
|
||||
'';
|
||||
};
|
||||
|
||||
# execs env from PATH, so that we can probe the environment
|
||||
# does not allow arguments, because we don't need them
|
||||
env = mkDerivation {
|
||||
name = "env";
|
||||
outputs = [ "out" ];
|
||||
buildCommand =
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
|
||||
cat > $out/bin/env <<EOF
|
||||
#! ${shell}
|
||||
if [ $# -ne 0 ]; then
|
||||
echo "env: Unexpected arguments ($#): $@" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
exec env
|
||||
EOF
|
||||
chmod +x $out/bin/env
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ let pkgs = rec {
|
|||
ASCII_PERCENT = "%";
|
||||
ASCII_AT = "@";
|
||||
TEST_inNixShell = if inNixShell then "true" else "false";
|
||||
FOO = fooContents;
|
||||
inherit stdenv;
|
||||
outputs = ["dev" "out"];
|
||||
} // {
|
||||
|
|
|
@ -23,6 +23,25 @@ nix shell -f shell-hello.nix hello-symlink -c hello | grep 'Hello World'
|
|||
# Test that symlinks outside of the store don't work.
|
||||
expect 1 nix shell -f shell-hello.nix forbidden-symlink -c hello 2>&1 | grepQuiet "is not in the Nix store"
|
||||
|
||||
# Test that we're not setting any more environment variables than necessary.
|
||||
# For instance, we might set an environment variable temporarily to affect some
|
||||
# initialization or whatnot, but this must not leak into the environment of the
|
||||
# command being run.
|
||||
env > $TEST_ROOT/expected-env
|
||||
nix shell -f shell-hello.nix hello -c env > $TEST_ROOT/actual-env
|
||||
# Remove/reset variables we expect to be different.
|
||||
# - PATH is modified by nix shell
|
||||
# - _ is set by bash and is expectedf to differ because it contains the original command
|
||||
# - __CF_USER_TEXT_ENCODING is set by macOS and is beyond our control
|
||||
sed -i \
|
||||
-e 's/PATH=.*/PATH=.../' \
|
||||
-e 's/_=.*/_=.../' \
|
||||
-e '/^__CF_USER_TEXT_ENCODING=.*$/d' \
|
||||
$TEST_ROOT/expected-env $TEST_ROOT/actual-env
|
||||
sort $TEST_ROOT/expected-env > $TEST_ROOT/expected-env.sorted
|
||||
sort $TEST_ROOT/actual-env > $TEST_ROOT/actual-env.sorted
|
||||
diff $TEST_ROOT/expected-env.sorted $TEST_ROOT/actual-env.sorted
|
||||
|
||||
if isDaemonNewer "2.20.0pre20231220"; then
|
||||
# Test that command line attribute ordering is reflected in the PATH
|
||||
# https://github.com/NixOS/nix/issues/7905
|
||||
|
|
9
tests/functional/shell.shebang.expr
Executable file
9
tests/functional/shell.shebang.expr
Executable file
|
@ -0,0 +1,9 @@
|
|||
#! @ENV_PROG@ nix-shell
|
||||
#! nix-shell "{ script, path, ... }: assert path == ./shell.nix; script { }"
|
||||
#! nix-shell --no-substitute
|
||||
#! nix-shell --expr
|
||||
#! nix-shell --arg script "import ./shell.nix"
|
||||
#! nix-shell --arg path "./shell.nix"
|
||||
#! nix-shell -A shellDrv
|
||||
#! nix-shell -i bash
|
||||
echo "$FOO"
|
10
tests/functional/shell.shebang.legacy.expr
Executable file
10
tests/functional/shell.shebang.legacy.expr
Executable file
|
@ -0,0 +1,10 @@
|
|||
#! @ENV_PROG@ nix-shell
|
||||
#! nix-shell "{ script, path, ... }: assert path == ./shell.nix; script { fooContents = toString ./.; }"
|
||||
#! nix-shell --no-substitute
|
||||
#! nix-shell --expr
|
||||
#! nix-shell --arg script "import ((builtins.getEnv ''TEST_ROOT'')+''/shell.nix'')"
|
||||
#! nix-shell --arg path "./shell.nix"
|
||||
#! nix-shell -A shellDrv
|
||||
#! nix-shell -i bash
|
||||
#! nix-shell --option nix-shell-shebang-arguments-relative-to-script false
|
||||
echo "$FOO"
|
|
@ -83,3 +83,20 @@ path="$(nix flake prefetch --json "tarball+file://$(pwd)/tree.tar.gz" | jq -r .s
|
|||
[[ $(cat "$path/a/zzz") = bar ]]
|
||||
[[ $(cat "$path/c/aap") = bar ]]
|
||||
[[ $(cat "$path/fnord") = bar ]]
|
||||
|
||||
# Test a tarball that has multiple top-level directories.
|
||||
rm -rf "$TEST_ROOT/tar_root"
|
||||
mkdir -p "$TEST_ROOT/tar_root" "$TEST_ROOT/tar_root/foo" "$TEST_ROOT/tar_root/bar"
|
||||
tar cvf "$TEST_ROOT/tar.tar" -C "$TEST_ROOT/tar_root" .
|
||||
path="$(nix flake prefetch --json "tarball+file://$TEST_ROOT/tar.tar" | jq -r .storePath)"
|
||||
[[ -d "$path/foo" ]]
|
||||
[[ -d "$path/bar" ]]
|
||||
|
||||
# Test a tarball that has a single regular file.
|
||||
rm -rf "$TEST_ROOT/tar_root"
|
||||
mkdir -p "$TEST_ROOT/tar_root"
|
||||
echo bar > "$TEST_ROOT/tar_root/foo"
|
||||
chmod +x "$TEST_ROOT/tar_root/foo"
|
||||
tar cvf "$TEST_ROOT/tar.tar" -C "$TEST_ROOT/tar_root" .
|
||||
path="$(nix flake prefetch --refresh --json "tarball+file://$TEST_ROOT/tar.tar" | jq -r .storePath)"
|
||||
[[ $(cat "$path/foo") = bar ]]
|
||||
|
|
|
@ -13,6 +13,25 @@ expect 1 false
|
|||
# `expect` will fail when we get it wrong
|
||||
expect 1 expect 0 false
|
||||
|
||||
function ret() {
|
||||
return $1
|
||||
}
|
||||
|
||||
# `expect` can call functions, not just executables
|
||||
expect 0 ret 0
|
||||
expect 1 ret 1
|
||||
|
||||
# `expect` supports negative exit codes
|
||||
expect -1 ret -1
|
||||
|
||||
# or high positive ones, equivalent to negative ones
|
||||
expect 255 ret 255
|
||||
expect 255 ret -1
|
||||
expect -1 ret 255
|
||||
|
||||
# but it doesn't confuse negative exit codes with positive ones
|
||||
expect 1 expect -10 ret 10
|
||||
|
||||
noisyTrue () {
|
||||
echo YAY! >&2
|
||||
true
|
||||
|
@ -69,6 +88,10 @@ funBang () {
|
|||
expect 1 funBang
|
||||
unset funBang
|
||||
|
||||
# callerPrefix can be used by the test framework to improve error messages
|
||||
# it reports about our call site here
|
||||
echo "<[$(callerPrefix)]>" | grepQuiet -F "<[test-infra.sh:$LINENO: ]>"
|
||||
|
||||
# `grep -v -q` is not what we want for exit codes, but `grepInverse` is
|
||||
# Avoid `grep -v -q`. The following line proves the point, and if it fails,
|
||||
# we'll know that `grep` had a breaking change or `-v -q` may not be portable.
|
||||
|
@ -85,3 +108,12 @@ unset res
|
|||
res=$(set -eu -o pipefail; echo foo | expect 1 grepQuietInverse foo | wc -c)
|
||||
(( res == 0 ))
|
||||
unset res
|
||||
|
||||
# `grepQuiet` does not allow newlines in its arguments, because grep quietly
|
||||
# treats them as multiple queries.
|
||||
{ echo foo; echo bar; } | expectStderr -101 grepQuiet $'foo\nbar' \
|
||||
| grepQuiet -E 'test-infra\.sh:[0-9]+: in call to grepQuiet: newline not allowed in arguments; grep would try each line individually as if connected by an OR operator'
|
||||
|
||||
# We took the blue pill and woke up in a world where `grep` is moderately safe.
|
||||
expectStderr -101 grep $'foo\nbar' \
|
||||
| grepQuiet -E 'test-infra\.sh:[0-9]+: in call to grep: newline not allowed in arguments; grep would try each line individually as if connected by an OR operator'
|
||||
|
|
|
@ -104,7 +104,15 @@ in
|
|||
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'")
|
||||
# Make sure the builder can handle our login correctly
|
||||
builder.wait_for_unit("multi-user.target")
|
||||
# Make sure there's no funny business on the client either
|
||||
# (should not be necessary, but we have reason to be careful)
|
||||
client.wait_for_unit("multi-user.target")
|
||||
client.succeed(f"""
|
||||
ssh -o StrictHostKeyChecking=no {builder.name} \
|
||||
'echo hello world on $(hostname)' >&2
|
||||
""")
|
||||
|
||||
# Perform a build and check that it was performed on the builder.
|
||||
out = client.succeed(
|
||||
|
|
|
@ -27,6 +27,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
||||
|
|
|
@ -66,12 +66,8 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
|
|
|
@ -34,6 +34,9 @@ int main (int argc, char **argv) {
|
|||
setEnv("_NIX_TEST_NO_SANDBOX", "1");
|
||||
#endif
|
||||
|
||||
// For pipe operator tests in trivial.cc
|
||||
experimentalFeatureSettings.set("experimental-features", "pipe-operators");
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
@ -41,8 +42,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
|
@ -72,28 +71,28 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
nix-expr-tests
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'';
|
||||
'');
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = finalAttrs.pname + stdenv.hostPlatform.extensions.executable;
|
||||
};
|
||||
|
||||
})
|
||||
|
|
|
@ -182,6 +182,60 @@ namespace nix {
|
|||
ASSERT_THAT(v, IsIntEq(15));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, forwardPipe) {
|
||||
auto v = eval("1 |> builtins.add 2 |> builtins.mul 3");
|
||||
ASSERT_THAT(v, IsIntEq(9));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, backwardPipe) {
|
||||
auto v = eval("builtins.add 1 <| builtins.mul 2 <| 3");
|
||||
ASSERT_THAT(v, IsIntEq(7));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, forwardPipeEvaluationOrder) {
|
||||
auto v = eval("1 |> null |> (x: 2)");
|
||||
ASSERT_THAT(v, IsIntEq(2));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, backwardPipeEvaluationOrder) {
|
||||
auto v = eval("(x: 1) <| null <| 2");
|
||||
ASSERT_THAT(v, IsIntEq(1));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, differentPipeOperatorsDoNotAssociate) {
|
||||
ASSERT_THROW(eval("(x: 1) <| 2 |> (x: 3)"), ParseError);
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, differentPipeOperatorsParensLeft) {
|
||||
auto v = eval("((x: 1) <| 2) |> (x: 3)");
|
||||
ASSERT_THAT(v, IsIntEq(3));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, differentPipeOperatorsParensRight) {
|
||||
auto v = eval("(x: 1) <| (2 |> (x: 3))");
|
||||
ASSERT_THAT(v, IsIntEq(1));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, forwardPipeLowestPrecedence) {
|
||||
auto v = eval("false -> true |> (x: !x)");
|
||||
ASSERT_THAT(v, IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, backwardPipeLowestPrecedence) {
|
||||
auto v = eval("(x: !x) <| false -> true");
|
||||
ASSERT_THAT(v, IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, forwardPipeStrongerThanElse) {
|
||||
auto v = eval("if true then 1 else 2 |> 3");
|
||||
ASSERT_THAT(v, IsIntEq(1));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, backwardPipeStrongerThanElse) {
|
||||
auto v = eval("if true then 1 else 2 <| 3");
|
||||
ASSERT_THAT(v, IsIntEq(1));
|
||||
}
|
||||
|
||||
TEST_F(TrivialExpressionTest, bindOr) {
|
||||
auto v = eval("{ or = 1; }");
|
||||
ASSERT_THAT(v, IsAttrsOfSize(1));
|
||||
|
|
|
@ -77,7 +77,7 @@ TEST_F(GitUtilsTest, sink_basic)
|
|||
|
||||
// sink->createHardlink("foo-1.1/links/foo-2", CanonPath("foo-1.1/hello"));
|
||||
|
||||
auto result = sink->sync();
|
||||
auto result = repo->dereferenceSingletonDirectory(sink->sync());
|
||||
auto accessor = repo->getAccessor(result, false);
|
||||
auto entries = accessor->readDirectory(CanonPath::root);
|
||||
ASSERT_EQ(entries.size(), 5);
|
||||
|
@ -103,7 +103,7 @@ TEST_F(GitUtilsTest, sink_hardlink)
|
|||
sink->createHardlink(CanonPath("foo-1.1/link"), CanonPath("hello"));
|
||||
FAIL() << "Expected an exception";
|
||||
} catch (const nix::Error & e) {
|
||||
ASSERT_THAT(e.msg(), testing::HasSubstr("invalid hard link target"));
|
||||
ASSERT_THAT(e.msg(), testing::HasSubstr("cannot find hard link target"));
|
||||
ASSERT_THAT(e.msg(), testing::HasSubstr("/hello"));
|
||||
ASSERT_THAT(e.msg(), testing::HasSubstr("foo-1.1/link"));
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
@ -40,8 +41,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
|
@ -70,28 +69,28 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
nix-fetchers-tests
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'';
|
||||
'');
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = finalAttrs.pname + stdenv.hostPlatform.extensions.executable;
|
||||
};
|
||||
|
||||
})
|
||||
|
|
|
@ -24,6 +24,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
@ -40,8 +41,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
|
@ -70,28 +69,28 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
nix-flake-tests
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'';
|
||||
'');
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = finalAttrs.pname + stdenv.hostPlatform.extensions.executable;
|
||||
};
|
||||
|
||||
})
|
||||
|
|
|
@ -25,6 +25,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
||||
|
|
|
@ -66,12 +66,8 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
|
|
21
tests/unit/libstore/http-binary-cache-store.cc
Normal file
21
tests/unit/libstore/http-binary-cache-store.cc
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "http-binary-cache-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(HttpBinaryCacheStore, constructConfig)
|
||||
{
|
||||
HttpBinaryCacheStoreConfig config{"http", "foo.bar.baz", {}};
|
||||
|
||||
EXPECT_EQ(config.cacheUri, "http://foo.bar.baz");
|
||||
}
|
||||
|
||||
TEST(HttpBinaryCacheStore, constructConfigNoTrailingSlash)
|
||||
{
|
||||
HttpBinaryCacheStoreConfig config{"https", "foo.bar.baz/a/b/", {}};
|
||||
|
||||
EXPECT_EQ(config.cacheUri, "https://foo.bar.baz/a/b");
|
||||
}
|
||||
|
||||
} // namespace nix
|
14
tests/unit/libstore/local-binary-cache-store.cc
Normal file
14
tests/unit/libstore/local-binary-cache-store.cc
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "local-binary-cache-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(LocalBinaryCacheStore, constructConfig)
|
||||
{
|
||||
LocalBinaryCacheStoreConfig config{"local", "/foo/bar/baz", {}};
|
||||
|
||||
EXPECT_EQ(config.binaryCacheDir, "/foo/bar/baz");
|
||||
}
|
||||
|
||||
} // namespace nix
|
34
tests/unit/libstore/local-overlay-store.cc
Normal file
34
tests/unit/libstore/local-overlay-store.cc
Normal file
|
@ -0,0 +1,34 @@
|
|||
// FIXME: Odd failures for templates that are causing the PR to break
|
||||
// for now with discussion with @Ericson2314 to comment out.
|
||||
#if 0
|
||||
# include <gtest/gtest.h>
|
||||
|
||||
# include "local-overlay-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(LocalOverlayStore, constructConfig_rootQueryParam)
|
||||
{
|
||||
LocalOverlayStoreConfig config{
|
||||
"local-overlay",
|
||||
"",
|
||||
{
|
||||
{
|
||||
"root",
|
||||
"/foo/bar",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"});
|
||||
}
|
||||
|
||||
TEST(LocalOverlayStore, constructConfig_rootPath)
|
||||
{
|
||||
LocalOverlayStoreConfig config{"local-overlay", "/foo/bar", {}};
|
||||
|
||||
EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"});
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
#endif
|
40
tests/unit/libstore/local-store.cc
Normal file
40
tests/unit/libstore/local-store.cc
Normal file
|
@ -0,0 +1,40 @@
|
|||
// FIXME: Odd failures for templates that are causing the PR to break
|
||||
// for now with discussion with @Ericson2314 to comment out.
|
||||
#if 0
|
||||
# include <gtest/gtest.h>
|
||||
|
||||
# include "local-store.hh"
|
||||
|
||||
// Needed for template specialisations. This is not good! When we
|
||||
// overhaul how store configs work, this should be fixed.
|
||||
# include "args.hh"
|
||||
# include "config-impl.hh"
|
||||
# include "abstract-setting-to-json.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(LocalStore, constructConfig_rootQueryParam)
|
||||
{
|
||||
LocalStoreConfig config{
|
||||
"local",
|
||||
"",
|
||||
{
|
||||
{
|
||||
"root",
|
||||
"/foo/bar",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"});
|
||||
}
|
||||
|
||||
TEST(LocalStore, constructConfig_rootPath)
|
||||
{
|
||||
LocalStoreConfig config{"local", "/foo/bar", {}};
|
||||
|
||||
EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"});
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
#endif
|
|
@ -25,6 +25,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
|
||||
|
@ -58,7 +60,11 @@ sources = files(
|
|||
'derivation.cc',
|
||||
'derived-path.cc',
|
||||
'downstream-placeholder.cc',
|
||||
'http-binary-cache-store.cc',
|
||||
'legacy-ssh-store.cc',
|
||||
'local-binary-cache-store.cc',
|
||||
'local-overlay-store.cc',
|
||||
'local-store.cc',
|
||||
'machines.cc',
|
||||
'nar-info-disk-cache.cc',
|
||||
'nar-info.cc',
|
||||
|
@ -67,9 +73,11 @@ sources = files(
|
|||
'path-info.cc',
|
||||
'path.cc',
|
||||
'references.cc',
|
||||
's3-binary-cache-store.cc',
|
||||
'serve-protocol.cc',
|
||||
'ssh-store.cc',
|
||||
'store-reference.cc',
|
||||
'uds-remote-store.cc',
|
||||
'worker-protocol.cc',
|
||||
)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
@ -42,8 +43,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
|
@ -74,12 +73,8 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
|
@ -94,17 +89,22 @@ mkMesonDerivation (finalAttrs: {
|
|||
../../functional/derivation
|
||||
];
|
||||
};
|
||||
in runCommand "${finalAttrs.pname}-run" {} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
in runCommand "${finalAttrs.pname}-run" {
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${data + "/unit/libstore/data"}
|
||||
nix-store-tests
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'';
|
||||
'');
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = finalAttrs.pname + stdenv.hostPlatform.extensions.executable;
|
||||
};
|
||||
|
||||
})
|
||||
|
|
18
tests/unit/libstore/s3-binary-cache-store.cc
Normal file
18
tests/unit/libstore/s3-binary-cache-store.cc
Normal file
|
@ -0,0 +1,18 @@
|
|||
#if ENABLE_S3
|
||||
|
||||
# include <gtest/gtest.h>
|
||||
|
||||
# include "s3-binary-cache-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(S3BinaryCacheStore, constructConfig)
|
||||
{
|
||||
S3BinaryCacheStoreConfig config{"s3", "foobar", {}};
|
||||
|
||||
EXPECT_EQ(config.bucketName, "foobar");
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
||||
#endif
|
|
@ -1,6 +1,9 @@
|
|||
#include <gtest/gtest.h>
|
||||
// FIXME: Odd failures for templates that are causing the PR to break
|
||||
// for now with discussion with @Ericson2314 to comment out.
|
||||
#if 0
|
||||
# include <gtest/gtest.h>
|
||||
|
||||
#include "ssh-store.hh"
|
||||
# include "ssh-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -15,7 +18,9 @@ TEST(SSHStore, constructConfig)
|
|||
// TODO #11106, no more split on space
|
||||
"foo bar",
|
||||
},
|
||||
}};
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_EQ(
|
||||
config.remoteProgram.get(),
|
||||
(Strings{
|
||||
|
@ -23,4 +28,28 @@ TEST(SSHStore, constructConfig)
|
|||
"bar",
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(MountedSSHStore, constructConfig)
|
||||
{
|
||||
MountedSSHStoreConfig config{
|
||||
"mounted-ssh",
|
||||
"localhost",
|
||||
StoreConfig::Params{
|
||||
{
|
||||
"remote-program",
|
||||
// TODO #11106, no more split on space
|
||||
"foo bar",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_EQ(
|
||||
config.remoteProgram.get(),
|
||||
(Strings{
|
||||
"foo",
|
||||
"bar",
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
23
tests/unit/libstore/uds-remote-store.cc
Normal file
23
tests/unit/libstore/uds-remote-store.cc
Normal file
|
@ -0,0 +1,23 @@
|
|||
// FIXME: Odd failures for templates that are causing the PR to break
|
||||
// for now with discussion with @Ericson2314 to comment out.
|
||||
#if 0
|
||||
# include <gtest/gtest.h>
|
||||
|
||||
# include "uds-remote-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TEST(UDSRemoteStore, constructConfig)
|
||||
{
|
||||
UDSRemoteStoreConfig config{"unix", "/tmp/socket", {}};
|
||||
|
||||
EXPECT_EQ(config.path, "/tmp/socket");
|
||||
}
|
||||
|
||||
TEST(UDSRemoteStore, constructConfigWrongScheme)
|
||||
{
|
||||
EXPECT_THROW(UDSRemoteStoreConfig("http", "/tmp/socket", {}), UsageError);
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
#endif
|
|
@ -658,15 +658,15 @@ TEST_F(WorkerProtoTest, handshake_log)
|
|||
FdSink out { toServer.writeSide.get() };
|
||||
FdSource in0 { toClient.readSide.get() };
|
||||
TeeSource in { in0, toClientLog };
|
||||
clientResult = WorkerProto::BasicClientConnection::handshake(
|
||||
out, in, defaultVersion);
|
||||
clientResult = std::get<0>(WorkerProto::BasicClientConnection::handshake(
|
||||
out, in, defaultVersion, {}));
|
||||
});
|
||||
|
||||
{
|
||||
FdSink out { toClient.writeSide.get() };
|
||||
FdSource in { toServer.readSide.get() };
|
||||
WorkerProto::BasicServerConnection::handshake(
|
||||
out, in, defaultVersion);
|
||||
out, in, defaultVersion, {});
|
||||
};
|
||||
|
||||
thread.join();
|
||||
|
@ -675,6 +675,33 @@ TEST_F(WorkerProtoTest, handshake_log)
|
|||
});
|
||||
}
|
||||
|
||||
TEST_F(WorkerProtoTest, handshake_features)
|
||||
{
|
||||
Pipe toClient, toServer;
|
||||
toClient.create();
|
||||
toServer.create();
|
||||
|
||||
std::tuple<WorkerProto::Version, std::set<WorkerProto::Feature>> clientResult;
|
||||
|
||||
auto clientThread = std::thread([&]() {
|
||||
FdSink out { toServer.writeSide.get() };
|
||||
FdSource in { toClient.readSide.get() };
|
||||
clientResult = WorkerProto::BasicClientConnection::handshake(
|
||||
out, in, 123, {"bar", "aap", "mies", "xyzzy"});
|
||||
});
|
||||
|
||||
FdSink out { toClient.writeSide.get() };
|
||||
FdSource in { toServer.readSide.get() };
|
||||
auto daemonResult = WorkerProto::BasicServerConnection::handshake(
|
||||
out, in, 456, {"foo", "bar", "xyzzy"});
|
||||
|
||||
clientThread.join();
|
||||
|
||||
EXPECT_EQ(clientResult, daemonResult);
|
||||
EXPECT_EQ(std::get<0>(clientResult), 123);
|
||||
EXPECT_EQ(std::get<1>(clientResult), std::set<WorkerProto::Feature>({"bar", "xyzzy"}));
|
||||
}
|
||||
|
||||
/// Has to be a `BufferedSink` for handshake.
|
||||
struct NullBufferedSink : BufferedSink {
|
||||
void writeUnbuffered(std::string_view data) override { }
|
||||
|
@ -686,8 +713,8 @@ TEST_F(WorkerProtoTest, handshake_client_replay)
|
|||
NullBufferedSink nullSink;
|
||||
|
||||
StringSource in { toClientLog };
|
||||
auto clientResult = WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion);
|
||||
auto clientResult = std::get<0>(WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion, {}));
|
||||
|
||||
EXPECT_EQ(clientResult, defaultVersion);
|
||||
});
|
||||
|
@ -705,13 +732,13 @@ TEST_F(WorkerProtoTest, handshake_client_truncated_replay_throws)
|
|||
if (len < 8) {
|
||||
EXPECT_THROW(
|
||||
WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion),
|
||||
nullSink, in, defaultVersion, {}),
|
||||
EndOfFile);
|
||||
} else {
|
||||
// Not sure why cannot keep on checking for `EndOfFile`.
|
||||
EXPECT_THROW(
|
||||
WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion),
|
||||
nullSink, in, defaultVersion, {}),
|
||||
Error);
|
||||
}
|
||||
}
|
||||
|
@ -734,17 +761,17 @@ TEST_F(WorkerProtoTest, handshake_client_corrupted_throws)
|
|||
// magic bytes don't match
|
||||
EXPECT_THROW(
|
||||
WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion),
|
||||
nullSink, in, defaultVersion, {}),
|
||||
Error);
|
||||
} else if (idx < 8 || idx >= 12) {
|
||||
// Number out of bounds
|
||||
EXPECT_THROW(
|
||||
WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion),
|
||||
nullSink, in, defaultVersion, {}),
|
||||
SerialisationError);
|
||||
} else {
|
||||
auto ver = WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion);
|
||||
auto ver = std::get<0>(WorkerProto::BasicClientConnection::handshake(
|
||||
nullSink, in, defaultVersion, {}));
|
||||
// `std::min` of this and the other version saves us
|
||||
EXPECT_EQ(ver, defaultVersion);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
||||
|
|
|
@ -64,12 +64,8 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace nix::testing {
|
||||
|
||||
void observe_string_cb(const char * start, unsigned int n, std::string * user_data)
|
||||
void observe_string_cb(const char * start, unsigned int n, void * user_data)
|
||||
{
|
||||
*user_data = std::string(start);
|
||||
auto user_data_casted = reinterpret_cast<std::string *>(user_data);
|
||||
*user_data_casted = std::string(start);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
namespace nix::testing {
|
||||
|
||||
void observe_string_cb(const char * start, unsigned int n, std::string * user_data);
|
||||
void observe_string_cb(const char * start, unsigned int n, void * user_data);
|
||||
|
||||
inline void * observe_string_cb_data(std::string & out)
|
||||
{
|
||||
return (void *) &out;
|
||||
};
|
||||
|
||||
#define OBSERVE_STRING(str) \
|
||||
(nix_get_string_callback) nix::testing::observe_string_cb, nix::testing::observe_string_cb_data(str)
|
||||
#define OBSERVE_STRING(str) nix::testing::observe_string_cb, nix::testing::observe_string_cb_data(str)
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ deps_public_maybe_subproject = [
|
|||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/threads')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ lib
|
||||
, buildPackages
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
@ -40,8 +41,6 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
|
@ -71,28 +70,28 @@ mkMesonDerivation (finalAttrs: {
|
|||
LDFLAGS = "-fuse-ld=gold";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
|
||||
} (lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export HOME="$PWD/home-dir"
|
||||
mkdir -p "$HOME"
|
||||
'' + ''
|
||||
export _NIX_TEST_UNIT_DATA=${./data}
|
||||
nix-util-tests
|
||||
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
|
||||
touch $out
|
||||
'';
|
||||
'');
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
mainProgram = finalAttrs.pname + stdenv.hostPlatform.extensions.executable;
|
||||
};
|
||||
|
||||
})
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
# define FS_ROOT FS_SEP
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
namespace nix {
|
||||
|
||||
/* ----------- tests for util.hh ------------------------------------------------*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue