The extraction in the previous commit did what #521 asked for — a
should_swap() predicate with a test for each value — and I measured that
it does not close the defect. With the main flow reading
`if should_swap "$DO_BUILD"; then`, changing that line to `if false; then`
left the whole suite at exit 0 with zero FAIL lines. The swap still never
ran, and a redeploy would still report success while starting on no jar.
That is my ticket's fault, not the implementer's: "extract the decision so
the suite can call it" pins the decision and never the wiring. Extraction
moved the untested decision up one level instead of removing it.
Fix: the decision and the action now live together in swap_if_built(),
which the main flow calls unconditionally — there is no guard left in the
main flow to get wrong. should_swap() stays, because it is the decision
and is worth naming and testing on its own. Two new tests call
swap_if_built() with a recording stub in place of the real mv, so they
fail if the guard is removed, inverted, or stops being consulted.
Also fixed, found while verifying this:
* test_swap_ordered_after_wait_and_before_start had to follow the call
site to `swap_if_built "$DO_BUILD"`. Left on the old needle it reported
"swap_staged_jar (line 215) is not after wait_for_daemon_exit (line
730)" — true of a function definition, and nothing about step order.
* That test's three `[ -n ... ] || fail "could not find ... call site"`
guards were dead code. Under `set -euo pipefail` an absent needle fails
the assignment and `set -e` kills the suite before the guard runs.
Measured: deleting the swap call gave exit 1 with ZERO bytes of output,
no FAIL line, nothing naming what was missing. Each grep now ends in
`|| true` so the assignment succeeds empty and the guard can speak.
Verified by me on this revision:
* suite exit 0, 0 `^FAIL:` lines, 44 tests defined and 44 invoked
* bash -n rc=0 on both scripts under /bin/bash 3.2.57 and bash 5.3.9
* four mutations, each killed with its own named FAIL line, each restored
byte-identical, green control after the battery:
- guard removed inside swap_if_built -> "must not swap, but it did"
- guard inverted -> "must perform the swap, and did not"
- should_swap's comparison changed -> "must return true"
- main-flow call deleted -> "could not find the swap call
site in redeploy-fleetd.sh" (this one printed 0 bytes before the
dead-guard fix, which is the before/after proof for it)
Not fixed here, filed separately: drain_gate_refusal has the same shape.
Replacing `die "$(drain_gate_refusal ...)"` with `die "aborted — nothing
changed"` leaves the suite at exit 0 with output byte-identical to a clean
run, which reinstates the exact wrong message #517 was filed to fix.
Mutating the swap step's guard (if [ "$DO_BUILD" = 1 ] -> if false) left the
whole test suite green: test_swap_ordered_after_wait_and_before_start only
checks source positions, which an in-place if-condition edit never moves.
Extracts the decision into should_swap(do_build), following the same shape as
#510's wait_for_daemon_exit and #517's drain_gate_refusal, with a direct test
for each value.