Skip to content

Commit 2d26784

Browse files
committed
Retry fixture listens on eaddrinuse
Even with stop/0 waiting on the DOWN signal, ERTS releases the dead fixture's ports asynchronously, so the next start/0 can still hit eaddrinuse when it rebinds immediately. Retry the listens briefly instead.
1 parent cc52a6f commit 2d26784

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

test/buoy_http_server.erl

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ init(Parent) ->
5151
register(?MODULE, self()),
5252
persistent_term:put({?MODULE, connections}, counters:new(1, [])),
5353
{ok, _} = application:ensure_all_started(ssl),
54-
{ok, LSocket} = gen_tcp:listen(?PORT, ?LISTEN_OPTIONS),
54+
{ok, LSocket} = listen(gen_tcp, ?PORT, ?LISTEN_OPTIONS),
5555
%% the default pkix_test_data key (secp112r2, sha1) is not
5656
%% negotiable by a modern TLS client
5757
KeyOpts = [{key, {namedCurve, secp256r1}}, {digest, sha256}],
5858
SslOptions = public_key:pkix_test_data(#{root => KeyOpts,
5959
peer => KeyOpts}),
60-
{ok, LSocketSsl} = ssl:listen(?PORT_SSL,
60+
{ok, LSocketSsl} = listen(ssl, ?PORT_SSL,
6161
?LISTEN_OPTIONS ++ SslOptions),
6262
spawn_link(fun () -> accept_ssl(LSocketSsl) end),
6363
Parent ! {self(), started},
@@ -67,6 +67,22 @@ init(Parent) ->
6767
Parent ! {self(), {error, {Class, Error, Stacktrace}}}
6868
end.
6969

70+
%% the previous fixture's ports can linger briefly after its death:
71+
%% ERTS releases them asynchronously once the DOWN signal fires
72+
listen(Transport, Port, Options) ->
73+
listen(Transport, Port, Options, 50).
74+
75+
listen(Transport, Port, Options, Retries) ->
76+
case Transport:listen(Port, Options) of
77+
{ok, LSocket} ->
78+
{ok, LSocket};
79+
{error, eaddrinuse} when Retries > 0 ->
80+
timer:sleep(10),
81+
listen(Transport, Port, Options, Retries - 1);
82+
{error, _} = E ->
83+
E
84+
end.
85+
7086
accept(LSocket) ->
7187
{ok, Socket} = gen_tcp:accept(LSocket),
7288
counters:add(persistent_term:get({?MODULE, connections}), 1, 1),

0 commit comments

Comments
 (0)