diff options
Diffstat (limited to 'erts/emulator/test')
-rw-r--r-- | erts/emulator/test/dirty_bif_SUITE.erl | 54 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE.erl | 37 | ||||
-rw-r--r-- | erts/emulator/test/socket_SUITE.erl | 198 | ||||
-rw-r--r-- | erts/emulator/test/socket_test_evaluator.erl | 101 |
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 |