aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2019-03-12 15:59:57 +0100
committerMicael Karlberg <[email protected]>2019-03-12 15:59:57 +0100
commitaf62db244589a1412443030090b9c9f9d8567990 (patch)
tree71a63c45dfffbe6d8ac59b72b8569da04f21fbc5 /erts
parent276880a0ba8e16e3f5c0682cd7c924cc9c281c08 (diff)
downloadotp-af62db244589a1412443030090b9c9f9d8567990.tar.gz
otp-af62db244589a1412443030090b9c9f9d8567990.tar.bz2
otp-af62db244589a1412443030090b9c9f9d8567990.zip
[socket|test] Make the evaluator processes linked
If a test case timed out, all processes created by it should die. But because the 'evaluator' processes where created with spawn_monitor, that was not the case, and therefor, these processes could linger.
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/test/socket_SUITE.erl17
-rw-r--r--erts/emulator/test/socket_test_evaluator.erl101
2 files changed, 79 insertions, 39 deletions
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index aec280485c..8a32efcd85 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -4541,7 +4541,7 @@ api_to_recv_tcp4(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recv(Sock, 0, To) end,
InitState = #{domain => inet,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_tcp(InitState)
end).
@@ -4566,7 +4566,7 @@ api_to_recv_tcp6(_Config) when is_list(_Config) ->
end,
InitState = #{domain => inet6,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_tcp(InitState);
false ->
skip("ipv6 not supported")
@@ -4900,7 +4900,7 @@ api_to_recvfrom_udp4(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recvfrom(Sock, 0, To) end,
InitState = #{domain => inet,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_udp(InitState)
end).
@@ -4921,7 +4921,7 @@ api_to_recvfrom_udp6(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recvfrom(Sock, 0, To) end,
InitState = #{domain => inet6,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_udp(InitState)
end).
@@ -4984,6 +4984,7 @@ api_to_receive_udp(InitState) ->
%% *** Termination ***
#{desc => "close socket",
cmd => fun(#{sock := Sock} = _State) ->
+ socket:setopt(Sock, otp, debug, true),
sock_close(Sock),
ok
end},
@@ -5015,7 +5016,7 @@ api_to_recvmsg_udp4(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_udp(InitState)
end).
@@ -5036,7 +5037,7 @@ api_to_recvmsg_udp6(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet6,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_udp(InitState)
end).
@@ -5056,7 +5057,7 @@ api_to_recvmsg_tcp4(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_tcp(InitState)
end).
@@ -5077,7 +5078,7 @@ api_to_recvmsg_tcp6(_Config) when is_list(_Config) ->
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet6,
recv => Recv,
- timeout => 5000},
+ timeout => 2000},
ok = api_to_receive_tcp(InitState)
end).
diff --git a/erts/emulator/test/socket_test_evaluator.erl b/erts/emulator/test/socket_test_evaluator.erl
index bd86b3b92e..c5748ac21b 100644
--- a/erts/emulator/test/socket_test_evaluator.erl
+++ b/erts/emulator/test/socket_test_evaluator.erl
@@ -104,8 +104,9 @@ start(Name, Seq, InitState)
erlang:error({already_used, parent});
error ->
InitState2 = InitState#{parent => self()},
- {Pid, MRef} = erlang:spawn_monitor(
- fun() -> init(Name, Seq, InitState2) end),
+ Pid = erlang:spawn_link(
+ fun() -> init(Name, Seq, InitState2) end),
+ MRef = erlang:monitor(process, Pid),
#ev{name = Name, pid = Pid, mref = MRef}
end.
@@ -149,55 +150,93 @@ loop(ID, [#{desc := Desc,
Evs :: [ev()].
await_finish(Evs) ->
- await_finish(Evs, []).
+ await_finish(Evs, [], []).
-await_finish([], []) ->
+await_finish([], _, []) ->
ok;
-await_finish([], Fails) ->
+await_finish([], _OK, Fails) ->
?SEV_EPRINT("Fails: "
"~n ~p", [Fails]),
Fails;
-await_finish(Evs, Fails) ->
+await_finish(Evs, OK, Fails) ->
receive
%% Successfull termination of evaluator
{'DOWN', _MRef, process, Pid, normal} ->
- case lists:keysearch(Pid, #ev.pid, Evs) of
- {value, #ev{name = Name}} ->
- iprint("evaluator '~s' (~p) success", [Name, Pid]),
- NewEvs = lists:keydelete(Pid, #ev.pid, Evs),
- await_finish(NewEvs, Fails);
- false ->
- iprint("unknown process ~p died (normal)", [Pid]),
- await_finish(Evs, Fails)
- end;
+ {Evs2, OK2, Fails2} = await_finish_normal(Pid, Evs, OK, Fails),
+ await_finish(Evs2, OK2, Fails2);
+ {'EXIT', Pid, normal} ->
+ {Evs2, OK2, Fails2} = await_finish_normal(Pid, Evs, OK, Fails),
+ await_finish(Evs2, OK2, Fails2);
%% The evaluator can skip the teat case:
{'DOWN', _MRef, process, Pid, {skip, Reason}} ->
- case lists:keysearch(Pid, #ev.pid, Evs) of
- {value, #ev{name = Name}} ->
- iprint("evaluator '~s' (~p) issued SKIP: "
- "~n ~p", [Name, Pid, Reason]);
+ await_finish_skip(Pid, Reason, Evs, OK);
+ {'EXIT', Pid, {skip, Reason}} ->
+ await_finish_skip(Pid, Reason, Evs, OK);
+
+ %% Evaluator failed
+ {'DOWN', _MRef, process, Pid, Reason} ->
+ {Evs2, OK2, Fails2} = await_finish_fail(Pid, Reason, Evs, OK, Fails),
+ await_finish(Evs2, OK2, Fails2);
+ {'EXIT', Pid, Reason} ->
+ {Evs2, OK2, Fails2} = await_finish_fail(Pid, Reason, Evs, OK, Fails),
+ await_finish(Evs2, OK2, Fails2)
+ end.
+
+
+await_finish_normal(Pid, Evs, OK, Fails) ->
+ case lists:keysearch(Pid, #ev.pid, Evs) of
+ {value, #ev{name = Name}} ->
+ iprint("evaluator '~s' (~p) success", [Name, Pid]),
+ NewEvs = lists:keydelete(Pid, #ev.pid, Evs),
+ {NewEvs, [Pid|OK], Fails};
+ false ->
+ case lists:member(Pid, OK) of
+ true ->
+ ok;
+ false ->
+ iprint("unknown process ~p died (normal)", [Pid]),
+ ok
+ end,
+ {Evs, OK, Fails}
+ end.
+
+await_finish_skip(Pid, Reason, Evs, OK) ->
+ case lists:keysearch(Pid, #ev.pid, Evs) of
+ {value, #ev{name = Name}} ->
+ iprint("evaluator '~s' (~p) issued SKIP: "
+ "~n ~p", [Name, Pid, Reason]);
+ false ->
+ case lists:member(Pid, OK) of
+ true ->
+ ok;
false ->
iprint("unknown process ~p issued SKIP: "
"~n ~p", [Pid, Reason])
- end,
- ?LIB:skip(Reason);
+ end
+ end,
+ ?LIB:skip(Reason).
- %% Evaluator failed
- {'DOWN', _MRef, process, Pid, Reason} ->
- case lists:keysearch(Pid, #ev.pid, Evs) of
- {value, #ev{name = Name}} ->
- iprint("evaluator '~s' (~p) failed", [Name, Pid]),
- NewEvs = lists:keydelete(Pid, #ev.pid, Evs),
- await_finish(NewEvs, [{Pid, Reason}|Fails]);
+
+await_finish_fail(Pid, Reason, Evs, OK, Fails) ->
+ case lists:keysearch(Pid, #ev.pid, Evs) of
+ {value, #ev{name = Name}} ->
+ iprint("evaluator '~s' (~p) failed", [Name, Pid]),
+ NewEvs = lists:keydelete(Pid, #ev.pid, Evs),
+ {NewEvs, OK, [{Pid, Reason}|Fails]};
+ false ->
+ case lists:member(Pid, OK) of
+ true ->
+ ok;
false ->
iprint("unknown process ~p died: "
- "~n ~p", [Pid, Reason]),
- await_finish(Evs, Fails)
- end
+ "~n ~p", [Pid, Reason])
+ end,
+ {Evs, OK, Fails}
end.
+
%% ============================================================================
-spec announce_start(To) -> ok when