1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-13 17:10:47 +02:00

Tagging release 2.26.2

-----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCAAxFiEEtUHVUwEnDgvPFcpdgXC0cm1xmN4FAmetA5oTHGVkb2xzdHJh
 QGdtYWlsLmNvbQAKCRCBcLRybXGY3g2pB/9JAFyjmaXuccbMTO/6x9qwsWuuXNLk
 OQWzfbdUekvsihZZSFZg1r7KqqXHCi64f0nxLPsJ/0oeDWZktJ5KnbV630nuUlDj
 ulLCpKdvhWFa8dVx9LiziGwQw4KLx8PjOfwThtQ4DqCWxWEmu6lKkijag9cE+ai4
 3mw9YtUjBRxlXyhYLzWz3whLbv37c/m+R8iGS8xm8W260pmei6D0beOIPdfXYBQF
 PzPlPORyI08A06uqyA3z7bTxzmSMnzvu0QInCPCKSHzFUnTZPHUYuYStFl28NrZS
 fXKK59L0G7QEfdTRAmqQkdHdtPj2RlYFiMN0kQiNLflvKfGGWdi/kvdx
 =rRix
 -----END PGP SIGNATURE-----

Merge tag '2.26.2' into sync-2.26.2

Tagging release 2.26.2
This commit is contained in:
Eelco Dolstra 2025-02-18 19:56:22 +01:00
commit 4055239936
1395 changed files with 24694 additions and 16040 deletions

1
tests/functional/.version Symbolic link
View file

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

View file

@ -29,6 +29,47 @@ echo "$hash2"
test "$hash1" = "sha256:$hash2"
# The contents can be accessed through a symlink, and this symlink has no effect on the hash
# https://github.com/NixOS/nix/issues/11941
test_issue_11941() {
local expected actual
mkdir -p "$TEST_ROOT/foo/bar" && ln -s "$TEST_ROOT/foo" "$TEST_ROOT/foo-link"
# legacy
expected=$(nix-store --add-fixed --recursive sha256 "$TEST_ROOT/foo/bar")
actual=$(nix-store --add-fixed --recursive sha256 "$TEST_ROOT/foo-link/bar")
[[ "$expected" == "$actual" ]]
actual=$(nix-store --add "$TEST_ROOT/foo-link/bar")
[[ "$expected" == "$actual" ]]
# nix store add
actual=$(nix store add --hash-algo sha256 --mode nar "$TEST_ROOT/foo/bar")
[[ "$expected" == "$actual" ]]
# cleanup
rm -r "$TEST_ROOT/foo" "$TEST_ROOT/foo-link"
}
test_issue_11941
# A symlink is added to the store as a symlink, not as a copy of the target
test_add_symlink() {
ln -s /bin "$TEST_ROOT/my-bin"
# legacy
path=$(nix-store --add-fixed --recursive sha256 "$TEST_ROOT/my-bin")
[[ "$(readlink "$path")" == /bin ]]
path=$(nix-store --add "$TEST_ROOT/my-bin")
[[ "$(readlink "$path")" == /bin ]]
# nix store add
path=$(nix store add --hash-algo sha256 --mode nar "$TEST_ROOT/my-bin")
[[ "$(readlink "$path")" == /bin ]]
# cleanup
rm "$TEST_ROOT/my-bin"
}
test_add_symlink
#### New style commands
clearStoreIfPossible

View file

@ -1,6 +1,25 @@
let
sixteenBytes = "0123456789abcdef";
times16 = s: builtins.concatStringsSep "" [s s s s s s s s s s s s s s s s];
times16 =
s:
builtins.concatStringsSep "" [
s
s
s
s
s
s
s
s
s
s
s
s
s
s
s
s
];
exp = n: x: if n == 1 then x else times16 (exp (n - 1) x);
sixteenMegabyte = exp 6 sixteenBytes;
in

View file

