Commit b4ea9e3
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 #9531 parent 9ae1f2c commit b4ea9e3
2 files changed
Lines changed: 717 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2031 | 2031 | | |
2032 | 2032 | | |
2033 | 2033 | | |
| 2034 | + | |
2034 | 2035 | | |
2035 | 2036 | | |
2036 | 2037 | | |
| 2038 | + | |
| 2039 | + | |
2037 | 2040 | | |
2038 | 2041 | | |
2039 | 2042 | | |
| |||
0 commit comments