Skip to content

test(quic): expand coverage for frame.cpp#1047

Merged
kcenon merged 1 commit into
developfrom
test/issue-1033-quic-frame-coverage
Apr 26, 2026
Merged

test(quic): expand coverage for frame.cpp#1047
kcenon merged 1 commit into
developfrom
test/issue-1033-quic-frame-coverage

Conversation

@kcenon

@kcenon kcenon commented Apr 26, 2026

Copy link
Copy Markdown
Owner

Closes #1033

What

Adds tests/unit/quic_frame_extra_coverage_test.cpp with 63 additional unit tests for src/protocols/quic/frame.cpp, complementing the existing quic_frame_coverage_test.cpp (Issue #1011) and quic_frame_types_test.cpp (Issue #974).

Why

src/protocols/quic/frame.cpp is one of the lowest-coverage source files in src/protocols/ per the #953 audit. The uncovered region concentrates in error and boundary paths -- exactly the surfaces that regress during the ongoing Result<T> migration. The existing coverage tests handle the common paths, but several branches and edge cases remained untouched: longer varint type prefixes, the non-zero ranges ACK accumulation loop, the non-zero CRYPTO offset path, CONNECTION_CLOSE with non-empty reason / non-zero frame_type / multi-byte error_code, the per-bit consistency of stream-flag helpers, and most frame_type_to_string branches.

Where

  • New file: tests/unit/quic_frame_extra_coverage_test.cpp (63 tests, gtest)
  • tests/CMakeLists.txt: registered network_quic_frame_extra_coverage_test next to the other extra_coverage tests
  • CHANGELOG.md and docs/CHANGELOG.md: one-line entry each under [Unreleased] > Added
  • Source under test (src/protocols/quic/frame.cpp): NOT MODIFIED

How

New test scope

  • peek_type: 4-byte and 8-byte varint type prefixes
  • parse_all: heterogeneous frame mix (PING + HANDSHAKE_DONE + MAX_DATA + PATH_CHALLENGE) and mid-sequence parse-error surfacing
  • parse_padding: empty buffer rejected at parse() entry
  • parse_ack: ACK_ECN dispatch via parse(), large delay / largest_acknowledged at varint boundaries, multi-range accumulation through the parse_ack loop, truncation at range gap, range length, ECT(1), and ECN-CE
  • parse_stream: every concrete type byte 0x08..0x0f routed through parse() covering the FIN/LEN/OFF flag matrix, large stream_id varint, zero-length data with LEN flag
  • parse_crypto: non-zero offset and 200-byte payload round-trips
  • parse_new_token: empty-token and 150-byte token round-trips
  • parse_new_connection_id: 1-byte CID minimum, 16384-sequence variant, cid_len=20 with insufficient remaining bytes
  • parse_retire_connection_id: 4-byte varint sequence round-trip
  • parse_path_challenge / parse_path_response: all-zero and all-0xFF payload round-trips
  • parse_connection_close: transport-with-frame-type, application long-reason (120 chars forcing 2-byte length varint), multi-byte error_code
  • parse_handshake_done: dispatch consumes exactly 1 byte, trailing buffer untouched
  • frame_builder::build_padding(0): zero-count guard returns empty vector
  • frame_type_to_string: 18 previously-unasserted branches
  • is_stream_frame / get_stream_flags / make_stream_type: per-bit consistency at boundaries 0x07, 0x08, 0x0f, 0x10

Test plan

  • All tests are hermetic: no network, no filesystem, no sleeps. Hand-rolled byte sequences follow RFC 9000 wire format so error-path tests are independent of builder behavior.
  • Source under test is unchanged; this is a test-only PR.
  • Local C++ toolchain (cmake/ninja/make) is unavailable in the working environment, so local build verification was skipped per project convention -- relying on the multi-platform CI matrix (Ubuntu GCC/Clang, macOS, Windows MSVC, ASAN/TSAN/UBSAN).

Breaking changes

None. Test additions only.

Notes

  • The existing quic_frame_coverage_test.cpp documents an asymmetry between build_ack (writes ranges.size() as ACK Range Count) and parse_ack (treats it as "additional gap/length pairs after First ACK Range"), causing any non-empty-ranges round-trip to fail. This PR continues to avoid round-trips with non-empty ranges in builder-produced inputs and instead validates the parse_ack range-loop branch by hand-crafted byte sequences. Fixing the divergence is out of scope for the test-expansion track.
  • Coverage measurement against develop HEAD: deferred to CI (no local lcov toolchain).

Add tests/unit/quic_frame_extra_coverage_test.cpp with 63 additional
test cases targeting branches not exercised by the existing
quic_frame_coverage_test.cpp (#1011) or quic_frame_types_test.cpp (#974):

- peek_type with 4-byte and 8-byte varint type prefixes
- parse_all with heterogeneous frame mix (PING + HANDSHAKE_DONE +
  MAX_DATA + PATH_CHALLENGE) and mid-sequence error surfacing
- Every concrete STREAM type byte (0x08-0x0f) routed through parse()
- ACK_ECN dispatch with truncation at each ECN field, ACK ranges
  accumulation, per-range truncation, large delay/largest_acked
- CRYPTO non-zero offset and 200-byte payload round-trips
- NEW_TOKEN empty-token and 150-byte token round-trips
- NEW_CONNECTION_ID minimal 1-byte CID, 16384-sequence variant,
  cid_len=20 with insufficient bytes
- RETIRE_CONNECTION_ID 4-byte varint sequence
- PATH_CHALLENGE all-zero / PATH_RESPONSE all-0xFF round-trips
- CONNECTION_CLOSE transport-with-frame-type, application long-reason,
  multi-byte (4-byte varint) error_code
- HANDSHAKE_DONE dispatch with trailing buffer bytes
- frame_builder::build_padding(0) zero-count guard
- frame_type_to_string for 18 previously-unasserted branches
- is_stream_frame / get_stream_flags / make_stream_type per-bit
  consistency at boundaries 0x07 / 0x08 / 0x0f / 0x10

Source file unchanged; tests are hermetic (no I/O).
Registered network_quic_frame_extra_coverage_test in tests/CMakeLists.txt.
Updated CHANGELOG.md and docs/CHANGELOG.md under Unreleased > Added.

Closes #1033
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Metric Value
Line Coverage 66.4%
Branch Coverage 32.9%
Target 80% lines / 70% branches
Coverage Details

Full HTML report is available as a build artifact.

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