_ _
| |_ ___| |_ _
| | . | | | |
|_|_|___|_|_ |
|___|
git mirror - github.com/owenewans/holy - branch master
file tests/repo-closure.sh
#!/bin/sh
set -eu
bin=$(realpath "$1")
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
mkdir -p "$tmp/root" "$tmp/repo" "$tmp/tree/HOLY" "$tmp/tree/DATA/usr/share"
build() {
name=$1
required=$2
kind=${3:-package}
printf 'format holy-package-1\nname %s\nversion 1\nrelease 1\nos linux\narch noarch\nlibc nolibc\n' "$name" > "$tmp/tree/HOLY/meta"
if test "$name" = or-root; then
printf 'x-version-family deb\n' >> "$tmp/tree/HOLY/meta"
fi
for field in files deps provides hooks origin transform; do : > "$tmp/tree/HOLY/$field"; done
if test -n "$required"; then
printf 'require dep-1 %s %s %s any any any - %s metadata\n' \
"$name" "$kind" "$required" "$required" > "$tmp/tree/HOLY/deps"
fi
rm -f "$tmp/tree/DATA/usr/share/"*
printf '%s\n' "$name" > "$tmp/tree/DATA/usr/share/$name"
"$bin" manifest generate "$tmp/tree" --output "$tmp/files" > "$tmp/out"
mv "$tmp/files" "$tmp/tree/HOLY/files"
"$bin" pack "$tmp/tree" --output "$tmp/repo/$name.holy" > "$tmp/out"
}
build root dep
build dep leaf
build leaf ''
build file-root /usr/share/file-provider file
build file-provider ''
build unrelated ''
build foreign-root foreign-dep
build reuse-root foreign-dep
build foreign-dep ''
build foreign-unused ''
build local-root local-dep
build local-dep ''
build provider-root external-package
build external-package ''
build external-file-root /usr/share/external-file file
build external-file ''
build auto-root auto-child
build auto-child auto-leaf
build auto-leaf ''
build auto-file-root /usr/share/auto-file file
build auto-file ''
build missing-root absent-package
build or-root 'or-first@ge@2|or-second@any@-' package-or
build or-first ''
build or-second ''
mkdir -p "$tmp/other-repo"
mv "$tmp/repo/foreign-dep.holy" "$tmp/other-repo/foreign-dep.holy"
mv "$tmp/repo/foreign-unused.holy" "$tmp/other-repo/foreign-unused.holy"
mkdir -p "$tmp/local-artifacts"
mv "$tmp/repo/local-dep.holy" "$tmp/local-artifacts/local-dep.holy"
mv "$tmp/repo/external-package.holy" "$tmp/other-repo/external-package.holy"
mv "$tmp/repo/external-file.holy" "$tmp/other-repo/external-file.holy"
mv "$tmp/repo/auto-child.holy" "$tmp/other-repo/auto-child.holy"
mv "$tmp/repo/auto-leaf.holy" "$tmp/other-repo/auto-leaf.holy"
mv "$tmp/repo/auto-file.holy" "$tmp/other-repo/auto-file.holy"
mv "$tmp/repo/or-second.holy" "$tmp/other-repo/or-second.holy"
case "$(uname -m)" in
x86_64)
arch=x86_64
printf '.global _start\n_start:\n mov $60, %%rax\n xor %%rdi, %%rdi\n syscall\n' > "$tmp/helper.s"
;;
i?86)
arch=x86
printf '.global _start\n_start:\n mov $1, %%eax\n xor %%ebx, %%ebx\n int $0x80\n' > "$tmp/helper.s"
;;
*) arch= ;;
esac
if test -n "$arch"; then
"${CC:-cc}" -nostdlib -static -o "$tmp/helper" "$tmp/helper.s"
rm -rf "$tmp/tree/DATA"
mkdir -p "$tmp/tree/DATA/usr/bin"
printf 'format holy-package-1\nname helper\nversion 1\nrelease 1\nos linux\narch %s\nlibc nolibc\n' "$arch" > "$tmp/tree/HOLY/meta"
for field in files deps provides hooks origin transform; do : > "$tmp/tree/HOLY/$field"; done
cp "$tmp/helper" "$tmp/tree/DATA/usr/bin/closure-helper"
"$bin" manifest generate "$tmp/tree" --output "$tmp/files" > "$tmp/out"
mv "$tmp/files" "$tmp/tree/HOLY/files"
"$bin" pack "$tmp/tree" --output "$tmp/repo/helper.holy" > "$tmp/out"
rm -rf "$tmp/tree/DATA"
mkdir -p "$tmp/tree/DATA/usr/bin"
printf 'format holy-package-1\nname script\nversion 1\nrelease 1\nos linux\narch noarch\nlibc nolibc\n' > "$tmp/tree/HOLY/meta"
for field in files deps provides hooks origin transform; do : > "$tmp/tree/HOLY/$field"; done
printf '#!/usr/bin/closure-helper\n' > "$tmp/tree/DATA/usr/bin/closure-script"
chmod 755 "$tmp/tree/DATA/usr/bin/closure-script"
"$bin" manifest generate "$tmp/tree" --output "$tmp/files" > "$tmp/out"
mv "$tmp/files" "$tmp/tree/HOLY/files"
"$bin" pack "$tmp/tree" --output "$tmp/repo/script.holy" > "$tmp/out"
cat > "$tmp/foo.c" <<'C'
int foo(void) { return 2; }
C
cat > "$tmp/wrong.c" <<'C'
int bar(void) { return 2; }
C
cat > "$tmp/good.map" <<'MAP'
GOOD_1 { global: foo; };
MAP
cat > "$tmp/bad.map" <<'MAP'
BAD_1 { global: foo; };
MAP
cat > "$tmp/wrong.map" <<'MAP'
GOOD_1 { global: bar; };
MAP
printf 'extern int foo(void); int consumer(void) { return foo(); }\n' > "$tmp/consumer.c"
"${CC:-cc}" -shared -fPIC -o "$tmp/libgood.so" "$tmp/foo.c" \
-Wl,-soname,libchoice.so.1 -Wl,--version-script="$tmp/good.map" \
-Wl,--no-as-needed -lc
"${CC:-cc}" -shared -fPIC -o "$tmp/libbad.so" "$tmp/foo.c" \
-Wl,-soname,libchoice.so.1 -Wl,--version-script="$tmp/bad.map" \
-Wl,--no-as-needed -lc
"${CC:-cc}" -shared -fPIC -o "$tmp/libwrong.so" "$tmp/wrong.c" \
-Wl,-soname,libchoice.so.1 -Wl,--version-script="$tmp/wrong.map" \
-Wl,--no-as-needed -lc
"${CC:-cc}" -shared -fPIC -o "$tmp/libconsumer.so" "$tmp/consumer.c" \
-L"$tmp" -lgood -Wl,--no-as-needed -lc
for name in good bad wrong consumer; do
rm -rf "$tmp/tree/DATA"
mkdir -p "$tmp/tree/DATA/usr/lib/holy/${arch}-linux-gnu"
printf 'format holy-package-1\nname %s\nversion 1\nrelease 1\nos linux\narch %s\nlibc glibc\n' \
"$name" "$arch" > "$tmp/tree/HOLY/meta"
for field in files deps provides hooks origin transform; do : > "$tmp/tree/HOLY/$field"; done
cp "$tmp/lib$name.so" "$tmp/tree/DATA/usr/lib/holy/${arch}-linux-gnu/lib$name.so"
"$bin" manifest generate "$tmp/tree" --output "$tmp/files" > "$tmp/out"
mv "$tmp/files" "$tmp/tree/HOLY/files"
"$bin" pack "$tmp/tree" --output "$tmp/repo/$name.holy" > "$tmp/out"
done
fi
if test -n "$arch"; then
mv "$tmp/repo/helper.holy" "$tmp/other-repo/helper.holy"
fi
"$bin" repo index "$tmp/repo" > "$tmp/out"
if test -n "$arch"; then
good_export=$(sha256sum "$tmp/repo/good.holy" | cut -d ' ' -f 1)
grep -F "elf-export $good_export " "$tmp/repo/index" | grep -q '"foo" "GOOD_1"'
cp "$tmp/repo/index" "$tmp/original-index"
sed 's/"foo" "GOOD_1"/"forged" "GOOD_1"/' "$tmp/original-index" > "$tmp/repo/index"
if "$bin" repo seal "$tmp/repo" > "$tmp/out" 2> "$tmp/err"; then exit 1; fi
cp "$tmp/original-index" "$tmp/repo/index"
fi
"$bin" repo seal "$tmp/repo" > "$tmp/out"
"$bin" repo index "$tmp/other-repo" > "$tmp/out"
"$bin" repo seal "$tmp/other-repo" > "$tmp/out"
index=$(sed -n 's/^sha256 //p' "$tmp/repo/current")
other_index=$(sed -n 's/^sha256 //p' "$tmp/other-repo/current")
"$bin" db init --root "$tmp/root" > "$tmp/out"
printf '[source fixture]\ntype holy-http\nurl https://fixture.example/holy/\n[source other]\ntype holy-http\nurl https://other.example/holy/\n' > "$tmp/config"
"$bin" source plan --config "$tmp/config" --root "$tmp/root" > "$tmp/plan"
plan=$(sha256sum "$tmp/plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/plan" --sha256 "$plan" --root "$tmp/root" > "$tmp/out"
"$bin" source list --root "$tmp/root" > "$tmp/out"
source_id=$(sed -n 's/^source \([0-9a-f]*\) "fixture" active$/\1/p' "$tmp/out")
other_id=$(sed -n 's/^source \([0-9a-f]*\) "other" active$/\1/p' "$tmp/out")
printf 'format holy-mirror-1\nurl "https://fixture.example/holy/"\nindex-sha256 %s\nverification digest-pinned-unsigned\nsource-id %s\n' \
"$index" "$source_id" > "$tmp/repo/mirror-origin"
printf 'format holy-mirror-1\nurl "https://other.example/holy/"\nindex-sha256 %s\nverification digest-pinned-unsigned\nsource-id %s\n' \
"$other_index" "$other_id" > "$tmp/other-repo/mirror-origin"
"$bin" source catalog bind fixture "$tmp/repo" --root "$tmp/root" > "$tmp/out"
"$bin" source catalog bind other "$tmp/other-repo" --root "$tmp/root" > "$tmp/out"
if "$bin" add fixture:missing-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"; then
exit 1
else
test "$?" -eq 4
fi
test ! -e "$tmp/root/usr/share/missing-root"
if "$bin" add fixture:foreign-root --candidate other:foreign-dep \
--candidate other:foreign-unused --root "$tmp/root" \
> "$tmp/out" 2> "$tmp/err" < /dev/null; then exit 1; else test "$?" -eq 3; fi
test ! -e "$tmp/root/usr/share/foreign-root"
"$bin" add fixture:foreign-root --candidate other:foreign-dep \
--candidate other:foreign-unused --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
foreign_hash=$(sha256sum "$tmp/other-repo/foreign-dep.holy" | cut -d ' ' -f 1)
test -f "$tmp/root/usr/share/foreign-root"
test -f "$tmp/root/usr/share/foreign-dep"
test ! -e "$tmp/root/usr/share/foreign-unused"
grep -q "$other_id" "$tmp/root/var/lib/holypkg/installed/$foreign_hash/source"
if "$bin" add fixture:local-root \
--candidate-local "other=$tmp/local-artifacts/local-dep.holy" \
--root "$tmp/root" > "$tmp/out" 2> "$tmp/err" < /dev/null; then
exit 1
else
test "$?" -eq 3
fi
test ! -e "$tmp/root/usr/share/local-root"
if "$bin" add fixture:local-root \
--candidate-local "absent=$tmp/local-artifacts/local-dep.holy" \
--root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"; then
exit 1
else
test "$?" -eq 6
fi
"$bin" add fixture:local-root \
--candidate-local "other=$tmp/local-artifacts/local-dep.holy" \
--root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/local-root"
test -f "$tmp/root/usr/share/local-dep"
local_hash=$(sha256sum "$tmp/local-artifacts/local-dep.holy" | cut -d ' ' -f 1)
grep -q "$other_id" "$tmp/root/var/lib/holypkg/installed/$local_hash/source"
"$bin" db check --all --root "$tmp/root" > "$tmp/out"
mkdir -p "$tmp/third-repo"
cp "$tmp/other-repo/auto-child.holy" "$tmp/third-repo/auto-child.holy"
"$bin" repo index "$tmp/third-repo" > "$tmp/out"
"$bin" repo seal "$tmp/third-repo" > "$tmp/out"
third_index=$(sed -n 's/^sha256 //p' "$tmp/third-repo/current")
printf '[source fixture]\ntype holy-http\nurl https://fixture.example/holy/\n[source other]\ntype holy-http\nurl https://other.example/holy/\n[source third]\ntype holy-http\nurl https://third.example/holy/\n[source foreign]\ntype apk\nrepo main https://foreign.example/alpine/\n' > "$tmp/three-sources"
"$bin" source plan --config "$tmp/three-sources" --root "$tmp/root" > "$tmp/plan"
plan=$(sha256sum "$tmp/plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/plan" --sha256 "$plan" --root "$tmp/root" > "$tmp/out"
"$bin" source list --root "$tmp/root" > "$tmp/out"
third_id=$(sed -n 's/^source \([0-9a-f]*\) "third" active$/\1/p' "$tmp/out")
test -n "$third_id"
printf 'format holy-mirror-1\nurl "https://third.example/holy/"\nindex-sha256 %s\nverification digest-pinned-unsigned\nsource-id %s\n' \
"$third_index" "$third_id" > "$tmp/third-repo/mirror-origin"
"$bin" source catalog bind third "$tmp/third-repo" --root "$tmp/root" > "$tmp/out"
if "$bin" add fixture:auto-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"; then
exit 1
else
test "$?" -eq 3
fi
grep -q 'provider package:auto-child available from other' "$tmp/err"
grep -q 'provider package:auto-child available from third' "$tmp/err"
grep -q 'decision-required' "$tmp/err"
test ! -e "$tmp/root/usr/share/auto-root"
sed '/^\[source fixture\]$/a parent other' "$tmp/three-sources" > "$tmp/parent-sources"
mkdir -p "$tmp/parent-root"
"$bin" db init --root "$tmp/parent-root" > "$tmp/out"
"$bin" source plan --config "$tmp/parent-sources" --root "$tmp/parent-root" > "$tmp/parent-plan"
parent_plan=$(sha256sum "$tmp/parent-plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/parent-plan" --sha256 "$parent_plan" --root "$tmp/parent-root" > "$tmp/out"
grep -q " $other_id \"-\" 0$" "$tmp/parent-root/var/lib/holypkg/sources"
for source in fixture other third; do
case "$source" in
fixture) parent_catalog=$tmp/repo ;;
other) parent_catalog=$tmp/other-repo ;;
third) parent_catalog=$tmp/third-repo ;;
esac
"$bin" source catalog bind "$source" "$parent_catalog" --root "$tmp/parent-root" > "$tmp/out"
done
mkdir -p "$tmp/renamed-parent-root"
cp -a "$tmp/parent-root/." "$tmp/renamed-parent-root/"
sed -e 's/^parent other$/parent preferred/' \
-e 's/^\[source other\]$/[source preferred]/' \
"$tmp/parent-sources" > "$tmp/renamed-parent-sources"
"$bin" source plan --config "$tmp/renamed-parent-sources" \
--root "$tmp/renamed-parent-root" > "$tmp/renamed-parent-plan"
renamed_parent_plan=$(sha256sum "$tmp/renamed-parent-plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/renamed-parent-plan" --sha256 "$renamed_parent_plan" \
--root "$tmp/renamed-parent-root" > "$tmp/out"
"$bin" add fixture:auto-root --root "$tmp/renamed-parent-root" --yes --noninteractive \
> "$tmp/out" 2> "$tmp/err"
grep -q 'selected preferred for package:auto-child by parent preference' "$tmp/err"
test -f "$tmp/renamed-parent-root/usr/share/auto-child"
"$bin" add fixture:auto-root --root "$tmp/parent-root" --yes --noninteractive \
> "$tmp/out" 2> "$tmp/err"
grep -q 'selected other for package:auto-child by parent preference' "$tmp/err"
test -f "$tmp/parent-root/usr/share/auto-root"
test -f "$tmp/parent-root/usr/share/auto-child"
auto_child_hash=$(sha256sum "$tmp/other-repo/auto-child.holy" | cut -d ' ' -f 1)
grep -q "$other_id" "$tmp/parent-root/var/lib/holypkg/installed/$auto_child_hash/source"
"$bin" db check --all --root "$tmp/parent-root" > "$tmp/out"
for policy in family priority; do
policy_root="$tmp/$policy-root"
policy_config="$tmp/$policy-sources"
if test "$policy" = family; then
printf '[source fixture]\ntype holy-http\nurl https://fixture.example/holy/\nfamily workstation\n[source other]\ntype holy-http\nurl https://other.example/holy/\nfamily workstation\npriority -5\n[source third]\ntype holy-http\nurl https://third.example/holy/\nfamily unrelated\npriority 100\n' > "$policy_config"
else
printf '[source fixture]\ntype holy-http\nurl https://fixture.example/holy/\n[source other]\ntype holy-http\nurl https://other.example/holy/\npriority 10\n[source third]\ntype holy-http\nurl https://third.example/holy/\npriority 5\n' > "$policy_config"
fi
mkdir -p "$policy_root"
"$bin" db init --root "$policy_root" > "$tmp/out"
"$bin" source plan --config "$policy_config" --root "$policy_root" > "$tmp/policy-plan"
policy_plan=$(sha256sum "$tmp/policy-plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/policy-plan" --sha256 "$policy_plan" --root "$policy_root" > "$tmp/out"
for source in fixture other third; do
case "$source" in
fixture) policy_catalog=$tmp/repo ;;
other) policy_catalog=$tmp/other-repo ;;
third) policy_catalog=$tmp/third-repo ;;
esac
"$bin" source catalog bind "$source" "$policy_catalog" --root "$policy_root" > "$tmp/out"
done
"$bin" add fixture:auto-root --root "$policy_root" --yes --noninteractive \
> "$tmp/out" 2> "$tmp/err"
grep -q "selected other for package:auto-child by $policy preference" "$tmp/err"
test -f "$policy_root/usr/share/auto-child"
"$bin" db check --all --root "$policy_root" > "$tmp/out"
done
for target in choice-root answers-root; do
mkdir -p "$tmp/$target"
"$bin" db init --root "$tmp/$target" > "$tmp/out"
"$bin" source plan --config "$tmp/three-sources" --root "$tmp/$target" > "$tmp/choice-plan"
choice_plan=$(sha256sum "$tmp/choice-plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/choice-plan" --sha256 "$choice_plan" --root "$tmp/$target" > "$tmp/out"
for source in fixture other third; do
case "$source" in
fixture) catalog=$tmp/repo ;;
other) catalog=$tmp/other-repo ;;
third) catalog=$tmp/third-repo ;;
esac
"$bin" source catalog bind "$source" "$catalog" --root "$tmp/$target" > "$tmp/out"
done
done
python3 - "$bin" "$tmp/choice-root" <<'PY'
import os
import pty
import subprocess
import sys
master, slave = pty.openpty()
process = subprocess.Popen([sys.argv[1], "add", "fixture:auto-root",
"--root", sys.argv[2], "--yes"], stdin=slave,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True)
os.close(slave)
os.write(master, b"other\n")
stdout, stderr = process.communicate(timeout=30)
os.close(master)
assert process.returncode == 0, (process.returncode, stdout, stderr)
assert "Select source for package:auto-child" in stderr
PY
test -f "$tmp/choice-root/usr/share/auto-root"
test -f "$tmp/choice-root/usr/share/auto-child"
"$bin" db check --all --root "$tmp/choice-root" > "$tmp/out"
auto_root_hash=$(sha256sum "$tmp/repo/auto-root.holy" | cut -d ' ' -f 1)
printf 'format holy-answers-1\nsource %s dep-1 other\nsource %s dep-1 third\n' \
"$auto_root_hash" "$auto_root_hash" > "$tmp/duplicate-answers"
if "$bin" add fixture:auto-root --root "$tmp/answers-root" --yes --noninteractive \
--answers "$tmp/duplicate-answers" > "$tmp/out" 2> "$tmp/err"; then exit 1
else test "$?" -eq 2; fi
printf 'format holy-answers-1\nsource %s dep-1 absent\n' \
"$auto_root_hash" > "$tmp/stale-answers"
if "$bin" add fixture:auto-root --root "$tmp/answers-root" --yes --noninteractive \
--answers "$tmp/stale-answers" > "$tmp/out" 2> "$tmp/err"; then exit 1
else test "$?" -eq 3; fi
test ! -e "$tmp/answers-root/usr/share/auto-root"
printf 'format holy-answers-1\nsource %s dep-1 other' "$auto_root_hash" > "$tmp/answers"
if ! "$bin" add fixture:auto-root --root "$tmp/answers-root" --yes --noninteractive \
--answers "$tmp/answers" > "$tmp/out" 2> "$tmp/err"; then
cat "$tmp/err" >&2
exit 1
fi
test -f "$tmp/answers-root/usr/share/auto-root"
test -f "$tmp/answers-root/usr/share/auto-child"
"$bin" db check --all --root "$tmp/answers-root" > "$tmp/out"
"$bin" source plan --config "$tmp/config" --root "$tmp/root" > "$tmp/plan"
plan=$(sha256sum "$tmp/plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/plan" --sha256 "$plan" --root "$tmp/root" > "$tmp/out"
if "$bin" add fixture:auto-root --root "$tmp/root" \
> "$tmp/out" 2> "$tmp/err" < /dev/null; then
exit 1
else
test "$?" -eq 3
fi
test ! -e "$tmp/root/usr/share/auto-root"
"$bin" add fixture:auto-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/auto-child"
test -f "$tmp/root/usr/share/auto-leaf"
"$bin" add fixture:auto-file-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/auto-file"
"$bin" add fixture:or-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/or-root"
test -f "$tmp/root/usr/share/or-second"
test ! -e "$tmp/root/usr/share/or-first"
"$bin" db check --all --root "$tmp/root" > "$tmp/out"
"$bin" add fixture:provider-root --candidate-provider other:package:external-package \
--root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/external-package"
if "$bin" add fixture:external-file-root \
--candidate-provider other:file:/usr/share/missing-provider \
--root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"; then
exit 1
else
test "$?" -eq 4
fi
"$bin" add fixture:external-file-root \
--candidate-provider other:file:/usr/share/external-file \
--root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/external-file"
"$bin" db check --all --root "$tmp/root" > "$tmp/out"
if test -n "$arch"; then
grep -q '"GOOD_1"' "$tmp/repo/index"
grep -q '"BAD_1"' "$tmp/repo/index"
bad=$(sha256sum "$tmp/repo/bad.holy" | cut -d ' ' -f 1)
good=$(sha256sum "$tmp/repo/good.holy" | cut -d ' ' -f 1)
wrong=$(sha256sum "$tmp/repo/wrong.holy" | cut -d ' ' -f 1)
grep -F "elf-version $wrong " "$tmp/repo/index" | grep -q '"GOOD_1"'
grep -F "soname $wrong " "$tmp/repo/index" | grep -q '"libchoice.so.1"'
cp "$tmp/repo/bad.holy" "$tmp/bad.saved"
printf 'corrupt\n' > "$tmp/repo/bad.holy"
if "$bin" add fixture:consumer --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"; then exit 1; fi
if grep -q 'invalid or stale repository index' "$tmp/err"; then cat "$tmp/err"; exit 1; fi
test -f "$tmp/root/var/cache/holypkg/objects/sha256/$good.holy"
test ! -e "$tmp/root/var/cache/holypkg/objects/sha256/$bad.holy"
test ! -e "$tmp/root/var/cache/holypkg/objects/sha256/$wrong.holy"
cp "$tmp/bad.saved" "$tmp/repo/bad.holy"
fi
cp "$tmp/repo/dep.holy" "$tmp/dep.saved"
printf 'corrupt\n' > "$tmp/repo/dep.holy"
if "$bin" add fixture:root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"; then exit 1; fi
test ! -e "$tmp/root/usr/share/root"
cp "$tmp/dep.saved" "$tmp/repo/dep.holy"
unrelated=$(sha256sum "$tmp/repo/unrelated.holy" | cut -d ' ' -f 1)
printf 'corrupt\n' > "$tmp/repo/unrelated.holy"
"$bin" add fixture:root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
for name in root dep leaf; do
test -f "$tmp/root/usr/share/$name"
digest=$(sha256sum "$tmp/repo/$name.holy" | cut -d ' ' -f 1)
test -f "$tmp/root/var/cache/holypkg/objects/sha256/$digest.holy"
done
test ! -e "$tmp/root/var/cache/holypkg/objects/sha256/$unrelated.holy"
"$bin" db check --all --root "$tmp/root" > "$tmp/out"
"$bin" add fixture:file-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/file-root"
test -f "$tmp/root/usr/share/file-provider"
if test -n "$arch"; then
"$bin" add fixture:script --candidate-provider other:command:closure-helper \
--root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -x "$tmp/root/usr/bin/closure-helper"
test -x "$tmp/root/usr/bin/closure-script"
fi
printf '[source fixture]\ntype holy-http\nurl https://fixture.example/holy/\n' > "$tmp/fixture-only"
"$bin" source plan --config "$tmp/fixture-only" --root "$tmp/root" > "$tmp/plan"
plan=$(sha256sum "$tmp/plan" | cut -d ' ' -f 1)
"$bin" source apply "$tmp/plan" --sha256 "$plan" --root "$tmp/root" > "$tmp/out"
"$bin" add fixture:reuse-root --root "$tmp/root" --yes > "$tmp/out" 2> "$tmp/err"
test -f "$tmp/root/usr/share/reuse-root"
"$bin" db check --all --root "$tmp/root" > "$tmp/out"