aboutsummaryrefslogtreecommitdiff
path: root/tests/functional/dyn-drv
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-10-05 12:12:18 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-12-01 12:06:43 -0500
commit30dcc19d1f30fc203be460134c4578509cce704f (patch)
tree6cc32609b9984a2c4d5ecc0cac5cf30609e208b9 /tests/functional/dyn-drv
parent72425212657d795dc215b334b7c8c8cd36d06b72 (diff)
Put functional tests in `tests/functional`
I think it is bad for these reasons when `tests/` contains a mix of functional and integration tests - Concepts is harder to understand, the documentation makes a good unit vs functional vs integration distinction, but when the integration tests are just two subdirs within `tests/` this is not clear. - Source filtering in the `flake.nix` is more complex. We need to filter out some of the dirs from `tests/`, rather than simply pick the dirs we want and take all of them. This is a good sign the structure of what we are trying to do is not matching the structure of the files. With this change we have a clean: ```shell-session $ git show 'HEAD:tests' tree HEAD:tests functional/ installer/ nixos/ ``` (cherry picked from commit 68c81c737571794f7246db53fb4774e94fcf4b7e)
Diffstat (limited to 'tests/functional/dyn-drv')
-rw-r--r--tests/functional/dyn-drv/build-built-drv.sh21
-rw-r--r--tests/functional/dyn-drv/common.sh8
l---------tests/functional/dyn-drv/config.nix.in1
-rw-r--r--tests/functional/dyn-drv/dep-built-drv.sh11
-rw-r--r--tests/functional/dyn-drv/eval-outputOf.sh80
-rw-r--r--tests/functional/dyn-drv/local.mk15
-rw-r--r--tests/functional/dyn-drv/old-daemon-error-hack.nix20
-rw-r--r--tests/functional/dyn-drv/old-daemon-error-hack.sh11
-rw-r--r--tests/functional/dyn-drv/recursive-mod-json.nix33
-rw-r--r--tests/functional/dyn-drv/recursive-mod-json.sh27
-rw-r--r--tests/functional/dyn-drv/text-hashed-output.nix33
-rw-r--r--tests/functional/dyn-drv/text-hashed-output.sh26
12 files changed, 286 insertions, 0 deletions
diff --git a/tests/functional/dyn-drv/build-built-drv.sh b/tests/functional/dyn-drv/build-built-drv.sh
new file mode 100644
index 000000000..647be9457
--- /dev/null
+++ b/tests/functional/dyn-drv/build-built-drv.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+source common.sh
+
+# In the corresponding nix file, we have two derivations: the first, named `hello`,
+# is a normal recursive derivation, while the second, named dependent, has the
+# new outputHashMode "text". Note that in "dependent", we don't refer to the
+# build output of `hello`, but only to the path of the drv file. For this reason,
+# we only need to:
+#
+# - instantiate `hello`
+# - build `producingDrv`
+# - check that the path of the output coincides with that of the original derivation
+
+out1=$(nix build -f ./text-hashed-output.nix hello --no-link)
+
+clearStore
+
+drvDep=$(nix-instantiate ./text-hashed-output.nix -A producingDrv)
+
+expectStderr 1 nix build "${drvDep}^out^out" --no-link | grepQuiet "Building dynamic derivations in one shot is not yet implemented"
diff --git a/tests/functional/dyn-drv/common.sh b/tests/functional/dyn-drv/common.sh
new file mode 100644
index 000000000..c786f6925
--- /dev/null
+++ b/tests/functional/dyn-drv/common.sh
@@ -0,0 +1,8 @@
+source ../common.sh
+
+# Need backend to support text-hashing too
+requireDaemonNewerThan "2.16.0pre20230419"
+
+enableFeatures "ca-derivations dynamic-derivations"
+
+restartDaemon
diff --git a/tests/functional/dyn-drv/config.nix.in b/tests/functional/dyn-drv/config.nix.in
new file mode 120000
index 000000000..af24ddb30
--- /dev/null
+++ b/tests/functional/dyn-drv/config.nix.in
@@ -0,0 +1 @@
+../config.nix.in \ No newline at end of file
diff --git a/tests/functional/dyn-drv/dep-built-drv.sh b/tests/functional/dyn-drv/dep-built-drv.sh
new file mode 100644
index 000000000..4f6e9b080
--- /dev/null
+++ b/tests/functional/dyn-drv/dep-built-drv.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+source common.sh
+
+out1=$(nix-build ./text-hashed-output.nix -A hello --no-out-link)
+
+clearStore
+
+expectStderr 1 nix-build ./text-hashed-output.nix -A wrapper --no-out-link | grepQuiet "Building dynamic derivations in one shot is not yet implemented"
+
+# diff -r $out1 $out2
diff --git a/tests/functional/dyn-drv/eval-outputOf.sh b/tests/functional/dyn-drv/eval-outputOf.sh
new file mode 100644
index 000000000..9467feb8d
--- /dev/null
+++ b/tests/functional/dyn-drv/eval-outputOf.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+
+source ./common.sh
+
+# Without the dynamic-derivations XP feature, we don't have the builtin.
+nix --experimental-features 'nix-command' eval --impure --expr \
+ 'assert ! (builtins ? outputOf); ""'
+
+# Test that a string is required.
+#
+# We currently require a string to be passed, rather than a derivation
+# object that could be coerced to a string. We might liberalise this in
+# the future so it does work, but there are some design questions to
+# resolve first. Adding a test so we don't liberalise it by accident.
+expectStderr 1 nix --experimental-features 'nix-command dynamic-derivations' eval --impure --expr \
+ 'builtins.outputOf (import ../dependencies.nix {}) "out"' \
+ | grepQuiet "value is a set while a string was expected"
+
+# Test that "DrvDeep" string contexts are not supported at this time
+#
+# Like the above, this is a restriction we could relax later.
+expectStderr 1 nix --experimental-features 'nix-command dynamic-derivations' eval --impure --expr \
+ 'builtins.outputOf (import ../dependencies.nix {}).drvPath "out"' \
+ | grepQuiet "has a context which refers to a complete source and binary closure. This is not supported at this time"
+
+# Test using `builtins.outputOf` with static derivations
+testStaticHello () {
+ nix eval --impure --expr \
+ 'with (import ./text-hashed-output.nix); let
+ a = hello.outPath;
+ b = builtins.outputOf (builtins.unsafeDiscardOutputDependency hello.drvPath) "out";
+ in builtins.trace a
+ (builtins.trace b
+ (assert a == b; null))'
+}
+
+# Test with a regular old input-addresed derivation
+#
+# `builtins.outputOf` works without ca-derivations and doesn't create a
+# placeholder but just returns the output path.
+testStaticHello
+
+# Test with content addressed derivation.
+NIX_TESTS_CA_BY_DEFAULT=1 testStaticHello
+
+# Test with derivation-producing derivation
+#
+# This is hardly different from the preceding cases, except that we're
+# only taking 1 outputOf out of 2 possible outputOfs. Note that
+# `.outPath` could be defined as `outputOf drvPath`, which is what we're
+# testing here. The other `outputOf` that we're not testing here is the
+# use of _dynamic_ derivations.
+nix eval --impure --expr \
+ 'with (import ./text-hashed-output.nix); let
+ a = producingDrv.outPath;
+ b = builtins.outputOf (builtins.builtins.unsafeDiscardOutputDependency producingDrv.drvPath) "out";
+ in builtins.trace a
+ (builtins.trace b
+ (assert a == b; null))'
+
+# Test with unbuilt output of derivation-producing derivation.
+#
+# This function similar to `testStaticHello` used above, but instead of
+# checking the property on a constant derivation, we check it on a
+# derivation that's from another derivation's output (outPath).
+testDynamicHello () {
+ nix eval --impure --expr \
+ 'with (import ./text-hashed-output.nix); let
+ a = builtins.outputOf producingDrv.outPath "out";
+ b = builtins.outputOf (builtins.outputOf (builtins.unsafeDiscardOutputDependency producingDrv.drvPath) "out") "out";
+ in builtins.trace a
+ (builtins.trace b
+ (assert a == b; null))'
+}
+
+# inner dynamic derivation is input-addressed
+testDynamicHello
+
+# inner dynamic derivation is content-addressed
+NIX_TESTS_CA_BY_DEFAULT=1 testDynamicHello
diff --git a/tests/functional/dyn-drv/local.mk b/tests/functional/dyn-drv/local.mk
new file mode 100644
index 000000000..c87534944
--- /dev/null
+++ b/tests/functional/dyn-drv/local.mk
@@ -0,0 +1,15 @@
+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
diff --git a/tests/functional/dyn-drv/old-daemon-error-hack.nix b/tests/functional/dyn-drv/old-daemon-error-hack.nix
new file mode 100644
index 000000000..c9d4a62d4
--- /dev/null
+++ b/tests/functional/dyn-drv/old-daemon-error-hack.nix
@@ -0,0 +1,20 @@
+with import ./config.nix;
+
+# A simple content-addressed derivation.
+# The derivation can be arbitrarily modified by passing a different `seed`,
+# but the output will always be the same
+rec {
+ stub = mkDerivation {
+ name = "stub";
+ buildCommand = ''
+ echo stub > $out
+ '';
+ };
+ wrapper = mkDerivation {
+ name = "has-dynamic-drv-dep";
+ buildCommand = ''
+ exit 1 # we're not building this derivation
+ ${builtins.outputOf stub.outPath "out"}
+ '';
+ };
+}
diff --git a/tests/functional/dyn-drv/old-daemon-error-hack.sh b/tests/functional/dyn-drv/old-daemon-error-hack.sh
new file mode 100644
index 000000000..43b049973
--- /dev/null
+++ b/tests/functional/dyn-drv/old-daemon-error-hack.sh
@@ -0,0 +1,11 @@
+# Purposely bypassing our usual common for this subgroup
+source ../common.sh
+
+# Need backend to support text-hashing too
+isDaemonNewer "2.18.0pre20230906" && skipTest "Daemon is too new"
+
+enableFeatures "ca-derivations dynamic-derivations"
+
+restartDaemon
+
+expectStderr 1 nix-instantiate --read-write-mode ./old-daemon-error-hack.nix | grepQuiet "the daemon is too old to understand dependencies on dynamic derivations"
diff --git a/tests/functional/dyn-drv/recursive-mod-json.nix b/tests/functional/dyn-drv/recursive-mod-json.nix
new file mode 100644
index 000000000..c6a24ca4f
--- /dev/null
+++ b/tests/functional/dyn-drv/recursive-mod-json.nix
@@ -0,0 +1,33 @@
+with import ./config.nix;
+
+let innerName = "foo"; in
+
+mkDerivation rec {
+ name = "${innerName}.drv";
+ SHELL = shell;
+
+ requiredSystemFeatures = [ "recursive-nix" ];
+
+ drv = builtins.unsafeDiscardOutputDependency (import ./text-hashed-output.nix).hello.drvPath;
+
+ buildCommand = ''
+ export NIX_CONFIG='experimental-features = nix-command ca-derivations'
+
+ PATH=${builtins.getEnv "EXTRA_PATH"}:$PATH
+
+ # JSON of pre-existing drv
+ nix derivation show $drv | jq .[] > drv0.json
+
+ # Fix name
+ jq < drv0.json '.name = "${innerName}"' > drv1.json
+
+ # Extend `buildCommand`
+ jq < drv1.json '.env.buildCommand += "echo \"I am alive!\" >> $out/hello\n"' > drv0.json
+
+ # Used as our output
+ cp $(nix derivation add < drv0.json) $out
+ '';
+ __contentAddressed = true;
+ outputHashMode = "text";
+ outputHashAlgo = "sha256";
+}
diff --git a/tests/functional/dyn-drv/recursive-mod-json.sh b/tests/functional/dyn-drv/recursive-mod-json.sh
new file mode 100644
index 000000000..0698b81bd
--- /dev/null
+++ b/tests/functional/dyn-drv/recursive-mod-json.sh
@@ -0,0 +1,27 @@
+source common.sh
+
+# FIXME
+if [[ $(uname) != Linux ]]; then skipTest "Not running Linux"; fi
+
+export NIX_TESTS_CA_BY_DEFAULT=1
+
+enableFeatures 'recursive-nix'
+restartDaemon
+
+clearStore
+
+rm -f $TEST_ROOT/result
+
+EXTRA_PATH=$(dirname $(type -p nix)):$(dirname $(type -p jq))
+export EXTRA_PATH
+
+# Will produce a drv
+metaDrv=$(nix-instantiate ./recursive-mod-json.nix)
+
+# computed "dynamic" derivation
+drv=$(nix-store -r $metaDrv)
+
+# build that dyn drv
+res=$(nix-store -r $drv)
+
+grep 'I am alive!' $res/hello
diff --git a/tests/functional/dyn-drv/text-hashed-output.nix b/tests/functional/dyn-drv/text-hashed-output.nix
new file mode 100644
index 000000000..99203b518
--- /dev/null
+++ b/tests/functional/dyn-drv/text-hashed-output.nix
@@ -0,0 +1,33 @@
+with import ./config.nix;
+
+# A simple content-addressed derivation.
+# The derivation can be arbitrarily modified by passing a different `seed`,
+# but the output will always be the same
+rec {
+ hello = mkDerivation {
+ name = "hello";
+ buildCommand = ''
+ set -x
+ echo "Building a CA derivation"
+ mkdir -p $out
+ echo "Hello World" > $out/hello
+ '';
+ };
+ producingDrv = mkDerivation {
+ name = "hello.drv";
+ buildCommand = ''
+ echo "Copying the derivation"
+ cp ${builtins.unsafeDiscardOutputDependency hello.drvPath} $out
+ '';
+ __contentAddressed = true;
+ outputHashMode = "text";
+ outputHashAlgo = "sha256";
+ };
+ wrapper = mkDerivation {
+ name = "use-dynamic-drv-in-non-dynamic-drv";
+ buildCommand = ''
+ echo "Copying the output of the dynamic derivation"
+ cp -r ${builtins.outputOf producingDrv.outPath "out"} $out
+ '';
+ };
+}
diff --git a/tests/functional/dyn-drv/text-hashed-output.sh b/tests/functional/dyn-drv/text-hashed-output.sh
new file mode 100644
index 000000000..f3e5aa93b
--- /dev/null
+++ b/tests/functional/dyn-drv/text-hashed-output.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+source common.sh
+
+# In the corresponding nix file, we have two derivations: the first, named root,
+# is a normal recursive derivation, while the second, named dependent, has the
+# new outputHashMode "text". Note that in "dependent", we don't refer to the
+# build output of root, but only to the path of the drv file. For this reason,
+# we only need to:
+#
+# - instantiate the root derivation
+# - build the dependent derivation
+# - check that the path of the output coincides with that of the original derivation
+
+drv=$(nix-instantiate ./text-hashed-output.nix -A hello)
+nix show-derivation "$drv"
+
+drvProducingDrv=$(nix-instantiate ./text-hashed-output.nix -A producingDrv)
+nix show-derivation "$drvProducingDrv"
+
+out1=$(nix-build ./text-hashed-output.nix -A producingDrv --no-out-link)
+
+nix path-info $drv --derivation --json | jq
+nix path-info $out1 --derivation --json | jq
+
+test $out1 == $drv