test(connect): black-box bats regression suite for connect*.sh + CI#73
Conversation
1558834 to
fe5890d
Compare
ben-dz
left a comment
There was a problem hiding this comment.
Test-only + CI + docs PR adding black-box bats regression tests for the connect*.sh installers. Verified locally: the suite passes across all three scripts and genuinely catches the #70 regression (reintroducing the pre-#70 bug makes it fail). The harness is hermetic and the CI workflow is least-privilege and safe. No critical/high issues; no merge-safety concern. NOTE: a two-dot git diff main HEAD in a shallow checkout makes it look like the PR reverts #71 (cee8d00) by removing ~33 lines from each installer — this is a diff-base artifact; the PR's own commits touch no installer script and a 3-way merge preserves #71. The PR description's 'no runtime code changed' is accurate. Findings are Medium/Low: (M1) the committed design doc describes a source-guard+refactor approach and ~3x the coverage that shipped, contradicting the black-box approach actually taken; (M2) the busy-port test is a near-duplicate of the free-port test and can't fail for its stated reason (doesn't assert port detection fired); plus low-severity polish (first-failure short-circuit, unquoted heredoc in ss_reports_busy, naming).
- M1 (medium) — docs/superpowers/specs/2026-07-06-connect-script-unit-tests-design.md contradicts the implementation. The committed 'approved' design mandates a source guard inside each script plus function extraction (dz_token_to_json, build_env_args) — i.e. editing the shipped installers — and lists six test files / four coverage buckets. The PR deliberately did the opposite (black-box, byte-identical scripts, no guard/refactor) and shipped only set_e_regression.bats + _helpers.bash. A committed spec that contradicts its own implementation misleads the next maintainer and invites re-introducing the CDN-served source guard the PR intentionally avoided. Add a 'Superseded — implemented as black-box, see PR #73' note or update the doc.
- L5 (low) — Naming: set_e_regression.bats's second test is a general preflight-continues case, not a set -e case; if the suite stays black-box, preflight_ws_port.bats would read more accurately. Also the .bats/.bash files are mode 0664 (non-executable) despite the bats shebang — harmless, just inconsistent.
…ame, doc Apply the review findings from #73: - M1: mark the design doc SUPERSEDED. It described a source-guard + function extraction approach (editing the CDN-served installers) that the PR deliberately rejected for a black-box suite. Add a superseding note so the next maintainer doesn't reintroduce the guard. - M2: the busy-port test was a near-duplicate of the free-port test — with DZ_ASSUME_YES=1 both paths reach `docker run`, so it passed even if port detection never fired. It now captures stderr and asserts the "already in use" warn, pinning that preflight actually detected the bound port. - L5: rename set_e_regression.bats -> preflight_ws_port.bats (the file covers the WS-port preflight path, not only the set -e case); chmod +x the .bats / .bash files to match their shebang. - polish: quote the ss_reports_busy heredoc (port passed via env at runtime); both tests now collect failures across all three scripts instead of short-circuiting on the first.
Add a 'Commits & authorship' rule to CLAUDE.md: no Co-Authored-By: Claude, no 'Generated with Claude Code' trailers, no AI-attribution comments in source.
Drive the byte-identical installers end-to-end through a stub-first PATH (fake docker/sudo/ss/curl/...) and assert on what each script tried to do, so no source guard or refactor is added to the files served over the CDN. - tests/scripts/_helpers.bash: stub-PATH harness (docker argv capture, free/busy ss toggle, hermetic offline stubs), iterating all three installers. - tests/scripts/set_e_regression.bats: pins the #70 fix — with the WS port free the installer must survive preflight and reach `docker run` (the pre-#70 code aborted here under set -e). - .github/workflows/shell-tests.yml: runs `bats tests/scripts/` on PRs and main/hotfix pushes; unconditional (not paths-filtered) so it is safe as a required check, mirroring rust.yml.
…ame, doc Apply the review findings from #73: - M1: mark the design doc SUPERSEDED. It described a source-guard + function extraction approach (editing the CDN-served installers) that the PR deliberately rejected for a black-box suite. Add a superseding note so the next maintainer doesn't reintroduce the guard. - M2: the busy-port test was a near-duplicate of the free-port test — with DZ_ASSUME_YES=1 both paths reach `docker run`, so it passed even if port detection never fired. It now captures stderr and asserts the "already in use" warn, pinning that preflight actually detected the bound port. - L5: rename set_e_regression.bats -> preflight_ws_port.bats (the file covers the WS-port preflight path, not only the set -e case); chmod +x the .bats / .bash files to match their shebang. - polish: quote the ss_reports_busy heredoc (port passed via env at runtime); both tests now collect failures across all three scripts instead of short-circuiting on the first.
29c1165 to
e11fdaf
Compare
|
Thanks for the review. Addressed all findings in the latest push (rebased on M1 — M2 — the busy-port test now captures stderr and asserts the L5 — renamed Polish — the Good call on the two-dot |
What
Adds behavioral regression tests for the
scripts/connect*.shinstallers, plus a CI workflow to run them.The tests drive the byte-identical shipped installers end-to-end through a stub-first
PATH(fakedocker/sudo/ss/curl/python3/...) and assert on what each script tried to do (the argv handed to thedockerstub, its exit status). No source guard, refactor, or test-only seam is added to the files served over the CDN viacurl | bash.Why
The installers carry non-trivial logic and ship verbatim to users. #70 was a silent regression: under
set -e, a bareport_in_use "$p"returning non-zero (the common case — the WS port is free) trippederrexitand aborted the whole installer before it started the container. Nothing caught it (no shell tests;shellcheckdoesn't reliably flag thatset -efootgun).Contents
tests/scripts/_helpers.bash— stub-PATHharness:dockerargv capture, free/busysstoggle, hermetic offline stubs, and helpers that iterate all three installers so per-script drift is caught.tests/scripts/set_e_regression.bats— pins the fix(connect): WS port preflight aborts under set -e when the port is free #70 fix: with the WS port free (and busy, non-interactive) the installer must survive preflight and reachdocker run. Fails against the pre-fix(connect): WS port preflight aborts under set -e when the port is free #70 code, passes against the fix..github/workflows/shell-tests.yml— installsbatsand runsbats tests/scripts/on PRs andmain/hotfixpushes. Runs unconditionally (notpaths-filtered) so it is safe as a required check, mirroringrust.ymland the reasoning documented inactionlint.yml.Verification
bats tests/scripts/→ both tests pass across all three installers (connect,connect-testnet,connect-devnet).connect-devnet.shrequiresDZ_GHCR_TOKENwhere the others don't).Follow-ups (not in this PR)
The remaining coverage buckets from the design doc —
ws_port.bats(preflight decision table +build_env_argsvia docker-argv capture) andaccesspass.bats(embedded Python checker with the realpython3+ mock RPC). The workflow globstests/scripts/*.bats, so they're picked up automatically when added.