fleetd #517: pin the drain-gate abort branch and jar_id absent case #520

Merged
ltms merged 1 commits from worker/517-abort-branch-and-jar-id-41b641-2 into main 2026-09-12 06:29:09 +02:00
Member

fleetd #517 — a source-text test pins what a message SAYS and never whether it is REACHED

Two mutation-testing survivors in scripts/redeploy-fleetd.sh, both fixed. No Java in this unit — all shell.

Defect 1: the drain-gate abort branch was not pinned

Extracted the decision into a pure function:

drain_gate_refusal() {
  local do_build="$1" staged_path="$2"
  if [ "$do_build" = 1 ] && [ -f "$staged_path" ]; then
    printf 'aborted — ... sitting at %s ...' ...
  else
    printf 'aborted — nothing changed'
  fi
}

The main flow now calls die "$(drain_gate_refusal "$DO_BUILD" "$JAR_STAGED")". Added 4 new tests covering all four combinations:

  • build ran, staged present → names the staged jar, tells the operator to rerun WITHOUT --no-build
  • build ran, staged absent → "nothing changed"
  • --no-build, staged present → ALSO "nothing changed", deliberately — --no-build never builds or stages anything itself, so a staged jar found here is a leftover from an earlier, unrelated run; this run truly changed nothing. Documented in a comment above the function.
  • --no-build, staged absent → "nothing changed"

The existing source-text grep test (test_drain_gate_abort_message_says_no_no_build) is kept, not deleted — it catches a re-wording, the new tests catch a dead branch. Neither replaces the other.

Defect 2: jar_id's "absent" branch was unpinned

Added test_jar_id_reports_absent_for_missing_file: points $JAR at a path that does not exist and asserts the output is exactly absent, for both the no-argument default and an explicit missing path (the mutation sits on one shared || echo, so both halves are covered).