@ -238,7 +238,7 @@ clearCache
# preserve quotes variables in the single-quoted string
# shellcheck disable=SC2016
outPath=$(nix-build --no-out-link -E '
with import ./config.nix;
with import '"${config_nix}"';
mkDerivation {
name = "nar-listing";
buildCommand = "mkdir $out; echo foo > $out/bar; ln -s xyzzy $out/link";
@ -258,7 +258,7 @@ clearCache
# preserve quotes variables in the single-quoted string
# shellcheck disable=SC2016
outPath=$(nix-build --no-out-link -E '
with import ./config.nix;
with import '"${config_nix}"';
mkDerivation {
name = "debug-info";
buildCommand = "mkdir -p $out/lib/debug/.build-id/02; echo foo > $out/lib/debug/.build-id/02/623eda209c26a59b1a8638ff7752f6b945c26b.debug";
@ -276,7 +276,7 @@ diff -u \
# preserve quotes variables in the single-quoted string
# shellcheck disable=SC2016
expr='
with import ./config.nix;
with import '"${config_nix}"';
mkDerivation {
name = "multi-output";
buildCommand = "mkdir -p $out; echo foo > $doc; echo $doc > $out/docref";

View file

@ -4,24 +4,39 @@ with import ./config.nix;
let
mkDerivation = args:
derivation ({
inherit system;
builder = busybox;
args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')];
outputHashMode = "recursive";
outputHashAlgo = "sha256";
} // removeAttrs args ["builder" "meta" "passthru"])
// { meta = args.meta or {}; passthru = args.passthru or {}; };
mkDerivation =
args:
derivation (
{
inherit system;
builder = busybox;
args = [
"sh"
"-e"
args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')
];
outputHashMode = "recursive";
outputHashAlgo = "sha256";
}
// removeAttrs args [
"builder"
"meta"
"passthru"
]
)
// {
meta = args.meta or { };
passthru = args.passthru or { };
};
input1 = mkDerivation {
shell = busybox;
name = "build-remote-input-1";
buildCommand = "echo hi-input1; echo FOO > $out";
requiredSystemFeatures = ["foo"];
requiredSystemFeatures = [ "foo" ];
outputHash = "sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc=";
};
@ -29,7 +44,7 @@ let
shell = busybox;
name = "build-remote-input-2";
buildCommand = "echo hi; echo BAR > $out";
requiredSystemFeatures = ["bar"];
requiredSystemFeatures = [ "bar" ];
outputHash = "sha256-XArauVH91AVwP9hBBQNlkX9ccuPpSYx9o0zeIHb6e+Q=";
};
@ -41,21 +56,20 @@ let
read x < ${input2}
echo $x BAZ > $out
'';
requiredSystemFeatures = ["baz"];
requiredSystemFeatures = [ "baz" ];
outputHash = "sha256-daKAcPp/+BYMQsVi/YYMlCKoNAxCNDsaivwSHgQqD2s=";
};
in
mkDerivation {
shell = busybox;
name = "build-remote";
passthru = { inherit input1 input2 input3; };
buildCommand =
''
read x < ${input1}
read y < ${input3}
echo "$x $y" > $out
'';
outputHash = "sha256-5SxbkUw6xe2l9TE1uwCvTtTDysD1vhRor38OtDF0LqQ=";
}
mkDerivation {
shell = busybox;
name = "build-remote";
passthru = { inherit input1 input2 input3; };
buildCommand = ''
read x < ${input1}
read y < ${input3}
echo "$x $y" > $out
'';
outputHash = "sha256-5SxbkUw6xe2l9TE1uwCvTtTDysD1vhRor38OtDF0LqQ=";
}

View file

@ -1,39 +1,61 @@
{ busybox, contentAddressed ? false }:
{
busybox,
contentAddressed ? false,
}:
with import ./config.nix;
let
caArgs = if contentAddressed then {
outputHashMode = "recursive";
outputHashAlgo = "sha256";
__contentAddressed = true;
} else {};
caArgs =
if contentAddressed then
{
outputHashMode = "recursive";
outputHashAlgo = "sha256";
__contentAddressed = true;
}
else
{ };
mkDerivation = args:
derivation ({
inherit system;
builder = busybox;
args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')];
} // removeAttrs args ["builder" "meta" "passthru"]
// caArgs)
// { meta = args.meta or {}; passthru = args.passthru or {}; };
mkDerivation =
args:
derivation (
{
inherit system;
builder = busybox;
args = [
"sh"
"-e"
args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')
];
}
// removeAttrs args [
"builder"
"meta"
"passthru"
]
// caArgs
)
// {
meta = args.meta or { };
passthru = args.passthru or { };
};
input1 = mkDerivation {
shell = busybox;
name = "build-remote-input-1";
buildCommand = "echo hi-input1; echo FOO > $out";
requiredSystemFeatures = ["foo"];
requiredSystemFeatures = [ "foo" ];
};
input2 = mkDerivation {
shell = busybox;
name = "build-remote-input-2";
buildCommand = "echo hi; echo BAR > $out";
requiredSystemFeatures = ["bar"];
requiredSystemFeatures = [ "bar" ];
};
input3 = mkDerivation {
@ -44,19 +66,18 @@ let
read x < ${input2}
echo $x BAZ > $out
'';
requiredSystemFeatures = ["baz"];
requiredSystemFeatures = [ "baz" ];
};
in
mkDerivation {
shell = busybox;
name = "build-remote";
passthru = { inherit input1 input2 input3; };
buildCommand =
''
read x < ${input1}
read y < ${input3}
echo "$x $y" > $out
'';
}
mkDerivation {
shell = busybox;
name = "build-remote";
passthru = { inherit input1 input2 input3; };
buildCommand = ''
read x < ${input1}
read y < ${input3}
echo "$x $y" > $out
'';
}

View file

@ -8,6 +8,7 @@ TODO_NixOS
restartDaemon
requireSandboxSupport
requiresUnprivilegedUserNamespaces
[[ $busybox =~ busybox ]] || skipTest "no busybox"
unset NIX_STORE_DIR

View file

@ -5,6 +5,7 @@
# shellcheck disable=SC2154
requireSandboxSupport
requiresUnprivilegedUserNamespaces
[[ "$busybox" =~ busybox ]] || skipTest "no busybox"
unset NIX_STORE_DIR

View file

@ -3,6 +3,7 @@
: "${file?must be defined by caller (remote building test case using this)}"
requireSandboxSupport
requiresUnprivilegedUserNamespaces
[[ "${busybox-}" =~ busybox ]] || skipTest "no busybox"
# Avoid store dir being inside sandbox build-dir
@ -27,6 +28,7 @@ builders=(
chmod -R +w "$TEST_ROOT/machine"* || true
rm -rf "$TEST_ROOT/machine"* || true
# Note: ssh://localhost bypasses ssh, directly invoking nix-store as a
# child process. This allows us to test LegacySSHStore::buildDerivation().
# ssh-ng://... likewise allows us to test RemoteStore::buildDerivation().

View file

@ -84,6 +84,7 @@ expectStderr 1 nix build --expr '""' --no-link \
| grepQuiet "has 0 entries in its context. It should only have exactly one entry"
# Too much string context
# shellcheck disable=SC2016 # The ${} in this is Nix, not shell
expectStderr 1 nix build --impure --expr 'with (import ./multiple-outputs.nix).e.a_a; "${drvPath}${outPath}"' --no-link \
| grepQuiet "has 2 entries in its context. It should only have exactly one entry"
@ -160,7 +161,7 @@ printf "%s\n" "$drv^*" | nix build --no-link --stdin --json | jq --exit-status '
out="$(nix build -f fod-failing.nix -L 2>&1)" && status=0 || status=$?
test "$status" = 1
# one "hash mismatch" error, one "build of ... failed"
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2
test "$(<<<"$out" grep -cE '^error:')" = 2
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
@ -169,7 +170,7 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2
out="$(nix build -f fod-failing.nix -L x1 x2 x3 --keep-going 2>&1)" && status=0 || status=$?
test "$status" = 1
# three "hash mismatch" errors - for each failing fod, one "build of ... failed"
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 4
test "$(<<<"$out" grep -cE '^error:')" = 4
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
@ -177,13 +178,13 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 4
out="$(nix build -f fod-failing.nix -L x4 2>&1)" && status=0 || status=$?
test "$status" = 1
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2
test "$(<<<"$out" grep -cE '^error:')" = 2
<<<"$out" grepQuiet -E "error: 1 dependencies of derivation '.*-x4\\.drv' failed to build"
<<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x2\\.drv'"
out="$(nix build -f fod-failing.nix -L x4 --keep-going 2>&1)" && status=0 || status=$?
test "$status" = 1
test "$(<<<"$out" grep -E '^error:' | wc -l)" = 3
test "$(<<<"$out" grep -cE '^error:')" = 3
<<<"$out" grepQuiet -E "error: 2 dependencies of derivation '.*-x4\\.drv' failed to build"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'"
<<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'"

View file

@ -1 +1,5 @@
{ inNixShell ? false, ... }@args: import ./shell.nix (args // { contentAddressed = true; })
{
inNixShell ? false,
...
}@args:
import ./shell.nix (args // { contentAddressed = true; })

View file

@ -0,0 +1,2 @@
# Shim to get generated file
import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/ca/config.nix"

View file

@ -1,13 +1,21 @@
with import ./config.nix;
let mkCADerivation = args: mkDerivation ({
__contentAddressed = true;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
} // args);
let
mkCADerivation =
args:
mkDerivation (
{
__contentAddressed = true;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
}
// args
);
in
{ seed ? 0 }:
{
seed ? 0,
}:
# A simple content-addressed derivation.
# The derivation can be arbitrarily modified by passing a different `seed`,
# but the output will always be the same
@ -23,7 +31,11 @@ rec {
};
rootCA = mkCADerivation {
name = "rootCA";
outputs = [ "out" "dev" "foo" ];
outputs = [
"out"
"dev"
"foo"
];
buildCommand = ''
echo "building a CA derivation"
echo "The seed is ${toString seed}"

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#
source common.sh
export NIX_TESTS_CA_BY_DEFAULT=1

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash
source ./common.sh
source common.sh
requireDaemonNewerThan "2.4pre20210625"

View file

@ -1,3 +1,3 @@
{
outputs = { self }: import ./content-addressed.nix {};
outputs = { self }: import ./content-addressed.nix { };
}

View file

@ -1,6 +0,0 @@
source common.sh
export NIX_TESTS_CA_BY_DEFAULT=1
cd .. && source import-derivation.sh

View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
source common.sh
export NIX_TESTS_CA_BY_DEFAULT=1
cd .. && source import-from-derivation.sh

View file

@ -1,29 +0,0 @@
ca-tests := \
$(d)/build-with-garbage-path.sh \
$(d)/build.sh \
$(d)/build-cache.sh \
$(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 \
$(d)/nix-copy.sh \
$(d)/nix-run.sh \
$(d)/nix-shell.sh \
$(d)/post-hook.sh \
$(d)/recursive.sh \
$(d)/repl.sh \
$(d)/selfref-gc.sh \
$(d)/signatures.sh \
$(d)/substitute.sh \
$(d)/why-depends.sh
install-tests-groups += ca
clean-files += \
$(d)/config.nix
test-deps += \
tests/functional/ca/config.nix

View file

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

View file

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

View file

@ -2,6 +2,8 @@
source common.sh
FLAKE_PATH=path:$PWD
flakeDir="$TEST_HOME/flake"
mkdir -p "${flakeDir}"
cp flake.nix "${_NIX_TEST_BUILD_DIR}/ca/config.nix" content-addressed.nix "${flakeDir}"
nix run --no-write-lock-file "$FLAKE_PATH#runnable"
nix run --no-write-lock-file "path:${flakeDir}#runnable"

View file

@ -5,4 +5,3 @@ source common.sh
CONTENT_ADDRESSED=true
cd ..
source ./nix-shell.sh

View file

@ -1,10 +1,16 @@
with import ./config.nix;
let mkCADerivation = args: mkDerivation ({
__contentAddressed = true;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
} // args);
let
mkCADerivation =
args:
mkDerivation (
{
__contentAddressed = true;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
}
// args
);
in
rec {
@ -15,13 +21,15 @@ rec {
echo $(date) > $out/current-time
'';
};
dep = seed: mkCADerivation {
name = "dep";
inherit seed;
buildCommand = ''
echo ${currentTime} > $out
'';
};
dep =
seed:
mkCADerivation {
name = "dep";
inherit seed;
buildCommand = ''
echo ${currentTime} > $out
'';
};
dep1 = dep 1;
dep2 = dep 2;
toplevel = mkCADerivation {
@ -32,4 +40,3 @@ rec {
'';
};
}

View file

@ -1,7 +1,6 @@
# A derivation that would certainly fail if several builders tried to
# build it at once.
with import ./config.nix;
mkDerivation {

View file

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

View file

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

View file

@ -2,11 +2,16 @@ with import ./config.nix;
rec {
dep = import ./dependencies.nix {};
dep = import ./dependencies.nix { };
makeTest = nr: args: mkDerivation ({
name = "check-refs-" + toString nr;
} // args);
makeTest =
nr: args:
mkDerivation (
{
name = "check-refs-" + toString nr;
}
// args
);
src = builtins.toFile "aux-ref" "bla bla";
@ -22,31 +27,31 @@ rec {
test3 = makeTest 3 {
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link";
allowedReferences = [];
allowedReferences = [ ];
inherit dep;
};
test4 = makeTest 4 {
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link";
allowedReferences = [dep];
allowedReferences = [ dep ];
inherit dep;
};
test5 = makeTest 5 {
builder = builtins.toFile "builder.sh" "mkdir $out";
allowedReferences = [];
allowedReferences = [ ];
inherit dep;
};
test6 = makeTest 6 {
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $out $out/link";
allowedReferences = [];
allowedReferences = [ ];
inherit dep;
};
test7 = makeTest 7 {
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $out $out/link";
allowedReferences = ["out"];
allowedReferences = [ "out" ];
inherit dep;
};
@ -58,19 +63,19 @@ rec {
test9 = makeTest 9 {
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $dep $out/link";
inherit dep;
disallowedReferences = [dep];
disallowedReferences = [ dep ];
};
test10 = makeTest 10 {
builder = builtins.toFile "builder.sh" "mkdir $out; echo $test5; ln -s $dep $out/link";
inherit dep test5;
disallowedReferences = [test5];
disallowedReferences = [ test5 ];
};
test11 = makeTest 11 {
__structuredAttrs = true;
unsafeDiscardReferences.out = true;
outputChecks.out.allowedReferences = [];
outputChecks.out.allowedReferences = [ ];
buildCommand = ''echo ${dep} > "''${outputs[out]}"'';
};

View file

@ -22,36 +22,48 @@ rec {
'';
};
makeTest = nr: allowreqs: mkDerivation {
name = "check-reqs-" + toString nr;
inherit deps;
builder = builtins.toFile "builder.sh" ''
mkdir $out
ln -s $deps $out/depdir1
'';
allowedRequisites = allowreqs;
};
makeTest =
nr: allowreqs:
mkDerivation {
name = "check-reqs-" + toString nr;
inherit deps;
builder = builtins.toFile "builder.sh" ''
mkdir $out
ln -s $deps $out/depdir1
'';
allowedRequisites = allowreqs;
};
# When specifying all the requisites, the build succeeds.
test1 = makeTest 1 [ dep1 dep2 deps ];
test1 = makeTest 1 [
dep1
dep2
deps
];
# But missing anything it fails.
test2 = makeTest 2 [ dep2 deps ];
test3 = makeTest 3 [ dep1 deps ];
test2 = makeTest 2 [
dep2
deps
];
test3 = makeTest 3 [
dep1
deps
];
test4 = makeTest 4 [ deps ];
test5 = makeTest 5 [];
test5 = makeTest 5 [ ];
test6 = mkDerivation {
name = "check-reqs";
inherit deps;
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $deps $out/depdir1";
disallowedRequisites = [dep1];
disallowedRequisites = [ dep1 ];
};
test7 = mkDerivation {
name = "check-reqs";
inherit deps;
builder = builtins.toFile "builder.sh" "mkdir $out; ln -s $deps $out/depdir1";
disallowedRequisites = [test1];
disallowedRequisites = [ test1 ];
};
}

View file

@ -1,4 +1,6 @@
{checkBuildId ? 0}:
{
checkBuildId ? 0,
}:
with import ./config.nix;
@ -6,41 +8,38 @@ with import ./config.nix;
nondeterministic = mkDerivation {
inherit checkBuildId;
name = "nondeterministic";
buildCommand =
''
mkdir $out
date +%s.%N > $out/date
echo "CHECK_TMPDIR=$TMPDIR"
echo "checkBuildId=$checkBuildId"
echo "$checkBuildId" > $TMPDIR/checkBuildId
'';
buildCommand = ''
mkdir $out
date +%s.%N > $out/date
echo "CHECK_TMPDIR=$TMPDIR"
echo "checkBuildId=$checkBuildId"
echo "$checkBuildId" > $TMPDIR/checkBuildId
'';
};
deterministic = mkDerivation {
inherit checkBuildId;
name = "deterministic";
buildCommand =
''
mkdir $out
echo date > $out/date
echo "CHECK_TMPDIR=$TMPDIR"
echo "checkBuildId=$checkBuildId"
echo "$checkBuildId" > $TMPDIR/checkBuildId
'';
buildCommand = ''
mkdir $out
echo date > $out/date
echo "CHECK_TMPDIR=$TMPDIR"
echo "checkBuildId=$checkBuildId"
echo "$checkBuildId" > $TMPDIR/checkBuildId
'';
};
failed = mkDerivation {
inherit checkBuildId;
name = "failed";
buildCommand =
''
mkdir $out
echo date > $out/date
echo "CHECK_TMPDIR=$TMPDIR"
echo "checkBuildId=$checkBuildId"
echo "$checkBuildId" > $TMPDIR/checkBuildId
false
'';
buildCommand = ''
mkdir $out
echo date > $out/date
echo "CHECK_TMPDIR=$TMPDIR"
echo "checkBuildId=$checkBuildId"
echo "$checkBuildId" > $TMPDIR/checkBuildId
false
'';
};
hashmismatch = import <nix/fetchurl.nix> {

View file

@ -7,9 +7,9 @@ buggyNeedLocalStore "see #4813"
checkBuildTempDirRemoved ()
{
buildDir=$(sed -n 's/CHECK_TMPDIR=//p' $1 | head -1)
buildDir=$(sed -n 's/CHECK_TMPDIR=//p' "$1" | head -1)
checkBuildIdFile=${buildDir}/checkBuildId
[[ ! -f $checkBuildIdFile ]] || ! grep $checkBuildId $checkBuildIdFile
[[ ! -f $checkBuildIdFile ]] || ! grep "$checkBuildId" "$checkBuildIdFile"
}
# written to build temp directories to verify created by this instance
@ -23,20 +23,20 @@ nix-build dependencies.nix --no-out-link
nix-build dependencies.nix --no-out-link --check
# Build failure exit codes (100, 104, etc.) are from
# doc/manual/src/command-ref/status-build-failure.md
# doc/manual/source/command-ref/status-build-failure.md
# check for dangling temporary build directories
# only retain if build fails and --keep-failed is specified, or...
# ...build is non-deterministic and --check and --keep-failed are both specified
nix-build check.nix -A failed --argstr checkBuildId $checkBuildId \
--no-out-link 2> $TEST_ROOT/log || status=$?
nix-build check.nix -A failed --argstr checkBuildId "$checkBuildId" \
--no-out-link 2> "$TEST_ROOT/log" || status=$?
[ "$status" = "100" ]
checkBuildTempDirRemoved $TEST_ROOT/log
checkBuildTempDirRemoved "$TEST_ROOT/log"
nix-build check.nix -A failed --argstr checkBuildId $checkBuildId \
--no-out-link --keep-failed 2> $TEST_ROOT/log || status=$?
nix-build check.nix -A failed --argstr checkBuildId "$checkBuildId" \
--no-out-link --keep-failed 2> "$TEST_ROOT/log" || status=$?
[ "$status" = "100" ]
if checkBuildTempDirRemoved $TEST_ROOT/log; then false; fi
if checkBuildTempDirRemoved "$TEST_ROOT/log"; then false; fi
test_custom_build_dir() {
local customBuildDir="$TEST_ROOT/custom-build-dir"
@ -44,42 +44,46 @@ test_custom_build_dir() {
# Nix does not create the parent directories, and perhaps it shouldn't try to
# decide the permissions of build-dir.
mkdir "$customBuildDir"
nix-build check.nix -A failed --argstr checkBuildId $checkBuildId \
--no-out-link --keep-failed --option build-dir "$TEST_ROOT/custom-build-dir" 2> $TEST_ROOT/log || status=$?
nix-build check.nix -A failed --argstr checkBuildId "$checkBuildId" \
--no-out-link --keep-failed --option build-dir "$TEST_ROOT/custom-build-dir" 2> "$TEST_ROOT/log" || status=$?
[ "$status" = "100" ]
[[ 1 == "$(count "$customBuildDir/nix-build-"*)" ]]
local buildDir="$customBuildDir/nix-build-"*""
if [[ -e $buildDir/build ]]; then
buildDir=$buildDir/build
local buildDir=("$customBuildDir/nix-build-"*)
if [[ "${#buildDir[@]}" -ne 1 ]]; then
echo "expected one nix-build-* directory, got: ${buildDir[*]}" >&2
exit 1
fi
grep $checkBuildId $buildDir/checkBuildId
if [[ -e ${buildDir[*]}/build ]]; then
buildDir[0]="${buildDir[*]}/build"
fi
grep "$checkBuildId" "${buildDir[*]}/checkBuildId"
}
test_custom_build_dir
nix-build check.nix -A deterministic --argstr checkBuildId $checkBuildId \
--no-out-link 2> $TEST_ROOT/log
checkBuildTempDirRemoved $TEST_ROOT/log
nix-build check.nix -A deterministic --argstr checkBuildId "$checkBuildId" \
--no-out-link 2> "$TEST_ROOT/log"
checkBuildTempDirRemoved "$TEST_ROOT/log"
nix-build check.nix -A deterministic --argstr checkBuildId $checkBuildId \
--no-out-link --check --keep-failed 2> $TEST_ROOT/log
if grepQuiet 'may not be deterministic' $TEST_ROOT/log; then false; fi
checkBuildTempDirRemoved $TEST_ROOT/log
nix-build check.nix -A deterministic --argstr checkBuildId "$checkBuildId" \
--no-out-link --check --keep-failed 2> "$TEST_ROOT/log"
if grepQuiet 'may not be deterministic' "$TEST_ROOT/log"; then false; fi
checkBuildTempDirRemoved "$TEST_ROOT/log"
nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \
--no-out-link 2> $TEST_ROOT/log
checkBuildTempDirRemoved $TEST_ROOT/log
nix-build check.nix -A nondeterministic --argstr checkBuildId "$checkBuildId" \
--no-out-link 2> "$TEST_ROOT/log"
checkBuildTempDirRemoved "$TEST_ROOT/log"
nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \
--no-out-link --check 2> $TEST_ROOT/log || status=$?
grep 'may not be deterministic' $TEST_ROOT/log
nix-build check.nix -A nondeterministic --argstr checkBuildId "$checkBuildId" \
--no-out-link --check 2> "$TEST_ROOT/log" || status=$?
grep 'may not be deterministic' "$TEST_ROOT/log"
[ "$status" = "104" ]
checkBuildTempDirRemoved $TEST_ROOT/log
checkBuildTempDirRemoved "$TEST_ROOT/log"
nix-build check.nix -A nondeterministic --argstr checkBuildId $checkBuildId \
--no-out-link --check --keep-failed 2> $TEST_ROOT/log || status=$?
grep 'may not be deterministic' $TEST_ROOT/log
nix-build check.nix -A nondeterministic --argstr checkBuildId "$checkBuildId" \
--no-out-link --check --keep-failed 2> "$TEST_ROOT/log" || status=$?
grep 'may not be deterministic' "$TEST_ROOT/log"
[ "$status" = "104" ]
if checkBuildTempDirRemoved $TEST_ROOT/log; then false; fi
if checkBuildTempDirRemoved "$TEST_ROOT/log"; then false; fi
TODO_NixOS
@ -87,24 +91,24 @@ clearStore
path=$(nix-build check.nix -A fetchurl --no-out-link)
chmod +w $path
echo foo > $path
chmod -w $path
chmod +w "$path"
echo foo > "$path"
chmod -w "$path"
nix-build check.nix -A fetchurl --no-out-link --check
# Note: "check" doesn't repair anything, it just compares to the hash stored in the database.
[[ $(cat $path) = foo ]]
[[ $(cat "$path") = foo ]]
nix-build check.nix -A fetchurl --no-out-link --repair
[[ $(cat $path) != foo ]]
[[ $(cat "$path") != foo ]]
echo 'Hello World' > $TEST_ROOT/dummy
echo 'Hello World' > "$TEST_ROOT/dummy"
nix-build check.nix -A hashmismatch --no-out-link || status=$?
[ "$status" = "102" ]
echo -n > $TEST_ROOT/dummy
echo -n > "$TEST_ROOT/dummy"
nix-build check.nix -A hashmismatch --no-out-link
echo 'Hello World' > $TEST_ROOT/dummy
echo 'Hello World' > "$TEST_ROOT/dummy"
nix-build check.nix -A hashmismatch --no-out-link --check || status=$?
[ "$status" = "102" ]

View file

@ -37,9 +37,10 @@ if canUseSandbox; then
}
EOF
cp simple.nix shell.nix simple.builder.sh config.nix "$flakeDir/"
cp simple.nix shell.nix simple.builder.sh "${config_nix}" "$flakeDir/"
TODO_NixOS
requiresUnprivilegedUserNamespaces
outPath=$(nix build --print-out-paths --no-link --sandbox-paths '/nix? /bin? /lib? /lib64? /usr?' --store "$TEST_ROOT/x" path:"$flakeDir")

View file

@ -8,7 +8,8 @@ COMMON_SH_SOURCED=1
functionalTestsDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
source "$functionalTestsDir/common/vars-and-functions.sh"
source "$functionalTestsDir/common/vars.sh"
source "$functionalTestsDir/common/functions.sh"
source "$functionalTestsDir/common/init.sh"
if [[ -n "${NIX_DAEMON_PACKAGE:-}" ]]; then

View file

@ -1,10 +1,10 @@
# NOTE: instances of @variable@ are substituted as defined in /mk/templates.mk
# shellcheck shell=bash
set -eu -o pipefail
if [[ -z "${COMMON_VARS_AND_FUNCTIONS_SH_SOURCED-}" ]]; then
if [[ -z "${COMMON_FUNCTIONS_SH_SOURCED-}" ]]; then
COMMON_VARS_AND_FUNCTIONS_SH_SOURCED=1
COMMON_FUNCTIONS_SH_SOURCED=1
isTestOnNixOS() {
[[ "${isTestOnNixOS:-}" == 1 ]]
@ -15,70 +15,20 @@ die() {
exit 1
}
set +x
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
source "$commonDir/subst-vars.sh"
# Make sure shellcheck knows all these will be defined by the above generated snippet
: "${bindir?} ${coreutils?} ${dot?} ${SHELL?} ${PAGER?} ${busybox?} ${version?} ${system?} ${BUILD_SHARED_LIBS?}"
source "$commonDir/paths.sh"
source "$commonDir/test-root.sh"
test_nix_conf_dir=$TEST_ROOT/etc
test_nix_conf=$test_nix_conf_dir/nix.conf
export TEST_HOME=$TEST_ROOT/test-home
if ! isTestOnNixOS; then
export NIX_STORE_DIR
if ! NIX_STORE_DIR=$(readlink -f $TEST_ROOT/store 2> /dev/null); then
# Maybe the build directory is symlinked.
export NIX_IGNORE_SYMLINK_STORE=1
NIX_STORE_DIR=$TEST_ROOT/store
fi
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_CONF_DIR=$test_nix_conf_dir
export NIX_DAEMON_SOCKET_PATH=$TEST_ROOT/dSocket
unset NIX_USER_CONF_FILES
export _NIX_TEST_SHARED=$TEST_ROOT/shared
if [[ -n $NIX_STORE ]]; then
export _NIX_TEST_NO_SANDBOX=1
fi
export _NIX_IN_TEST=$TEST_ROOT/shared
export _NIX_TEST_NO_LSOF=1
export NIX_REMOTE=${NIX_REMOTE_-}
fi # ! isTestOnNixOS
unset NIX_PATH
export HOME=$TEST_HOME
unset XDG_STATE_HOME
unset XDG_DATA_HOME
unset XDG_CONFIG_HOME
unset XDG_CONFIG_DIRS
unset XDG_CACHE_HOME
export IMPURE_VAR1=foo
export IMPURE_VAR2=bar
cacheDir=$TEST_ROOT/binary-cache
readLink() {
# TODO fix this
# shellcheck disable=SC2012
ls -l "$1" | sed 's/.*->\ //'
}
clearProfiles() {
profiles="$HOME"/.local/state/nix/profiles
profiles="$HOME/.local/state/nix/profiles"
rm -rf "$profiles"
}
# Clear the store, but do not fail if we're in an environment where we can't.
# This allows the test to run in a NixOS test environment, where we use the system store.
# See doc/manual/src/contributing/testing.md / Running functional tests on NixOS.
# See doc/manual/source/contributing/testing.md / Running functional tests on NixOS.
clearStoreIfPossible() {
if isTestOnNixOS; then
echo "clearStoreIfPossible: Not clearing store, because we're on NixOS. Moving on."
@ -105,11 +55,11 @@ doClearStore() {
}
clearCache() {
rm -rf "$cacheDir"
rm -rf "${cacheDir?}"
}
clearCacheCache() {
rm -f $TEST_HOME/.cache/nix/binary-cache*
rm -f "$TEST_HOME/.cache/nix/binary-cache"*
}
startDaemon() {
@ -122,9 +72,9 @@ startDaemon() {
return
fi
# Start the daemon, wait for the socket to appear.
rm -f $NIX_DAEMON_SOCKET_PATH
rm -f "$NIX_DAEMON_SOCKET_PATH"
# TODO: remove the nix-command feature when we're no longer testing against old daemons.
PATH=$DAEMON_PATH nix daemon --extra-experimental-features nix-command &
PATH=$DAEMON_PATH nix --extra-experimental-features 'nix-command' daemon &
_NIX_TEST_DAEMON_PID=$!
export _NIX_TEST_DAEMON_PID
for ((i = 0; i < 300; i++)); do
@ -152,14 +102,14 @@ killDaemon() {
if [[ "${_NIX_TEST_DAEMON_PID-}" == '' ]]; then
return
fi
kill $_NIX_TEST_DAEMON_PID
kill "$_NIX_TEST_DAEMON_PID"
for i in {0..100}; do
kill -0 $_NIX_TEST_DAEMON_PID 2> /dev/null || break
kill -0 "$_NIX_TEST_DAEMON_PID" 2> /dev/null || break
sleep 0.1
done
kill -9 $_NIX_TEST_DAEMON_PID 2> /dev/null || true
wait $_NIX_TEST_DAEMON_PID || true
rm -f $NIX_DAEMON_SOCKET_PATH
kill -9 "$_NIX_TEST_DAEMON_PID" 2> /dev/null || true
wait "$_NIX_TEST_DAEMON_PID" || true
rm -f "$NIX_DAEMON_SOCKET_PATH"
# Indicate daemon is stopped
unset _NIX_TEST_DAEMON_PID
# Restore old nix remote
@ -178,14 +128,11 @@ restartDaemon() {
startDaemon
}
if [[ $(uname) == Linux ]] && [[ -L /proc/self/ns/user ]] && unshare --user true; then
_canUseSandbox=1
fi
isDaemonNewer () {
[[ -n "${NIX_DAEMON_PACKAGE:-}" ]] || return 0
local requiredVersion="$1"
local daemonVersion=$($NIX_DAEMON_PACKAGE/bin/nix daemon --version | sed 's/.*) //')
local daemonVersion
daemonVersion=$("$NIX_DAEMON_PACKAGE/bin/nix" daemon --version | sed 's/.*) //')
[[ $(nix eval --expr "builtins.compareVersions ''$daemonVersion'' ''$requiredVersion''") -ge 0 ]]
}
@ -238,7 +185,7 @@ expect() {
shift
"$@" && res=0 || res="$?"
# also match "negative" codes, which wrap around to >127
if [[ $res -ne $expected && $res -ne $[256 + expected] ]]; then
if [[ $res -ne $expected && $res -ne $((256 + expected)) ]]; then
echo "Expected exit code '$expected' but got '$res' from command ${*@Q}" >&2
return 1
fi
@ -253,7 +200,7 @@ expectStderr() {
shift
"$@" 2>&1 && res=0 || res="$?"
# also match "negative" codes, which wrap around to >127
if [[ $res -ne $expected && $res -ne $[256 + expected] ]]; then
if [[ $res -ne $expected && $res -ne $((256 + expected)) ]]; then
echo "Expected exit code '$expected' but got '$res' from command ${*@Q}" >&2
return 1
fi
@ -268,7 +215,7 @@ expectStderr() {
# error: This error is expected
# EOF
assertStderr() {
diff -u /dev/stdin <($@ 2>/dev/null 2>&1)
diff -u /dev/stdin <("$@" 2>/dev/null 2>&1)
}
needLocalStore() {
@ -284,11 +231,9 @@ buggyNeedLocalStore() {
enableFeatures() {
local features="$1"
sed -i 's/experimental-features .*/& '"$features"'/' "$test_nix_conf_dir"/nix.conf
sed -i 's/experimental-features .*/& '"$features"'/' "${test_nix_conf?}"
}
set -x
onError() {
set +x
echo "$0: test failed at:" >&2
@ -312,15 +257,15 @@ callerPrefix() {
local i file line fn savedFn
# Use `caller`
for i in $(seq 0 100); do
caller $i > /dev/null || {
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)"
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
@ -343,7 +288,7 @@ checkGrepArgs() {
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
return 155 # = -101 mod 256
fi
done
}
@ -401,4 +346,15 @@ count() {
trap onError ERR
fi # COMMON_VARS_AND_FUNCTIONS_SH_SOURCED
requiresUnprivilegedUserNamespaces() {
if [[ -f /proc/sys/kernel/apparmor_restrict_unprivileged_userns ]] && [[ $(< /proc/sys/kernel/apparmor_restrict_unprivileged_userns) -eq 1 ]]; then
skipTest "Unprivileged user namespaces are disabled. Run 'sudo sysctl -w /proc/sys/kernel/apparmor_restrict_unprivileged_userns=0' to allow, and run these tests."
fi
}
execUnshare () {
requiresUnprivilegedUserNamespaces
exec unshare --mount --map-root-user "$SHELL" "$@"
}
fi # COMMON_FUNCTIONS_SH_SOURCED

View file

@ -7,10 +7,10 @@ if isTestOnNixOS; then
mkdir -p "$test_nix_conf_dir" "$TEST_HOME"
export NIX_USER_CONF_FILES="$test_nix_conf_dir/nix.conf"
export NIX_USER_CONF_FILES="$test_nix_conf"
mkdir -p "$test_nix_conf_dir" "$TEST_HOME"
! test -e "$test_nix_conf"
cat > "$test_nix_conf_dir/nix.conf" <<EOF
cat > "$test_nix_conf" <<EOF
# TODO: this is not needed for all tests and prevents stable commands from be tested in isolation
flake-registry = $TEST_ROOT/registry.json
show-trace = true
@ -18,7 +18,7 @@ EOF
# When we're doing everything in the same store, we need to bring
# dependencies into context.
sed -i "$(dirname "${BASH_SOURCE[0]}")"/../config.nix \
sed -i "${_NIX_TEST_BUILD_DIR}/config.nix" \
-e 's^\(shell\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
-e 's^\(path\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
;

View file

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

View file

@ -1,14 +1,24 @@
# shellcheck shell=bash
set -eu -o pipefail
if [[ -z "${COMMON_PATHS_SH_SOURCED-}" ]]; then
COMMON_PATHS_SH_SOURCED=1
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
# Since this is a generated file
# Just for `isTestOnNixOS`
source "$commonDir/functions.sh"
# shellcheck disable=SC1091
source "$commonDir/subst-vars.sh"
source "${_NIX_TEST_BUILD_DIR}/common/subst-vars.sh"
# Make sure shellcheck knows this will be defined by the above generated snippet
: "${bindir?}"
: "${bash?}" "${bindir?}"
export PATH="$bindir:$PATH"
if ! isTestOnNixOS; then
export SHELL="$bash"
export PATH="$bindir:$PATH"
fi
if [[ -n "${NIX_CLIENT_PACKAGE:-}" ]]; then
export PATH="$NIX_CLIENT_PACKAGE/bin":$PATH
@ -18,3 +28,5 @@ DAEMON_PATH="$PATH"
if [[ -n "${NIX_DAEMON_PACKAGE:-}" ]]; then
DAEMON_PATH="${NIX_DAEMON_PACKAGE}/bin:$DAEMON_PATH"
fi
fi # COMMON_PATHS_SH_SOURCED

View file

@ -1,25 +1,17 @@
# NOTE: instances of @variable@ are substituted as defined in /mk/templates.mk
# NOTE: instances of @variable@ are substituted by the build system
if [[ -z "${COMMON_SUBST_VARS_SH_SOURCED-}" ]]; then
COMMON_SUBST_VARS_SH_SOURCED=1
bash=@bash@
bindir=@bindir@
export coreutils=@coreutils@
#lsof=@lsof@
coreutils=@coreutils@
export dot=@dot@
export PAGER=cat
export busybox="@sandbox_shell@"
dot=@dot@
busybox="@sandbox_shell@"
export version=@PACKAGE_VERSION@
export system=@system@
export BUILD_SHARED_LIBS=@BUILD_SHARED_LIBS@
if ! isTestOnNixOS; then
export SHELL="@bash@"
export PATH=@bindir@:$PATH
fi
version=@PACKAGE_VERSION@
system=@system@
fi

View file

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

View file

@ -0,0 +1,2 @@
# Shim to get generated file
import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix"

View file

@ -1,7 +1,9 @@
{ hashInvalidator ? "" }:
{
hashInvalidator ? "",
}:
with import ./config.nix;
let {
let
input0 = mkDerivation {
name = "dependencies-input-0";
@ -33,16 +35,15 @@ let {
outputHash = "1dq9p0hnm1y75q2x40fws5887bq1r840hzdxak0a9djbwvx0b16d";
};
body = mkDerivation {
name = "dependencies-top";
builder = ./dependencies.builder0.sh + "/FOOBAR/../.";
input1 = input1 + "/.";
input2 = "${input2}/.";
input1_drv = input1;
input2_drv = input2;
input0_drv = input0;
fod_input_drv = fod_input;
meta.description = "Random test package";
};
in
mkDerivation {
name = "dependencies-top";
builder = ./dependencies.builder0.sh + "/FOOBAR/../.";
input1 = input1 + "/.";
input2 = "${input2}/.";
input1_drv = input1;
input2_drv = input2;
input0_drv = input0;
fod_input_drv = fod_input;
meta.description = "Random test package";
}

View file

@ -3,7 +3,7 @@
source common/test-root.sh
source common/paths.sh
set -o pipefail
set -eu -o pipefail
source characterisation/framework.sh
@ -13,7 +13,7 @@ badExitCode=0
store="$TEST_ROOT/store"
for nixFile in derivation/*.nix; do
drvPath=$(nix-instantiate --store "$store" --pure-eval --expr "$(< "$nixFile")")
drvPath=$(env -u NIX_STORE nix-instantiate --store "$store" --pure-eval --expr "$(< "$nixFile")")
testName=$(basename "$nixFile" .nix)
got="${store}${drvPath}"
expected="derivation/$testName.drv"

View file

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

View file

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

View file

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

View file

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

BIN
tests/functional/dot.nar Normal file

Binary file not shown.

BIN
tests/functional/dotdot.nar Normal file

Binary file not shown.

View file

@ -0,0 +1,2 @@
# Shim to get generated file
import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/dyn-drv/config.nix"

View file

@ -1,15 +0,0 @@
dyn-drv-tests := \
$(d)/text-hashed-output.sh \
$(d)/recursive-mod-json.sh \
$(d)/build-built-drv.sh \
$(d)/eval-outputOf.sh \
$(d)/dep-built-drv.sh \
$(d)/old-daemon-error-hack.sh
install-tests-groups += dyn-drv
clean-files += \
$(d)/config.nix
test-deps += \
tests/functional/dyn-drv/config.nix

View file

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

View file

@ -1,6 +1,8 @@
with import ./config.nix;
let innerName = "foo"; in
let
innerName = "foo";
in
mkDerivation rec {
name = "${innerName}.drv";

BIN
tests/functional/empty.nar Normal file

Binary file not shown.

View file

@ -1,5 +1,5 @@
{
int = 123;
str = "foo";
str = "foo\nbar";
attr.foo = "bar";
}

View file

@ -16,8 +16,8 @@ EOF
nix eval --expr 'assert 1 + 2 == 3; true'
[[ $(nix eval int -f "./eval.nix") == 123 ]]
[[ $(nix eval str -f "./eval.nix") == '"foo"' ]]
[[ $(nix eval str --raw -f "./eval.nix") == 'foo' ]]
[[ $(nix eval str -f "./eval.nix") == '"foo\nbar"' ]]
[[ $(nix eval str --raw -f "./eval.nix") == $'foo\nbar' ]]
[[ "$(nix eval attr -f "./eval.nix")" == '{ foo = "bar"; }' ]]
[[ $(nix eval attr --json -f "./eval.nix") == '{"foo":"bar"}' ]]
[[ $(nix eval int -f - < "./eval.nix") == 123 ]]
@ -28,24 +28,25 @@ nix eval --expr 'assert 1 + 2 == 3; true'
nix-instantiate --eval -E 'assert 1 + 2 == 3; true'
[[ $(nix-instantiate -A int --eval "./eval.nix") == 123 ]]
[[ $(nix-instantiate -A str --eval "./eval.nix") == '"foo"' ]]
[[ $(nix-instantiate -A str --eval "./eval.nix") == '"foo\nbar"' ]]
[[ $(nix-instantiate -A str --raw --eval "./eval.nix") == $'foo\nbar' ]]
[[ "$(nix-instantiate -A attr --eval "./eval.nix")" == '{ foo = "bar"; }' ]]
[[ $(nix-instantiate -A attr --eval --json "./eval.nix") == '{"foo":"bar"}' ]]
[[ $(nix-instantiate -A int --eval - < "./eval.nix") == 123 ]]
[[ "$(nix-instantiate --eval -E '{"assert"=1;bar=2;}')" == '{ "assert" = 1; bar = 2; }' ]]
# Check that symlink cycles don't cause a hang.
ln -sfn cycle.nix $TEST_ROOT/cycle.nix
(! nix eval --file $TEST_ROOT/cycle.nix)
ln -sfn cycle.nix "$TEST_ROOT/cycle.nix"
(! nix eval --file "$TEST_ROOT/cycle.nix")
# Check that relative symlinks are resolved correctly.
mkdir -p $TEST_ROOT/xyzzy $TEST_ROOT/foo
ln -sfn ../xyzzy $TEST_ROOT/foo/bar
printf 123 > $TEST_ROOT/xyzzy/default.nix
mkdir -p "$TEST_ROOT/xyzzy" "$TEST_ROOT/foo"
ln -sfn ../xyzzy "$TEST_ROOT/foo/bar"
printf 123 > "$TEST_ROOT/xyzzy/default.nix"
[[ $(nix eval --impure --expr "import $TEST_ROOT/foo/bar") = 123 ]]
# Test --arg-from-file.
[[ "$(nix eval --raw --arg-from-file foo config.nix --expr '{ foo }: { inherit foo; }' foo)" = "$(cat config.nix)" ]]
[[ "$(nix eval --raw --arg-from-file foo "${config_nix}" --expr '{ foo }: { inherit foo; }' foo)" = "$(cat "${config_nix}")" ]]
# Check that special(-ish) files are drained.
if [[ -e /proc/version ]]; then
@ -57,7 +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 ]]
[[ "$(echo "$out" | grep -c foobar)" = 1 ]]
# Test flag alias
out="$(nix eval --expr '{}' --build-cores 1)"

Binary file not shown.

View file

@ -2,28 +2,33 @@ with import ./config.nix;
rec {
printRefs =
''
echo $exportReferencesGraph
while read path; do
read drv
read nrRefs
echo "$path has $nrRefs references"
echo "$path" >> $out
for ((n = 0; n < $nrRefs; n++)); do read ref; echo "ref $ref"; test -e "$ref"; done
done < refs
'';
printRefs = ''
echo $exportReferencesGraph
while read path; do
read drv
read nrRefs
echo "$path has $nrRefs references"
echo "$path" >> $out
for ((n = 0; n < $nrRefs; n++)); do read ref; echo "ref $ref"; test -e "$ref"; done
done < refs
'';
foo."bar.runtimeGraph" = mkDerivation {
name = "dependencies";
builder = builtins.toFile "build-graph-builder" "${printRefs}";
exportReferencesGraph = ["refs" (import ./dependencies.nix {})];
exportReferencesGraph = [
"refs"
(import ./dependencies.nix { })
];
};
foo."bar.buildGraph" = mkDerivation {
name = "dependencies";
builder = builtins.toFile "build-graph-builder" "${printRefs}";
exportReferencesGraph = ["refs" (import ./dependencies.nix {}).drvPath];
exportReferencesGraph = [
"refs"
(import ./dependencies.nix { }).drvPath
];
};
}

View file

@ -2,16 +2,29 @@
with import ./config.nix;
let
mkDerivation = args:
derivation ({
inherit system;
builder = busybox;
args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')];
} // removeAttrs args ["builder" "meta"])
// { meta = args.meta or {}; };
mkDerivation =
args:
derivation (
{
inherit system;
builder = busybox;
args = [
"sh"
"-e"
args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')
];
}
// removeAttrs args [
"builder"
"meta"
]
)
// {
meta = args.meta or { };
};
in
{

View file

@ -37,6 +37,7 @@ nix-instantiate --eval -E "builtins.readFile ((builtins.fetchGit file://$TEST_RO
# Fetch a worktree.
unset _NIX_FORCE_HTTP
expectStderr 0 nix eval -vvvv --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath" | grepQuiet "copying '$TEST_ROOT/worktree/' to the store"
path0=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath")
path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = file://$TEST_ROOT/worktree; }).outPath")
[[ $path0 = $path0_ ]]

View file

@ -6,3 +6,6 @@ touch "$TEST_ROOT/foo" -t 202211111111
# We only check whether 2022-11-1* **:**:** is the last modified date since
# `lastModified` is transformed into UTC in `builtins.fetchTarball`.
[[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]]
# Check that we can override lastModified for "path:" inputs.
[[ "$(nix eval --impure --expr "(builtins.fetchTree { type = \"path\"; path = \"$TEST_ROOT/foo\"; lastModified = 123; }).lastModified")" = 123 ]]

View file

@ -9,12 +9,12 @@ clearStore
# Test fetching a flat file.
hash=$(nix-hash --flat --type sha256 ./fetchurl.sh)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file://$(pwd)/fetchurl.sh --argstr sha256 $hash --no-out-link)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url "file://$(pwd)/fetchurl.sh" --argstr sha256 "$hash" --no-out-link)
cmp $outPath fetchurl.sh
cmp "$outPath" fetchurl.sh
# Do not re-fetch paths already present.
outPath2=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///does-not-exist/must-remain-unused/fetchurl.sh --argstr sha256 $hash --no-out-link)
outPath2=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///does-not-exist/must-remain-unused/fetchurl.sh --argstr sha256 "$hash" --no-out-link)
test "$outPath" == "$outPath2"
# Now using a base-64 hash.
@ -22,9 +22,9 @@ clearStore
hash=$(nix hash file --type sha512 --base64 ./fetchurl.sh)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file://$(pwd)/fetchurl.sh --argstr sha512 $hash --no-out-link)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url "file://$(pwd)/fetchurl.sh" --argstr sha512 "$hash" --no-out-link)
cmp $outPath fetchurl.sh
cmp "$outPath" fetchurl.sh
# Now using an SRI hash.
clearStore
@ -33,58 +33,58 @@ hash=$(nix hash file ./fetchurl.sh)
[[ $hash =~ ^sha256- ]]
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file://$(pwd)/fetchurl.sh --argstr hash $hash --no-out-link)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url "file://$(pwd)/fetchurl.sh" --argstr hash "$hash" --no-out-link)
cmp $outPath fetchurl.sh
cmp "$outPath" fetchurl.sh
# Test that we can substitute from a different store dir.
clearStore
other_store=file://$TEST_ROOT/other_store?store=/fnord/store
other_store="file://$TEST_ROOT/other_store?store=/fnord/store"
hash=$(nix hash file --type sha256 --base16 ./fetchurl.sh)
storePath=$(nix --store $other_store store add-file ./fetchurl.sh)
nix --store "$other_store" store add-file ./fetchurl.sh
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///no-such-dir/fetchurl.sh --argstr sha256 $hash --no-out-link --substituters $other_store)
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///no-such-dir/fetchurl.sh --argstr sha256 "$hash" --no-out-link --substituters "$other_store")
# Test hashed mirrors with an SRI hash.
nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///no-such-dir/fetchurl.sh --argstr hash $(nix hash to-sri --type sha256 $hash) \
--no-out-link --substituters $other_store
nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file:///no-such-dir/fetchurl.sh --argstr hash "$(nix hash to-sri --type sha256 "$hash")" \
--no-out-link --substituters "$other_store"
# Test unpacking a NAR.
rm -rf $TEST_ROOT/archive
mkdir -p $TEST_ROOT/archive
cp ./fetchurl.sh $TEST_ROOT/archive
chmod +x $TEST_ROOT/archive/fetchurl.sh
ln -s foo $TEST_ROOT/archive/symlink
nar=$TEST_ROOT/archive.nar
nix-store --dump $TEST_ROOT/archive > $nar
rm -rf "$TEST_ROOT/archive"
mkdir -p "$TEST_ROOT/archive"
cp ./fetchurl.sh "$TEST_ROOT/archive"
chmod +x "$TEST_ROOT/archive/fetchurl.sh"
ln -s foo "$TEST_ROOT/archive/symlink"
nar="$TEST_ROOT/archive.nar"
nix-store --dump "$TEST_ROOT/archive" > "$nar"
hash=$(nix-hash --flat --type sha256 $nar)
hash=$(nix-hash --flat --type sha256 "$nar")
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file://$nar --argstr sha256 $hash \
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url "file://$nar" --argstr sha256 "$hash" \
--arg unpack true --argstr name xyzzy --no-out-link)
echo $outPath | grepQuiet 'xyzzy'
echo "$outPath" | grepQuiet 'xyzzy'
test -x $outPath/fetchurl.sh
test -L $outPath/symlink
test -x "$outPath/fetchurl.sh"
test -L "$outPath/symlink"
nix-store --delete $outPath
nix-store --delete "$outPath"
# Test unpacking a compressed NAR.
narxz=$TEST_ROOT/archive.nar.xz
rm -f $narxz
xz --keep $nar
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url file://$narxz --argstr sha256 $hash \
narxz="$TEST_ROOT/archive.nar.xz"
rm -f "$narxz"
xz --keep "$nar"
outPath=$(nix-build -vvvvv --expr 'import <nix/fetchurl.nix>' --argstr url "file://$narxz" --argstr sha256 "$hash" \
--arg unpack true --argstr name xyzzy --no-out-link)
test -x $outPath/fetchurl.sh
test -L $outPath/symlink
test -x "$outPath/fetchurl.sh"
test -L "$outPath/symlink"
# Make sure that *not* passing a outputHash fails.
requireDaemonNewerThan "2.20"
expected=100
if [[ -v NIX_DAEMON_PACKAGE ]]; then expected=1; fi # work around the daemon not returning a 100 status correctly
expectStderr $expected nix-build --expr '{ url }: builtins.derivation { name = "nix-cache-info"; system = "x86_64-linux"; builder = "builtin:fetchurl"; inherit url; outputHashMode = "flat"; }' --argstr url file://$narxz 2>&1 | grep 'must be a fixed-output or impure derivation'
expectStderr $expected nix-build --expr '{ url }: builtins.derivation { name = "nix-cache-info"; system = "x86_64-linux"; builder = "builtin:fetchurl"; inherit url; outputHashMode = "flat"; }' --argstr url "file://$narxz" 2>&1 | grep 'must be a fixed-output or impure derivation'

View file

@ -4,9 +4,12 @@ mkDerivation {
name = "filter";
builder = builtins.toFile "builder" "ln -s $input $out";
input =
let filter = path: type:
type != "symlink"
&& baseNameOf path != "foo"
&& !((import ./lang/lib.nix).hasSuffix ".bak" (baseNameOf path));
in builtins.filterSource filter ((builtins.getEnv "TEST_ROOT") + "/filterin");
let
filter =
path: type:
type != "symlink"
&& baseNameOf path != "foo"
&& !((import ./lang/lib.nix).hasSuffix ".bak" (baseNameOf path));
in
builtins.filterSource filter ((builtins.getEnv "TEST_ROOT") + "/filterin");
}

View file

@ -2,15 +2,20 @@ with import ./config.nix;
rec {
f2 = dummy: builder: mode: algo: hash: mkDerivation {
name = "fixed";
inherit builder;
outputHashMode = mode;
outputHashAlgo = algo;
outputHash = hash;
inherit dummy;
impureEnvVars = ["IMPURE_VAR1" "IMPURE_VAR2"];
};
f2 =
dummy: builder: mode: algo: hash:
mkDerivation {
name = "fixed";
inherit builder;
outputHashMode = mode;
outputHashAlgo = algo;
outputHash = hash;
inherit dummy;
impureEnvVars = [
"IMPURE_VAR1"
"IMPURE_VAR2"
];
};
f = f2 "";
@ -37,7 +42,8 @@ rec {
];
sameAsAdd =
f ./fixed.builder2.sh "recursive" "sha256" "1ixr6yd3297ciyp9im522dfxpqbkhcw0pylkb2aab915278fqaik";
f ./fixed.builder2.sh "recursive" "sha256"
"1ixr6yd3297ciyp9im522dfxpqbkhcw0pylkb2aab915278fqaik";
bad = [
(f ./fixed.builder1.sh "flat" "md5" "0ddd8be4b179a529afa5f2ffae4b9858")

View file

@ -79,7 +79,7 @@ cat > "$flake1Dir"/flake.nix <<EOF
}
EOF
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$flake1Dir/"
echo bar > "$flake1Dir/foo"

View file

@ -2,7 +2,7 @@
source common.sh
cp ../simple.nix ../simple.builder.sh ../config.nix "$TEST_HOME"
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$TEST_HOME"
cd "$TEST_HOME"

View file

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

View file

@ -0,0 +1,44 @@
#!/usr/bin/env bash
source ./common.sh
TODO_NixOS
createFlake1
lockfileSummaryFlake=$TEST_ROOT/lockfileSummaryFlake
createGitRepo "$lockfileSummaryFlake" "--initial-branch=main"
# Test that the --commit-lock-file-summary flag and its alias work
cat > "$lockfileSummaryFlake/flake.nix" <<EOF
{
inputs = {
flake1.url = "git+file://$flake1Dir";
};
description = "lockfileSummaryFlake";
outputs = inputs: rec {
packages.$system.default = inputs.flake1.packages.$system.foo;
};
}
EOF
git -C "$lockfileSummaryFlake" add flake.nix
git -C "$lockfileSummaryFlake" commit -m 'Add lockfileSummaryFlake'
testSummary="test summary 1"
nix flake lock "$lockfileSummaryFlake" --commit-lock-file --commit-lock-file-summary "$testSummary"
[[ -e "$lockfileSummaryFlake/flake.lock" ]]
[[ -z $(git -C "$lockfileSummaryFlake" diff main || echo failed) ]]
[[ "$(git -C "$lockfileSummaryFlake" log --format=%s -n 1)" = "$testSummary" ]]
git -C "$lockfileSummaryFlake" rm :/:flake.lock
git -C "$lockfileSummaryFlake" commit -m "remove flake.lock"
testSummary="test summary 2"
# NOTE(cole-h): We use `--option` here because Nix settings do not currently support flag-ifying the
# alias of a setting: https://github.com/NixOS/nix/issues/10989
nix flake lock "$lockfileSummaryFlake" --commit-lock-file --option commit-lockfile-summary "$testSummary"
[[ -e "$lockfileSummaryFlake/flake.lock" ]]
[[ -z $(git -C "$lockfileSummaryFlake" diff main || echo failed) ]]
[[ "$(git -C "$lockfileSummaryFlake" log --format=%s -n 1)" = "$testSummary" ]]

View file

@ -1,10 +1,13 @@
# shellcheck shell=bash
source ../common.sh
# shellcheck disable=SC2034 # this variable is used by tests that source this file
registry=$TEST_ROOT/registry.json
writeSimpleFlake() {
local flakeDir="$1"
cat > $flakeDir/flake.nix <<EOF
cat > "$flakeDir/flake.nix" <<EOF
{
description = "Bla bla";
@ -31,19 +34,51 @@ writeSimpleFlake() {
}
EOF
cp ../simple.nix ../shell.nix ../simple.builder.sh ../config.nix $flakeDir/
cp ../simple.nix ../shell.nix ../simple.builder.sh "${config_nix}" "$flakeDir/"
}
createSimpleGitFlake() {
requireGit
local flakeDir="$1"
writeSimpleFlake $flakeDir
git -C $flakeDir add flake.nix simple.nix shell.nix simple.builder.sh config.nix
git -C $flakeDir commit -m 'Initial'
writeSimpleFlake "$flakeDir"
git -C "$flakeDir" add flake.nix simple.nix shell.nix simple.builder.sh config.nix
git -C "$flakeDir" commit -m 'Initial'
}
# Create a simple Git flake and add it to the registry as "flake1".
createFlake1() {
flake1Dir="$TEST_ROOT/flake1"
createGitRepo "$flake1Dir" ""
createSimpleGitFlake "$flake1Dir"
nix registry add --registry "$registry" flake1 "git+file://$flake1Dir"
}
createFlake2() {
flake2Dir="$TEST_ROOT/flake 2"
percentEncodedFlake2Dir="$TEST_ROOT/flake%202"
# Give one repo a non-main initial branch.
createGitRepo "$flake2Dir" "--initial-branch=main"
cat > "$flake2Dir/flake.nix" <<EOF
{
description = "Fnord";
outputs = { self, flake1 }: rec {
packages.$system.bar = flake1.packages.$system.foo;
};
}
EOF
git -C "$flake2Dir" add flake.nix
git -C "$flake2Dir" commit -m 'Initial'
nix registry add --registry "$registry" flake2 "git+file://$percentEncodedFlake2Dir"
}
writeDependentFlake() {
local flakeDir="$1"
cat > $flakeDir/flake.nix <<EOF
cat > "$flakeDir/flake.nix" <<EOF
{
outputs = { self, flake1 }: {
packages.$system.default = flake1.packages.$system.default;
@ -55,7 +90,7 @@ EOF
writeTrivialFlake() {
local flakeDir="$1"
cat > $flakeDir/flake.nix <<EOF
cat > "$flakeDir/flake.nix" <<EOF
{
outputs = { self }: {
expr = 123;
@ -71,6 +106,7 @@ createGitRepo() {
rm -rf "$repo" "$repo".tmp
mkdir -p "$repo"
# shellcheck disable=SC2086 # word splitting of extraArgs is intended
git -C "$repo" init $extraArgs
git -C "$repo" config user.email "foobar@example.com"
git -C "$repo" config user.name "Foobar"

View file

@ -2,7 +2,7 @@
source common.sh
cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
cp ../simple.nix ../simple.builder.sh "${config_nix}" $TEST_HOME
cd $TEST_HOME
@ -26,7 +26,17 @@ cat <<EOF > flake.nix
EOF
# Without --accept-flake-config, the post hook should not run.
# To test variations in stderr tty-ness, we run the command in different ways,
# none of which should block on stdin or accept the `nixConfig`s.
nix build < /dev/null
nix build < /dev/null 2>&1 | cat
# EOF counts as no, even when interactive (throw EOF error before)
if type -p script >/dev/null && script -q -c true /dev/null; then
echo "script is available and GNU-like, so we can ensure a tty"
script -q -c 'nix build < /dev/null' /dev/null
else
echo "script is not available or not GNU-like, so we skip testing with an added tty"
fi
(! [[ -f post-hook-ran ]])
TODO_NixOS
clearStore

View file

@ -5,11 +5,11 @@ source ../common.sh
TODO_NixOS
clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
rm -rf "$TEST_HOME/.cache" "$TEST_HOME/.config" "$TEST_HOME/.local"
# Create flake under test.
cp ../shell-hello.nix ../config.nix $TEST_HOME/
cat <<EOF >$TEST_HOME/flake.nix
cp ../shell-hello.nix "$config_nix" "$TEST_HOME/"
cat <<EOF >"$TEST_HOME/flake.nix"
{
inputs.nixpkgs.url = "$TEST_HOME/nixpkgs";
outputs = {self, nixpkgs}: {
@ -24,9 +24,10 @@ cat <<EOF >$TEST_HOME/flake.nix
EOF
# Create fake nixpkgs flake.
mkdir -p $TEST_HOME/nixpkgs
cp ../config.nix ../shell.nix $TEST_HOME/nixpkgs
cat <<EOF >$TEST_HOME/nixpkgs/flake.nix
mkdir -p "$TEST_HOME/nixpkgs"
cp "${config_nix}" ../shell.nix "$TEST_HOME/nixpkgs"
cat <<EOF >"$TEST_HOME/nixpkgs/flake.nix"
{
outputs = {self}: {
legacyPackages.$system.bashInteractive = (import ./shell.nix {}).bashInteractive;
@ -34,7 +35,7 @@ cat <<EOF >$TEST_HOME/nixpkgs/flake.nix
}
EOF
cd $TEST_HOME
cd "$TEST_HOME"
# Test whether `nix develop` passes through environment variables.
[[ "$(
@ -43,13 +44,86 @@ echo "\$ENVVAR"
EOF
)" = "a" ]]
# Test whether `nix develop --ignore-environment` does _not_ pass through environment variables.
# Test whether `nix develop --ignore-env` does _not_ pass through environment variables.
[[ -z "$(
ENVVAR=a nix develop --ignore-environment --no-write-lock-file .#hello <<EOF
ENVVAR=a nix develop --ignore-env --no-write-lock-file .#hello <<EOF
echo "\$ENVVAR"
EOF
)" ]]
# Test wether `--keep-env-var` keeps the environment variable.
(
expect='BAR'
got="$(FOO='BAR' nix develop --ignore-env --keep-env-var FOO --no-write-lock-file .#hello <<EOF
echo "\$FOO"
EOF
)"
[[ "$got" == "$expect" ]]
)
# Test wether duplicate `--keep-env-var` keeps the environment variable.
(
expect='BAR'
got="$(FOO='BAR' nix develop --ignore-env --keep-env-var FOO --keep-env-var FOO --no-write-lock-file .#hello <<EOF
echo "\$FOO"
EOF
)"
[[ "$got" == "$expect" ]]
)
# Test wether `--set-env-var` sets the environment variable.
(
expect='BAR'
got="$(nix develop --ignore-env --set-env-var FOO 'BAR' --no-write-lock-file .#hello <<EOF
echo "\$FOO"
EOF
)"
[[ "$got" == "$expect" ]]
)
# Test that `--set-env-var` overwrites previously set variables.
(
expect='BLA'
got="$(FOO='BAR' nix develop --set-env-var FOO 'BLA' --no-write-lock-file .#hello <<EOF
echo "\$FOO"
EOF
)"
[[ "$got" == "$expect" ]]
)
# Test that multiple `--set-env-var` work.
(
expect='BARFOO'
got="$(nix develop --set-env-var FOO 'BAR' --set-env-var BAR 'FOO' --no-write-lock-file .#hello <<EOF | tr -d '\n'
echo "\$FOO"
echo "\$BAR"
EOF
)"
[[ "$got" == "$expect" ]]
)
# Check that we throw an error when `--keep-env-var` is used without `--ignore-env`.
expectStderr 1 nix develop --keep-env-var FOO .#hello |
grepQuiet "error: --keep-env-var does not make sense without --ignore-env"
# Check that we throw an error when `--unset-env-var` is used with `--ignore-env`.
expectStderr 1 nix develop --ignore-env --unset-env-var FOO .#hello |
grepQuiet "error: --unset-env-var does not make sense with --ignore-env"
# Test wether multiple occurances of `--set-env-var` throws.
expectStderr 1 nix develop --set-env-var FOO 'BAR' --set-env-var FOO 'BLA' --no-write-lock-file .#hello |
grepQuiet "error: Duplicate definition of environment variable 'FOO' with '--set-env-var' is ambiguous"
# Test wether similar `--unset-env-var` and `--set-env-var` throws.
expectStderr 1 nix develop --set-env-var FOO 'BAR' --unset-env-var FOO --no-write-lock-file .#hello |
grepQuiet "error: Cannot unset environment variable 'FOO' that is set with '--set-env-var'"
expectStderr 1 nix develop --unset-env-var FOO --set-env-var FOO 'BAR' --no-write-lock-file .#hello |
grepQuiet "error: Cannot set environment variable 'FOO' that is unset with '--unset-env-var'"
# Check that multiple `--ignore-env`'s are okay.
expectStderr 0 nix develop --ignore-env --set-env-var FOO 'BAR' --ignore-env .#hello < /dev/null
# Determine the bashInteractive executable.
nix build --no-write-lock-file './nixpkgs#bashInteractive' --out-link ./bash-interactive
BASH_INTERACTIVE_EXECUTABLE="$PWD/bash-interactive/bin/bash"
@ -63,7 +137,7 @@ EOF
# Test whether `nix develop` with ignore environment sets `SHELL` to nixpkgs#bashInteractive shell.
[[ "$(
SHELL=custom nix develop --ignore-environment --no-write-lock-file .#hello <<EOF
SHELL=custom nix develop --ignore-env --no-write-lock-file .#hello <<EOF
echo "\$SHELL"
EOF
)" -ef "$BASH_INTERACTIVE_EXECUTABLE" ]]

View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
source ./common.sh
createFlake1
repoDir="$flake1Dir"
# Check that a flakeref without a query is accepted correctly.
expectStderr 0 nix --offline build --dry-run "git+file://$repoDir#foo"
# Check that a flakeref with a good query is accepted correctly.
expectStderr 0 nix --offline build --dry-run "git+file://$repoDir?foo=bar#foo"
# Check that we get the dubious query warning, when passing in a query without an equal sign.
expectStderr 0 nix --offline build --dry-run "git+file://$repoDir?bar#foo" \
| grepQuiet "warning: dubious URI query 'bar' is missing equal sign '=', ignoring"
# Check that the anchor (#) is taken as a whole, not split, and throws an error.
expectStderr 1 nix --offline build --dry-run "git+file://$repoDir#foo?bar" \
| grepQuiet "error: flake 'git+file://$repoDir' does not provide attribute 'packages.$system.foo?bar', 'legacyPackages.$system.foo?bar' or 'foo?bar'"
# Check that a literal `?` in the query doesn't print dubious query warning.
expectStderr 0 nix --offline build --dry-run "git+file://$repoDir?#foo" \
| grepInverse "warning: dubious URI query "
# Check that a literal `?=` in the query doesn't print dubious query warning.
expectStderr 0 nix --offline build --dry-run "git+file://$repoDir?=#foo" \
| grepInverse "warning: dubious URI query "

View file

@ -2,12 +2,7 @@
source ./common.sh
requireGit
flake1Dir=$TEST_ROOT/flake1
createGitRepo "$flake1Dir"
createSimpleGitFlake "$flake1Dir"
createFlake1
export EDITOR=cat
nix edit "$flake1Dir#" | grepQuiet simple.builder.sh

View file

@ -7,7 +7,7 @@ requireGit
flake1Dir="$TEST_ROOT/eval-cache-flake"
createGitRepo "$flake1Dir" ""
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
cp ../simple.nix ../simple.builder.sh "${config_nix}" "$flake1Dir/"
git -C "$flake1Dir" add simple.nix simple.builder.sh config.nix
git -C "$flake1Dir" commit -m "config.nix"

View file

@ -63,3 +63,34 @@ flakeref=git+file://$rootRepo\?submodules=1\&dir=submodule
echo '"foo"' > "$rootRepo"/submodule/sub.nix
[[ $(nix eval --json "$flakeref#sub" ) = '"foo"' ]]
[[ $(nix flake metadata --json "$flakeref" | jq -r .locked.rev) = null ]]
# Test that `nix flake metadata` parses `submodule` correctly.
cat > "$rootRepo"/flake.nix <<EOF
{
outputs = { self }: {
};
}
EOF
git -C "$rootRepo" add flake.nix
git -C "$rootRepo" commit -m "Add flake.nix"
storePath=$(nix flake metadata --json "$rootRepo?submodules=1" | jq -r .path)
[[ -e "$storePath/submodule" ]]
# The root repo may use the submodule repo as an input
# through the relative path. This may change in the future;
# see: https://discourse.nixos.org/t/57783 and #9708.
cat > "$rootRepo"/flake.nix <<EOF
{
inputs.subRepo.url = "git+file:./submodule";
outputs = { ... }: { };
}
EOF
git -C "$rootRepo" add flake.nix
git -C "$rootRepo" commit -m "Add subRepo input"
(
cd "$rootRepo"
# The submodule must be locked to the relative path,
# _not_ the absolute path:
[[ $(nix flake metadata --json | jq -r .locks.nodes.subRepo.locked.url) = "file:./submodule" ]]
)

View file

@ -9,46 +9,20 @@ requireGit
clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config
flake1Dir=$TEST_ROOT/flake1
flake2Dir=$TEST_ROOT/flake\ 2
percentEncodedFlake2Dir=$TEST_ROOT/flake%202
createFlake1
createFlake2
flake3Dir=$TEST_ROOT/flake%20
percentEncodedFlake3Dir=$TEST_ROOT/flake%2520
flake5Dir=$TEST_ROOT/flake5
flake7Dir=$TEST_ROOT/flake7
nonFlakeDir=$TEST_ROOT/nonFlake
badFlakeDir=$TEST_ROOT/badFlake
flakeGitBare=$TEST_ROOT/flakeGitBare
lockfileSummaryFlake=$TEST_ROOT/lockfileSummaryFlake
for repo in "$flake1Dir" "$flake2Dir" "$flake3Dir" "$flake7Dir" "$nonFlakeDir" "$lockfileSummaryFlake"; do
# Give one repo a non-main initial branch.
extraArgs=
if [[ "$repo" == "$flake2Dir" ]]; then
extraArgs="--initial-branch=main"
fi
if [[ "$repo" == "$lockfileSummaryFlake" ]]; then
extraArgs="--initial-branch=main"
fi
createGitRepo "$repo" "$extraArgs"
for repo in "$flake3Dir" "$flake7Dir"; do
createGitRepo "$repo" ""
done
createSimpleGitFlake "$flake1Dir"
cat > "$flake2Dir/flake.nix" <<EOF
{
description = "Fnord";
outputs = { self, flake1 }: rec {
packages.$system.bar = flake1.packages.$system.foo;
};
}
EOF
git -C "$flake2Dir" add flake.nix
git -C "$flake2Dir" commit -m 'Initial'
cat > "$flake3Dir/flake.nix" <<EOF
{
description = "Fnord";
@ -70,113 +44,13 @@ EOF
git -C "$flake3Dir" add flake.nix default.nix
git -C "$flake3Dir" commit -m 'Initial'
cat > "$nonFlakeDir/README.md" <<EOF
FNORD
EOF
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-different-comments.sh <<EOF
#! $(type -P env) nix
# some comments
// some comments
/* some comments
* some comments
\ some comments
% some comments
@ some comments
-- some comments
(* some comments
#! nix --offline shell
#! nix flake1#fooScript
#! nix --no-write-lock-file --command cat
foo
EOF
chmod +x $nonFlakeDir/shebang-different-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"
nix registry add --registry "$registry" flake3 "git+file://$percentEncodedFlake3Dir"
nix registry add --registry "$registry" flake4 flake3
nix registry add --registry "$registry" nixpkgs flake1
# Test 'nix registry list'.
[[ $(nix registry list | wc -l) == 5 ]]
[[ $(nix registry list | wc -l) == 4 ]]
nix registry list | grep '^global'
nix registry list | grepInverse '^user' # nothing in user registry
@ -184,6 +58,9 @@ nix registry list | grepInverse '^user' # nothing in user registry
nix flake metadata flake1
nix flake metadata flake1 | grepQuiet 'Locked URL:.*flake1.*'
# Test 'nix flake metadata' on a chroot store.
nix flake metadata --store $TEST_ROOT/chroot-store flake1
# Test 'nix flake metadata' on a local flake.
(cd "$flake1Dir" && nix flake metadata) | grepQuiet 'URL:.*flake1.*'
(cd "$flake1Dir" && nix flake metadata .) | grepQuiet 'URL:.*flake1.*'
@ -200,6 +77,7 @@ hash1=$(echo "$json" | jq -r .revision)
echo foo > "$flake1Dir/foo"
git -C "$flake1Dir" add $flake1Dir/foo
[[ $(nix flake metadata flake1 --json --refresh | jq -r .dirtyRevision) == "$hash1-dirty" ]]
[[ "$(nix flake metadata flake1 --json | jq -r .fingerprint)" != null ]]
echo -n '# foo' >> "$flake1Dir/flake.nix"
flake1OriginalCommit=$(git -C "$flake1Dir" rev-parse HEAD)
@ -219,6 +97,9 @@ nix build -o "$TEST_ROOT/result" flake1
nix build -o "$TEST_ROOT/result" "$flake1Dir"
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir"
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" ".")
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" "path:.")
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" "git+file:.")
# Test explicit packages.default.
nix build -o "$TEST_ROOT/result" "$flake1Dir#default"
@ -228,6 +109,15 @@ nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir#default"
nix build -o "$TEST_ROOT/result" "$flake1Dir?ref=HEAD#default"
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir?ref=HEAD#default"
# Check that relative paths are allowed for git flakes.
# This may change in the future once git submodule support is refined.
# See: https://discourse.nixos.org/t/57783 and #9708.
(
# This `cd` should not be required and is indicative of aforementioned bug.
cd "$flake1Dir/.."
nix build -o "$TEST_ROOT/result" "git+file:./$(basename "$flake1Dir")"
)
# 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"
@ -343,77 +233,8 @@ _NIX_FORCE_HTTP=1 nix build -o "$TEST_ROOT/result" "git+file://$percentEncodedFl
mv "$flake1Dir.tmp" "$flake1Dir"
mv "$flake2Dir.tmp" "$flake2Dir"
# Add nonFlakeInputs to flake3.
rm "$flake3Dir/flake.nix"
cat > "$flake3Dir/flake.nix" <<EOF
{
inputs = {
flake1 = {};
flake2 = {};
nonFlake = {
url = git+file://$nonFlakeDir;
flake = false;
};
nonFlakeFile = {
url = path://$nonFlakeDir/README.md;
flake = false;
};
nonFlakeFile2 = {
url = "$nonFlakeDir/README.md";
flake = false;
};
};
description = "Fnord";
outputs = inputs: rec {
packages.$system.xyzzy = inputs.flake2.packages.$system.bar;
packages.$system.sth = inputs.flake1.packages.$system.foo;
packages.$system.fnord =
with import ./config.nix;
mkDerivation {
inherit system;
name = "fnord";
dummy = builtins.readFile (builtins.path { name = "source"; path = ./.; filter = path: type: baseNameOf path == "config.nix"; } + "/config.nix");
dummy2 = builtins.readFile (builtins.path { name = "source"; path = inputs.flake1; filter = path: type: baseNameOf path == "simple.nix"; } + "/simple.nix");
buildCommand = ''
cat \${inputs.nonFlake}/README.md > \$out
[[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]]
[[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]]
'';
};
};
}
EOF
cp ../config.nix "$flake3Dir"
git -C "$flake3Dir" add flake.nix config.nix
git -C "$flake3Dir" commit -m 'Add nonFlakeInputs'
# Check whether `nix build` works with a lockfile which is missing a
# nonFlakeInputs.
nix build -o "$TEST_ROOT/result" "$flake3Dir#sth" --commit-lock-file
nix build -o "$TEST_ROOT/result" flake3#fnord
[[ $(cat $TEST_ROOT/result) = FNORD ]]
# Check whether flake input fetching is lazy: flake3#sth does not
# depend on flake2, so this shouldn't fail.
rm -rf "$TEST_HOME/.cache"
clearStore
mv "$flake2Dir" "$flake2Dir.tmp"
mv "$nonFlakeDir" "$nonFlakeDir.tmp"
nix build -o "$TEST_ROOT/result" flake3#sth
(! nix build -o "$TEST_ROOT/result" flake3#xyzzy)
(! nix build -o "$TEST_ROOT/result" flake3#fnord)
mv "$flake2Dir.tmp" "$flake2Dir"
mv "$nonFlakeDir.tmp" "$nonFlakeDir"
nix build -o "$TEST_ROOT/result" flake3#xyzzy flake3#fnord
# Test doing multiple `lookupFlake`s
nix build -o "$TEST_ROOT/result" flake4#xyzzy
nix build -o "$TEST_ROOT/result" flake3#xyzzy
# Test 'nix flake update' and --override-flake.
nix flake lock "$flake3Dir"
@ -422,53 +243,15 @@ nix flake lock "$flake3Dir"
nix flake update --flake "$flake3Dir" --override-flake flake2 nixpkgs
[[ ! -z $(git -C "$flake3Dir" diff master || echo failed) ]]
# Make branch "removeXyzzy" where flake3 doesn't have xyzzy anymore
git -C "$flake3Dir" checkout -b removeXyzzy
rm "$flake3Dir/flake.nix"
cat > "$flake3Dir/flake.nix" <<EOF
{
inputs = {
nonFlake = {
url = "$nonFlakeDir";
flake = false;
};
};
description = "Fnord";
outputs = { self, flake1, flake2, nonFlake }: rec {
packages.$system.sth = flake1.packages.$system.foo;
packages.$system.fnord =
with import ./config.nix;
mkDerivation {
inherit system;
name = "fnord";
buildCommand = ''
cat \${nonFlake}/README.md > \$out
'';
};
};
}
EOF
nix flake lock "$flake3Dir"
git -C "$flake3Dir" add flake.nix flake.lock
git -C "$flake3Dir" commit -m 'Remove packages.xyzzy'
git -C "$flake3Dir" checkout master
# Test whether fuzzy-matching works for registry entries.
(! nix build -o "$TEST_ROOT/result" flake4/removeXyzzy#xyzzy)
nix build -o "$TEST_ROOT/result" flake4/removeXyzzy#sth
# Testing the nix CLI
nix registry add flake1 flake3
[[ $(nix registry list | wc -l) == 6 ]]
nix registry pin flake1
[[ $(nix registry list | wc -l) == 6 ]]
nix registry pin flake1 flake3
[[ $(nix registry list | wc -l) == 6 ]]
nix registry remove flake1
[[ $(nix registry list | wc -l) == 5 ]]
nix registry pin flake1
[[ $(nix registry list | wc -l) == 5 ]]
nix registry pin flake1 flake3
[[ $(nix registry list | wc -l) == 5 ]]
nix registry remove flake1
[[ $(nix registry list | wc -l) == 4 ]]
# Test 'nix registry list' with a disabled global registry.
nix registry add user-flake1 git+file://$flake1Dir
@ -478,7 +261,7 @@ nix --flake-registry "" registry list | grepQuietInverse '^global' # nothing in
nix --flake-registry "" registry list | grepQuiet '^user'
nix registry remove user-flake1
nix registry remove user-flake2
[[ $(nix registry list | wc -l) == 5 ]]
[[ $(nix registry list | wc -l) == 4 ]]
# Test 'nix flake clone'.
rm -rf $TEST_ROOT/flake1-v2
@ -640,46 +423,3 @@ 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-different-comments.sh)" = "$(cat $nonFlakeDir/shebang-different-comments.sh)" ]]
[[ $($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?'
# Test that the --commit-lock-file-summary flag and its alias work
cat > "$lockfileSummaryFlake/flake.nix" <<EOF
{
inputs = {
flake1.url = "git+file://$flake1Dir";
};
description = "lockfileSummaryFlake";
outputs = inputs: rec {
packages.$system.default = inputs.flake1.packages.$system.foo;
};
}
EOF
git -C "$lockfileSummaryFlake" add flake.nix
git -C "$lockfileSummaryFlake" commit -m 'Add lockfileSummaryFlake'
testSummary="test summary 1"
nix flake lock "$lockfileSummaryFlake" --commit-lock-file --commit-lock-file-summary "$testSummary"
[[ -e "$lockfileSummaryFlake/flake.lock" ]]
[[ -z $(git -C "$lockfileSummaryFlake" diff main || echo failed) ]]
[[ "$(git -C "$lockfileSummaryFlake" log --format=%s -n 1)" = "$testSummary" ]]
git -C "$lockfileSummaryFlake" rm :/:flake.lock
git -C "$lockfileSummaryFlake" commit -m "remove flake.lock"
testSummary="test summary 2"
# NOTE(cole-h): We use `--option` here because Nix settings do not currently support flag-ifying the
# alias of a setting: https://github.com/NixOS/nix/issues/10989
nix flake lock "$lockfileSummaryFlake" --commit-lock-file --option commit-lockfile-summary "$testSummary"
[[ -e "$lockfileSummaryFlake/flake.lock" ]]
[[ -z $(git -C "$lockfileSummaryFlake" diff main || echo failed) ]]
[[ "$(git -C "$lockfileSummaryFlake" log --format=%s -n 1)" = "$testSummary" ]]

View file

@ -117,7 +117,7 @@ nix flake lock $flakeFollowsA
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '"foobar"' ]]
jq -r -c '.nodes | keys | .[]' $flakeFollowsA/flake.lock | grep "^foobar$"
# Ensure a relative path is not allowed to go outside the store path
# Check that path: inputs cannot escape from their root.
cat > $flakeFollowsA/flake.nix <<EOF
{
description = "Flake A";
@ -130,7 +130,28 @@ EOF
git -C $flakeFollowsA add flake.nix
expect 1 nix flake lock $flakeFollowsA 2>&1 | grep 'points outside'
expect 1 nix flake lock $flakeFollowsA 2>&1 | grep '/flakeB.*is forbidden in pure evaluation mode'
expect 1 nix flake lock --impure $flakeFollowsA 2>&1 | grep '/flakeB.*does not exist'
# Test relative non-flake inputs.
cat > $flakeFollowsA/flake.nix <<EOF
{
description = "Flake A";
inputs = {
E.flake = false;
E.url = "./foo.nix"; # test relative paths without 'path:'
};
outputs = { E, ... }: { e = import E; };
}
EOF
echo 123 > $flakeFollowsA/foo.nix
git -C $flakeFollowsA add flake.nix foo.nix
nix flake lock $flakeFollowsA
[[ $(nix eval --json $flakeFollowsA#e) = 123 ]]
# Non-existant follows should print a warning.
cat >$flakeFollowsA/flake.nix <<EOF
@ -335,6 +356,6 @@ json=$(nix flake metadata "$flakeFollowsCustomUrlA" --json)
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)
json=$(nix flake metadata "$flakeFollowsCustomUrlA" --override-input B/C "$flakeFollowsCustomUrlD" --json)
echo "$json" | jq .locks.nodes.C.original
[[ $(echo "$json" | jq -r .locks.nodes.C.original.path) = './flakeC' ]]

View file

@ -1,24 +0,0 @@
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

View file

@ -0,0 +1,33 @@
suites += {
'name': 'flakes',
'deps': [],
'tests': [
'flakes.sh',
'develop.sh',
'edit.sh',
'run.sh',
'mercurial.sh',
'circular.sh',
'init.sh',
'inputs.sh',
'follow-paths.sh',
'bundle.sh',
'check.sh',
'unlocked-override.sh',
'absolute-paths.sh',
'absolute-attr-paths.sh',
'build-paths.sh',
'flake-in-submodule.sh',
'prefetch.sh',
'eval-cache.sh',
'search-root.sh',
'config.sh',
'show.sh',
'dubious-query.sh',
'shebang.sh',
'commit-lock-file-summary.sh',
'non-flake-inputs.sh',
'relative-paths.sh',
],
'workdir': meson.current_source_dir(),
}

View file

@ -0,0 +1,128 @@
#!/usr/bin/env bash
source ./common.sh
TODO_NixOS
createFlake1
createFlake2
nonFlakeDir=$TEST_ROOT/nonFlake
createGitRepo "$nonFlakeDir" ""
cat > "$nonFlakeDir/README.md" <<EOF
FNORD
EOF
git -C "$nonFlakeDir" add README.md
git -C "$nonFlakeDir" commit -m 'Initial'
flake3Dir=$TEST_ROOT/flake3
createGitRepo "$flake3Dir" ""
cat > "$flake3Dir/flake.nix" <<EOF
{
inputs = {
flake1 = {};
flake2 = {};
nonFlake = {
url = git+file://$nonFlakeDir;
flake = false;
};
nonFlakeFile = {
url = path://$nonFlakeDir/README.md;
flake = false;
};
nonFlakeFile2 = {
url = "$nonFlakeDir/README.md";
flake = false;
};
};
description = "Fnord";
outputs = inputs: rec {
packages.$system.xyzzy = inputs.flake2.packages.$system.bar;
packages.$system.sth = inputs.flake1.packages.$system.foo;
packages.$system.fnord =
with import ./config.nix;
mkDerivation {
inherit system;
name = "fnord";
dummy = builtins.readFile (builtins.path { name = "source"; path = ./.; filter = path: type: baseNameOf path == "config.nix"; } + "/config.nix");
dummy2 = builtins.readFile (builtins.path { name = "source"; path = inputs.flake1; filter = path: type: baseNameOf path == "simple.nix"; } + "/simple.nix");
buildCommand = ''
cat \${inputs.nonFlake}/README.md > \$out
[[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]]
[[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]]
'';
};
};
}
EOF
cp "${config_nix}" "$flake3Dir"
git -C "$flake3Dir" add flake.nix config.nix
git -C "$flake3Dir" commit -m 'Add nonFlakeInputs'
# Check whether `nix build` works with a lockfile which is missing a
# nonFlakeInputs.
nix build -o "$TEST_ROOT/result" "$flake3Dir#sth" --commit-lock-file
nix registry add --registry "$registry" flake3 "git+file://$flake3Dir"
nix build -o "$TEST_ROOT/result" flake3#fnord
[[ $(cat "$TEST_ROOT/result") = FNORD ]]
# Check whether flake input fetching is lazy: flake3#sth does not
# depend on flake2, so this shouldn't fail.
rm -rf "$TEST_HOME/.cache"
clearStore
mv "$flake2Dir" "$flake2Dir.tmp"
mv "$nonFlakeDir" "$nonFlakeDir.tmp"
nix build -o "$TEST_ROOT/result" flake3#sth
(! nix build -o "$TEST_ROOT/result" flake3#xyzzy)
(! nix build -o "$TEST_ROOT/result" flake3#fnord)
mv "$flake2Dir.tmp" "$flake2Dir"
mv "$nonFlakeDir.tmp" "$nonFlakeDir"
nix build -o "$TEST_ROOT/result" flake3#xyzzy flake3#fnord
# Make branch "removeXyzzy" where flake3 doesn't have xyzzy anymore
git -C "$flake3Dir" checkout -b removeXyzzy
rm "$flake3Dir/flake.nix"
cat > "$flake3Dir/flake.nix" <<EOF
{
inputs = {
nonFlake = {
url = "$nonFlakeDir";
flake = false;
};
};
description = "Fnord";
outputs = { self, flake1, flake2, nonFlake }: rec {
packages.$system.sth = flake1.packages.$system.foo;
packages.$system.fnord =
with import ./config.nix;
mkDerivation {
inherit system;
name = "fnord";
buildCommand = ''
cat \${nonFlake}/README.md > \$out
'';
};
};
}
EOF
nix flake lock "$flake3Dir"
git -C "$flake3Dir" add flake.nix flake.lock
git -C "$flake3Dir" commit -m 'Remove packages.xyzzy'
git -C "$flake3Dir" checkout master
# Test whether fuzzy-matching works for registry entries.
nix registry add --registry "$registry" flake4 flake3
(! nix build -o "$TEST_ROOT/result" flake4/removeXyzzy#xyzzy)
nix build -o "$TEST_ROOT/result" flake4/removeXyzzy#sth

View file

@ -0,0 +1,97 @@
#!/usr/bin/env bash
source ./common.sh
requireGit
rootFlake="$TEST_ROOT/flake1"
subflake0="$rootFlake/sub0"
subflake1="$rootFlake/sub1"
subflake2="$rootFlake/sub2"
rm -rf "$rootFlake"
mkdir -p "$rootFlake" "$subflake0" "$subflake1" "$subflake2"
cat > "$rootFlake/flake.nix" <<EOF
{
inputs.sub0.url = ./sub0;
outputs = { self, sub0 }: {
x = 2;
y = self.x * sub0.x;
};
}
EOF
cat > "$subflake0/flake.nix" <<EOF
{
outputs = { self }: {
x = 7;
};
}
EOF
[[ $(nix eval "$rootFlake#x") = 2 ]]
[[ $(nix eval "$rootFlake#y") = 14 ]]
cat > "$subflake1/flake.nix" <<EOF
{
inputs.root.url = "../";
outputs = { self, root }: {
x = 3;
y = self.x * root.x;
};
}
EOF
[[ $(nix eval "$rootFlake?dir=sub1#y") = 6 ]]
git init "$rootFlake"
git -C "$rootFlake" add flake.nix sub0/flake.nix sub1/flake.nix
[[ $(nix eval "$subflake1#y") = 6 ]]
cat > "$subflake2/flake.nix" <<EOF
{
inputs.root.url = ./..;
inputs.sub1.url = "../sub1";
outputs = { self, root, sub1 }: {
x = 5;
y = self.x * sub1.x;
};
}
EOF
git -C "$rootFlake" add flake.nix sub2/flake.nix
[[ $(nix eval "$subflake2#y") = 15 ]]
# Make sure that this still works after commiting the lock file.
git -C "$rootFlake" add sub2/flake.lock
[[ $(nix eval "$subflake2#y") = 15 ]]
# Make sure there are no content locks for relative path flakes.
(! grep "$TEST_ROOT" "$subflake2/flake.lock")
if ! isTestOnNixOS; then
(! grep "$NIX_STORE_DIR" "$subflake2/flake.lock")
fi
(! grep narHash "$subflake2/flake.lock")
# Test circular relative path flakes. FIXME: doesn't work at the moment.
if false; then
cat > "$rootFlake/flake.nix" <<EOF
{
inputs.sub1.url = "./sub1";
inputs.sub2.url = "./sub1";
outputs = { self, sub1, sub2 }: {
x = 2;
y = self.x * sub1.x * sub2.x;
z = sub1.y * sub2.y;
};
}
EOF
[[ $(nix eval "$rootFlake#x") = 30 ]]
[[ $(nix eval "$rootFlake#z") = 90 ]]
fi

View file

@ -6,7 +6,8 @@ TODO_NixOS
clearStore
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
cp ../shell-hello.nix ../config.nix $TEST_HOME
cp ../shell-hello.nix "${config_nix}" $TEST_HOME
cd $TEST_HOME
cat <<EOF > flake.nix
@ -37,11 +38,13 @@ 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
# - we unset TMPDIR on macOS if it contains /var/folders. bad. https://github.com/NixOS/nix/issues/7731
# - _ 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 '/^TMPDIR=\/var\/folders\/.*/d' \
-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

View file

@ -0,0 +1,109 @@
#!/usr/bin/env bash
source ./common.sh
TODO_NixOS
createFlake1
scriptDir="$TEST_ROOT/nonFlake"
mkdir -p "$scriptDir"
cat > "$scriptDir/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 "$scriptDir/shebang.sh"
# this also tests a fairly trivial double backtick quoted string, ``--command``
cat > "$scriptDir/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 "$scriptDir/shebang-comments.sh"
cat > "$scriptDir/shebang-different-comments.sh" <<EOF
#! $(type -P env) nix
# some comments
// some comments
/* some comments
* some comments
\ some comments
% some comments
@ some comments
-- some comments
(* some comments
#! nix --offline shell
#! nix flake1#fooScript
#! nix --no-write-lock-file --command cat
foo
EOF
chmod +x "$scriptDir/shebang-different-comments.sh"
cat > "$scriptDir/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 "$scriptDir/shebang-reject.sh"
cat > "$scriptDir/shebang-inline-expr.sh" <<EOF
#! $(type -P env) nix
EOF
cat >> "$scriptDir/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 "$scriptDir/shebang-inline-expr.sh"
cat > "$scriptDir/fooScript.nix" <<"EOF"
let flake = (builtins.getFlake (toString ../flake1)).packages;
fooScript = flake.${builtins.currentSystem}.fooScript;
in fooScript
EOF
cat > "$scriptDir/shebang-file.sh" <<EOF
#! $(type -P env) nix
EOF
cat >> "$scriptDir/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 "$scriptDir/shebang-file.sh"
[[ $("$scriptDir/shebang.sh") = "foo" ]]
[[ $("$scriptDir/shebang.sh" "bar") = "foo"$'\n'"bar" ]]
[[ $("$scriptDir/shebang-comments.sh" ) = "foo" ]]
[[ "$("$scriptDir/shebang-different-comments.sh")" = "$(cat "$scriptDir/shebang-different-comments.sh")" ]]
[[ $("$scriptDir/shebang-inline-expr.sh" baz) = "foo"$'\n'"baz" ]]
[[ $("$scriptDir/shebang-file.sh" baz) = "foo"$'\n'"baz" ]]
expect 1 "$scriptDir/shebang-reject.sh" 2>&1 | grepQuiet -F 'error: unsupported unquoted character in nix shebang: *. Use double backticks to escape?'

View file

@ -30,3 +30,15 @@ git -C "$flake2Dir" add flake.nix
echo 456 > "$flake1Dir"/x.nix
[[ $(nix eval --json "$flake2Dir#x" --override-input flake1 "$TEST_ROOT/flake1") = 456 ]]
# Dirty overrides require --allow-dirty-locks.
expectStderr 1 nix flake lock "$flake2Dir" --override-input flake1 "$TEST_ROOT/flake1" |
grepQuiet "Will not write lock file.*because it has an unlocked input"
nix flake lock "$flake2Dir" --override-input flake1 "$TEST_ROOT/flake1" --allow-dirty-locks
# Using a lock file with a dirty lock requires --allow-dirty-locks as well.
expectStderr 1 nix eval "$flake2Dir#x" |
grepQuiet "Lock file contains unlocked input"
[[ $(nix eval "$flake2Dir#x" --allow-dirty-locks) = 456 ]]

View file

@ -5,13 +5,13 @@ source common.sh
TODO_NixOS # Provide a `shell` variable. Try not to `export` it, perhaps.
clearStoreIfPossible
rm -rf $TEST_HOME/.cache $TEST_HOME/.config $TEST_HOME/.local
rm -rf "$TEST_HOME"/.cache "$TEST_HOME"/.config "$TEST_HOME"/.local
cp ./simple.nix ./simple.builder.sh ./fmt.simple.sh ./config.nix $TEST_HOME
cp ./simple.nix ./simple.builder.sh ./fmt.simple.sh "${config_nix}" "$TEST_HOME"
cd $TEST_HOME
cd "$TEST_HOME"
nix fmt --help | grep "Format"
nix fmt --help | grep "forward"
cat << EOF > flake.nix
{
@ -30,6 +30,9 @@ cat << EOF > flake.nix
};
}
EOF
nix fmt ./file ./folder | grep 'Formatting: ./file ./folder'
# No arguments check
[[ "$(nix fmt)" = "Formatting(0):" ]]
# Argument forwarding check
nix fmt ./file ./folder | grep 'Formatting(2): ./file ./folder'
nix flake check
nix flake show | grep -P "package 'formatter'"

View file

@ -1 +1,2 @@
echo Formatting: "${@}"
#!/usr/bin/env bash
echo "Formatting(${#}):" "${@}"

View file

@ -2,38 +2,34 @@ with import ./config.nix;
rec {
x1 = mkDerivation {
name = "x1";
builder = builtins.toFile "builder.sh"
''
echo $name > $out
'';
builder = builtins.toFile "builder.sh" ''
echo $name > $out
'';
outputHashMode = "recursive";
outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
x2 = mkDerivation {
name = "x2";
builder = builtins.toFile "builder.sh"
''
echo $name > $out
'';
builder = builtins.toFile "builder.sh" ''
echo $name > $out
'';
outputHashMode = "recursive";
outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
x3 = mkDerivation {
name = "x3";
builder = builtins.toFile "builder.sh"
''
echo $name > $out
'';
builder = builtins.toFile "builder.sh" ''
echo $name > $out
'';
outputHashMode = "recursive";
outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
x4 = mkDerivation {
name = "x4";
inherit x2 x3;
builder = builtins.toFile "builder.sh"
''
echo $x2 $x3
exit 1
'';
builder = builtins.toFile "builder.sh" ''
echo $x2 $x3
exit 1
'';
};
}

View file

@ -23,7 +23,7 @@ fifoLock=$TEST_ROOT/fifoLock
mkfifo "$fifoLock"
expr=$(cat <<EOF
with import ./config.nix; mkDerivation {
with import ${config_nix}; mkDerivation {
name = "gc-A";
buildCommand = ''
set -x
@ -51,7 +51,7 @@ EOF
)
expr2=$(cat <<EOF
with import ./config.nix; mkDerivation {
with import ${config_nix}; mkDerivation {
name = "gc-B";
buildCommand = ''
set -x

View file

@ -1,6 +1,8 @@
with import ./config.nix;
{ lockFifo ? null }:
{
lockFifo ? null,
}:
rec {

View file

@ -38,7 +38,7 @@ pid2=$!
# Start a build. This should not be blocked by the GC in progress.
outPath=$(nix-build --max-silent-time 60 -o "$TEST_ROOT/result" -E "
with import ./config.nix;
with import ${config_nix};
mkDerivation {
name = \"non-blocking\";
buildCommand = \"set -x; test -e $running; mkdir \$out; echo > $fifo2\";

View file

@ -11,46 +11,46 @@ outPath=$(nix-store -rvv "$drvPath")
# Set a GC root.
rm -f "$NIX_STATE_DIR/gcroots/foo"
ln -sf $outPath "$NIX_STATE_DIR/gcroots/foo"
ln -sf "$outPath" "$NIX_STATE_DIR/gcroots/foo"
[ "$(nix-store -q --roots $outPath)" = "$NIX_STATE_DIR/gcroots/foo -> $outPath" ]
[ "$(nix-store -q --roots "$outPath")" = "$NIX_STATE_DIR/gcroots/foo -> $outPath" ]
nix-store --gc --print-roots | grep $outPath
nix-store --gc --print-live | grep $outPath
nix-store --gc --print-dead | grep $drvPath
if nix-store --gc --print-dead | grep -E $outPath$; then false; fi
nix-store --gc --print-roots | grep "$outPath"
nix-store --gc --print-live | grep "$outPath"
nix-store --gc --print-dead | grep "$drvPath"
if nix-store --gc --print-dead | grep -E "$outPath"$; then false; fi
nix-store --gc --print-dead
inUse=$(readLink $outPath/reference-to-input-2)
if nix-store --delete $inUse; then false; fi
test -e $inUse
inUse=$(readLink "$outPath/reference-to-input-2")
if nix-store --delete "$inUse"; then false; fi
test -e "$inUse"
if nix-store --delete $outPath; then false; fi
test -e $outPath
if nix-store --delete "$outPath"; then false; fi
test -e "$outPath"
for i in $NIX_STORE_DIR/*; do
for i in "$NIX_STORE_DIR"/*; do
if [[ $i =~ /trash ]]; then continue; fi # compat with old daemon
touch $i.lock
touch $i.chroot
touch "$i.lock"
touch "$i.chroot"
done
nix-collect-garbage
# Check that the root and its dependencies haven't been deleted.
cat $outPath/foobar
cat $outPath/reference-to-input-2/bar
cat "$outPath/foobar"
cat "$outPath/reference-to-input-2/bar"
# Check that the derivation has been GC'd.
if test -e $drvPath; then false; fi
if test -e "$drvPath"; then false; fi
rm "$NIX_STATE_DIR/gcroots/foo"
nix-collect-garbage
# Check that the output has been GC'd.
if test -e $outPath/foobar; then false; fi
if test -e "$outPath/foobar"; then false; fi
# Check that the store is empty.
rmdir $NIX_STORE_DIR/.links
rmdir $NIX_STORE_DIR
rmdir "$NIX_STORE_DIR/.links"
rmdir "$NIX_STORE_DIR"

View file

@ -1,7 +0,0 @@
git-hashing-tests := \
$(d)/simple.sh
install-tests-groups += git-hashing
clean-files += \
$(d)/config.nix

View file

@ -0,0 +1,8 @@
suites += {
'name': 'git-hashing',
'deps': [],
'tests': [
'simple.sh',
],
'workdir': meson.current_source_dir(),
}

2
tests/functional/git-hashing/simple.sh Normal file → Executable file
View file

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

View file

@ -4,14 +4,22 @@ let {
name = "dependencies-input-1";
system = "i086-msdos";
builder = "/bar/sh";
args = ["-e" "-x" ./dummy];
args = [
"-e"
"-x"
./dummy
];
};
input2 = derivation {
name = "dependencies-input-2";
system = "i086-msdos";
builder = "/bar/sh";
args = ["-e" "-x" ./dummy];
args = [
"-e"
"-x"
./dummy
];
outputHashMode = "recursive";
outputHashAlgo = "md5";
outputHash = "ffffffffffffffffffffffffffffffff";
@ -21,9 +29,13 @@ let {
name = "dependencies";
system = "i086-msdos";
builder = "/bar/sh";
args = ["-e" "-x" (./dummy + "/FOOBAR/../.")];
args = [
"-e"
"-x"
(./dummy + "/FOOBAR/../.")
];
input1 = input1 + "/.";
inherit input2;
};
}
}

View file

@ -93,15 +93,19 @@ try3() {
# Asserting input format fails.
#
fail=$(nix hash convert --hash-algo "$1" --from nix32 "$2" 2>&1 || echo "exit: $?")
[[ "$fail" == *"error: input hash"*"exit: 1" ]]
fail=$(nix hash convert --hash-algo "$1" --from base16 "$3" 2>&1 || echo "exit: $?")
[[ "$fail" == *"error: input hash"*"exit: 1" ]]
fail=$(nix hash convert --hash-algo "$1" --from nix32 "$4" 2>&1 || echo "exit: $?")
[[ "$fail" == *"error: input hash"*"exit: 1" ]]
expectStderr 1 nix hash convert --hash-algo "$1" --from sri "$2" | grepQuiet "is not SRI"
expectStderr 1 nix hash convert --hash-algo "$1" --from nix32 "$2" | grepQuiet "input hash"
expectStderr 1 nix hash convert --hash-algo "$1" --from base16 "$3" | grepQuiet "input hash"
expectStderr 1 nix hash convert --hash-algo "$1" --from nix32 "$4" | grepQuiet "input hash"
# Base-16 hashes can be in uppercase.
nix hash convert --hash-algo "$1" --from base16 "$(echo $2 | tr [a-z] [A-Z])"
}
try3 sha1 "800d59cfcd3c05e900cb4e214be48f6b886a08df" "vw46m23bizj4n8afrc0fj19wrp7mj3c0" "gA1Zz808BekAy04hS+SPa4hqCN8="
try3 sha256 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" "1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s" "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="
try3 sha512 "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" "12k9jiq29iyqm03swfsgiw5mlqs173qazm3n7daz43infy12pyrcdf30fkk3qwv4yl2ick8yipc2mqnlh48xsvvxl60lbx8vp38yji0" "IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ=="
# Test SRI hashes that lack trailing '=' characters. These are incorrect but we need to support them for backward compatibility.
[[ $(nix hash convert --from sri "sha256-ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0") = sha256-ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0= ]]
[[ $(nix hash convert --from sri "sha512-IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ") = sha512-IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ== ]]

View file

@ -92,3 +92,32 @@ try2 md5 "20f3ffe011d4cfa7d72bfabef7882836"
rm "$TEST_ROOT/hash-path/hello"
ln -s x "$TEST_ROOT/hash-path/hello"
try2 md5 "f78b733a68f5edbdf9413899339eaa4a"
# Flat mode supports process substitution
h=$(nix hash path --mode flat --type sha256 --base32 <(printf "SMASH THE STATE"))
[[ 0d9n3r2i4m1zgy0wpqbsyabsfzgs952066bfp8gwvcg4mkr4r5g8 == "$h" ]]
# Flat mode supports process substitution (hash file)
h=$(nix hash file --type sha256 --base32 <(printf "SMASH THE STATE"))
[[ 0d9n3r2i4m1zgy0wpqbsyabsfzgs952066bfp8gwvcg4mkr4r5g8 == "$h" ]]
# Symlinks in the ancestry are ok and don't affect the result
mkdir -p "$TEST_ROOT/simple" "$TEST_ROOT/try/to/mess/with/it"
echo hi > "$TEST_ROOT/simple/hi"
ln -s "$TEST_ROOT/simple" "$TEST_ROOT/try/to/mess/with/it/simple-link"
h=$(nix hash path --type sha256 --base32 "$TEST_ROOT/simple/hi")
[[ 1xmr8jicvzszfzpz46g37mlpvbzjl2wpwvl2b05psipssyp1sm8h == "$h" ]]
h=$(nix hash path --type sha256 --base32 "$TEST_ROOT/try/to/mess/with/it/simple-link/hi")
[[ 1xmr8jicvzszfzpz46g37mlpvbzjl2wpwvl2b05psipssyp1sm8h == "$h" ]]
# nix hash --mode nar does not canonicalize a symlink argument.
# Otherwise it can't generate a NAR whose root is a symlink.
# If you want to follow the symlink, pass $(realpath -s ...) instead.
ln -s /non-existent-48cujwe8ndf4as0bne "$TEST_ROOT/symlink-to-nowhere"
h=$(nix hash path --mode nar --type sha256 --base32 "$TEST_ROOT/symlink-to-nowhere")
[[ 1bl5ry3x1fcbwgr5c2x50bn572iixh4j1p6ax5isxly2ddgn8pbp == "$h" ]] # manually verified hash
if [[ -e /bin ]]; then
ln -s /bin "$TEST_ROOT/symlink-to-bin"
h=$(nix hash path --mode nar --type sha256 --base32 "$TEST_ROOT/symlink-to-bin")
[[ 0z2mdmkd43l0ijdxfbj1y8vzli15yh9b09n3a3rrygmjshbyypsw == "$h" ]] # manually verified hash
fi

View file

@ -65,5 +65,6 @@ def recurse($prefix):
}
nix __dump-cli | subcommands | while IFS= read -r cmd; do
# shellcheck disable=SC2086 # word splitting of cmd is intended
nix $cmd --help
done

View file

@ -1,31 +1,51 @@
{ busybox
, seed
# If we want the final derivation output to have references to its
# dependencies. Some tests need/want this, other don't.
, withFinalRefs ? false
{
busybox,
seed,
# If we want the final derivation output to have references to its
# dependencies. Some tests need/want this, other don't.
withFinalRefs ? false,
}:
with import ./config.nix;
let
contentAddressedByDefault = builtins.getEnv "NIX_TESTS_CA_BY_DEFAULT" == "1";
caArgs = if contentAddressedByDefault then {
__contentAddressed = true;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
} else {};
caArgs =
if contentAddressedByDefault then
{
__contentAddressed = true;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
}
else
{ };
mkDerivation = args:
derivation ({
inherit system;
builder = busybox;
args = ["sh" "-e" args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')];
} // removeAttrs args ["builder" "meta" "passthru"]
// caArgs)
// { meta = args.meta or {}; passthru = args.passthru or {}; };
mkDerivation =
args:
derivation (
{
inherit system;
builder = busybox;
args = [
"sh"
"-e"
args.builder or (builtins.toFile "builder-${args.name}.sh" ''
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source $NIX_ATTRS_SH_FILE; fi;
eval "$buildCommand"
'')
];
}
// removeAttrs args [
"builder"
"meta"
"passthru"
]
// caArgs
)
// {
meta = args.meta or { };
passthru = args.passthru or { };
};
input1 = mkDerivation {
shell = busybox;
@ -51,14 +71,15 @@ let
in
mkDerivation {
shell = busybox;
name = "hermetic";
passthru = { inherit input1 input2 input3; };
buildCommand =
''
read x < ${input1}
read y < ${input3}
echo ${if (builtins.trace withFinalRefs withFinalRefs) then "${input1} ${input3}" else ""} "$x $y" > $out
'';
}
mkDerivation {
shell = busybox;
name = "hermetic";
passthru = { inherit input1 input2 input3; };
buildCommand = ''
read x < ${input1}
read y < ${input3}
echo ${
if (builtins.trace withFinalRefs withFinalRefs) then "${input1} ${input3}" else ""
} "$x $y" > $out
'';
}

View file

@ -1,10 +1,8 @@
with import ./config.nix;
import (
mkDerivation {
name = "foo";
bla = import ./dependencies.nix {};
buildCommand = "
import (mkDerivation {
name = "foo";
bla = import ./dependencies.nix { };
buildCommand = "
echo \\\"hi\\\" > $out
";
}
)
})

View file

@ -1,26 +0,0 @@
with import ./config.nix;
let
bar = mkDerivation {
name = "bar";
builder = builtins.toFile "builder.sh"
''
echo 'builtins.add 123 456' > $out
'';
};
value =
# Test that pathExists can check the existence of /nix/store paths
assert builtins.pathExists bar;
import bar;
in
mkDerivation {
name = "foo";
builder = builtins.toFile "builder.sh"
''
echo -n FOO${toString value} > $out
'';
}

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