ceremony/test/preflight.test.sh
2026-08-31 11:24:53 +00:00

121 lines
4.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# Contract tests for lib/preflight.sh (issue #273) — every row of the
# merge-door resume table, offline. set -u, not -e: refusals are behavior for
# the harness to inspect.
set -u
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=test/harness.sh
. "$ROOT/test/harness.sh"
PREFLIGHT="$ROOT/lib/preflight.sh"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
VER=1.2.3
MERGE_SHA=1111111111111111111111111111111111111111
FOREIGN_SHA=2222222222222222222222222222222222222222
# preflight <VER> <MERGE_SHA> <TAG_SHAS> <RELEASED> — run the pure decision
# with exactly the four gathered facts in its environment.
preflight() {
# shellcheck disable=SC2016 # PREFLIGHT expands inside the isolated child
env VER="$1" MERGE_SHA="$2" TAG_SHAS="$3" RELEASED="$4" \
PREFLIGHT="$PREFLIGHT" bash -c '. "$PREFLIGHT"; release_preflight'
}
preflight_stdout() {
preflight "$@" 2>/dev/null
}
preflight_stderr() {
{ preflight "$@" >/dev/null; } 2>&1
}
refuses_without_output() {
local out rc
out="$(preflight "$@" 2>/dev/null)"
rc=$?
[ "$rc" -eq 1 ] && [ -z "$out" ]
}
# --- the four table rows ----------------------------------------------------
check "row 1: a published release refuses even with no tag" 1 \
"release '$VER' already exists — this release already happened" \
preflight_stderr "$VER" "$MERGE_SHA" "" yes
check "row 1: a published release refuses with the matching tag" 1 \
"release '$VER' already exists — this release already happened" \
preflight_stderr "$VER" "$MERGE_SHA" "$MERGE_SHA" yes
check "row 1: a published release refuses with a foreign tag" 1 \
"release '$VER' already exists — this release already happened" \
preflight_stderr "$VER" "$MERGE_SHA" "$FOREIGN_SHA" yes
check "row 1: refusal emits no workflow output" 0 "" \
refuses_without_output "$VER" "$MERGE_SHA" "$MERGE_SHA" yes
check "row 2: an ordinary first run proceeds" 0 "resume=no" \
preflight_stdout "$VER" "$MERGE_SHA" "" no
check "row 3: the matching tag resumes" 0 "resume=yes" \
preflight_stdout "$VER" "$MERGE_SHA" "$MERGE_SHA" no
check "row 3: resume notice names the previous failed publish" 0 \
"a previous run of this door tagged and then failed to publish" \
preflight_stdout "$VER" "$MERGE_SHA" "$MERGE_SHA" no
check "row 3: an annotated tag resumes when the peeled ref matches" 0 \
"resume=yes" preflight_stdout "$VER" "$MERGE_SHA" \
"$FOREIGN_SHA"$'\n'"$MERGE_SHA" no
check "row 3: an annotated tag resumes when the direct ref matches" 0 \
"resume=yes" preflight_stdout "$VER" "$MERGE_SHA" \
"$MERGE_SHA"$'\n'"$FOREIGN_SHA" no
check "row 4: a foreign tag refuses" 1 "tag '$VER' already exists" \
preflight_stderr "$VER" "$MERGE_SHA" "$FOREIGN_SHA" no
check "row 4: the refusal names the foreign tag SHA" 1 "$FOREIGN_SHA" \
preflight_stderr "$VER" "$MERGE_SHA" "$FOREIGN_SHA" no
check "row 4: the refusal names the merge SHA" 1 "$MERGE_SHA" \
preflight_stderr "$VER" "$MERGE_SHA" "$FOREIGN_SHA" no
check "row 4: refusal emits no workflow output" 0 "" \
refuses_without_output "$VER" "$MERGE_SHA" "$FOREIGN_SHA" no
# A ref object that merely contains MERGE_SHA is not the merge commit. Each
# ls-remote object name is compared as a whole line.
PREFIX_SHA="${MERGE_SHA%?}"
check "a prefix of MERGE_SHA does not resume" 1 "already exists at $PREFIX_SHA" \
preflight_stderr "$VER" "$MERGE_SHA" "$PREFIX_SHA" no
check "a line containing MERGE_SHA does not resume" 1 \
"already exists at x${MERGE_SHA}y" \
preflight_stderr "$VER" "$MERGE_SHA" "x${MERGE_SHA}y" no
# --- fact validation --------------------------------------------------------
check "empty VER refuses" 1 "VER is empty" \
preflight_stderr "" "$MERGE_SHA" "" no
check "empty MERGE_SHA refuses" 1 "MERGE_SHA is empty" \
preflight_stderr "$VER" "" "" no
check "empty RELEASED refuses" 1 "RELEASED is empty" \
preflight_stderr "$VER" "$MERGE_SHA" "" ""
check "malformed RELEASED refuses" 1 "RELEASED='maybe' — expected yes or no" \
preflight_stderr "$VER" "$MERGE_SHA" "" maybe
# --- stream discipline and purity ------------------------------------------
notice_stays_on_stdout() {
local stdout stderr
stdout="$(preflight "$VER" "$MERGE_SHA" "$MERGE_SHA" no 2>"$TMP/preflight.err")"
stderr="$(cat "$TMP/preflight.err")"
[ -n "$stdout" ] && [ -z "$stderr" ]
}
refusal_stays_on_stderr() {
local stdout stderr rc
stdout="$(preflight "$VER" "$MERGE_SHA" "$FOREIGN_SHA" no 2>"$TMP/preflight.err")"
rc=$?
stderr="$(cat "$TMP/preflight.err")"
[ "$rc" -eq 1 ] && [ -z "$stdout" ] && [ -n "$stderr" ]
}
no_tool_calls() {
! grep -v '^[[:space:]]*#' "$PREFLIGHT" | grep -Ewq 'git|gh|curl|wget'
}
check "resume notice and output stay on stdout" 0 "" notice_stays_on_stdout
check "refusal stays on stderr" 0 "" refusal_stays_on_stderr
check "preflight calls no git/gh/network tools" 0 "" no_tool_calls
summary