Author: kotkov Date: Fri Apr 21 10:34:44 2023 New Revision: 1909311 URL: http://svn.apache.org/viewvc?rev=1909311&view=rev Log: On the '1.3.x' branch: When starting the test server, retry upon receiving a EADDRINUSE.
Some of the tests, such as the ones testing the SSL tunnels, can leave the source port we use for tests blocked due to a TIME_WAIT: tcp 0 0 localhost:12345 localhost:37920 TIME_WAIT Trying to bind a socket in such a state will result in EADDRINUSE. On trunk, this issue is solved by making the test server try other ports starting from the current one. But we cannot really do that on the 1.3.x branch, as that would require altering most of the tests that currently hardcode the port number. And we also cannot use APR_SO_REUSEADDR due to the problems listed in r1711233. So we use a retry loop, making some of the test runs longer -- but also solving the issue without having to change the tests on the stable branch. See r1758902, r1711233 and an example of a failed test run [1] for details. [1] https://github.com/apache/serf/actions/runs/4753565147/jobs/8445297350 * test/server/test_server.c (start_test_server): Retry upon receiving a EADDRINUSE when binding the socket. Modified: serf/branches/1.3.x/test/server/test_server.c Modified: serf/branches/1.3.x/test/server/test_server.c URL: http://svn.apache.org/viewvc/serf/branches/1.3.x/test/server/test_server.c?rev=1909311&r1=1909310&r2=1909311&view=diff ============================================================================== --- serf/branches/1.3.x/test/server/test_server.c (original) +++ serf/branches/1.3.x/test/server/test_server.c Fri Apr 21 10:34:44 2023 @@ -633,6 +633,7 @@ apr_status_t start_test_server(serv_ctx_ { apr_status_t status; apr_socket_t *serv_sock; + apr_time_t retry_end; /* create server socket */ #if APR_VERSION_AT_LEAST(1, 0, 0) @@ -651,9 +652,44 @@ apr_status_t start_test_server(serv_ctx_ apr_socket_opt_set(serv_sock, APR_SO_NONBLOCK, 1); apr_socket_timeout_set(serv_sock, 0); - status = apr_socket_bind(serv_sock, servctx->serv_addr); - if (status != APR_SUCCESS) - return status; + retry_end = apr_time_now() + apr_time_from_sec(120); + while (1) { + status = apr_socket_bind(serv_sock, servctx->serv_addr); + + /* Some of the tests, such as the ones testing the SSL tunnels, can + leave the source port we use for tests blocked due to a TIME_WAIT: + + tcp 0 0 localhost:12345 localhost:37920 TIME_WAIT + + Trying to bind a socket in such a state will result in EADDRINUSE. + On trunk, this issue is solved by making the test server try other + ports starting from the current one. But we cannot really do that + on the 1.3.x branch, as that would require altering most of the tests + that currently hardcode the port number. And we also cannot use + APR_SO_REUSEADDR due to the problems listed in r1711233. + + So we use a retry loop, making some of the test runs longer -- but + also solving the issue without having to change the tests on the + stable branch. + */ +#ifdef WIN32 + if (status == APR_FROM_OS_ERROR(WSAEADDRINUSE)) +#else + if (status == EADDRINUSE) +#endif + { + if (apr_time_now() > retry_end) + return status; + else + apr_sleep(apr_time_from_sec(1)); + } + else if (status != APR_SUCCESS) { + return status; + } + else { + break; + } + } /* listen for clients */ status = apr_socket_listen(serv_sock, SOMAXCONN);