fleetd #550: portable hash256 helper for jar_id, Linux CI job for the shell suite #554

Merged
ltms merged 2 commits from worker/550-shasum-linux-196132-1 into main 2026-09-12 10:20:29 +02:00
Member

Closes fleetd #550.

Item 1 (scripts/redeploy-fleetd.sh): jar_id called shasum directly. On GNU coreutils Linux (no shasum), the command-not-found made cut succeed on empty input; under pipefail the pipeline still failed, and the caller's own || echo "absent" then reported an existing jar as gone, with exit 0. Added a hash256 helper (prefer sha256sum, fall back to shasum -a 256, same idiom as probe-member-credentials.sh:273-279) and pointed jar_id at it. jar_id now has three distinct answers: absent (file really isn't there), a 12-char hash (hashed successfully), or unhashable (file is there but neither hasher is on PATH). absent is never returned for a file that exists.

Item 2 (scripts/test-redeploy-fleetd.sh:298-299): same direct shasum call in the suite's own reference-hash computation, which is why the suite died at exit 127 on Linux with zero FAIL: lines printed — indistinguishable from a clean pass by that count alone. Now uses hash256 too.

Item 3 (.gitea/workflows/ci.yml): added a shell-tests job on ubuntu-latest that runs bash scripts/test-redeploy-fleetd.sh. Gated on the step's own exit code, not a FAIL: count — item 2 is the proof that a count alone cannot be the gate.

