aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/dirty_bif_SUITE.erl54
-rw-r--r--erts/emulator/test/nif_SUITE.erl37
-rw-r--r--erts/emulator/test/socket_SUITE.erl198
-rw-r--r--erts/emulator/test/socket_test_evaluator.erl101
4 files changed, 284 insertions, 106 deletions
diff --git a/erts/emulator/test/dirty_bif_SUITE.erl b/erts/emulator/test/dirty_bif_SUITE.erl
index 46eb0cba58..4f5ad0295a 100644
--- a/erts/emulator/test/dirty_bif_SUITE.erl
+++ b/erts/emulator/test/dirty_bif_SUITE.erl
@@ -38,7 +38,8 @@
dirty_process_info/1,
dirty_process_register/1,
dirty_process_trace/1,
- code_purge/1]).
+ code_purge/1,
+ otp_15688/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -64,7 +65,8 @@ all() ->
dirty_process_info,
dirty_process_register,
dirty_process_trace,
- code_purge].
+ code_purge,
+ otp_15688].
init_per_suite(Config) ->
case erlang:system_info(dirty_cpu_schedulers) of
@@ -498,10 +500,58 @@ code_purge(Config) when is_list(Config) ->
true = Time =< 1000,
ok.
+otp_15688(Config) when is_list(Config) ->
+ ImBack = make_ref(),
+ {See, SeeMon} = spawn_monitor(fun () ->
+ erts_debug:dirty_io(wait, 2000),
+ exit(ImBack)
+ end),
+ wait_until(fun () ->
+ [{current_function, {erts_debug, dirty_io, 2}},
+ {status, running}]
+ == process_info(See,
+ [current_function, status])
+ end),
+ {Ser1, Ser1Mon} = spawn_monitor(fun () ->
+ erlang:suspend_process(See,
+ [asynchronous])
+ end),
+ erlang:suspend_process(See, [asynchronous]),
+ receive {'DOWN', Ser1Mon, process, Ser1, normal} -> ok end,
+
+ %% Verify that we sent the suspend request while it was executing dirty...
+ [{current_function, {erts_debug, dirty_io, 2}},
+ {status, running}] = process_info(See, [current_function, status]),
+
+ wait_until(fun () ->
+ {status, suspended} == process_info(See, status)
+ end),
+ erlang:resume_process(See),
+
+ receive
+ {'DOWN', SeeMon, process, See, Reason} ->
+ ImBack = Reason
+ after 4000 ->
+ %% Resume bug seems to have hit us...
+ PI = process_info(See),
+ exit(See, kill),
+ ct:fail({suspendee_stuck, PI})
+ end.
+
+
%%
%% Internal...
%%
+wait_until(Fun) ->
+ case Fun() of
+ true ->
+ ok;
+ _ ->
+ receive after 100 -> ok end,
+ wait_until(Fun)
+ end.
+
access_dirty_process(Config, Start, Test, Finish) ->
{ok, Node} = start_node(Config, ""),
[ok] = mcall(Node,
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 119ccc71dc..b824daea67 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -1231,7 +1231,7 @@ maps(Config) when is_list(Config) ->
repeat_while(fun({35,_}) -> false;
({K,Map}) ->
Map = maps_from_list_nif(maps:to_list(Map)),
- Map = maps:filter(fun(K,V) -> V =:= K*100 end, Map),
+ Map = maps:filter(fun(K2,V) -> V =:= K2*100 end, Map),
{K+1, maps:put(K,K*100,Map)}
end,
{1,#{}}),
@@ -1302,24 +1302,29 @@ resource_hugo_do(Type) ->
release_resource(HugoPtr),
erlang:garbage_collect(),
{HugoPtr,HugoBin} = get_resource(Type,Hugo),
- Pid = spawn_link(fun() ->
- receive {Pid, Type, Resource, Ptr, Bin} ->
- Pid ! {self(), got_it},
- receive {Pid, check_it} ->
- {Ptr,Bin} = get_resource(Type,Resource),
- Pid ! {self(), ok}
- end
- end
- end),
+ {Pid,_} =
+ spawn_monitor(fun() ->
+ receive {Pid, Type, Resource, Ptr, Bin} ->
+ Pid ! {self(), got_it},
+ receive {Pid, check_it} ->
+ {Ptr,Bin} = get_resource(Type,Resource)
+ end
+ end,
+ gc_and_exit(ok)
+ end),
Pid ! {self(), Type, Hugo, HugoPtr, HugoBin},
{Pid, got_it} = receive_any(),
erlang:garbage_collect(), % just to make our ProcBin move in memory
Pid ! {self(), check_it},
- {Pid, ok} = receive_any(),
+ {'DOWN', _, process, Pid, ok} = receive_any(),
[] = last_resource_dtor_call(),
{HugoPtr,HugoBin} = get_resource(Type,Hugo),
{HugoPtr, HugoBin, 1}.
+gc_and_exit(Reason) ->
+ erlang:garbage_collect(),
+ exit(Reason).
+
resource_otto(Type) ->
{OttoPtr, OttoBin} = resource_otto_do(Type),
erlang:garbage_collect(),
@@ -1396,14 +1401,14 @@ resource_binary_do() ->
ResInfo = {Ptr,_} = get_resource(binary_resource_type,ResBin1),
Papa = self(),
- Forwarder = spawn_link(fun() -> forwarder(Papa) end),
+ {Forwarder,_} = spawn_monitor(fun() -> forwarder(Papa) end),
io:format("sending to forwarder pid=~p\n",[Forwarder]),
Forwarder ! ResBin1,
ResBin2 = receive_any(),
ResBin2 = ResBin1,
ResInfo = get_resource(binary_resource_type,ResBin2),
Forwarder ! terminate,
- {Forwarder, 1} = receive_any(),
+ {'DOWN', _, process, Forwarder, 1} = receive_any(),
erlang:garbage_collect(),
ResInfo = get_resource(binary_resource_type,ResBin1),
ResInfo = get_resource(binary_resource_type,ResBin2),
@@ -1924,11 +1929,11 @@ send2_do1(SendBlobF) ->
send2_do2(SendBlobF, self()),
Papa = self(),
- Forwarder = spawn_link(fun() -> forwarder(Papa) end),
+ {Forwarder,_} = spawn_monitor(fun() -> forwarder(Papa) end),
io:format("sending to forwarder pid=~p\n",[Forwarder]),
send2_do2(SendBlobF, Forwarder),
Forwarder ! terminate,
- {Forwarder, 4} = receive_any(),
+ {'DOWN', _, process, Forwarder, 4} = receive_any(),
ok.
send2_do2(SendBlobF, To) ->
@@ -1984,7 +1989,7 @@ forwarder(To) ->
forwarder(To, N) ->
case receive_any() of
terminate ->
- To ! {self(), N};
+ gc_and_exit(N);
Msg ->
To ! Msg,
forwarder(To, N+1)
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index aec280485c..2e3f40a350 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -3404,7 +3404,9 @@ api_to_connect_tcp4(suite) ->
api_to_connect_tcp4(doc) ->
[];
api_to_connect_tcp4(_Config) when is_list(_Config) ->
+ Cond = fun() -> api_to_connect_cond() end,
tc_try(api_to_connect_tcp4,
+ Cond,
fun() ->
?TT(?SECS(10)),
InitState = #{domain => inet,
@@ -3414,6 +3416,41 @@ api_to_connect_tcp4(_Config) when is_list(_Config) ->
ok = api_to_connect_tcp(InitState)
end).
+api_to_connect_cond() ->
+ api_to_connect_cond(os:type(), os:version()).
+
+%% I don't know exactly at which version this starts to work.
+%% I know it does not work for 4.4.*, but is does for 4.15.
+%% So, just to simplify, we require atleast 4.15
+api_to_connect_cond({unix, linux}, {Maj, Min, _Rev}) ->
+ if
+ ((Maj >= 4) andalso (Min >= 15)) ->
+ ok;
+ true ->
+ skip("TC does not work")
+ end;
+%% Only test on one machine, which has version 6.3, and there it does
+%% not work, so disable for all.
+api_to_connect_cond({unix, openbsd}, _) ->
+ skip("TC does not work");
+api_to_connect_cond({unix, freebsd}, {Maj, Min, _Rev}) ->
+ if
+ ((Maj >= 10) andalso (Min >= 4)) ->
+ ok;
+ true ->
+ skip("TC may not work")
+ end;
+api_to_connect_cond({unix, sunos}, {Maj, Min, _Rev}) ->
+ if
+ ((Maj >= 5) andalso (Min >= 10)) ->
+ ok;
+ true ->
+ skip("TC may not work")
+ end;
+api_to_connect_cond(_, _) ->
+ skip("TC may not work").
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -3425,8 +3462,8 @@ api_to_connect_tcp6(doc) ->
[];
api_to_connect_tcp6(_Config) when is_list(_Config) ->
tc_try(api_to_connect_tcp6,
+ fun() -> has_support_ipv6(), api_to_connect_cond() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
InitState = #{domain => inet6,
backlog => 1,
@@ -3937,8 +3974,8 @@ api_to_accept_tcp6(doc) ->
[];
api_to_accept_tcp6(_Config) when is_list(_Config) ->
tc_try(api_to_accept_tcp4,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
InitState = #{domain => inet6, timeout => 5000},
ok = api_to_accept_tcp(InitState)
@@ -4053,8 +4090,8 @@ api_to_maccept_tcp6(doc) ->
api_to_maccept_tcp6(_Config) when is_list(_Config) ->
?TT(?SECS(20)),
tc_try(api_to_maccept_tcp4,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
InitState = #{domain => inet6, timeout => 5000},
ok = api_to_maccept_tcp(InitState)
end).
@@ -4541,7 +4578,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).
@@ -4556,8 +4593,8 @@ api_to_recv_tcp6(doc) ->
[];
api_to_recv_tcp6(_Config) when is_list(_Config) ->
tc_try(api_to_recv_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
case socket:supports(ipv6) of
true ->
?TT(?SECS(10)),
@@ -4566,7 +4603,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 +4937,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).
@@ -4915,13 +4952,13 @@ api_to_recvfrom_udp6(doc) ->
[];
api_to_recvfrom_udp6(_Config) when is_list(_Config) ->
tc_try(api_to_recvfrom_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
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 +5021,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 +5053,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).
@@ -5030,13 +5068,13 @@ api_to_recvmsg_udp6(doc) ->
[];
api_to_recvmsg_udp6(_Config) when is_list(_Config) ->
tc_try(api_to_recvmsg_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
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 +5094,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).
@@ -5071,13 +5109,13 @@ api_to_recvmsg_tcp6(doc) ->
[];
api_to_recvmsg_tcp6(_Config) when is_list(_Config) ->
tc_try(api_to_recvmsg_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
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).
@@ -5103,7 +5141,6 @@ sc_cpe_socket_cleanup_tcp4(doc) ->
sc_cpe_socket_cleanup_tcp4(_Config) when is_list(_Config) ->
tc_try(sc_cpe_socket_cleanup_tcp4,
fun() ->
- %% not_yet_implemented(),
?TT(?SECS(5)),
InitState = #{domain => inet,
type => stream,
@@ -5123,8 +5160,8 @@ sc_cpe_socket_cleanup_tcp6(doc) ->
[];
sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_cpe_socket_cleanup_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(5)),
InitState = #{domain => inet6,
type => stream,
@@ -5165,8 +5202,8 @@ sc_cpe_socket_cleanup_udp6(doc) ->
[];
sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) ->
tc_try(sc_cpe_socket_cleanup_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(5)),
InitState = #{domain => inet6,
type => dgram,
@@ -5341,8 +5378,8 @@ sc_lc_recv_response_tcp6(doc) ->
[];
sc_lc_recv_response_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_lc_recv_response_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recv(Sock) end,
InitState = #{domain => inet6,
@@ -5957,8 +5994,8 @@ sc_lc_recvfrom_response_udp6(doc) ->
[];
sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) ->
tc_try(sc_lc_recvfrom_response_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(30)),
Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
InitState = #{domain => inet6,
@@ -6377,8 +6414,8 @@ sc_lc_recvmsg_response_tcp6(doc) ->
[];
sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_recvmsg_response_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet6,
@@ -6420,8 +6457,8 @@ sc_lc_recvmsg_response_udp6(doc) ->
[];
sc_lc_recvmsg_response_udp6(_Config) when is_list(_Config) ->
tc_try(sc_recvmsg_response_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet6,
@@ -6466,8 +6503,8 @@ sc_lc_acceptor_response_tcp6(doc) ->
[];
sc_lc_acceptor_response_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_lc_acceptor_response_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
InitState = #{domain => inet,
type => stream,
@@ -6901,8 +6938,8 @@ sc_rc_recv_response_tcp6(doc) ->
[];
sc_rc_recv_response_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_rc_recv_response_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recv(Sock) end,
InitState = #{domain => inet6,
@@ -7782,8 +7819,8 @@ sc_rc_recvmsg_response_tcp6(doc) ->
[];
sc_rc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_rc_recvmsg_response_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet6,
@@ -7842,8 +7879,8 @@ sc_rs_recv_send_shutdown_receive_tcp6(doc) ->
[];
sc_rs_recv_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_rs_recv_send_shutdown_receive_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
MsgData = ?DATA,
Recv = fun(Sock) ->
@@ -8666,8 +8703,8 @@ sc_rs_recvmsg_send_shutdown_receive_tcp6(doc) ->
[];
sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
tc_try(sc_rs_recvmsg_send_shutdown_receive_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(10)),
MsgData = ?DATA,
Recv = fun(Sock) ->
@@ -8727,8 +8764,8 @@ traffic_send_and_recv_chunks_tcp6(doc) ->
[];
traffic_send_and_recv_chunks_tcp6(_Config) when is_list(_Config) ->
tc_try(traffic_send_and_recv_chunks_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(30)),
InitState = #{domain => inet6},
ok = traffic_send_and_recv_chunks_tcp(InitState)
@@ -9729,8 +9766,8 @@ traffic_ping_pong_small_send_and_recv_tcp6(_Config) when is_list(_Config) ->
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_send_and_recv_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(15)),
InitState = #{domain => inet6,
msg => Msg,
@@ -9782,8 +9819,8 @@ traffic_ping_pong_medium_send_and_recv_tcp6(_Config) when is_list(_Config) ->
Msg = l2b(?TPP_MEDIUM),
Num = ?TPP_MEDIUM_NUM,
tc_try(traffic_ping_pong_medium_send_and_recv_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(30)),
InitState = #{domain => inet6,
msg => Msg,
@@ -9836,8 +9873,8 @@ traffic_ping_pong_large_send_and_recv_tcp6(_Config) when is_list(_Config) ->
Msg = l2b(?TPP_LARGE),
Num = ?TPP_LARGE_NUM,
tc_try(traffic_ping_pong_large_send_and_recv_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(45)),
InitState = #{domain => inet6,
msg => Msg,
@@ -9943,8 +9980,8 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_MEDIUM),
Num = ?TPP_MEDIUM_NUM,
tc_try(traffic_ping_pong_medium_sendto_and_recvfrom_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(45)),
InitState = #{domain => inet6,
msg => Msg,
@@ -9997,8 +10034,8 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(20)),
InitState = #{domain => inet6,
msg => Msg,
@@ -10050,8 +10087,8 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_MEDIUM),
Num = ?TPP_MEDIUM_NUM,
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(20)),
InitState = #{domain => ine6,
msg => Msg,
@@ -10103,8 +10140,8 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_LARGE),
Num = ?TPP_LARGE_NUM,
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(30)),
InitState = #{domain => inet6,
msg => Msg,
@@ -10157,8 +10194,8 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(20)),
InitState = #{domain => inet,
msg => Msg,
@@ -10210,8 +10247,8 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_MEDIUM),
Num = ?TPP_MEDIUM_NUM,
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- not_yet_implemented(),
?TT(?SECS(20)),
InitState = #{domain => ine6,
msg => Msg,
@@ -17171,17 +17208,17 @@ convert_time(TStrRev, Convert) ->
?TTEST_RUNTIME
end.
-ttest_tcp(TC,
- Domain,
- ServerMod, ServerActive,
- ClientMod, ClientActive,
- MsgID, MaxOutstanding) ->
- ttest_tcp(TC,
- ?TTEST_RUNTIME,
- Domain,
- ServerMod, ServerActive,
- ClientMod, ClientActive,
- MsgID, MaxOutstanding).
+%% ttest_tcp(TC,
+%% Domain,
+%% ServerMod, ServerActive,
+%% ClientMod, ClientActive,
+%% MsgID, MaxOutstanding) ->
+%% ttest_tcp(TC,
+%% ?TTEST_RUNTIME,
+%% Domain,
+%% ServerMod, ServerActive,
+%% ClientMod, ClientActive,
+%% MsgID, MaxOutstanding).
ttest_tcp(TC,
Runtime,
Domain,
@@ -17190,7 +17227,12 @@ ttest_tcp(TC,
MsgID, MaxOutstanding) ->
tc_try(TC,
fun() ->
- if (Domain =/= inet) -> not_yet_implemented(); true -> ok end,
+ if
+ (Domain =/= inet) -> has_support_ipv6();
+ true -> ok
+ end
+ end,
+ fun() ->
%% This may be overkill, depending on the runtime,
%% but better safe then sorry...
?TT(Runtime + ?SECS(60)),
@@ -17832,6 +17874,18 @@ which_addr2(Domain, [_|IFO]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Here are all the *general* test vase condition functions.
+
+%% The idea is that this function shall test if the test host has
+%% support for IPv6. If not there is no point in running IPv6 tests.
+%% Currently we just skip.
+has_support_ipv6() ->
+ not_yet_implemented().
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
not_yet_implemented() ->
skip("not yet implemented").
@@ -17885,15 +17939,45 @@ tc_end(Result) when is_list(Result) ->
"", "----------------------------------------------------~n~n"),
ok.
-
-tc_try(Case, Fun) when is_atom(Case) andalso is_function(Fun, 0) ->
+%% *** tc_try/2,3 ***
+%% Case: Basically the test case name
+%% TCCondFun: A fun that is evaluated before the actual test case
+%% The point of this is that it can performs checks to
+%% see if we shall run the test case at all.
+%% For instance, the test case may only work in specific
+%% conditions.
+%% FCFun: The test case fun
+tc_try(Case, TCFun) ->
+ TCCondFun = fun() -> ok end,
+ tc_try(Case, TCCondFun, TCFun).
+
+tc_try(Case, TCCondFun, TCFun)
+ when is_atom(Case) andalso
+ is_function(TCCondFun, 0) andalso
+ is_function(TCFun, 0) ->
tc_begin(Case),
- try
- begin
- Fun(),
- ?SLEEP(?SECS(1)),
- tc_end("ok")
- end
+ try TCCondFun() of
+ ok ->
+ try
+ begin
+ TCFun(),
+ ?SLEEP(?SECS(1)),
+ tc_end("ok")
+ end
+ catch
+ throw:{skip, _} = SKIP ->
+ tc_end("skipping"),
+ SKIP;
+ Class:Error:Stack ->
+ tc_end("failed"),
+ erlang:raise(Class, Error, Stack)
+ end;
+ {skip, _} = SKIP ->
+ tc_end("skipping"),
+ SKIP;
+ {error, Reason} ->
+ tc_end("failed"),
+ exit({tc_cond_failed, Reason})
catch
throw:{skip, _} = SKIP ->
tc_end("skipping"),
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