From 3104aac6f321b29c74bf72a2a7d6f97a30450483 Mon Sep 17 00:00:00 2001 From: codex-bot-andresmgsl Date: Mon, 31 Aug 2026 11:12:22 +0000 Subject: [PATCH] test: specify release preflight contract --- test/preflight.test.sh | 119 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100755 test/preflight.test.sh diff --git a/test/preflight.test.sh b/test/preflight.test.sh new file mode 100755 index 0000000..6cf2bb4 --- /dev/null +++ b/test/preflight.test.sh @@ -0,0 +1,119 @@ +#!/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 — run the pure decision +# with exactly the four gathered facts in its environment. +preflight() { + VER="$1" MERGE_SHA="$2" TAG_SHAS="$3" RELEASED="$4" bash "$PREFLIGHT" +} + +preflight_stdout() { + preflight "$@" 2>/dev/null +} + +preflight_stderr() { + preflight "$@" 2>&1 >/dev/null +} + +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