Acceptance

  1. bash scripts/test-redeploy-fleetd.sh exits 0. Test functions defined: 40 (was 35). Test functions invoked: 40 (was 35) — counts match (grep -c '^test_[a-zA-Z_]*() {' vs grep -cE '^test_[a-zA-Z_]+$').
  2. bash -n passes on both scripts/redeploy-fleetd.sh and scripts/test-redeploy-fleetd.sh.
  3. Both mutations reproduced, killed, and reverted:
    • Mutation 1 (if [ "$do_build" = 1 ] && [ -f "$staged_path" ]; then → if false; then at the extracted function): suite went red — FAIL: build-ran+staged-present refusal does not name the staged jar path.
    • Mutation 2 (jar_id's echo "absent" → echo "present"): suite went red — FAIL: jar_id with no arguments must report absent when $JAR does not exist: expected absent, got present.
    • Each mutation confirmed applied via two greps with different, single-quoted search strings (mutant text found, original text gone — never a 0-and-0 result) plus a grep -n re-read of the exact line, then restored and confirmed byte-identical to the pre-mutation copy, then a green control run.
  4. scripts/redeploy-fleetd.sh pristine hash before any edits: e502f7498f8cca0b8fb9cf83d10751445a0dfbe9c119fc44a980f4d660124dfa (matches the ticket's stated hash, confirmed with shasum -a 256 at the start of this work). Every restore during mutation testing matched the fixed script's own hash (2cb83dc3...) byte-for-byte.

Also (not fixed — separate ticket, per the brief)

Found one more branch with the same shape: the swap step's guard if [ "$DO_BUILD" = 1 ]; then at the line right before swap_staged_jar "$JAR_STAGED" "$JAR" is only checked by test_swap_ordered_after_wait_and_before_start, which greps for line positions of call-site text in the source — it does not check that this guard is ever true. Mutating it to if false; then would leave every line position unchanged (a one-line in-place edit), so that test would still pass while the built jar would silently never get swapped into the live path after a "successful" redeploy.

Prohibitions honored

Never ran scripts/redeploy-fleetd.sh against the live daemon (not even --check) — all testing was done by sourcing the script into throwaway shells / calling extracted functions directly, per the ticket's hard prohibition. Never printed the value of any env var — only checked presence (GITEA_TOKEN/GITEA_HOST set: yes/yes). Staged only the two changed files explicitly (no git add -A).

## fleetd #517 — a source-text test pins what a message SAYS and never whether it is REACHED Two mutation-testing survivors in `scripts/redeploy-fleetd.sh`, both fixed. No Java in this unit — all shell. ### Defect 1: the drain-gate abort branch was not pinned Extracted the decision into a pure function: ```bash drain_gate_refusal() { local do_build="$1" staged_path="$2" if [ "$do_build" = 1 ] && [ -f "$staged_path" ]; then printf 'aborted — ... sitting at %s ...' ... else printf 'aborted — nothing changed' fi } ``` The main flow now calls `die "$(drain_gate_refusal "$DO_BUILD" "$JAR_STAGED")"`. Added 4 new tests covering all four combinations: - build ran, staged present → names the staged jar, tells the operator to rerun WITHOUT `--no-build` - build ran, staged absent → "nothing changed" - `--no-build`, staged present → ALSO "nothing changed", deliberately — `--no-build` never builds or stages anything itself, so a staged jar found here is a leftover from an earlier, unrelated run; this run truly changed nothing. Documented in a comment above the function. - `--no-build`, staged absent → "nothing changed" The existing source-text grep test (`test_drain_gate_abort_message_says_no_no_build`) is **kept**, not deleted — it catches a re-wording, the new tests catch a dead branch. Neither replaces the other. ### Defect 2: `jar_id`'s "absent" branch was unpinned Added `test_jar_id_reports_absent_for_missing_file`: points `$JAR` at a path that does not exist and asserts the output is exactly `absent`, for both the no-argument default and an explicit missing path (the mutation sits on one shared `|| echo`, so both halves are covered). ### Acceptance 1. `bash scripts/test-redeploy-fleetd.sh` exits 0. Test functions defined: **40** (was 35). Test functions invoked: **40** (was 35) — counts match (`grep -c '^test_[a-zA-Z_]*() {'` vs `grep -cE '^test_[a-zA-Z_]+$'`). 2. `bash -n` passes on both `scripts/redeploy-fleetd.sh` and `scripts/test-redeploy-fleetd.sh`. 3. Both mutations reproduced, killed, and reverted: - Mutation 1 (`if [ "$do_build" = 1 ] && [ -f "$staged_path" ]; then` → `if false; then` at the extracted function): suite went red — `FAIL: build-ran+staged-present refusal does not name the staged jar path`. - Mutation 2 (`jar_id`'s `echo "absent"` → `echo "present"`): suite went red — `FAIL: jar_id with no arguments must report absent when $JAR does not exist: expected absent, got present`. - Each mutation confirmed applied via two greps with different, single-quoted search strings (mutant text found, original text gone — never a 0-and-0 result) plus a `grep -n` re-read of the exact line, then restored and confirmed byte-identical to the pre-mutation copy, then a green control run. 4. `scripts/redeploy-fleetd.sh` pristine hash before any edits: `e502f7498f8cca0b8fb9cf83d10751445a0dfbe9c119fc44a980f4d660124dfa` (matches the ticket's stated hash, confirmed with `shasum -a 256` at the start of this work). Every restore during mutation testing matched the fixed script's own hash (`2cb83dc3...`) byte-for-byte. ### Also (not fixed — separate ticket, per the brief) Found one more branch with the same shape: the swap step's guard `if [ "$DO_BUILD" = 1 ]; then` at the line right before `swap_staged_jar "$JAR_STAGED" "$JAR"` is only checked by `test_swap_ordered_after_wait_and_before_start`, which greps for line *positions* of call-site text in the source — it does not check that this guard is ever true. Mutating it to `if false; then` would leave every line position unchanged (a one-line in-place edit), so that test would still pass while the built jar would silently never get swapped into the live path after a "successful" redeploy. ### Prohibitions honored Never ran `scripts/redeploy-fleetd.sh` against the live daemon (not even `--check`) — all testing was done by sourcing the script into throwaway shells / calling extracted functions directly, per the ticket's hard prohibition. Never printed the value of any env var — only checked presence (`GITEA_TOKEN`/`GITEA_HOST` set: yes/yes). Staged only the two changed files explicitly (no `git add -A`).
agent added 1 commit 2026-09-12 06:24:18 +02:00
fleetd #517: pin the drain-gate abort branch and jar_id's absent case
CI / contract (pull_request) Successful in 1m15s
CI / build (pull_request) Successful in 1m31s
3833d8e52b
Two mutation-testing survivors in scripts/redeploy-fleetd.sh: a source-text
test pins what a message SAYS but never whether the branch that prints it is
REACHED.

- Extract the drain-gate abort decision into drain_gate_refusal(do_build,
  staged_path), a pure function the suite can call directly for all four
  build/staged combinations. The existing source-text grep test is kept
  alongside it (it catches a re-wording; the new tests catch a dead branch).
- Extend jar_id's test to cover the missing-file path (both the no-argument
  default and an explicit path), which the #511 test never exercised.
ltms merged commit c71ac231e5 into main 2026-09-12 06:29:09 +02:00
Sign in to join this conversation.