Skip to content

Commit 02d955b

Browse files
committed
Merge pull request #2023 from pguyot/w49/fix-test_gen_server-flappiness-case
Fix flappiness case of `test_gen_server:test_timeout_info/0` These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 6ef7459 + 0d8ee10 commit 02d955b

File tree

1 file changed

+27
-29
lines changed

1 file changed

+27
-29
lines changed

tests/libs/estdlib/test_gen_server.erl

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,17 @@ test_start_name() ->
119119
ok = gen_server:stop(Pid1),
120120
undefined = whereis(?MODULE),
121121

122+
PreviousTrapExit = erlang:process_flag(trap_exit, true),
122123
{ok, Pid2} = gen_server:start_link({local, ?MODULE}, ?MODULE, [], []),
123124
Pid2 = whereis(?MODULE),
124125
ok = gen_server:stop(Pid2),
126+
normal =
127+
receive
128+
{'EXIT', Pid2, Reason} -> Reason
129+
after 5000 -> timeout
130+
end,
125131
undefined = whereis(?MODULE),
132+
true = erlang:process_flag(trap_exit, PreviousTrapExit),
126133

127134
case get_otp_version() of
128135
%% Test on AtomVM and OTP 23 and later
@@ -330,32 +337,21 @@ test_timeout_cast() ->
330337
test_timeout_info() ->
331338
{ok, Pid} = gen_server:start(?MODULE, [], []),
332339
0 = gen_server:call(Pid, get_num_timeouts),
333-
ok = gen_server:cast(Pid, {set_info_timeout, 10}),
334-
timer:sleep(11),
335-
0 = gen_server:call(Pid, get_num_timeouts),
340+
Ref = make_ref(),
341+
ok = gen_server:cast(Pid, {set_info_timeout, 10, self(), Ref}),
336342
Pid ! ping,
337-
timer:sleep(11),
338-
N = gen_server:call(Pid, get_num_timeouts),
339-
true = N > 0,
340-
ok = test_timeout_info_repeats(Pid, 30),
343+
ok =
344+
receive
345+
{Ref, 1} -> ok
346+
after 5000 -> timeout
347+
end,
348+
ok =
349+
receive
350+
{Ref, 2} -> ok
351+
after 5000 -> timeout
352+
end,
341353
gen_server:stop(Pid).
342354

343-
% timeout message itself is repeated as it is a handle_info message.
344-
% This test is flappy as there is no guarantee that Pid would be
345-
% scheduled if the system is very busy.
346-
test_timeout_info_repeats(_Pid, Sleep) when Sleep > 5000 -> fail;
347-
test_timeout_info_repeats(Pid, Sleep) ->
348-
N = gen_server:call(Pid, get_num_timeouts),
349-
Pid ! ping,
350-
timer:sleep(Sleep),
351-
M = gen_server:call(Pid, get_num_timeouts),
352-
if
353-
M > N + 1 ->
354-
ok;
355-
true ->
356-
test_timeout_info_repeats(Pid, 2 * Sleep)
357-
end.
358-
359355
test_timeout_tuple_return() ->
360356
case get_otp_version() of
361357
%% Test on AtomVM and OTP 28 and later
@@ -665,8 +661,8 @@ handle_cast({cast_timeout, Timeout}, State) ->
665661
{noreply, State, Timeout};
666662
handle_cast({tuple_timeout, Timeouts, Caller}, State) ->
667663
{noreply, State, {timeout, 1, {do_tuple_timeouts, Timeouts, Caller}}};
668-
handle_cast({set_info_timeout, Timeout}, State) ->
669-
{noreply, State#state{info_timeout = Timeout}};
664+
handle_cast({set_info_timeout, Timeout, Client, Ref}, State) ->
665+
{noreply, State#state{info_timeout = {Timeout, Client, Ref, 0}}};
670666
handle_cast({req_timeout_reply, Pid}, State) ->
671667
{noreply, State, {timeout, 1, {timeout_reply, Pid, cast}}};
672668
handle_cast({request_info_timeout, Pid}, State) ->
@@ -690,16 +686,18 @@ handle_info(ping, #state{num_infos = NumInfos, info_timeout = InfoTimeout} = Sta
690686
case InfoTimeout of
691687
none ->
692688
{noreply, NewState};
693-
Other ->
694-
{noreply, NewState, Other}
689+
{Timeout, _Client, _Ref, _Count} ->
690+
{noreply, NewState, Timeout}
695691
end;
696692
handle_info(timeout, #state{num_timeouts = NumTimeouts, info_timeout = InfoTimeout} = State) ->
697693
NewState = State#state{num_timeouts = NumTimeouts + 1},
698694
case InfoTimeout of
699695
none ->
700696
{noreply, NewState};
701-
Other ->
702-
{noreply, NewState, Other}
697+
{Timeout, Client, Ref, Count} ->
698+
NewCount = Count + 1,
699+
Client ! {Ref, NewCount},
700+
{noreply, NewState#state{info_timeout = {Timeout, Client, Ref, NewCount}}, Timeout}
703701
end;
704702
handle_info({timeout_reply, From, Tag} = _Info, State) ->
705703
From ! {reply_from_timeout, Tag},

0 commit comments

Comments
 (0)