@@ -33,13 +33,26 @@ struct StringMaker<KDNetwork::IpAddress> {
3333};
3434} // namespace doctest
3535
36+ namespace {
3637// Environment variable to control whether to run network tests
3738// Set KDUTILS_RUN_NETWORK_TESTS=1 to enable tests with real network requests
3839bool shouldRunNetworkTests ()
3940{
41+ #if defined(_WIN32)
42+ char *env = nullptr ;
43+ size_t len = 0 ;
44+ const errno_t err = _dupenv_s (&env, &len, " KDUTILS_RUN_NETWORK_TESTS" );
45+ const bool result = (err == 0 && env != nullptr && std::string (env) == " 1" );
46+ if (env) {
47+ free (env);
48+ }
49+ return result;
50+ #else
4051 const char *env = std::getenv (" KDUTILS_RUN_NETWORK_TESTS" );
4152 return env != nullptr && std::string (env) == " 1" ;
53+ #endif
4254}
55+ } // namespace
4356
4457using namespace KDFoundation ;
4558using namespace KDNetwork ;
@@ -54,34 +67,44 @@ class MockDnsResolver : public DnsResolver
5467 bool publicInitializeAres () { return initializeAres (); }
5568
5669 // Mock functions to simulate c-ares behavior without actual network calls
57- bool mockLookup (const std::string &hostname, LookupCallback callback)
70+ bool mockLookup (const std::string &hostname, const LookupCallback & callback)
5871 {
5972 if (m_failNextLookup) {
6073 return false ;
6174 }
6275
6376 if (m_simulateDelayedResponse) {
6477 // Schedule a future response
78+ // Disable the bugprone-exception-escape clang-tidy check here. It seems to be a bug in clang-tidy
79+ // as we catch all exceptions in the thread.
80+ // NOLINTBEGIN(bugprone-exception-escape)
6581 std::thread ([this , hostname, callback]() {
66- std::this_thread::sleep_for (std::chrono::milliseconds (50 ));
67-
68- std::error_code ec;
69- AddressInfoList addresses;
70-
71- if (m_simulateError) {
72- ec = std::error_code (1 , std::generic_category ());
73- } else {
74- if (hostname == " localhost" || hostname == " 127.0.0.1" ) {
75- addresses.push_back (IpAddress{ " 127.0.0.1" });
76- } else if (hostname == " example.com" ) {
77- addresses.push_back (IpAddress{ " 93.184.216.34" });
82+ try {
83+ std::this_thread::sleep_for (std::chrono::milliseconds (50 ));
84+
85+ std::error_code ec;
86+ AddressInfoList addresses;
87+
88+ if (m_simulateError) {
89+ ec = std::error_code (1 , std::generic_category ());
7890 } else {
79- addresses.push_back (IpAddress{ " 192.168.1.1" });
91+ if (hostname == " localhost" || hostname == " 127.0.0.1" ) {
92+ addresses.push_back (IpAddress{ " 127.0.0.1" });
93+ } else if (hostname == " example.com" ) {
94+ addresses.push_back (IpAddress{ " 93.184.216.34" });
95+ } else {
96+ addresses.push_back (IpAddress{ " 192.168.1.1" });
97+ }
8098 }
81- }
8299
83- callback (ec, addresses);
100+ callback (ec, addresses);
101+ } catch (const std::exception &e) {
102+ std::cerr << " Exception in mockLookup thread: " << e.what () << std::endl;
103+ } catch (...) {
104+ std::cerr << " Unknown exception in mockLookup thread." << std::endl;
105+ }
84106 }).detach ();
107+ // NOLINTEND(bugprone-exception-escape)
85108
86109 return true ;
87110 }
@@ -127,16 +150,16 @@ TEST_CASE("DNS Resolver Basic Tests")
127150{
128151 SUBCASE (" Can create a DnsResolver" )
129152 {
130- CoreApplication app;
131- DnsResolver resolver;
153+ const CoreApplication app;
154+ const DnsResolver resolver;
132155
133156 // The resolver should be created successfully without any errors
134157 CHECK_MESSAGE (true , " DnsResolver was created successfully" );
135158 }
136159
137160 SUBCASE (" Mock initialization test" )
138161 {
139- CoreApplication app;
162+ const CoreApplication app;
140163 MockDnsResolver resolver;
141164
142165 // Test the initialization of the c-ares library
@@ -146,7 +169,7 @@ TEST_CASE("DNS Resolver Basic Tests")
146169
147170TEST_CASE (" DNS Resolution Tests with Mock" )
148171{
149- CoreApplication app;
172+ const CoreApplication app;
150173
151174 SUBCASE (" Successful synchronous lookup" )
152175 {
@@ -158,7 +181,7 @@ TEST_CASE("DNS Resolution Tests with Mock")
158181
159182 // Perform a lookup that will complete immediately
160183 bool result = resolver.mockLookup (" example.com" , [&promise](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
161- bool success = !ec && !addresses.empty ();
184+ const bool success = !ec && !addresses.empty ();
162185 promise.set_value (success);
163186 });
164187
@@ -171,7 +194,7 @@ TEST_CASE("DNS Resolution Tests with Mock")
171194 MockDnsResolver resolver;
172195 resolver.setFailNextLookup (true );
173196
174- bool result = resolver.mockLookup (" example.com" , [](std::error_code ec , const DnsResolver::AddressInfoList &addresses) {
197+ bool result = resolver.mockLookup (" example.com" , [](std::error_code /* ec */ , const DnsResolver::AddressInfoList & /* addresses*/ ) {
175198 // This callback should not be called
176199 REQUIRE (false );
177200 });
@@ -187,8 +210,8 @@ TEST_CASE("DNS Resolution Tests with Mock")
187210 std::promise<bool > promise;
188211 std::future<bool > future = promise.get_future ();
189212
190- bool result = resolver.mockLookup (" example.com" , [&promise](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
191- bool hasError = ec.value () != 0 ;
213+ bool result = resolver.mockLookup (" example.com" , [&promise](std::error_code ec, const DnsResolver::AddressInfoList & /* addresses*/ ) {
214+ const bool hasError = ec.value () != 0 ;
192215 promise.set_value (hasError);
193216 });
194217
@@ -205,7 +228,7 @@ TEST_CASE("DNS Resolution Tests with Mock")
205228 std::future<bool > future = promise.get_future ();
206229
207230 bool result = resolver.mockLookup (" example.com" , [&promise](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
208- bool success = !ec && !addresses.empty ();
231+ const bool success = !ec && !addresses.empty ();
209232 promise.set_value (success);
210233 });
211234
@@ -227,12 +250,12 @@ TEST_CASE("DNS Resolution Tests with Mock")
227250 std::future<bool > future2 = promise2.get_future ();
228251
229252 bool result1 = resolver.mockLookup (" example.com" , [&promise1](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
230- bool success = !ec && !addresses.empty ();
253+ const bool success = !ec && !addresses.empty ();
231254 promise1.set_value (success);
232255 });
233256
234257 bool result2 = resolver.mockLookup (" localhost" , [&promise2](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
235- bool success = !ec && !addresses.empty ();
258+ const bool success = !ec && !addresses.empty ();
236259 promise2.set_value (success);
237260 });
238261
@@ -255,7 +278,7 @@ TEST_CASE("DNS Resolver Callback Context Tests")
255278 // This test case specifically tests our main fix: passing both DnsResolver* and requestId
256279 // as context to the c-ares callback
257280
258- CoreApplication app;
281+ const CoreApplication app;
259282
260283 SUBCASE (" Mock CallbackContext usage" )
261284 {
@@ -271,11 +294,11 @@ TEST_CASE("DNS Resolver Callback Context Tests")
271294 resolver1.setSimulateDelayedResponse (true );
272295 resolver2.setSimulateDelayedResponse (true );
273296
274- resolver1.mockLookup (" example.com" , [&promise1](std::error_code ec , const DnsResolver::AddressInfoList &addresses) {
297+ resolver1.mockLookup (" example.com" , [&promise1](std::error_code /* ec */ , const DnsResolver::AddressInfoList & /* addresses*/ ) {
275298 promise1.set_value (1 ); // Resolver 1 callback
276299 });
277300
278- resolver2.mockLookup (" example.com" , [&promise2](std::error_code ec , const DnsResolver::AddressInfoList &addresses) {
301+ resolver2.mockLookup (" example.com" , [&promise2](std::error_code /* ec */ , const DnsResolver::AddressInfoList & /* addresses*/ ) {
279302 promise2.set_value (2 ); // Resolver 2 callback
280303 });
281304
@@ -287,7 +310,7 @@ TEST_CASE("DNS Resolver Callback Context Tests")
287310
288311TEST_CASE (" DNS Resolver Error Handling" )
289312{
290- CoreApplication app;
313+ const CoreApplication app;
291314
292315 SUBCASE (" Handling network errors" )
293316 {
@@ -341,7 +364,7 @@ TEST_CASE("DNS Resolver Real Network Tests")
341364 bool lookupStarted = false ;
342365
343366 lookupStarted = resolver.lookup (" example.com" , [&promise, &app](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
344- bool success = !ec && !addresses.empty ();
367+ const bool success = !ec && !addresses.empty ();
345368
346369 if (success) {
347370 // Let's check if we have valid addresses
@@ -411,9 +434,9 @@ TEST_CASE("DNS Resolver Real Network Tests")
411434 std::promise<bool > promise;
412435 std::future<bool > future = promise.get_future ();
413436
414- resolver.lookup (" non-existent-domain-kdutils-test.local" , [&promise, &app](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
437+ resolver.lookup (" non-existent-domain-kdutils-test.local" , [&promise, &app](std::error_code ec, const DnsResolver::AddressInfoList & /* addresses*/ ) {
415438 // This should fail with an error
416- bool hasError = ec.value () != 0 ;
439+ const bool hasError = ec.value () != 0 ;
417440 MESSAGE (" Non-existent domain lookup error: " << ec.message ());
418441 promise.set_value (hasError);
419442
@@ -439,7 +462,7 @@ TEST_CASE("DNS Resolver Real Network Tests")
439462 std::future<bool > future2 = promise2.get_future ();
440463
441464 resolver.lookup (" example.com" , [&promise1, &future2, &app](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
442- bool success = !ec && !addresses.empty ();
465+ const bool success = !ec && !addresses.empty ();
443466 promise1.set_value (success);
444467
445468 // Quit the application event loop if future2 is also ready
@@ -449,7 +472,7 @@ TEST_CASE("DNS Resolver Real Network Tests")
449472 });
450473
451474 resolver.lookup (" github.com" , [&promise2, &future1, &app](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
452- bool success = !ec && !addresses.empty ();
475+ const bool success = !ec && !addresses.empty ();
453476 promise2.set_value (success);
454477
455478 // Quit the application event loop if future1 is also ready
@@ -481,7 +504,7 @@ TEST_CASE("DNS Resolver Real Network Tests")
481504
482505 resolver.lookup (" example.org" , [&](std::error_code ec, const DnsResolver::AddressInfoList &addresses) {
483506 // This should be called from the event loop
484- bool success = !ec && !addresses.empty ();
507+ const bool success = !ec && !addresses.empty ();
485508 if (success) {
486509 MESSAGE (" Successfully resolved example.org" );
487510 for (const auto &address : addresses) {
@@ -521,7 +544,7 @@ TEST_CASE("DNS Resolver Real Network Tests")
521544 DnsResolver resolver;
522545 std::atomic<bool > callbackCalled (false );
523546
524- resolver.lookup (" example.net" , [&callbackCalled](std::error_code ec , const DnsResolver::AddressInfoList &addresses) {
547+ resolver.lookup (" example.net" , [&callbackCalled](std::error_code /* ec */ , const DnsResolver::AddressInfoList & /* addresses*/ ) {
525548 // This callback might or might not be called depending on timing
526549 // If called after cancel, it should have an error
527550 callbackCalled = true ;
0 commit comments