git mirror - github.com/owenewans/holy - branch master
clone: https://src.holypkg.eu/holy/

file tests/up.sh

#!/bin/sh
set -eu

bin=$(realpath "$1")
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
root="$tmp/root"
repo="$tmp/repo"
mkdir -p "$root/usr/share" "$repo"
expect() {
    wanted=$1
    shift
    rc=0
    "$@" > "$tmp/out" 2> "$tmp/err" || rc=$?
    test "$rc" -eq "$wanted" || { cat "$tmp/out" "$tmp/err"; exit 1; }
}
package() {
    version=$1 comparator=${2:-pacman}
    tree="$tmp/tree-$version"
    mkdir -p "$tree/HOLY" "$tree/DATA/usr/share"
    printf 'format holy-package-1\nname update-fixture\nversion %s\nrelease 1\nos linux\narch noarch\nlibc nolibc\n' "$version" > "$tree/HOLY/meta"
    if test "$comparator" != unknown; then
        printf 'x-version-family %s\n' "$comparator" >> "$tree/HOLY/meta"
    fi
    for field in deps provides hooks origin transform; do : > "$tree/HOLY/$field"; done
    if test "$version" = 2; then
        printf 'record payload normalized before pack\n' > "$tree/HOLY/transform"
    fi
    printf 'version %s\n' "$version" > "$tree/DATA/usr/share/update-fixture"
    expect 0 "$bin" manifest generate "$tree" --output "$tmp/files-$version"
    mv "$tmp/files-$version" "$tree/HOLY/files"
    expect 0 "$bin" pack "$tree" --output "$repo/update-$version.holy"
}
seal() {
    expect 0 "$bin" repo index "$repo"
    expect 0 "$bin" repo seal "$repo"
    index=$(sed -n 's/^sha256 //p' "$repo/current")
    printf 'format holy-mirror-1\nurl "https://repo.example/holy/"\nindex-sha256 %s\nverification digest-pinned-unsigned\nsource-id %s\n' "$index" "$source_id" > "$repo/mirror-origin"
}
expect 0 "$bin" db init --root "$root"
printf '[source fixture]\ntype holy-http\nurl "https://repo.example/holy/"\n' > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$root"
cp "$tmp/out" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$root"
expect 0 "$bin" source list --root "$root"
source_id=$(awk '$1 == "source" && $4 == "active" {print $2}' "$tmp/out")
test "${#source_id}" -eq 64
package 1
old=$(sha256sum "$repo/update-1.holy" | cut -d ' ' -f 1)
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 0 "$bin" add fixture:update-fixture --root "$root" --yes
grep -qx 'version 1' "$root/usr/share/update-fixture"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/no-update" --root "$root"
grep -q '^up-to-date ' "$tmp/out"
test ! -e "$tmp/no-update"
package 2
next=$(sha256sum "$repo/update-2.holy" | cut -d ' ' -f 1)
cp -a "$tmp/tree-2" "$tmp/unrelated-tree"
sed -i 's/^name update-fixture$/name unrelated-fixture/' "$tmp/unrelated-tree/HOLY/meta"
mv "$tmp/unrelated-tree/DATA/usr/share/update-fixture" \
    "$tmp/unrelated-tree/DATA/usr/share/unrelated-fixture"
