Skip to content

test(quic): expand connection.cpp coverage to 80%/70% (Part of #953) #1145

Description

@kcenon

What

Expand unit-test coverage on src/protocols/quic/connection.cpp from the current 62.6% line / 34.4% branch baseline (develop @ fc52441, coverage run 25620254919) to ≥80% line AND ≥70% branch. This is the single largest remaining branch-coverage gap in the repository (655 unhit branches in this file alone, accounting for roughly 1.8pp of the ecosystem-wide branch deficit).

Part of #953.

Change Type

  • Test addition (no src/ behavioural change beyond optionally adding a friend/test-injection hook, gated by NETWORK_ENABLE_TEST_INJECTION)

Why

  • connection.cpp is the QUIC connection state machine and contains the largest dispatcher in the QUIC stack. Its branches are concentrated in process_packet / handle_frame / state-transition guards — exactly the surface most likely to hide regressions during Result<T> migration or API stabilization.
  • Round 7 (test(http2): expand http2_client.cpp coverage to 70%/50% #1119test(http): expand websocket_server.cpp coverage to 70%/50% #1124) drove file-level line coverage to 90%+ on all six targeted files but only moved the ecosystem line by +1.0pp and branch by +0.6pp, because branch coverage was not the explicit acceptance gate. This sub-issue uses branch coverage as the primary gate.
  • 655 unhit branches in a single file is the highest-ROI uplift available without architectural change.

Where

  • src/protocols/quic/connection.cpp (1584 physical LOC, 716 TU-instrumented lines)
  • src/internal/protocols/quic/connection.h — may need friend class QuicConnectionTestAccess; (or per-test friend) gated by NETWORK_ENABLE_TEST_INJECTION
  • tests/support/ — possibly extend mock_quic_peer_loop or add a quic_connection_test_access.h parallel to the existing http2_client_test_access.h
  • tests/unit/quic_connection_branch_test.cpp (new) — branch-focused TEST_F set
  • tests/unit/quic_connection_* (existing 185 cases across quic_connection_test.cpp, quic_connection_extended_test.cpp, quic_connection_id_test.cpp, etc.) — extend where appropriate, do not delete

How

Approach

  1. Read the current branch-coverage HTML for connection.cpp from the latest coverage artifact (coverage_html/protocols/quic/connection.cpp.gcov.html) to identify which branches are missing. Do not guess.
  2. Classify missing branches by category: (a) malformed-frame rejection, (b) state-transition guards (CLOSING/DRAINING/CLOSED), (c) error paths in process_packet, (d) reordering / out-of-window cases, (e) flow-control violations.
  3. Pick the friend-injection seam. If the dispatcher branches are reachable only through process_packet or handle_frame, add a friend declaration gated by NETWORK_ENABLE_TEST_INJECTION (same pattern as PR infra(test): pivot to friend-injected process_frame for hermetic dispatcher coverage (Round 6, Part of #1106, #953) #1115 / quic_server_probe). Otherwise drive the existing public API directly.
  4. Write TEST_F cases targeting one branch category per case. Each TEST_F must:
    • Reach connected state via the existing fixture without waiting on a hermetic handshake timer (handshake exceeds wait_for(3s) under coverage instrumentation — see PR docs(coverage): diagnose http2_client 0pp coverage delta after Round 1+2+3 (#1110) #1111 diagnosis).
    • Inject malformed/edge-case input via the friend seam or frame_injector.
    • Assert observable state change (connection_state getter, public statistics, callback invocation), NOT just no-crash.
  5. Verify the post-merge coverage workflow run measures the actual delta.

Acceptance Criteria

  • Post-merge develop coverage workflow run on this PR's merge commit measures src/protocols/quic/connection.cpp line ≥ 80% AND branch ≥ 70%.
  • Ecosystem-wide line coverage on the same run is strictly greater than the pre-PR baseline (no regression).
  • All Ubuntu/macOS/Windows CI checks pass on the PR (Debug + Release).
  • Coverage Analysis check passes (no wait_for budget violations introduced).
  • All sanitizer builds (ASAN, TSAN, UBSAN) pass.
  • No src/ behavioural change — only additive friend declaration (test-only, gated by macro) is permitted.
  • Closes #<this-issue-number> keyword in PR body; PR targets develop.

Anti-criteria (lessons from Round 1–6)

  • "Tests pass under coverage instrumentation" is NOT sufficient. Round 2 PR test(http2): add frame_injector-driven error coverage round 2 (#1106) #1108 passed coverage CI and produced 0pp delta. This sub-issue is gated on the measured per-file branch delta, not on PR CI greenness alone.
  • Negative-assertion tests that overlap with happy-path early-failure branches will contribute 0pp. Each TEST_F must target a branch NOT already exercised by the existing 185 connection-test cases — verify by inspecting the gcov report before adding the case.

Verification

  • Run the coverage workflow locally with cmake --preset coverage + cmake --build build/coverage --target coverage and inspect the per-file HTML before opening the PR.
  • After merge, link the coverage workflow run ID to this issue and post a closure comment with the measured delta.

Notes

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions