Skip to content

test(docker): close SIGTERM, hooksctl-vs-server, 0o755 coverage gaps from PR #2#4

Merged
aaronbrethorst merged 2 commits into
mainfrom
pr4
May 9, 2026
Merged

test(docker): close SIGTERM, hooksctl-vs-server, 0o755 coverage gaps from PR #2#4
aaronbrethorst merged 2 commits into
mainfrom
pr4

Conversation

@aaronbrethorst
Copy link
Copy Markdown
Member

@aaronbrethorst aaronbrethorst commented May 9, 2026

Summary

Closes the three coverage gaps the PR #2 review explicitly deferred:

  • TestImageGracefulShutdownOnSIGTERMdocker stop sends SIGTERM; we assert the binary honors signal.NotifyContext (exit 0, elapsed under the 30s shutdown deadline) rather than getting SIGKILL'd. The 30s value is now a shutdownDeadline constant so the doc, the docker stop -t arg, and the elapsed-time guard share a single source of truth.
  • TestImageHooksctlAgainstRunningServer — runs hooksctl token list inside the same container the server lives in. Captures the admin token from hooks init stdout via extractAdminToken (HasPrefix-anchored so a future init reformat can't leak it past the helper), passes it via -e HOOKS_TOKEN= (never argv), and redacts any echoed output before it reaches t.Fatalf. Assertion uses a whitespace-anchored field match so a future header rename can't false-positive.
  • TestImageInitFailsClearlyOn0o755HostDir — documents the README-literal scenario (mkdir -p ./hooks-data with default umask 022). Probes for daemon-side UID translation and skips on Docker Desktop / macOS where the scenario doesn't manifest; on Linux CI, asserts hooks init fails with permission denied rather than silently mis-scaffolding.

scaffoldDataDir now delegates to a new scaffoldDataDirCapturingToken (single body, no behavior change to existing callers).

Test plan

  • make lint — clean
  • go tool golangci-lint run --build-tags=docker ./dockertest/... — clean
  • make test — non-docker suite green
  • go test -tags=docker -count=1 ./dockertest/... (full suite) — ok in ~11s
  • Each new test verified individually with -v -run: SIGTERM PASS, hooksctl PASS, 0o755 SKIP (Docker Desktop UID translation, with the documented skip rationale)

Review notes (non-blocking, surfaced for the reviewer)

  • The SIGTERM test asserts exit==0 && elapsed < 30s. A future regression where the binary panics-and-recovers-to-0 within the window would still pass. Strengthening would mean adding a "shutting down" log line in cmd/hooks/main.go and grepping for it — out of scope here.
  • WAL-checkpoint-on-SIGTERM coverage is not added; could fold into TestImageRestartPreservesState by stopping via SIGTERM rather than docker rm -f in a follow-up.
  • The runServerContainer(t, dir, name, opts) helper that would dedupe the six near-identical docker run -d ... boot blocks (3 pre-existing + 2 new in this PR + 1 implicit) is intentionally not extracted — it touches code from the PR Add Docker support and Render Blueprint #2 surface and is scope creep for this follow-up.

Summary by CodeRabbit

  • Tests
    • Expanded Docker integration test suite with enhanced validation coverage
    • Added tests for graceful shutdown handling on termination signals
    • Added tests for CLI tool functionality against active server instances
    • Added tests for permission-related error scenarios

Review Change Stack

Three coverage gaps surfaced in the PR #2 review:

- TestImageGracefulShutdownOnSIGTERM: docker stop sends SIGTERM and we
  expect the binary to honor signal.NotifyContext rather than getting
  SIGKILL'd at the grace deadline. Asserts exit=0 and elapsed under the
  binary's 30s shutdown deadline (now extracted to a constant so the
  source of truth lives in one place).

- TestImageHooksctlAgainstRunningServer: runs `hooksctl token list`
  inside the same container the server is in, against 127.0.0.1:8080.
  Token from `hooks init` is captured via a redaction-aware helper and
  passed to docker exec via -e (never argv, never test logs).

