test(quic): expand quic_server.cpp coverage to 70%/50%#1135
Merged
Conversation
Drives the previously private dispatch helpers of messaging_quic_server through the existing quic_server_probe friend (gated by NETWORK_ENABLE_TEST_INJECTION) so the previously unreachable branches in src/experimental/quic_server.cpp can be exercised under coverage instrumentation. Probe additions (tests/support/quic_server_probe.[h|cpp]): - generate_session_id forwarder - on_session_close forwarder - cleanup_dead_sessions forwarder - start_receive forwarder (not-running guard) - start_cleanup_timer forwarder (not-running guard) - invoke_*_callback dispatcher forwarders for connection / disconnection / receive / stream_receive / error New test file tests/unit/quic_server_dispatcher_branch_test.cpp adds 34 tests covering: - generate_session_id: counter increment, server_id prefix preservation, cross-instance independence, concurrent invocation uniqueness - on_session_close: empty-map silent no-op, unknown-id silent no-op, populated-callback no-op when id is unknown - cleanup_dead_sessions: empty-map fall-through (not-running and running lifecycle states) - start_receive / start_cleanup_timer: not-running early-return guards - invoke_*_callback: empty-function branch and populated-function branch for all five callback types (legacy + interface adapters) - handle_packet: empty data, zero-filled buffer, random bytes, repeated invalid packets, varied source endpoints - Running-state integration: cleanup, start_receive, start_cleanup_timer, on_session_close, generate_session_id, handle_packet, all five invoke_*_callback dispatchers under start_server(0) lifecycle - max_connections=0 config round-trip lifecycle Mirrors the pattern from issue #1122 (quic_socket dispatcher) and #1121 (http2_server dispatcher). All new tests pass locally on macOS Debug. Existing quic_server_probe_test (2), quic_server_branch_test (78), and experimental_quic_server_test (14) continue to pass without regression. Closes #1123
Contributor
Coverage Report
Coverage DetailsFull HTML report is available as a build artifact. |
5 tasks
8 tasks
kcenon
added a commit
that referenced
this pull request
May 21, 2026
* test(quic): expand connection.cpp branch coverage Drives the private dispatch helpers of src/protocols/quic/connection.cpp through a new test-only friend class tests::support::quic_connection_test_access (gated by NETWORK_ENABLE_TEST_INJECTION) so the std::visit arms of handle_frame, plus process_frames / build_packet / generate_ack_frame / handle_loss_detection_result / generate_probe_packets / queue_frames_for_retransmission / update_state, are reachable under -fprofile-arcs -ftest-coverage without waiting on the TLS handshake (which exceeds wait_for(3s) per PR #1111 diagnosis). Coverage areas added: - handle_frame std::visit arms: padding, ping, ack (with seeded sent_packets to exercise the erase loop), crypto, max_data, max_stream_data, max_streams (bidi + uni), connection_close (transport + application), handshake_done (client connected + server no-op), reset_stream / stop_sending unknown-stream arms, new_connection_id, retire_connection_id error propagation, data_blocked / stream_data_blocked / streams_blocked / path_challenge / path_response / new_token catch-all arm. - process_frames empty + malformed payload dispatch. - build_packet no-keys early-return for all encryption levels. - generate_ack_frame nullopt vs populated arms (largest_received zero with ack_needed true exercises the OR-branch). - get_pn_space switch arms for both const and non-const overloads including the initial / zero_rtt aliasing. - update_state no-op when handshake not complete. - close / close_application re-entry guards (already closing, draining, closed). - enter_closing / enter_draining no-op arms. - on_timeout drain-timeout, idle-timeout, no-timeout. - next_timeout closed (nullopt) + draining (drain_deadline) arms. - handle_loss_detection_result: none, pto_expired (asserts PING frame appended), packet_lost (asserts pending_frames grew), ecn::congestion_signal, ecn::ecn_failure. - generate_probe_packets encryption-level cascade with and without pending crypto data. - queue_frames_for_retransmission per-variant arms: padding / ack (not requeued), crypto (per level routed to matching queue), stream (skipped), ping / new_token / handshake_done (requeued), flow-control frames (requeued), reset_stream / stop_sending (requeued), new_connection_id / retire_connection_id (requeued), path_challenge / path_response (skipped), connection_close (skipped). - start_handshake error guards (server-side rejection, non-idle state rejection) and init_server_handshake client-side rejection. src/internal/protocols/quic/connection.h change is additive only: a forward declaration of the probe and a friend declaration, both gated by #if defined(NETWORK_ENABLE_TEST_INJECTION). Production builds with BUILD_TESTS=OFF compile byte-identical. Pattern mirrors PR #1116 (http2_client_test_access) and PR #1135 (quic_socket_test_access). Closes #1145 * test(quic): extend connection branch coverage with derived keys Round 7 follow-up to the initial PR commit. Local coverage delta on the first round measured 62.6% -> 72.9% line / 34.4% -> 40.1% branch from the run-26200588035 artifact, short of the 80%/70% gate. The remaining gap is concentrated in build_packet's post-keys body, which is unreachable until initial keys are derived. Adding: - ConnectionBuildPacketInitialKeysTest: derives initial secrets via the public crypto().derive_initial_secrets() API (does not require init_client/init_server) so build_packet can be driven past the keys-result.is_err() early-return. Covers empty payload short-circuit, pending CRYPTO assembly, ACK frame assembly, CONNECTION_CLOSE assembly, pending_frames emission, generate_packets pendng-crypto path, generate_packets close_sent path, and generate_packets after closed. - generate_packets state-guard arms (idle, connected without data). - next_timeout idle-deadline path with no loss-detector timeout. - receive_packet draining and closed state arms (bytes/packets counters increment but no processing). - on_timeout no-timeout idle arm. All additions are header-include-only test cases routed through the existing quic_connection_test_access probe; no further src/ change required.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Expands unit test coverage for
src/experimental/quic_server.cppfrom current 43.7% line / 17.5% branch toward >=70% line / >=50% branch by driving the previously private dispatch helpers ofmessaging_quic_serverthrough the existingquic_server_probefriend (gated byNETWORK_ENABLE_TEST_INJECTION).Change Type
Affected Components
tests/support/quic_server_probe.[h|cpp]— extends the existing probe with forwarders forgenerate_session_id,on_session_close,cleanup_dead_sessions,start_receive,start_cleanup_timer, and the fiveinvoke_*_callbackdispatcherstests/unit/quic_server_dispatcher_branch_test.cpp(new) — 34 TEST_F cases driving the previously unreachable branchestests/CMakeLists.txt— wires the newnetwork_quic_server_dispatcher_branch_testtargetWhy
Part of #953. v1.0 readiness gate requires >=80% line coverage ecosystem-wide (#964) — applies even to experimental modules included in default build.
quic_server.cppis 378 LOC; its private dispatchers (session lookup / creation, callback invocation, periodic cleanup, async-receive guard) cannot be reached hermetically from the public API: doing so requires a live UDP peer that completes a TLS-1.3 handshake.Mirrors the strategy of #1122 (quic_socket dispatcher) and #1121 (http2_server dispatcher) which already proved the friend-probe pattern under coverage instrumentation.
Where
src/experimental/quic_server.cpp(378 LOC)tests/unit/quic_server_dispatcher_branch_test.cpp(744 LOC, 34 TEST_F)tests/support/quic_server_probe.[h|cpp]NETWORK_ENABLE_TEST_INJECTIONmacro defined PUBLIC onnetwork_systemwhenBUILD_TESTS=ON(cmake/network_system_targets.cmake)How
Coverage Targets per Private Surface
generate_session_id: counter increment,server_idprefix preservation, cross-instance independence, concurrent invocation uniquenesson_session_close: empty-map silent no-op branch, unknown-id silent no-op branch (find()==end short-circuit), populated-callback no-op when id is unknowncleanup_dead_sessions: empty-map fall-through (no log line emitted)start_receive: not-running early-return guardstart_cleanup_timer: not-running / null-timer early-return guardinvoke_*_callbackdispatchers: empty-function branch and populated-function branch for all five callback typeshandle_packet: empty data, zero-filled buffer (parse error), random bytes (parse error), repeated invalid packets, varied source endpointsstart_server(0)lifecyclemax_connections=0config round-trip lifecycleAcceptance Criteria
quic_server_probe_test: 2,quic_server_branch_test: 78,experimental_quic_server_test: 14)experimental/quic_server.cppTesting Done
Pre-existing test failures observed in
network_quic_socket_branch_test(4QuicSocketHermeticTransportTestcases) are unrelated to this PR — confirmed by reproducing them ondevelopHEAD before applying these changes.Pre-existing build errors in
examples/{tcp,udp}_echo*.cppare unrelated to this PR — also confirmed ondevelopHEAD.Closes #1123