Skip to content

test: coverage analysis + improvements across all identified gaps#8

Merged
naveed949 merged 7 commits into
mainfrom
claude/test-coverage-analysis-zxel4f
Jun 22, 2026
Merged

test: coverage analysis + improvements across all identified gaps#8
naveed949 merged 7 commits into
mainfrom
claude/test-coverage-analysis-zxel4f

Conversation

@naveed949

@naveed949 naveed949 commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

Started as a test-coverage analysis (docs/TEST_COVERAGE.md) and then implemented all six prioritized improvement areas it identified. The suite grew 236 → 273 tests, coverage is now enforced in CI, and a latent sandbox/coverage incompatibility is fixed.

Coverage before → after

Scope Before (stmt/branch) After (stmt/branch)
All files 85.5 / 70.6 88.6 / 73.7
src/platform 81.5 / 56.5 99.4 / 91.9
src/controllers 72.2 / 55.9 85.2 / 79.4
src/routes 76.1 / 69.4 88.3 / 83.3
src/edge 82.0 / 69.3 83.7 / 75.5

What changed

  1. Sandbox vs. coverage instrumentation + CI gate (ee99d16). The vm determinism sandbox compiles reducers from fn.toString(), so under jest --coverage Istanbul's injected cov_<hash>() counters reached the sandbox as undefined globals → ReferenceError → apply 500 (3 tests failed only under coverage). compileReducer now binds a no-op sink for those counter identifiers (before Proxy is stripped), so instrumented reducers run while a genuinely banned global still throws. Added collectCoverageFrom + coverageThreshold, a test:coverage script, and a CI coverage step on a Node 20.x + 22.x matrix.
  2. Leader forwarding (650d5c0) — tests/forward.test.ts: relay, content-type/body passthrough, X-Request-Id/X-Actor propagation, X-Forwarded-By anti-loop, connection-error and socket-timeout fallbacks. forward.ts 18% → 100%.
  3. Route/controller error paths (e1429ec) — tests/httpRouting.test.ts: follower 421 (book + module), strong reads on the leader, 404 on the strong-read path, raft membership admin routes (400/409/421), app /ready 503 and /metrics 404.
  4. raftNode failure branches (e1429ec) — tests/raftMetrics.test.ts: leader per-peer replication-lag series and its reset/rebuild after a member is removed.
  5. Edge replica resilience (f6f819b) — tests/edgeResilience.test.ts: reconnect-after-error resumes from the cursor, replays aren't re-applied, onCaughtUp advances past filtered scoped entries, snapshot bootstrap, waitForIndex resolve/reject — via a controllable fake stream source.
  6. Platform/wiring (a65a03d) — tests/logger.test.ts: level filtering, JSON/pretty output, base/child + request-context enrichment, env-driven createLogger. logger.ts 0% → ~100%.

Two branches were deliberately left (they need fault injection that risks flakiness): the read-barrier 2 s timeout, and the raw HTTP/EventSource socket internals (covered end-to-end by the edge integration suites).

Test plan

npx tsc --noEmit clean; yarn test and yarn test:coverage both green (273/273) with thresholds met (stmt 88.5%, branch 73.4%, func 89.7%, line 90.5%).

🤖 Generated with Claude Code

claude added 6 commits June 22, 2026 18:17
Captures jest coverage numbers, identifies the sandbox/instrumentation
incompatibility, and lists prioritized gaps (leader forwarding, route
error paths, raftNode failure branches, edge resilience).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
The vm determinism sandbox compiles reducers from fn.toString(), so under
`jest --coverage` Istanbul's injected `cov_<hash>()` counters reached the
sandbox as undefined free globals and threw ReferenceError -> apply 500.
Bind a no-op sink for those counter identifiers before SANDBOX_SETUP removes
Proxy, so instrumented reducers still run deterministically while a genuinely
banned global (Date, etc.) still throws.

Add coverageThreshold + collectCoverageFrom to jest.config.js, a
`test:coverage` script, and a CI coverage step; extend the CI Node matrix to
20.x and 22.x. Adds sandbox regression tests for the instrumentation case.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
forwardToLeader / isForwarded had ~18% coverage and no dedicated tests,
despite being the write path every non-leader node relies on. Add a suite
driving a stub leader server: successful relay, verbatim content-type/body
passthrough, request-context (X-Request-Id/X-Actor) propagation + the
X-Forwarded-By anti-loop mark, and the connection-error and socket-timeout
fallbacks. forward.ts now at 100% stmts / 89% branch.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
Add tests for the controller/route failure surface that the happy-path
single-node suites miss:
- book & module controllers on a 3-node cluster: follower writes -> 421
  (forward-then-fallback), the X-Forwarded-By anti-loop branch, strong reads
  on the leader, and 404 on the strong-read path
- raft membership admin routes: GET /members, 400 on missing id/url, 409 on
  removing an unknown member, 421 on a follower
- app-level /ready (503 pre-leader) and /metrics (404 when disabled)
- RaftNode.collectMetrics: leader per-peer replication-lag series and its
  reset/rebuild after a member is removed

controllers 72->85% stmt / 56->79% branch; routes 76->88% / 69->83%.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
The HTTP-backed edge suites don't reach the failure lifecycle. Drive
EdgeReplica through a controllable fake LogStreamSource: reconnect-after-error
resumes from the applied cursor (and closes the old conn), replayed entries
are not re-applied, onCaughtUp advances past filtered scoped entries, snapshot
bootstrap restores state + cursor, and waitForIndex resolves / rejects on stop
and timeout.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
Add tests/logger.test.ts (level filtering, JSON/pretty output, base/child +
request-context enrichment, env-driven createLogger) — logger.ts 0% -> ~100%,
lifting src/platform to 99% stmt / 92% branch. Ratchet the global
coverageThreshold up to the new floor (86/71/86/88). Update the analysis doc
with a resolution summary.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
@naveed949 naveed949 changed the title docs: test coverage analysis and prioritized improvement areas test: coverage analysis + improvements across all identified gaps Jun 22, 2026
The PR-open CI run executed on the initial docs commit only; the follow-up
push that added the coverage gate and the Node 20.x/22.x matrix did not fire
a synchronize run. Empty commit to run CI against the latest tree.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0159Rma834V7wPgft7fzoFtg
@naveed949
naveed949 marked this pull request as ready for review June 22, 2026 18:59
@naveed949
naveed949 merged commit 7b11fba into main Jun 22, 2026
2 checks passed
@naveed949
naveed949 deleted the claude/test-coverage-analysis-zxel4f branch June 23, 2026 05:54
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.

2 participants