- TestImageInitFailsClearlyOn0o755HostDir: documents the README-literal
  case (mkdir -p ./hooks-data without chmod). Probes for UID translation
  and skips on Docker Desktop / macOS where the scenario doesn't
  manifest; on Linux CI, asserts init fails with permission-denied.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

Warning

Rate limit exceeded

@aaronbrethorst has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 13 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 83af675b-c539-4937-9c48-cc0af5fc285e

📥 Commits

Reviewing files that changed from the base of the PR and between 8ba6ae4 and 9215a11.

📒 Files selected for processing (1)
  • dockertest/docker_test.go
📝 Walkthrough

Walkthrough

Three Docker integration tests are added to verify server shutdown behavior, hooksctl token operations against a running server, and initialization error handling under restrictive file permissions. New helpers extract admin tokens from output, redact secrets, and parse token list results. The data scaffolding logic is refactored to capture the one-time admin token during container initialization.

Changes

Docker Integration Tests

Layer / File(s) Summary
Import Changes
dockertest/docker_test.go
The bytes package is added for binary/text scanning used by output-parsing tests.
Output Parsing Helpers
dockertest/docker_test.go
Three new helpers are added: extractAdminToken parses admin tokens from hooks init output, redact removes secrets from test output, and tokenListContainsName searches for exact token field matches in hooksctl token list output.
Data Scaffolding with Token Capture
dockertest/docker_test.go
New scaffoldDataDirCapturingToken helper runs hooks init, extracts the admin token, and returns both the temp directory and token. Original scaffoldDataDir is refactored to delegate to this helper.
Test Timing Constants
dockertest/docker_test.go
shutdownDeadline constant is added to align graceful shutdown assertions with the binary's configured deadline.
Integration Tests
dockertest/docker_test.go
Three new tests added: TestImageGracefulShutdownOnSIGTERM verifies exit code and shutdown latency within deadline, TestImageHooksctlAgainstRunningServer validates token list operations via hooksctl against a running server with captured admin token, TestImageInitFailsClearlyOn0o755HostDir confirms hooks init fails with permission error when the bind-mounted data directory is 0o755.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • OneBusAway/hooks#2: This PR continues integration test coverage by adding three new Docker-gated tests that address test gaps left by the initial dockertest suite introduced in PR #2.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main changes: three specific test additions (SIGTERM, hooksctl-vs-server, 0o755) addressing coverage gaps from a prior PR.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@dockertest/docker_test.go`:
- Around line 445-489: TestImageInitFailsClearlyOn0o755HostDir currently prints
the raw `out` from the `hooks init` run (variable out), which may contain a
one-time admin token/signup code; replace those failing
t.Fatalf/t.Fatalf/t.Fatalf messages so they never include plaintext secrets. Fix
by introducing a redaction step before any log/Fail output (e.g., call a helper
like redactSecrets(out) or sanitizeOutput(out) that strips/masks known token
patterns such as "admin token", "signup code", long hex/base64 strings, or any
regex you use elsewhere) and use the redacted string in the t.Fatalf/t.Fatalf
messages; alternatively only include a short, non-secret summary (exit status or
length) instead of the raw `out`. Ensure the change is applied to the failure
branches that reference `out` in TestImageInitFailsClearlyOn0o755HostDir.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f02376d5-570e-4a7f-8688-8ed82e01ea46

📥 Commits

Reviewing files that changed from the base of the PR and between 74431bd and 8ba6ae4.

📒 Files selected for processing (1)
  • dockertest/docker_test.go

Comment thread dockertest/docker_test.go
When the 0o755 test's first assertion fires, hooks init unexpectedly
succeeded — which means it reached the  print
site in cmd/hooks/main.go and the token is in the captured output. Drop
the %s and route through a redaction-aware Fatal, matching the pattern
already used in scaffoldDataDir.

The second assertion's branch (init returned non-zero, no "permission
denied" found) is reached only when init failed before token issuance,
so the diagnostic %s there cannot leak the token. Comment the leak
analysis so future readers don't reflexively redact and lose the debug
output.
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 9, 2026

@aaronbrethorst aaronbrethorst merged commit 9a0f3f0 into main May 9, 2026
7 checks passed
@aaronbrethorst aaronbrethorst deleted the pr4 branch May 9, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant