Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/nix/script-tests/cache-pull-substitute.sh

95 lines
3.9 KiB
Shell

# Cases for the closure pull (hive-c0re/src/cache_pull.rs): `nix-store --realise
# <top> --max-jobs 0` against a store whose configuration is what the daemon
# has on a hive host, the host's own substituter plus the swarm cache from the
# nix.conf fragment.
#
# The swarm cache holds the top path and NOT its dependency, as attic does for
# a path cache.nixos.org serves; a second cache, standing for cache.nixos.org,
# holds the dependency. The stores are chroot stores, so the realise runs in
# this process where a host runs it in the daemon; the substitution logic is
# the same.
set -uo pipefail
failures=0
count=0
case="setup"
fail() {
echo "FAILED: $case: $*" >&2
failures=$((failures + 1))
}
expect() { # <description> <got> <want>
count=$((count + 1))
if [ "$2" != "$3" ]; then fail "$1: got '$2', wanted '$3'"; fi
}
T=$(mktemp -d)
export HOME=$T/home XDG_CONFIG_HOME=$T/home NIX_USER_CONF_FILES=
mkdir -p "$HOME" "$T/empty"
export NIX_CONF_DIR=$T/empty
printf 'build-users-group =\nsandbox = false\nexperimental-features = nix-command\n' >"$T/empty/nix.conf"
src="local?root=$T/src"
dep=$(nix eval --raw --store "$src" --expr 'builtins.toFile "dep" "dependency"')
top=$(nix eval --raw --store "$src" --expr 'let dep = builtins.toFile "dep" "dependency"; in builtins.toFile "top" "needs ${dep}"')
nix-store --generate-binary-cache-key swarm-test-1 "$T/swarm.sec" "$T/swarm.pub" >/dev/null
nix-store --generate-binary-cache-key upstream-test-1 "$T/up.sec" "$T/up.pub" >/dev/null
attic=file://$T/attic
upstream=file://$T/upstream
nix copy --from "$src" --to "$attic?secret-key=$T/swarm.sec" "$top"
nix copy --from "$src" --to "$upstream?secret-key=$T/up.sec" "$dep"
# What attic leaves out because the upstream serves it.
rm -f "$T/attic/$(basename "$dep" | cut -c1-32).narinfo"
# The daemon's nix.conf: its own substituter and key, then the include.
# conf <name> <fragment text>: a NIX_CONF_DIR with that fragment.
conf() {
mkdir -p "$T/$1"
printf 'build-users-group =\nsandbox = false\nsubstituters = %s\ntrusted-public-keys = %s\n!include %s/cache.conf\n' \
"$upstream" "$(cat "$T/up.pub")" "$T/$1" >"$T/$1/nix.conf"
printf '%s\n' "$2" >"$T/$1/cache.conf"
}
fragment="extra-substituters = $attic
extra-trusted-public-keys = $(cat "$T/swarm.pub")"
# The paths are content-addressed (`builtins.toFile`), which `require-sigs` does
# not apply to, so this test cannot show the signature gate; hive-priv's
# `nix store verify` step and the fragment test carry the key.
# pull <conf dir> <dest name>: the exact pull of cache_pull.rs.
pull() {
NIX_CONF_DIR=$T/$1 nix-store --store "local?root=$T/$2" --realise "$top" --max-jobs 0 >/dev/null 2>"$T/err"
}
valid() { # <dest name> <path>
nix-store --store "local?root=$T/$1" --check-validity "$2" 2>/dev/null && echo yes || echo no
}
narinfo() { # <cache dir> <store path>: whether the cache has its narinfo
if [ -e "$T/$1/$(basename "$2" | cut -c1-32).narinfo" ]; then echo yes; else echo no; fi
}
case="control: the swarm cache has the top path and lacks the dependency"
expect "attic has the top path" "$(narinfo attic "$top")" yes
expect "attic lacks the dependency" "$(narinfo attic "$dep")" no
expect "upstream has the dependency" "$(narinfo upstream "$dep")" yes
case="the client-side copy that failed on a host fails here too"
if nix copy --from "$attic" --to "local?root=$T/d0" "$top" 2>"$T/err"; then
fail "nix copy --from the swarm cache alone succeeded"
fi
expect "no top path" "$(valid d0 "$top")" no
case="the daemon with both substituters realises the top path and its dependency"
conf both "$fragment"
pull both d1
expect "exit" $? 0
expect "top path valid" "$(valid d1 "$top")" yes
expect "dependency valid" "$(valid d1 "$dep")" yes
case="without the fragment the daemon has only the upstream and cannot realise the top path"
conf plain ""
if pull plain d2; then fail "realised without the swarm cache"; fi
expect "no top path" "$(valid d2 "$top")" no
echo "$count checks, $failures failed"
[ "$failures" = 0 ]