Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Unit tests for 4 unified adapter modules: `ws_connection`, `ws_listener`, `quic_connection`, `quic_listener` — part of the #953 coverage expansion effort ([#967](https://github.com/kcenon/network_system/issues/967))

### Changed

- Unify vcpkg manifest mode across all CI platforms (Linux, macOS, Windows) replacing per-platform manual ecosystem dependency builds ([#885](https://github.com/kcenon/network_system/issues/885))
Expand Down
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- **Unit tests for unified adapter modules (#967)**
- Added dedicated unit tests for 4 unified adapters: `ws_connection_adapter`, `ws_listener_adapter`, `quic_connection_adapter`, `quic_listener_adapter` (68 tests total)
- Registered new test targets in `tests/CMakeLists.txt`
- Part of the #953 coverage expansion effort; complements #955 which covered the remaining 13 adapter modules
- **Modernized Doxygen Documentation with doxygen-awesome-css (#927)**
- Vendored doxygen-awesome-css theme with dark mode toggle, code copy buttons, and responsive sidebar
- Added custom header (`docs/header.html`) and branding CSS (`docs/custom.css`)
Expand Down
76 changes: 76 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4044,6 +4044,82 @@ set_target_properties(network_udp_listener_adapter_test PROPERTIES
network_gtest_discover_tests(network_udp_listener_adapter_test DISCOVERY_TIMEOUT 60)
message(STATUS "UDP listener adapter tests enabled")

##################################################
# WebSocket Connection Adapter Tests (Issue #967)
##################################################

add_executable(network_ws_connection_adapter_test
unit/test_ws_connection_adapter.cpp
)
target_link_libraries(network_ws_connection_adapter_test PRIVATE
network_system GTest::gtest GTest::gtest_main Threads::Threads)
setup_asio_integration(network_ws_connection_adapter_test)
if(COMMON_SYSTEM_INCLUDE_DIR)
target_include_directories(network_ws_connection_adapter_test PRIVATE ${COMMON_SYSTEM_INCLUDE_DIR})
target_compile_definitions(network_ws_connection_adapter_test PRIVATE WITH_COMMON_SYSTEM)
endif()
set_target_properties(network_ws_connection_adapter_test PROPERTIES
CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
network_gtest_discover_tests(network_ws_connection_adapter_test DISCOVERY_TIMEOUT 60)
message(STATUS "WebSocket connection adapter tests enabled")

##################################################
# WebSocket Listener Adapter Tests (Issue #967)
##################################################

add_executable(network_ws_listener_adapter_test
unit/test_ws_listener_adapter.cpp
)
target_link_libraries(network_ws_listener_adapter_test PRIVATE
network_system GTest::gtest GTest::gtest_main Threads::Threads)
setup_asio_integration(network_ws_listener_adapter_test)
if(COMMON_SYSTEM_INCLUDE_DIR)
target_include_directories(network_ws_listener_adapter_test PRIVATE ${COMMON_SYSTEM_INCLUDE_DIR})
target_compile_definitions(network_ws_listener_adapter_test PRIVATE WITH_COMMON_SYSTEM)
endif()
set_target_properties(network_ws_listener_adapter_test PROPERTIES
CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
network_gtest_discover_tests(network_ws_listener_adapter_test DISCOVERY_TIMEOUT 60)
message(STATUS "WebSocket listener adapter tests enabled")

##################################################
# QUIC Connection Adapter Tests (Issue #967)
##################################################

add_executable(network_quic_connection_adapter_test
unit/test_quic_connection_adapter.cpp
)
target_link_libraries(network_quic_connection_adapter_test PRIVATE
network_system GTest::gtest GTest::gtest_main Threads::Threads)
setup_asio_integration(network_quic_connection_adapter_test)
if(COMMON_SYSTEM_INCLUDE_DIR)
target_include_directories(network_quic_connection_adapter_test PRIVATE ${COMMON_SYSTEM_INCLUDE_DIR})
target_compile_definitions(network_quic_connection_adapter_test PRIVATE WITH_COMMON_SYSTEM)
endif()
set_target_properties(network_quic_connection_adapter_test PROPERTIES
CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
network_gtest_discover_tests(network_quic_connection_adapter_test DISCOVERY_TIMEOUT 60)
message(STATUS "QUIC connection adapter tests enabled")

##################################################
# QUIC Listener Adapter Tests (Issue #967)
##################################################

add_executable(network_quic_listener_adapter_test
unit/test_quic_listener_adapter.cpp
)
target_link_libraries(network_quic_listener_adapter_test PRIVATE
network_system GTest::gtest GTest::gtest_main Threads::Threads)
setup_asio_integration(network_quic_listener_adapter_test)
if(COMMON_SYSTEM_INCLUDE_DIR)
target_include_directories(network_quic_listener_adapter_test PRIVATE ${COMMON_SYSTEM_INCLUDE_DIR})
target_compile_definitions(network_quic_listener_adapter_test PRIVATE WITH_COMMON_SYSTEM)
endif()
set_target_properties(network_quic_listener_adapter_test PROPERTIES
CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
network_gtest_discover_tests(network_quic_listener_adapter_test DISCOVERY_TIMEOUT 60)
message(STATUS "QUIC listener adapter tests enabled")

##################################################
# Sliding Histogram Tests (Issue #873)
##################################################
Expand Down
209 changes: 209 additions & 0 deletions tests/unit/test_quic_connection_adapter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*****************************************************************************
BSD 3-Clause License

Copyright (c) 2025, 🍀☀🌕🌥 🌊
All rights reserved.
*****************************************************************************/

/**
* @file test_quic_connection_adapter.cpp
* @brief Unit tests for unified QUIC connection adapter (i_connection bridge)
*
* Tests validate:
* - Construction with quic_config and explicit connection ID
* - id() accessor returns constructor value
* - Initial state (not connected, not connecting)
* - Callback, options, timeout registration
* - Close idempotency before connect
* - Shutdown safety (destructor does not deadlock nor leak resources)
*
* Note: Live connect()/send() require UDP socket binding and a running QUIC
* server. Those paths are covered by integration tests.
*/

#include "internal/unified/adapters/quic_connection_adapter.h"

#include <gtest/gtest.h>

#include <chrono>
#include <string>

namespace kcenon::network::unified::adapters {
namespace {

namespace quic_ns = kcenon::network::protocol::quic;

// ============================================================================
// Helpers
// ============================================================================

quic_ns::quic_config make_default_config() {
quic_ns::quic_config cfg;
cfg.server_name = "example.com";
cfg.alpn_protocols = {"h3"};
return cfg;
}

// ============================================================================
// Construction Tests
// ============================================================================

TEST(QuicConnectionAdapterTest, ConstructWithExplicitId) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-quic-conn");
SUCCEED();
}

TEST(QuicConnectionAdapterTest, ConstructWithEmptyId) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "");
SUCCEED();
}

TEST(QuicConnectionAdapterTest, ConstructWithDefaultConfig) {
quic_ns::quic_config cfg;
quic_connection_adapter adapter(cfg, "test-conn");
SUCCEED();
}

TEST(QuicConnectionAdapterTest, IdReturnsConstructorValue) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "my-quic-connection");
EXPECT_EQ(adapter.id(), "my-quic-connection");
}

TEST(QuicConnectionAdapterTest, ConstructWithInsecureConfig) {
quic_ns::quic_config cfg;
cfg.server_name = "localhost";
cfg.insecure_skip_verify = true;
quic_connection_adapter adapter(cfg, "test-conn");
SUCCEED();
}

TEST(QuicConnectionAdapterTest, ConstructWithCustomStreamLimits) {
quic_ns::quic_config cfg;
cfg.server_name = "example.com";
cfg.max_bidi_streams = 50;
cfg.max_uni_streams = 50;
quic_connection_adapter adapter(cfg, "test-conn");
SUCCEED();
}

// ============================================================================
// Initial State Tests
// ============================================================================

TEST(QuicConnectionAdapterTest, IsNotConnectedBeforeConnect) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
EXPECT_FALSE(adapter.is_connected());
}

TEST(QuicConnectionAdapterTest, IsNotConnectingBeforeConnect) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
EXPECT_FALSE(adapter.is_connecting());
}

// ============================================================================
// Configuration Tests
// ============================================================================

TEST(QuicConnectionAdapterTest, SetCallbacks) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
connection_callbacks cbs;
cbs.on_connected = []() {};
cbs.on_disconnected = []() {};
cbs.on_data = [](std::span<const std::byte>) {};
cbs.on_error = [](std::error_code) {};
adapter.set_callbacks(std::move(cbs));
SUCCEED();
}

TEST(QuicConnectionAdapterTest, SetOptions) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
connection_options opts;
adapter.set_options(std::move(opts));
SUCCEED();
}

TEST(QuicConnectionAdapterTest, SetTimeout) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
adapter.set_timeout(std::chrono::seconds(30));
SUCCEED();
}

TEST(QuicConnectionAdapterTest, SetTimeoutMultipleTimes) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
adapter.set_timeout(std::chrono::seconds(5));
adapter.set_timeout(std::chrono::milliseconds(500));
adapter.set_timeout(std::chrono::minutes(1));
SUCCEED();
}

