@@ -44,9 +44,9 @@ using httpserver::http_response;
4444using httpserver::route_resolved_ctx;
4545using httpserver::webserver;
4646
47- #define PORT_DEFAULT 8211
48- #define PORT_CUSTOM 8212
49- #define PORT_ORDER 8213
47+ #define PORT_DEFAULT 8214
48+ #define PORT_CUSTOM 8215
49+ #define PORT_ORDER 8216
5050
5151namespace {
5252
@@ -72,6 +72,35 @@ CURLcode get_url(int port, const std::string& path,
7272 return rc;
7373}
7474
75+ // Poll the server until a TCP connection succeeds (or 2 s elapses).
76+ // Replaces the fixed sleep_for(50 ms) pattern: on a loaded CI host the server
77+ // may not be ready in 50 ms, causing CURLE_COULDNT_CONNECT and a spurious
78+ // test failure.
79+ //
80+ // Uses CURLOPT_CONNECT_ONLY so the poll sends no HTTP traffic — critical for
81+ // tests that count not-found-handler invocations: a probe /path would trigger
82+ // the handler before the real test request.
83+ void wait_for_server (int port) {
84+ using clock = std::chrono::steady_clock;
85+ auto deadline = clock::now () + std::chrono::seconds (2 );
86+ while (clock::now () < deadline) {
87+ CURL * curl = curl_easy_init ();
88+ if (curl == nullptr ) break ;
89+ std::string url =
90+ " http://127.0.0.1:" + std::to_string (port) + " /" ;
91+ curl_easy_setopt (curl, CURLOPT_URL , url.c_str ());
92+ curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT_MS , 100L );
93+ curl_easy_setopt (curl, CURLOPT_CONNECT_ONLY , 1L );
94+ CURLcode rc = curl_easy_perform (curl);
95+ curl_easy_cleanup (curl);
96+ // CURLE_OK means TCP connected; anything else except
97+ // CURLE_COULDNT_CONNECT is a different error (TLS, etc.) — still
98+ // counts as the TCP stack being up.
99+ if (rc != CURLE_COULDNT_CONNECT ) return ;
100+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
101+ }
102+ }
103+
75104} // namespace
76105
77106LT_BEGIN_SUITE (hooks_not_found_alias_suite)
@@ -87,7 +116,7 @@ LT_BEGIN_AUTO_TEST(hooks_not_found_alias_suite,
87116 not_found_alias_default_body_when_no_user_handler)
88117 webserver ws{create_webserver (PORT_DEFAULT )};
89118 ws.start(false );
90- std::this_thread::sleep_for (std::chrono::milliseconds( 50 ) );
119+ wait_for_server ( PORT_DEFAULT );
91120
92121 long code = 0 ; // NOLINT(runtime/int)
93122 std::string body;
@@ -116,7 +145,7 @@ LT_BEGIN_AUTO_TEST(hooks_not_found_alias_suite,
116145
117146 webserver ws{create_webserver (PORT_CUSTOM ).not_found_handler (user_not_found)};
118147 ws.start(false );
119- std::this_thread::sleep_for (std::chrono::milliseconds( 50 ) );
148+ wait_for_server ( PORT_CUSTOM );
120149
121150 long code = 0 ; // NOLINT(runtime/int)
122151 std::string body;
@@ -159,7 +188,7 @@ LT_BEGIN_AUTO_TEST(hooks_not_found_alias_suite,
159188 }));
160189
161190 ws.start(false );
162- std::this_thread::sleep_for (std::chrono::milliseconds( 50 ) );
191+ wait_for_server ( PORT_ORDER );
163192
164193 long code = 0 ; // NOLINT(runtime/int)
165194 std::string body;
0 commit comments