New tests in scripts/test-redeploy-fleetd.sh:

  • test_jar_id_reports_unhashable_when_no_hasher_on_path — drives the real jar_id/hash256 through a stubbed PATH containing neither hasher (same stub-PATH technique as test_detect_supervisor_systemd_probe_setup_failure_is_unclear, but replacing PATH rather than prepending to it, since the point is to hide BOTH hashers).
  • test_no_unguarded_macos_only_hasher_calls — a shape check across every script under scripts/, not named lines (per #545, this idiom already spread from 2 sites to 6 across 91 commits once).

Verification (in the worker's own worktree, on macOS):

  • bash -n clean on both changed shell scripts, under both /bin/bash (3.2.57) and env bash (5.3.9).
  • Full suite green under both bash versions: exit 0, 0 anchored ^FAIL: lines, each time.
  • Defined-vs-invoked test functions: 69/69, empty comm -3 (was 67/67 before this PR's two additions).
  • Two mutations applied and reverted, each with a pristine-anchor count (1->0) proving the mutation actually applied, each producing the new test's own FAIL message, each restored to a byte-identical file (confirmed via full shasum -a 256), each followed by a green control run.
  • CI-job command demonstrated directly (Gitea Actions cannot be run from this worktree): bash scripts/test-redeploy-fleetd.sh on the real suite -> exit 0; on a deliberately broken copy (one assertion's expected value swapped) -> exit 1. Both exit codes shown, not just a comment.

Never ran: scripts/redeploy-fleetd.sh itself, in any form — it restarts the live daemon.

Caveat for review: the hash256 "neither hasher on PATH" branch was only exercised via a stubbed PATH on macOS (where both hashers exist for real); it has not been run on an actual Linux host with neither sha256sum nor shasum installed. The stub technique itself is the same one three existing tests in this suite already rely on.

Closes fleetd #550. **Item 1** (`scripts/redeploy-fleetd.sh`): `jar_id` called `shasum` directly. On GNU coreutils Linux (no `shasum`), the command-not-found made `cut` succeed on empty input; under `pipefail` the pipeline still failed, and the caller's own `|| echo "absent"` then reported an existing jar as gone, with exit 0. Added a `hash256` helper (prefer `sha256sum`, fall back to `shasum -a 256`, same idiom as `probe-member-credentials.sh:273-279`) and pointed `jar_id` at it. `jar_id` now has three distinct answers: `absent` (file really isn't there), a 12-char hash (hashed successfully), or `unhashable` (file is there but neither hasher is on PATH). `absent` is never returned for a file that exists. **Item 2** (`scripts/test-redeploy-fleetd.sh:298-299`): same direct `shasum` call in the suite's own reference-hash computation, which is why the suite died at exit 127 on Linux with zero `FAIL:` lines printed — indistinguishable from a clean pass by that count alone. Now uses `hash256` too. **Item 3** (`.gitea/workflows/ci.yml`): added a `shell-tests` job on `ubuntu-latest` that runs `bash scripts/test-redeploy-fleetd.sh`. Gated on the step's own exit code, not a `FAIL:` count — item 2 is the proof that a count alone cannot be the gate. **New tests** in `scripts/test-redeploy-fleetd.sh`: - `test_jar_id_reports_unhashable_when_no_hasher_on_path` — drives the real `jar_id`/`hash256` through a stubbed `PATH` containing neither hasher (same stub-`PATH` technique as `test_detect_supervisor_systemd_probe_setup_failure_is_unclear`, but replacing `PATH` rather than prepending to it, since the point is to hide BOTH hashers). - `test_no_unguarded_macos_only_hasher_calls` — a shape check across every script under `scripts/`, not named lines (per #545, this idiom already spread from 2 sites to 6 across 91 commits once). **Verification** (in the worker's own worktree, on macOS): - `bash -n` clean on both changed shell scripts, under both `/bin/bash` (3.2.57) and `env bash` (5.3.9). - Full suite green under both bash versions: exit 0, 0 anchored `^FAIL:` lines, each time. - Defined-vs-invoked test functions: 69/69, empty `comm -3` (was 67/67 before this PR's two additions). - Two mutations applied and reverted, each with a pristine-anchor count (1->0) proving the mutation actually applied, each producing the new test's own FAIL message, each restored to a byte-identical file (confirmed via full `shasum -a 256`), each followed by a green control run. - CI-job command demonstrated directly (Gitea Actions cannot be run from this worktree): `bash scripts/test-redeploy-fleetd.sh` on the real suite -> exit 0; on a deliberately broken copy (one assertion's expected value swapped) -> exit 1. Both exit codes shown, not just a comment. **Never ran**: `scripts/redeploy-fleetd.sh` itself, in any form — it restarts the live daemon. **Caveat for review**: the `hash256` "neither hasher on PATH" branch was only exercised via a stubbed `PATH` on macOS (where both hashers exist for real); it has not been run on an actual Linux host with neither `sha256sum` nor `shasum` installed. The stub technique itself is the same one three existing tests in this suite already rely on.
agent added 1 commit 2026-09-12 10:07:12 +02:00
fleetd #550: replace shasum with a portable hash256 helper, add a Linux CI job for the shell suite
CI / shell-tests (pull_request) Successful in 5s
CI / contract (pull_request) Successful in 1m17s
CI / build (pull_request) Successful in 1m46s
3da44eed63
jar_id() in redeploy-fleetd.sh called shasum directly, which does not exist on GNU coreutils
Linux (Debian/Ubuntu/etc.) — there it silently reported an existing jar as "absent" with exit 0,
because the missing command made `cut` succeed on empty input and pipefail's failure was then
swallowed by the `|| echo "absent"` fallback. The shell test suite hit the same tool at
test-redeploy-fleetd.sh:298-299 and died at exit 127 with zero FAIL lines printed — the same shape
as a clean pass on the one channel anyone would check.

Adds one hash256() helper (prefer sha256sum, fall back to shasum -a 256, same idiom already used
in probe-member-credentials.sh) and points jar_id and the test suite's own reference hash at it.
jar_id now has three distinct answers instead of two: absent, a hash, or "unhashable" when neither
hasher is on PATH — "absent" is never used for a file that exists.

Adds a CI job (shell-tests) that runs scripts/test-redeploy-fleetd.sh on ubuntu-latest, gated on
the step's own exit code rather than a FAIL-line count, since a suite that dies before running is
exactly what a green run also looks like by that count.

New tests: test_jar_id_reports_unhashable_when_no_hasher_on_path (stubbed PATH with neither
hasher) and test_no_unguarded_macos_only_hasher_calls (a shape check across every script under
scripts/, not named lines — #545 already showed this idiom spreading from two sites to six).
agent added 1 commit 2026-09-12 10:16:51 +02:00
fleetd #550: pin hash256's algorithm against a literal SHA-256 test vector
CI / shell-tests (pull_request) Successful in 5s
CI / contract (pull_request) Successful in 59s
CI / build (pull_request) Successful in 2m27s
b8182c96c2
test_jar_id_defaults_to_live_and_reports_explicit_path's reference hash is computed by calling
hash256 itself (needed so it doesn't call the Linux-crashing bare shasum directly). That made
subject and reference the same instrument: they agree no matter which algorithm hash256 actually
runs, so a mutation swapping both of hash256's arms for the wrong algorithm was invisible to the
suite.

Adds test_hash256_computes_a_real_sha256, pinned against the published SHA-256 test vector for the
3-byte input "abc" (ba7816bf8f01...), written as a literal constant rather than computed by any
hasher at test time. Verified the constant myself both ways (sha256sum and shasum -a 256) before
writing it in.
ltms merged commit 26f380a00b into main 2026-09-12 10:20:29 +02:00
Sign in to join this conversation.