Skip to content

Commit edf676d

Browse files
authored
test(unit): add unit tests for 11 untested modules (#973)
* test(unit): add unit tests for 11 untested modules Add comprehensive unit tests for the following modules: Integration (5): - container_integration: basic_container, container_manager - io_context_thread_manager: singleton, run/stop io_context, metrics - logger_integration: basic_logger, log_level, logger_integration_manager - monitoring_integration: basic_monitoring, monitoring_integration_manager - thread_integration: basic_thread_pool, thread_integration_manager Protocol factories (4): - TCP: create_connection, create_listener, connect, listen - UDP: create_connection, create_listener, connect, listen - WebSocket: create_connection, create_listener, connect, listen - QUIC: quic_config, create_connection, create_listener, connect, listen HTTP/2 (1): - http2_server_stream: construction, accessors, send_headers, send_data, streaming response, reset, window management, error paths Internal (1): - websocket_socket: ws_state/ws_close_code enums, construction, initial state, callback registration Registered all tests in tests/CMakeLists.txt using add_network_test macro. Closes #968 * docs(tests): add changelog entry for unit tests on 11 untested modules Add entries to all three changelog files (root, docs/CHANGELOG.md, docs/CHANGELOG.kr.md) documenting the new unit tests added for integration bridges, protocol factories, HTTP/2, and internal websocket modules as part of the #953 coverage expansion effort. Relates to #968 * fix(test): replace deprecated asio::ip::address::from_string with make_address Use asio::ip::make_address() instead of the removed from_string() static method in websocket_socket_test.cpp. The from_string API was removed in standalone ASIO; make_address is the current replacement.
1 parent 3ad4118 commit edf676d

15 files changed

Lines changed: 2507 additions & 0 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Added
1515

1616
- 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))
17+
- Unit tests for 11 untested modules across 5 categories — part of the #953 coverage expansion effort ([#968](https://github.com/kcenon/network_system/issues/968))
18+
- Integration bridges (5): `container_integration`, `io_context_thread_manager`, `logger_integration`, `monitoring_integration`, `thread_integration`
19+
- Protocol factories (4): `tcp`, `udp`, `websocket`, `quic`
20+
- HTTP/2 (1): `http2_server_stream`
21+
- Internal (1): `websocket_socket`
1722

1823
### Changed
1924

docs/CHANGELOG.kr.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ Network System 프로젝트의 모든 주요 변경 사항이 이 파일에 문
8080
- NETWORK_SYSTEM_SANITIZER로 새니타이저 민감 테스트 일관되게 스킵
8181

8282
### 추가됨
83+
- **11개 미테스트 모듈에 대한 단위 테스트 (#968)**
84+
- 통합 브릿지 (5): `container_integration`, `io_context_thread_manager`, `logger_integration`, `monitoring_integration`, `thread_integration`
85+
- 프로토콜 팩토리 (4): `tcp`, `udp`, `websocket`, `quic`
86+
- HTTP/2 (1): `http2_server_stream`
87+
- 내부 (1): `websocket_socket`
88+
- 11개 테스트 타겟을 `tests/CMakeLists.txt`에 등록
89+
- 단위 테스트 커버리지 48%에서 80% 달성을 위한 #953 커버리지 확장 작업의 일환
8390
- **OpenTelemetry 호환 분산 트레이싱 (#408)**: 분산 관측성을 위한 핵심 트레이싱 인프라 추가
8491
- 트레이스 ID, 스팬 ID, 부모 관계 관리를 위한 `trace_context` 클래스
8592
- RAII 기반 생명주기, 속성, 이벤트, 상태를 가진 `span` 클래스

docs/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- Added dedicated unit tests for 4 unified adapters: `ws_connection_adapter`, `ws_listener_adapter`, `quic_connection_adapter`, `quic_listener_adapter` (68 tests total)
2929
- Registered new test targets in `tests/CMakeLists.txt`
3030
- Part of the #953 coverage expansion effort; complements #955 which covered the remaining 13 adapter modules
31+
- **Unit tests for 11 untested modules (#968)**
32+
- Integration bridges (5): `container_integration`, `io_context_thread_manager`, `logger_integration`, `monitoring_integration`, `thread_integration`
33+
- Protocol factories (4): `tcp`, `udp`, `websocket`, `quic`
34+
- HTTP/2 (1): `http2_server_stream`
35+
- Internal (1): `websocket_socket`
36+
- Registered all 11 test targets in `tests/CMakeLists.txt`
37+
- Part of the #953 coverage expansion effort targeting 48% to 80% unit test coverage
3138
- **Modernized Doxygen Documentation with doxygen-awesome-css (#927)**
3239
- Vendored doxygen-awesome-css theme with dark mode toggle, code copy buttons, and responsive sidebar
3340
- Added custom header (`docs/header.html`) and branding CSS (`docs/custom.css`)

tests/CMakeLists.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4607,6 +4607,41 @@ message(STATUS "Core messaging unit tests enabled (tcp, udp)")
46074607

46084608
# WebSocket tests already exist: test_messaging_ws_client.cpp, test_messaging_ws_server.cpp
46094609

4610+
##################################################
4611+
# Integration Module Unit Tests (Issue #968)
4612+
##################################################
4613+
4614+
add_network_test(network_thread_integration_test unit/thread_integration_test.cpp)
4615+
add_network_test(network_logger_integration_test unit/logger_integration_test.cpp)
4616+
add_network_test(network_monitoring_integration_test unit/monitoring_integration_test.cpp)
4617+
add_network_test(network_container_integration_test unit/container_integration_test.cpp)
4618+
add_network_test(network_io_context_thread_manager_test unit/io_context_thread_manager_test.cpp)
4619+
message(STATUS "Integration module unit tests enabled (Issue #968)")
4620+
4621+
##################################################
4622+
# Protocol Factory Unit Tests (Issue #968)
4623+
##################################################
4624+
4625+
add_network_test(network_protocol_tcp_factory_test unit/protocol_tcp_factory_test.cpp)
4626+
add_network_test(network_protocol_udp_factory_test unit/protocol_udp_factory_test.cpp)
4627+
add_network_test(network_protocol_websocket_factory_test unit/protocol_websocket_factory_test.cpp)
4628+
add_network_test(network_protocol_quic_factory_test unit/protocol_quic_factory_test.cpp)
4629+
message(STATUS "Protocol factory unit tests enabled (Issue #968)")
4630+
4631+
##################################################
4632+
# HTTP/2 Server Stream Unit Tests (Issue #968)
4633+
##################################################
4634+
4635+
add_network_test(network_http2_server_stream_test unit/http2_server_stream_test.cpp)
4636+
message(STATUS "HTTP/2 server stream unit tests enabled (Issue #968)")
4637+
4638+
##################################################
4639+
# WebSocket Socket Unit Tests (Issue #968)
4640+
##################################################
4641+
4642+
add_network_test(network_websocket_socket_test unit/websocket_socket_test.cpp)
4643+
message(STATUS "WebSocket socket unit tests enabled (Issue #968)")
4644+
46104645
##################################################
46114646
# Integration Tests
46124647
##################################################
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*****************************************************************************
2+
BSD 3-Clause License
3+
4+
Copyright (c) 2025, 🍀☀🌕🌥 🌊
5+
All rights reserved.
6+
*****************************************************************************/
7+
8+
#include "internal/integration/container_integration.h"
9+
#include <gtest/gtest.h>
10+
11+
#include <any>
12+
#include <functional>
13+
#include <string>
14+
#include <vector>
15+
16+
namespace integration = kcenon::network::integration;
17+
18+
/**
19+
* @file container_integration_test.cpp
20+
* @brief Unit tests for container_integration module
21+
*
22+
* Tests validate:
23+
* - basic_container construction
24+
* - basic_container type_name and is_valid
25+
* - basic_container serialize/deserialize with default behavior
26+
* - basic_container custom serializer/deserializer
27+
* - container_manager singleton access
28+
* - container_manager register/get containers
29+
* - container_manager default container
30+
* - container_manager serialize/deserialize through manager
31+
* - container_manager list_containers
32+
*/
33+
34+
// ============================================================================
35+
// basic_container Constructor Tests
36+
// ============================================================================
37+
38+
class BasicContainerConstructorTest : public ::testing::Test
39+
{
40+
};
41+
42+
TEST_F(BasicContainerConstructorTest, Construction)
43+
{
44+
integration::basic_container container;
45+
46+
EXPECT_FALSE(container.type_name().empty());
47+
}
48+
49+
TEST_F(BasicContainerConstructorTest, IsValid)
50+
{
51+
integration::basic_container container;
52+
53+
EXPECT_TRUE(container.is_valid());
54+
}
55+
56+
// ============================================================================
57+
// basic_container Operations Tests
58+
// ============================================================================
59+
60+
class BasicContainerOperationsTest : public ::testing::Test
61+
{
62+
protected:
63+
integration::basic_container container_;
64+
};
65+
66+
TEST_F(BasicContainerOperationsTest, TypeNameNotEmpty)
67+
{
68+
auto name = container_.type_name();
69+
70+
EXPECT_FALSE(name.empty());
71+
}
72+
73+
TEST_F(BasicContainerOperationsTest, SerializeReturnsData)
74+
{
75+
std::any data = std::string("test");
76+
77+
auto bytes = container_.serialize(data);
78+
79+
// Default serializer may return empty or actual data
80+
// Just verify it doesn't throw
81+
EXPECT_NO_THROW(container_.serialize(data));
82+
}
83+
84+
TEST_F(BasicContainerOperationsTest, DeserializeReturnsData)
85+
{
86+
std::vector<uint8_t> bytes = {0x01, 0x02, 0x03};
87+
88+
// Default deserializer may return empty any or actual data
89+
EXPECT_NO_THROW(container_.deserialize(bytes));
90+
}
91+
92+
TEST_F(BasicContainerOperationsTest, SetCustomSerializer)
93+
{
94+
bool serializer_called = false;
95+
96+
container_.set_serializer([&serializer_called](const std::any& data)
97+
-> std::vector<uint8_t> {
98+
serializer_called = true;
99+
return {0xDE, 0xAD};
100+
});
101+
102+
auto result = container_.serialize(std::any(42));
103+
104+
EXPECT_TRUE(serializer_called);
105+
EXPECT_EQ(result.size(), 2u);
106+
EXPECT_EQ(result[0], 0xDE);
107+
EXPECT_EQ(result[1], 0xAD);
108+
}
109+
110+
TEST_F(BasicContainerOperationsTest, SetCustomDeserializer)
111+
{
112+
bool deserializer_called = false;
113+
114+
container_.set_deserializer(
115+
[&deserializer_called](const std::vector<uint8_t>& bytes) -> std::any {
116+
deserializer_called = true;
117+
return std::string("deserialized");
118+
});
119+
120+
auto result = container_.deserialize({0x01, 0x02});
121+
122+
EXPECT_TRUE(deserializer_called);
123+
EXPECT_TRUE(result.has_value());
124+
EXPECT_EQ(std::any_cast<std::string>(result), "deserialized");
125+
}
126+
127+
// ============================================================================
128+
// container_manager Tests
129+
// ============================================================================
130+
131+
class ContainerManagerTest : public ::testing::Test
132+
{
133+
};
134+
135+
TEST_F(ContainerManagerTest, SingletonAccess)
136+
{
137+
auto& mgr1 = integration::container_manager::instance();
138+
auto& mgr2 = integration::container_manager::instance();
139+
140+
EXPECT_EQ(&mgr1, &mgr2);
141+
}
142+
143+
TEST_F(ContainerManagerTest, GetDefaultContainerNotNull)
144+
{
145+
auto& mgr = integration::container_manager::instance();
146+
147+
auto container = mgr.get_default_container();
148+
149+
EXPECT_NE(container, nullptr);
150+
}
151+
152+
TEST_F(ContainerManagerTest, RegisterAndGetContainer)
153+
{
154+
auto& mgr = integration::container_manager::instance();
155+
auto custom = std::make_shared<integration::basic_container>();
156+
157+
mgr.register_container("test-container", custom);
158+
159+
auto retrieved = mgr.get_container("test-container");
160+
EXPECT_NE(retrieved, nullptr);
161+
}
162+
163+
TEST_F(ContainerManagerTest, GetNonexistentContainerReturnsNull)
164+
{
165+
auto& mgr = integration::container_manager::instance();
166+
167+
auto retrieved = mgr.get_container("nonexistent-container-xyz");
168+
169+
EXPECT_EQ(retrieved, nullptr);
170+
}
171+
172+
TEST_F(ContainerManagerTest, SetDefaultContainer)
173+
{
174+
auto& mgr = integration::container_manager::instance();
175+
auto custom = std::make_shared<integration::basic_container>();
176+
177+
mgr.set_default_container(custom);
178+
179+
auto retrieved = mgr.get_default_container();
180+
EXPECT_NE(retrieved, nullptr);
181+
}
182+
183+
TEST_F(ContainerManagerTest, SerializeThroughManager)
184+
{
185+
auto& mgr = integration::container_manager::instance();
186+
187+
EXPECT_NO_THROW(mgr.serialize(std::any(std::string("data"))));
188+
}
189+
190+
TEST_F(ContainerManagerTest, DeserializeThroughManager)
191+
{
192+
auto& mgr = integration::container_manager::instance();
193+
194+
EXPECT_NO_THROW(mgr.deserialize({0x01, 0x02}));
195+
}
196+
197+
TEST_F(ContainerManagerTest, ListContainers)
198+
{
199+
auto& mgr = integration::container_manager::instance();
200+
mgr.register_container("list-test-container",
201+
std::make_shared<integration::basic_container>());
202+
203+
auto names = mgr.list_containers();
204+
205+
// Should contain at least the one we just registered
206+
bool found = false;
207+
for (const auto& name : names)
208+
{
209+
if (name == "list-test-container")
210+
{
211+
found = true;
212+
break;
213+
}
214+
}
215+
EXPECT_TRUE(found);
216+
}

0 commit comments

Comments
 (0)