#!/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() { # 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