// ============================================================================
// Shutdown Safety Tests
// ============================================================================

TEST(QuicConnectionAdapterTest, CloseBeforeConnectIsIdempotent) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
adapter.close();
EXPECT_FALSE(adapter.is_connected());
}

TEST(QuicConnectionAdapterTest, MultipleCloseCallsAreHarmless) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
adapter.close();
adapter.close();
adapter.close();
EXPECT_FALSE(adapter.is_connected());
}

TEST(QuicConnectionAdapterTest, DestructorDoesNotDeadlock) {
{
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
connection_callbacks cbs;
cbs.on_connected = []() {};
adapter.set_callbacks(std::move(cbs));
}
SUCCEED();
}

TEST(QuicConnectionAdapterTest, RapidCreationAndDestruction) {
for (int i = 0; i < 10; ++i) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "conn-" + std::to_string(i));
EXPECT_FALSE(adapter.is_connected());
}
SUCCEED();
}

// ============================================================================
// Full Configuration Tests
// ============================================================================

TEST(QuicConnectionAdapterTest, ConfigureAllSettingsBeforeConnect) {
auto cfg = make_default_config();
quic_connection_adapter adapter(cfg, "test-conn");
adapter.set_timeout(std::chrono::seconds(30));
connection_options opts;
adapter.set_options(std::move(opts));
connection_callbacks cbs;
cbs.on_connected = []() {};
cbs.on_disconnected = []() {};
cbs.on_data = [](std::span<const std::byte>) {};
cbs.on_error = [](std::error_code) {};
adapter.set_callbacks(std::move(cbs));
EXPECT_FALSE(adapter.is_connected());
EXPECT_FALSE(adapter.is_connecting());
}

} // namespace
} // namespace kcenon::network::unified::adapters
Loading
Loading