Skip to content

test(unit): run internal/app's tests in parallel to fit the unit budget - #811

Open
EricAndrechek wants to merge 1 commit into
mainfrom
test/unit-budget
Open

EricAndrechek wants to merge 1 commit into
mainfrom
test/unit-budget

Conversation

@EricAndrechek

Copy link
Copy Markdown
Member

internal/app's unit tests ran one after another and took 6–8 s of test time alone (8.3–10.6 s in CI's unit job), against the 15 s that make test-unit gives each package. Most of that was waiting: about 2.6 s of CPU over 7–8 s of wall time.

Verified

  • internal/app alone: 2.2–3.1 s of test time, down from 5.9–7.7 s, measured with old and new binaries interleaved on the same machine. Coverage is unchanged at 93.0%.
  • go test -race -count=5 passes, and so do -count=20 -cpu 4 and -cpu 2. A run under load beside internal/dedupe -count=3 passes too.
  • 40 runs with -shuffle=on, alternating -cpu 1 and -cpu 4, pass. One failure was seen in an earlier batch of 19 shuffled runs while the machine was also running a full suite; the failing test wasn't captured, and the 40 later runs did not reproduce it.
  • make verify, make lint-go (including tparallel), make test-unit and make ci are green.

Closes #739

🤖 Generated with Claude Code

internal/app's 77 tests ran one after another and took 6 to 8s of test
time alone under -race -cover, against the 15s make test-unit gives each
package. Most of that was waiting, not work: the binary used about 2.5s
of CPU over 8s of wall time.

- TestMain silences the default logger once, and newApp no longer swaps
  it or the OTel providers per test. guardGlobals stays only in the
  serial tests that turn Prometheus on or replace the logger themselves.
- Every test that leaves process-wide state alone calls t.Parallel, and
  so do its subtests where they are independent. The tests that capture
  the logger, turn on Prometheus, set the environment or signal the
  process stay serial, as does TestNew_NestedDirectory, whose subtests
  run before the reload it then checks.
- Two serial tests waited out a production retry. A moved tenant's
  schema discovery retried after a random wait of up to 2s (more when an
  attempt came before the fix), and the DynamoDB table check after 1s.
  discoveries.backoff and App.dynamoRetry now hold those first waits,
  at their production values, and each test shortens its own.

The package now takes 2.2 to 3.1s of test time alone, from 5.9 to 7.7s
interleaved on the same machine, with coverage unchanged at 93.0%.
internal/mq already fit after #745 (2.6s alone).

Closes #739

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 2605c00d-fb35-4047-9eba-ca26e40eaa19


📥 Commits

Reviewing files that changed from the base of the PR and between c01b912 and 6f7aca4.



📒 Files selected for processing (9)
  • CHANGELOG.md
  • internal/app/app.go
  • internal/app/app_test.go
  • internal/app/dedupe_dynamodb_test.go
  • internal/app/discoveries.go
  • internal/app/main_test.go
  • internal/app/mq_nats_test.go
  • internal/app/roles_test.go
  • internal/app/wire_dynamodb.go


Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.



📜 Recent review details
🧰 Additional context used
📚 Code guidelines (3)
AGENTS.md — auto-discovered
docs/src/content/docs/architecture.md — auto-discovered
CONTRIBUTING.md — auto-discovered

📓 Path-based instructions (6)
Source excerpt: **WH001 applies to every tracked Markdown file, with no carve-out** — `AGENTS.md`, `CHANGELOG.md`, `.github/` CI docs and `.claude/` agent prompts included.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • CHANGELOG.md

Source excerpt: **wire.go** — one `wire*` function per component, each handed the settings registry whole and deriving the per-call getters the internal packages take (`DLQFor`, `DedupeFor`, `GapWindow`, …) and registering its `AfterAdopt`...

📄 CodeRabbit inference engine (docs/src/content/docs/architecture.md)

Files:

  • internal/app/wire_dynamodb.go
  • internal/app/dedupe_dynamodb_test.go
  • internal/app/discoveries.go
  • internal/app/main_test.go
  • internal/app/app.go
  • internal/app/roles_test.go
  • internal/app/mq_nats_test.go
  • internal/app/app_test.go

Source excerpt: Update the documentation and `CHANGELOG.md` (under `## Unreleased`) that your change affects.

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • CHANGELOG.md

Source excerpt: **Never hard-wrap prose.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • CHANGELOG.md

Source excerpt: **Docs prose**: never hard-wrap Markdown — one paragraph is one line.

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • CHANGELOG.md

Source excerpt: **Go 1.26**, strict formatting (`gofumpt`, enforced by CI)

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • internal/app/wire_dynamodb.go
  • internal/app/dedupe_dynamodb_test.go
  • internal/app/discoveries.go
  • internal/app/main_test.go
  • internal/app/app.go
  • internal/app/roles_test.go
  • internal/app/mq_nats_test.go
  • internal/app/app_test.go



🔇 Additional comments (10)
CHANGELOG.md (1)

149-149: LGTM!


internal/app/app_test.go (2)

2304-2304: Retry-wait override is a safe, scoped change.

The test sets a.discoveries.backoff after newFakeClickHouse builds the loops and before the reload that starts the retry loop. Production keeps the 2-second default from newDiscoveries. The test runs serially because it calls logtest.Capture.


162-162: LGTM!

