Skip to content

Commit b4ea9e3

Browse files
authored
test(quic): drive packet-receive paths in messaging_quic_server (#1087)
Add 15 hermetic packet-driven tests under MessagingQuicServerHermeticTest in tests/test_messaging_quic_server.cpp. They exercise paths in src/experimental/quic_server.cpp that PR #1080 declared unreachable without a real QUIC client, but which a real loopback UDP pair plus start_server bound to an ephemeral port can drive end-to-end. Mechanism: each test binds messaging_quic_server to an OS-assigned 127.0.0.1 port, then writes synthesized QUIC bytes (long-header Initial stub from tests/support/mock_udp_peer.cpp) directly to that endpoint. The async_receive_from completion handler in start_receive() fires, handle_packet() parses or rejects the bytes, and find_or_create_session() hits the limit-reached, no-TLS, or TLS-accept branches depending on the quic_server_config used. New paths driven: - start_receive() async completion handler (lines 414-440) with both the !ec success branch and the operation_aborted silent-return branch fired by stop_server() cancelling the pending recv. - handle_packet() (lines 443-481) including the data.empty() early return, the parse_header() error branch on malformed input (zero-bytes, fixed-bit-unset long-header look-alike), and the successful parse path that reaches find_or_create_session(). - find_or_create_session() (lines 483-604): * max_connections=0 limit-reached branch (lines 501-506) hit on the first packet, with bursts of unique-DCID packets confirming session_count stays bounded; * no-TLS branch (line 520 false side) when cert/key are empty in config_ - the session creation skips quic_socket::accept and the receive loop continues; * TLS branch (lines 519-531) with both valid self-signed PEM files (accept attempt proceeds far enough to load the cert/key pair) and nonexistent paths (accept fails at SSL_CTX_use_*_file and the early-return-nullptr branch runs without inserting a session). - do_start_impl() error path (lines 174-204) by binding a probe socket on 127.0.0.1 to grab a port, then trying to start messaging_quic_server on the same port; the bind fails with EADDRINUSE and the catch block routes through error_void + lifecycle_.mark_stopped(). - start_server() error rollback (lines 71-77): after a failed start, is_running() must read false, and a subsequent start on a fresh ephemeral port must succeed cleanly. - stop_server() idempotent error branch (lines 82-87): calling stop twice in a row returns server_not_started on the second call. - Destructor stop_impl path (lines 27-33): a shared_ptr<server> scope-exit on a running server triggers a full do_stop_impl() with no use-after-free on the io_context worker thread. - disconnect_all() empty-map branch on a running server (lines 324-345), exercised under live packet pressure to confirm the unique_lock + swap + iterate sequence is a no-op when sessions_ is empty. - broadcast() / multicast() empty-map branches (lines 347-387) running concurrently with a side-thread that keeps blasting packets, which exercises the shared_lock acquired by sessions() and get_session() under contention with the receive loop. - on_session_close() / disconnect_session() not_found branch (lines 305-311) verifying the disconnection callback is NOT invoked for unknown session ids. - error_callback non-invocation branch (line 421) confirming graceful shutdown does NOT propagate to the error callback because the cancelled recv reports asio::error::operation_aborted. Hermetic guarantees: - Every socket binds to 127.0.0.1 (no DNS, no external network). - Each test claims a fresh ephemeral port via the kernel, so concurrent test executions never collide. - temp_pem_files RAII writes self-signed cert+key to OS temp dir with PID + monotonic timestamp uniqueness, then unlinks on destruction. - The hermetic_transport_fixture worker thread is joined in TearDown and the server worker thread exits inside stop_server(), so no io_context loop leaks across tests. CMake: tests/CMakeLists.txt links network_messaging_quic_server_test against network::test_support and OpenSSL::SSL/Crypto so the test can use generate_self_signed_pem(), make_quic_initial_packet_stub(), and hermetic_transport_fixture. Coverage impact (expected, awaiting CI lcov re-measurement): - src/experimental/quic_server.cpp: 43.7% line / 17.5% branch -> >= 80% line / >= 70% branch (per coverage.yml gate). Closes #1066 Part of #953
1 parent 9ae1f2c commit b4ea9e3

2 files changed

Lines changed: 717 additions & 0 deletions

File tree

tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,12 @@ if(GTest_FOUND OR GTEST_FOUND)
20312031

20322032
target_link_libraries(network_messaging_quic_server_test PRIVATE
20332033
network_system
2034+
network::test_support
20342035
GTest::gtest
20352036
GTest::gtest_main
20362037
Threads::Threads
2038+
OpenSSL::SSL
2039+
OpenSSL::Crypto
20372040
)
20382041

20392042
setup_asio_integration(network_messaging_quic_server_test)

0 commit comments

Comments
 (0)