expect 0 "$bin" manifest generate "$tmp/unrelated-tree" --output "$tmp/unrelated-files"
mv "$tmp/unrelated-files" "$tmp/unrelated-tree/HOLY/files"
expect 0 "$bin" pack "$tmp/unrelated-tree" --output "$repo/unrelated.holy"
unrelated=$(sha256sum "$repo/unrelated.holy" | cut -d ' ' -f 1)
seal
expect 6 "$bin" up fixture:update-fixture --prepare --output "$tmp/stale-binding" --root "$root"
test ! -e "$tmp/stale-binding"
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
cp "$repo/unrelated.holy" "$tmp/unrelated.original"
printf corrupt >> "$repo/unrelated.holy"
expect 6 "$bin" source catalog bind fixture "$repo" --root "$root"
cp "$repo/index.$index" "$tmp/saved-index"
printf corrupt >> "$repo/index.$index"
expect 6 "$bin" up fixture:update-fixture --prepare --output "$tmp/bad-index.plan" --root "$root"
test ! -e "$tmp/bad-index.plan"
cp "$tmp/saved-index" "$repo/index.$index"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/up.plan" --root "$root"
test ! -e "$root/var/cache/holypkg/objects/sha256/$unrelated"
plan=$(sha256sum "$tmp/up.plan" | cut -d ' ' -f 1)
grep -qx "prepared $plan $tmp/up.plan old $old new $next index $index" "$tmp/out"
cp "$repo/update-1.holy" "$tmp/old-source-artifact"
printf corrupt >> "$repo/update-1.holy"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/old-source-damaged.plan" --root "$root"
cmp "$tmp/up.plan" "$tmp/old-source-damaged.plan"
cp "$tmp/old-source-artifact" "$repo/update-1.holy"
grep -qx "source-id $source_id" "$tmp/up.plan"
grep -qx "index $index" "$tmp/up.plan"
grep -qx "old $old" "$tmp/up.plan"
grep -qx "new $next" "$tmp/up.plan"
grep -qx 'version 1' "$root/usr/share/update-fixture"
package 9
unlisted=$(sha256sum "$repo/update-9.holy" | cut -d ' ' -f 1)
expect 0 "$bin" cache stage "local:$repo/update-9.holy" --root "$root"
expect 0 "$bin" db plan-update "$old" "$unlisted" --root "$root"
sed '1d' "$tmp/out" > "$tmp/unlisted.body"
unlisted_inner=$(sha256sum "$tmp/unlisted.body" | cut -d ' ' -f 1)
python3 - "$tmp/up.plan" "$tmp/unlisted.body" "$next" "$unlisted" "$unlisted_inner" "$tmp/unlisted.plan" <<'PY'
from pathlib import Path
import sys
plan, body, old, new, inner, output = sys.argv[1:]
header = Path(plan).read_bytes().split(b'[update]\n', 1)[0]
header = header.replace(f'new {old}\n'.encode(), f'new {new}\n'.encode())
header = header.replace(next(line for line in header.splitlines(keepends=True)
                             if line.startswith(b'state-plan ')),
                        f'state-plan {inner}\n'.encode())
Path(output).write_bytes(header + Path(body).read_bytes())
PY
unlisted_plan=$(sha256sum "$tmp/unlisted.plan" | cut -d ' ' -f 1)
expect 3 "$bin" apply "$tmp/unlisted.plan" --sha256 "$unlisted_plan" --root "$root"
grep -q 'prepared artifact absent from source slot' "$tmp/err"
grep -qx 'version 1' "$root/usr/share/update-fixture"
rm "$repo/update-9.holy"
expect 3 "$bin" apply "$tmp/up.plan" --sha256 "$(printf '%064d' 0)" --root "$root"
cp "$repo/current" "$tmp/current"
cp "$repo/mirror-origin" "$tmp/origin"
printf 'sha256 %064d\n' 0 > "$repo/current"
expect 6 "$bin" apply "$tmp/up.plan" --sha256 "$plan" --root "$root"
cp "$tmp/current" "$repo/current"
cp "$tmp/origin" "$repo/mirror-origin"
printf '[source renamed]\ntype holy-http\nurl "https://repo.example/holy/"\n' > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$root"
cp "$tmp/out" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$root"
expect 6 "$bin" apply "$tmp/up.plan" --sha256 "$plan" --root "$root"
printf '[source fixture]\ntype holy-http\nurl "https://repo.example/holy/"\n' > "$tmp/source.conf"
expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$root"
cp "$tmp/out" "$tmp/source.plan"
source_plan=$(sha256sum "$tmp/source.plan" | cut -d ' ' -f 1)
expect 0 "$bin" source apply "$tmp/source.plan" --sha256 "$source_plan" --root "$root"
expect 3 "$bin" apply "$tmp/up.plan" --sha256 "$plan" --root "$root"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/fresh.plan" --root "$root"
fresh=$(sha256sum "$tmp/fresh.plan" | cut -d ' ' -f 1)
expect 0 "$bin" apply "$tmp/fresh.plan" --sha256 "$fresh" --root "$root"
grep -qx 'version 2' "$root/usr/share/update-fixture"
grep -qx "source-id $source_id" "$root/var/lib/holypkg/installed/$next/state"
expect 0 "$bin" db check --all --root "$root"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/no-newer" --root "$root"
test ! -e "$tmp/no-newer"
expect 0 "$bin" up fixture:update-fixture --prepare --choose "$old" --output "$tmp/downgrade.plan" --root "$root"
downgrade=$(sha256sum "$tmp/downgrade.plan" | cut -d ' ' -f 1)
expect 0 "$bin" apply "$tmp/downgrade.plan" --sha256 "$downgrade" --root "$root"
grep -qx 'version 1' "$root/usr/share/update-fixture"
expect 0 "$bin" db check --all --root "$root"
cp "$tmp/unrelated.original" "$repo/unrelated.holy"
package 3 unknown
third=$(sha256sum "$repo/update-3.holy" | cut -d ' ' -f 1)
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 3 "$bin" up fixture:update-fixture --prepare --output "$tmp/unknown.plan" --root "$root"
grep -q 'decision-required update candidate' "$tmp/err"
test ! -e "$tmp/unknown.plan"
expect 0 "$bin" up fixture:update-fixture --prepare --choose "$third" \
    --output "$tmp/chosen.plan" --root "$root"
