Test: Propagate update fixture failures

This commit is contained in:
Gabriel Brown
2026-08-26 22:53:39 -04:00
parent 803362ebad
commit 68b6664111
+61 -30
View File
@@ -121,7 +121,10 @@ run_install() {
# ── 1. The interview never runs on an upgrade ────────────────────────────────
build_fixture "$tmp/a"
ran="$(run_install "$tmp/a" --upgrade)"
install_status=0
ran="$(run_install "$tmp/a" --upgrade)" || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "initial install --upgrade failed with status $install_status"
if grep -qx 'interview' <<<"$ran"; then
note 'install --upgrade ran the interview, which is the whole regression this prevents'
@@ -129,7 +132,10 @@ fi
# And the control: a real install must still ask.
build_fixture "$tmp/b"
ran_install="$(run_install "$tmp/b")"
install_status=0
ran_install="$(run_install "$tmp/b")" || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "plain fixture install failed with status $install_status"
if ! grep -qx 'interview' <<<"$ran_install"; then
note 'a plain ./install no longer asks the interview, so a new machine is never configured'
fi
@@ -176,18 +182,27 @@ done
# ── 3. The packages hash gates the stage, and a failure does not record it ───
# Second run, nothing changed: the stage must be skipped.
ran_again="$(run_install "$tmp/a" --upgrade)"
install_status=0
ran_again="$(run_install "$tmp/a" --upgrade)" || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "repeat install --upgrade failed with status $install_status"
grep -qx 'install-packages' <<<"$ran_again" \
&& note 'install-packages ran again with the package lists unchanged'
# --packages overrides the hash.
ran_forced="$(run_install "$tmp/a" --upgrade --packages)"
install_status=0
ran_forced="$(run_install "$tmp/a" --upgrade --packages)" || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "install --upgrade --packages failed with status $install_status"
grep -qx 'install-packages' <<<"$ran_forced" \
|| note '--packages did not force install-packages to run'
# A changed list brings the stage back.
printf 'another-package\n' >>"$tmp/a/setup/packages/base"
ran_changed="$(run_install "$tmp/a" --upgrade)"
install_status=0
ran_changed="$(run_install "$tmp/a" --upgrade)" || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "install --upgrade failed after a package-list change with status $install_status"
grep -qx 'install-packages' <<<"$ran_changed" \
|| note 'a changed package list did not bring install-packages back'
@@ -203,8 +218,14 @@ fi
# A full install always runs the stage, whatever any recorded hash says.
build_fixture "$tmp/d"
run_install "$tmp/d" --upgrade >/dev/null
ran_full="$(run_install "$tmp/d")"
install_status=0
run_install "$tmp/d" --upgrade >/dev/null || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "hash-seeding install --upgrade failed with status $install_status"
install_status=0
ran_full="$(run_install "$tmp/d")" || install_status=$?
[[ "$install_status" -eq 0 ]] \
|| note "full fixture reinstall failed with status $install_status"
grep -qx 'install-packages' <<<"$ran_full" \
|| note 'a full ./install skipped install-packages because of a recorded hash'
@@ -216,42 +237,52 @@ grep -qx 'install-packages' <<<"$ran_full" \
# Each fixture has the same three repositories as a real update: a bare remote,
# a clone that publishes upstream changes, and the machine clone being updated.
build_cli_fixture() (
set -e
local root="$1"
rm -rf "$root"
mkdir -p "$root"
git init -q --bare "$root/origin.git"
git clone -q "$root/origin.git" "$root/upstream" 2>/dev/null
git -C "$root/upstream" config user.email contract@panama
git -C "$root/upstream" config user.name contract
rm -rf "$root" || return 1
mkdir -p "$root" || return 1
git init -q --bare "$root/origin.git" || return 1
git clone -q "$root/origin.git" "$root/upstream" 2>/dev/null || return 1
git -C "$root/upstream" config user.email contract@panama || return 1
git -C "$root/upstream" config user.name contract || return 1
mkdir -p "$root/upstream/bin"
cp "$panama" "$root/upstream/bin/panama"
cat >"$root/upstream/install" <<'EOF'
mkdir -p "$root/upstream/bin" || return 1
cp "$panama" "$root/upstream/bin/panama" || return 1
cat >"$root/upstream/install" <<'EOF' || return 1
#!/usr/bin/env bash
printf '%s\n' "$*" >>"${PANAMA_UPDATE_FIXTURE_LOG:?}"
exit "${PANAMA_UPDATE_INSTALL_RC:-0}"
EOF
chmod +x "$root/upstream/bin/panama" "$root/upstream/install"
printf 'one\n' >"$root/upstream/f"
git -C "$root/upstream" add -A
git -C "$root/upstream" commit -qm initial
git -C "$root/upstream" push -qu origin HEAD
chmod +x "$root/upstream/bin/panama" "$root/upstream/install" || return 1
printf 'one\n' >"$root/upstream/f" || return 1
git -C "$root/upstream" add -A || return 1
git -C "$root/upstream" commit -qm initial || return 1
git -C "$root/upstream" push -qu origin HEAD || return 1
git clone -q "$root/origin.git" "$root/machine"
git -C "$root/machine" config user.email contract@panama
git -C "$root/machine" config user.name contract
git clone -q "$root/origin.git" "$root/machine" || return 1
git -C "$root/machine" config user.email contract@panama || return 1
git -C "$root/machine" config user.name contract || return 1
)
advance_upstream() (
set -e
local root="$1" file="$2" contents="$3"
printf '%s\n' "$contents" >"$root/upstream/$file"
git -C "$root/upstream" add "$file"
git -C "$root/upstream" commit -qm "update $file"
git -C "$root/upstream" push -q
printf '%s\n' "$contents" >"$root/upstream/$file" || return 1
git -C "$root/upstream" add "$file" || return 1
git -C "$root/upstream" commit -qm "update $file" || return 1
git -C "$root/upstream" push -q || return 1
)
# This write fails before the later Git commands. The helper must return that
# failure rather than let a final successful push hide it.
helper_probe="$tmp/helper-failure"
if build_cli_fixture "$helper_probe"; then
if advance_upstream "$helper_probe" missing/child probe \
2>"$helper_probe/intermediate-failure.err"; then
note 'advance_upstream hid an intermediate fixture setup failure'
fi
else
note 'the fixture helper failure probe could not be built'
fi
clean="$tmp/clean-update"
if build_cli_fixture "$clean" && advance_upstream "$clean" release new; then
machine_before="$(git -C "$clean/machine" rev-parse HEAD)"