Also applies to: 186-186, 201-201, 226-226, 236-236, 260-260, 362-362, 437-437, 511-511, 574-574, 585-585, 600-600, 609-609, 616-616, 640-640, 648-648, 655-655, 674-674, 721-721, 773-773, 811-811, 830-830, 932-932, 989-989, 1026-1026, 1094-1094, 1180-1180, 1255-1255, 1264-1264, 1269-1269, 1286-1286, 1302-1302, 1312-1312, 1371-1371, 1396-1396, 1427-1427, 1504-1504, 1577-1577, 1600-1600, 1633-1633, 1681-1681, 1697-1697, 1770-1770, 1789-1789, 1799-1799, 1831-1831, 1861-1861, 1915-1915, 1948-1948, 2014-2014, 2095-2095, 2132-2132, 2145-2145, 2153-2153, 2234-2234, 2276-2276, 2354-2354, 2393-2393, 2424-2424


internal/app/main_test.go (1)

7-15: LGTM!


internal/app/mq_nats_test.go (1)

41-41: LGTM!

Also applies to: 85-86, 102-102, 112-112


internal/app/roles_test.go (1)

29-29: LGTM!

Also applies to: 62-62, 72-72, 93-93, 153-153, 166-166, 181-181, 194-194


internal/app/app.go (1)

108-110: LGTM!

Also applies to: 152-152


internal/app/discoveries.go (1)

40-42: LGTM!

Also applies to: 61-61, 145-145, 149-149


internal/app/dedupe_dynamodb_test.go (1)

347-347: LGTM!


internal/app/wire_dynamodb.go (1)

111-111: LGTM!





📝 Summary

Summary by CodeRabbit

  • Chores

    • App test runs are faster, with more tests running concurrently while tests that rely on shared process-wide state remain serialized.
    • Retry checks for tenant discovery and DynamoDB tables can use shorter waits in tests; production retry behavior retains its existing timing and limits.
  • Documentation

    • Updated the changelog to reflect the test execution changes and report the reduced app test runtime.
📝 Summary

Walkthrough

Most internal/app tests now run in parallel, while tests that access process-wide state retain isolation. Tenant discovery and DynamoDB table-check retry delays are configurable, with production defaults unchanged and shorter values used in tests. The changelog reports the package test runtime reduction.

Changes

Application test runtime

Layer / File(s) Summary
Configurable retry delays
internal/app/app.go, internal/app/discoveries.go, internal/app/wire_dynamodb.go, internal/app/dedupe_dynamodb_test.go, internal/app/app_test.go
Tenant discovery and DynamoDB table-check loops use configurable initial retry delays. Their production defaults remain 2 seconds and 1 second, respectively; tests set shorter delays.
Parallel tests and global-state isolation
internal/app/app_test.go, internal/app/main_test.go, internal/app/mq_nats_test.go, internal/app/roles_test.go, CHANGELOG.md
Many app, NATS, and roles tests now run in parallel. Tests that enable Prometheus or inspect global logging retain global-state guarding. TestMain silences the default logger. The changelog records the test changes and reported runtime.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Other · Severity of issue fixed: Medium

Suggested reviewers: taitelee



Merge Risk: ⚪ Minimal · up to 6f7ac

The retry behavior retains its production defaults, and the inspected parallel tests isolate their state. A reported shuffled-run failure was not reproduced; no actionable merge-blocking risk is established, so the PR appears ready for normal checks.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 74.63% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 67 functions across 8 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed The PR addresses the active coding requirement in #739 to keep the affected unit packages within the 15-second budget. In internal/app, eligible tests run in parallel, tests that use process-wide st…
Out of Scope Changes check Passed The changes stay within #739. The internal/app parallel test changes, process-wide state isolation, configurable test retry waits, and the changelog entry all support the unit-test budget objective.…
Title check Passed The title clearly and concisely describes the main change: running eligible internal/app unit tests in parallel to reduce test time.
Description check Passed The description directly explains the parallel test changes, preserved serial tests, configurable retry waits, measured performance improvement, and verification results.

Full details: Docstring Coverage

Explanation

Docstring coverage is 74.63% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 67 functions across 8 files. (1 skipped: 1 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR



🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


✨ Simplify code
  • Commit to this branch
  • Create a new PR



  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions github-actions Bot added go Pull requests that update go code area/docs Documentation, site/, README area/app Process wiring (internal/app): component build, run, release labels Oct 10, 2026
@github-code-quality

github-code-quality Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Go

Go

The overall line coverage in commit 6f7aca4 in the test/unit-budget branch remains at 93%, unchanged from commit c01b912 in the main branch.

Show a line coverage summary of the most impacted files.
File main c01b912 test/unit-budget 6f7aca4 +/-
internal/mq/nats_topology.go 92% 91% -1%
internal/app/discoveries.go 100% 100% 0%
internal/ingest/claims.go 91% 92% +1%

Updated October 10, 2026 20:10 UTC

@EricAndrechek

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@EricAndrechek

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@EricAndrechek
EricAndrechek marked this pull request as ready for review October 10, 2026 20:05
@EricAndrechek
EricAndrechek requested review from a team and taitelee October 10, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/app Process wiring (internal/app): component build, run, release area/docs Documentation, site/, README go Pull requests that update go code

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

test(unit): internal/mq and internal/app use 10-11 s of the 15 s unit budget

1 participant