chosen=$(sha256sum "$tmp/chosen.plan" | cut -d ' ' -f 1)
sed "s/^new $third/new $(printf '%064d' 0)/" "$tmp/chosen.plan" > "$tmp/forged.plan"
forged=$(sha256sum "$tmp/forged.plan" | cut -d ' ' -f 1)
expect 2 "$bin" apply "$tmp/forged.plan" --sha256 "$forged" --root "$root"
grep -qx 'version 1' "$root/usr/share/update-fixture"
expect 0 "$bin" apply "$tmp/chosen.plan" --sha256 "$chosen" --root "$root"
grep -qx 'version 3' "$root/usr/share/update-fixture"
expect 0 "$bin" db check --all --root "$root"
rm "$repo/update-1.holy" "$repo/update-2.holy" "$repo/update-3.holy"
package 4 holy
fourth=$(sha256sum "$repo/update-4.holy" | cut -d ' ' -f 1)
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 0 "$bin" up fixture:update-fixture --prepare --choose "$fourth" \
    --output "$tmp/native-switch.plan" --root "$root"
switch=$(sha256sum "$tmp/native-switch.plan" | cut -d ' ' -f 1)
expect 0 "$bin" apply "$tmp/native-switch.plan" --sha256 "$switch" --root "$root"
package 5 holy
fifth=$(sha256sum "$repo/update-5.holy" | cut -d ' ' -f 1)
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/native.plan" --root "$root"
grep -qx "new $fifth" "$tmp/native.plan"
native=$(sha256sum "$tmp/native.plan" | cut -d ' ' -f 1)
expect 0 "$bin" apply "$tmp/native.plan" --sha256 "$native" --root "$root"
grep -qx 'version 5' "$root/usr/share/update-fixture"
expect 0 "$bin" db check --all --root "$root"
cp -a "$tmp/tree-5" "$tmp/tree-5-r2"
sed -i 's/^release 1$/release 2/' "$tmp/tree-5-r2/HOLY/meta"
expect 0 "$bin" pack "$tmp/tree-5-r2" --output "$repo/update-5-r2.holy"
revision=$(sha256sum "$repo/update-5-r2.holy" | cut -d ' ' -f 1)
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/native-revision.plan" --root "$root"
grep -qx "new $revision" "$tmp/native-revision.plan"
revised=$(sha256sum "$tmp/native-revision.plan" | cut -d ' ' -f 1)
expect 0 "$bin" apply "$tmp/native-revision.plan" --sha256 "$revised" --root "$root"
grep -qx 'version 5' "$root/usr/share/update-fixture"
expect 0 "$bin" db check --all --root "$root"
package 6 holy
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 2 "$bin" up fixture:update-fixture --prepare --output "$tmp/invalid.plan" --yes --root "$root"
test ! -e "$tmp/invalid.plan"
expect 0 "$bin" up fixture:update-fixture --prepare --root "$root"
temporary=$(awk '$1 == "prepared" {print $3}' "$tmp/out")
test -f "$temporary"
test "$(stat -c '%a' "$temporary")" = 600
rm "$temporary"
rmdir "$(dirname "$temporary")"
expect 0 "$bin" up fixture:update-fixture --yes --root "$root"
applied_temp=$(awk '$1 == "prepared" {print $3}' "$tmp/out")
test ! -e "$applied_temp"
test ! -d "$(dirname "$applied_temp")"
grep -qx 'version 6' "$root/usr/share/update-fixture"
expect 0 "$bin" db check --all --root "$root"
package 7 holy
seal
expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
expect 3 "$bin" up fixture:update-fixture --noninteractive --output "$tmp/review.plan" --root "$root"
grep -q 'decision-required plan=' "$tmp/err"
expect 3 "$bin" up fixture:update-fixture --output "$tmp/implicit.plan" --root "$root"
cmp "$tmp/review.plan" "$tmp/implicit.plan"
grep -qx 'version 6' "$root/usr/share/update-fixture"
review=$(sha256sum "$tmp/review.plan" | cut -d ' ' -f 1)
expect 0 "$bin" apply "$tmp/review.plan" --sha256 "$review" --root "$root"
grep -qx 'version 7' "$root/usr/share/update-fixture"
expect 0 "$bin" db check --all --root "$root"
for family in apk xbps; do
    root="$tmp/$family-root"
    repo="$tmp/$family-repo"
    mkdir -p "$root/usr/share" "$repo"
    expect 0 "$bin" db init --root "$root"
    expect 0 "$bin" source plan --config "$tmp/source.conf" --root "$root"
    cp "$tmp/out" "$tmp/$family-source.plan"
    source_plan=$(sha256sum "$tmp/$family-source.plan" | cut -d ' ' -f 1)
    expect 0 "$bin" source apply "$tmp/$family-source.plan" --sha256 "$source_plan" --root "$root"
    expect 0 "$bin" source list --root "$root"
    source_id=$(awk '$1 == "source" && $4 == "active" {print $2}' "$tmp/out")
    if test "$family" = apk; then
        package 1.0-r0 apk
    else
        package 1.0 xbps
    fi
    seal
    expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
    expect 0 "$bin" add fixture:update-fixture --root "$root" --yes
    if test "$family" = apk; then
        package 1.0-r1 apk
        revision=$(sha256sum "$repo/update-1.0-r1.holy" | cut -d ' ' -f 1)
    else
        cp -a "$tmp/tree-1.0" "$tmp/tree-1.0-r2"
        sed -i 's/^release 1$/release 2/' "$tmp/tree-1.0-r2/HOLY/meta"
        expect 0 "$bin" pack "$tmp/tree-1.0-r2" --output "$repo/update-1.0-r2.holy"
        revision=$(sha256sum "$repo/update-1.0-r2.holy" | cut -d ' ' -f 1)
    fi
    seal
    expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
    expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/$family-revision.plan" --root "$root"
    grep -qx "new $revision" "$tmp/$family-revision.plan"
    prepared=$(sha256sum "$tmp/$family-revision.plan" | cut -d ' ' -f 1)
    expect 0 "$bin" apply "$tmp/$family-revision.plan" --sha256 "$prepared" --root "$root"
    package 1.1 "$family"
    newest=$(sha256sum "$repo/update-1.1.holy" | cut -d ' ' -f 1)
    seal
    expect 0 "$bin" source catalog bind fixture "$repo" --root "$root"
    expect 0 "$bin" up fixture:update-fixture --prepare --output "$tmp/$family-version.plan" --root "$root"
    grep -qx "new $newest" "$tmp/$family-version.plan"
    prepared=$(sha256sum "$tmp/$family-version.plan" | cut -d ' ' -f 1)
    expect 0 "$bin" apply "$tmp/$family-version.plan" --sha256 "$prepared" --root "$root"
    grep -qx 'version 1.1' "$root/usr/share/update-fixture"
    expect 0 "$bin" db check --all --root "$root"
done
printf 'source update preparation and apply fixtures passed\n'