diff options
Diffstat (limited to 'erts/emulator/test/signal_SUITE.erl')
-rw-r--r-- | erts/emulator/test/signal_SUITE.erl | 417 |
1 files changed, 4 insertions, 413 deletions
diff --git a/erts/emulator/test/signal_SUITE.erl b/erts/emulator/test/signal_SUITE.erl index f1d11d1814..fab2f45f28 100644 --- a/erts/emulator/test/signal_SUITE.erl +++ b/erts/emulator/test/signal_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -34,23 +34,9 @@ -export([init_per_testcase/2, end_per_testcase/2]). % Test cases --export([xm_sig_order/1, - pending_exit_unlink_process/1, - pending_exit_unlink_dist_process/1, - pending_exit_unlink_port/1, - pending_exit_trap_exit/1, - pending_exit_receive/1, - pending_exit_exit/1, - pending_exit_gc/1, - pending_exit_is_process_alive/1, - pending_exit_process_display/1, - pending_exit_process_info_1/1, - pending_exit_process_info_2/1, - pending_exit_group_leader/1, - exit_before_pending_exit/1]). +-export([xm_sig_order/1]). init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> - available_internal_state(true), [{testcase, Func}|Config]. end_per_testcase(_Func, _Config) -> @@ -60,24 +46,14 @@ init_per_suite(Config) -> Config. end_per_suite(_Config) -> - available_internal_state(true), - catch erts_debug:set_internal_state(not_running_optimization, true), - available_internal_state(false). + ok. suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap, {minutes, 2}}]. all() -> - [xm_sig_order, pending_exit_unlink_process, - pending_exit_unlink_dist_process, - pending_exit_unlink_port, pending_exit_trap_exit, - pending_exit_receive, pending_exit_trap_exit, - pending_exit_gc, pending_exit_is_process_alive, - pending_exit_process_display, - pending_exit_process_info_1, - pending_exit_process_info_2, pending_exit_group_leader, - exit_before_pending_exit]. + [xm_sig_order]. %% Test that exit signals and messages are received in correct order @@ -113,367 +89,9 @@ xm_sig_order_proc() -> end, xm_sig_order_proc(). -pending_exit_unlink_process(Config) when is_list(Config) -> - pending_exit_test(self(), unlink). - -pending_exit_unlink_dist_process(Config) when is_list(Config) -> - {ok, Node} = start_node(Config), - From = spawn(Node, fun () -> receive after infinity -> ok end end), - Res = pending_exit_test(From, unlink), - stop_node(Node), - Res. - -pending_exit_unlink_port(Config) when is_list(Config) -> - pending_exit_test(hd(erlang:ports()), unlink). - -pending_exit_trap_exit(Config) when is_list(Config) -> - pending_exit_test(self(), trap_exit). - -pending_exit_receive(Config) when is_list(Config) -> - pending_exit_test(self(), 'receive'). - -pending_exit_exit(Config) when is_list(Config) -> - pending_exit_test(self(), exit). - -pending_exit_gc(Config) when is_list(Config) -> - pending_exit_test(self(), gc). - -pending_exit_test(From, Type) -> - case catch erlang:system_info(smp_support) of - true -> - OTE = process_flag(trap_exit, true), - Ref = make_ref(), - Master = self(), - ExitBySignal = case Type of - gc -> - lists:duplicate(10000, - exit_by_signal); - _ -> - exit_by_signal - end, - Pid = spawn_link( - fun () -> - receive go -> ok end, - false = have_pending_exit(), - exit = fake_exit(From, - self(), - ExitBySignal), - true = have_pending_exit(), - Master ! {self(), Ref, Type}, - case Type of - gc -> - force_gc(), - erlang:yield(); - unlink -> - unlink(From); - trap_exit -> - process_flag(trap_exit, true); - 'receive' -> - receive _ -> ok - after 0 -> ok - end; - exit -> - ok - end, - exit(exit_by_myself) - end), - Mon = erlang:monitor(process, Pid), - Pid ! go, - Reason = receive - {'DOWN', Mon, process, Pid, R} -> - receive - {Pid, Ref, Type} -> - ok - after 0 -> - ct:fail(premature_exit) - end, - case Type of - exit -> - exit_by_myself = R; - _ -> - ExitBySignal = R - end - end, - receive - {'EXIT', Pid, R2} -> - Reason = R2 - end, - process_flag(trap_exit, OTE), - ok, - {comment, "Test only valid with current SMP emulator."}; - _ -> - {skipped, "SMP support not enabled. Test only valid with current SMP emulator."} - end. - - - -exit_before_pending_exit(Config) when is_list(Config) -> - %% This is a testcase testcase very specific to the smp - %% implementation as it is of the time of writing. - %% - %% The testcase tries to check that a process can - %% exit by itself even though it has a pending exit. - OTE = process_flag(trap_exit, true), - Master = self(), - Tester = spawn_link( - fun () -> - Opts = case {erlang:system_info(run_queues), - erlang:system_info(schedulers_online)} of - {RQ, SO} when RQ =:= 1; SO =:= 1 -> []; - _ -> - process_flag(scheduler, 1), - [{scheduler, 2}] - end, - P = self(), - Exiter = spawn_opt(fun () -> - receive - {exit_me, P, R} -> - exit(P, R) - end - end, Opts), - erlang:yield(), - Exiter ! {exit_me, self(), exited_by_exiter}, - %% We want to get a pending exit - %% before we exit ourselves. We - %% don't want to be scheduled out - %% since we will then see the - %% pending exit. - %% - %% Do something that takes - %% relatively long time but - %% consumes few reductions... - repeat(fun() -> erlang:system_info(procs) end,10), - %% ... then exit. - Master ! {self(), - pending_exit, - have_pending_exit()}, - exit(exited_by_myself) - end), - PendingExit = receive {Tester, pending_exit, PE} -> PE end, - receive - {'EXIT', Tester, exited_by_myself} -> - process_flag(trap_exit, OTE), - ok; - Msg -> - ct:fail({unexpected_message, Msg}) - end, - NoScheds = integer_to_list(erlang:system_info(schedulers_online)), - {comment, - "Was " - ++ case PendingExit of - true -> ""; - false ->"*not*" - end ++ " able to trigger a pending exit. " - ++ "Running on " ++ NoScheds ++ " scheduler(s). " - ++ "This test is only interesting with at least two schedulers."}. - --define(PE_INFO_REPEAT, 100). - -pending_exit_is_process_alive(Config) when is_list(Config) -> - S = exit_op_test_init(), - TestFun = fun (P) -> false = is_process_alive(P) end, - repeated_exit_op_test(TestFun, ?PE_INFO_REPEAT), - verify_pending_exit_success(S), - comment(). - -pending_exit_process_info_1(Config) when is_list(Config) -> - S = exit_op_test_init(), - TestFun = fun (P) -> - undefined = process_info(P) - end, - repeated_exit_op_test(TestFun, ?PE_INFO_REPEAT), - verify_pending_exit_success(S), - comment(). - -pending_exit_process_info_2(Config) when is_list(Config) -> - S0 = exit_op_test_init(), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, messages) - end, ?PE_INFO_REPEAT), - S1 = verify_pending_exit_success(S0), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, status) - end, ?PE_INFO_REPEAT), - S2 = verify_pending_exit_success(S1), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, links) - end, ?PE_INFO_REPEAT), - S3 = verify_pending_exit_success(S2), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [messages]) - end, ?PE_INFO_REPEAT), - S4 = verify_pending_exit_success(S3), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [status]) - end, ?PE_INFO_REPEAT), - S5 = verify_pending_exit_success(S4), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [links]) - end, ?PE_INFO_REPEAT), - S6 = verify_pending_exit_success(S5), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [status, - links]) - end, ?PE_INFO_REPEAT), - S7 = verify_pending_exit_success(S6), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [messages, - status]) - end, ?PE_INFO_REPEAT), - S8 = verify_pending_exit_success(S7), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [messages, - links]) - end, ?PE_INFO_REPEAT), - S9 = verify_pending_exit_success(S8), - repeated_exit_op_test( - fun (P) -> - undefined = process_info(P, [message_queue_len, - status]) - end, ?PE_INFO_REPEAT), - S10 = verify_pending_exit_success(S9), - repeated_exit_op_test(fun (P) -> - undefined = process_info(P, [messages, - links, - status]) - end, ?PE_INFO_REPEAT), - verify_pending_exit_success(S10), - comment(). - -pending_exit_process_display(Config) when is_list(Config) -> - S = exit_op_test_init(), - TestFun = fun (P) -> - badarg = try - erlang:process_display(P, backtrace) - catch - error:badarg -> badarg - end - end, - repeated_exit_op_test(TestFun, ?PE_INFO_REPEAT), - verify_pending_exit_success(S), - comment(). - -pending_exit_group_leader(Config) when is_list(Config) -> - S = exit_op_test_init(), - TestFun = fun (P) -> - badarg = try - group_leader(self(), P) - catch - error:badarg -> badarg - end - end, - repeated_exit_op_test(TestFun, ?PE_INFO_REPEAT), - verify_pending_exit_success(S), - comment(). - %% %% -- Internal utils -------------------------------------------------------- %% -exit_op_test_init() -> - put(no_pending_exit_success, 0), - put(no_pending_exit_tries, 0), - {case {erlang:system_info(run_queues), - erlang:system_info(schedulers_online)} of - {RQ, SO} when RQ =:= 1; SO =:= 1 -> false; - _ -> true - end, 0, 0}. - -verify_pending_exit_success({false, _, _} = S) -> - S; -verify_pending_exit_success({true, S, T}) -> - NewS = get(no_pending_exit_success), - NewT = get(no_pending_exit_tries), - case NewT =:= T of - true -> ok; - _ -> case NewS > S of - true -> ok; - _ -> exit(no_pending_exits) - end - end, - {true, NewS, NewT}. - -comment() -> - {comment, - "Pending exit trigger ratio " - ++ integer_to_list(get(no_pending_exit_success)) - ++ "/" - ++ integer_to_list(get(no_pending_exit_tries)) - ++ "." - ++ case get(not_running_opt_test) of - true -> " No 'not running optimization' to disable."; - _ -> "" - end}. - -repeated_exit_op_test(TestFun, N) -> - WorkFun0 = fun () -> - lists:sort(lists:reverse(lists:seq(1, 1000))) - end, - repeat(fun () -> exit_op_test(TestFun, WorkFun0) end, N), - try erts_debug:set_internal_state(not_running_optimization, false) of - Bool when Bool == true; Bool == false -> - WorkFun1 = fun () -> - erts_debug:set_internal_state(sleep, 0), - lists:sort(lists:reverse(lists:seq(1, 1000))) - end, - repeat(fun () -> - exit_op_test(TestFun, WorkFun1) - end, N) - catch - error:notsup -> put(not_running_opt_test, true) - after - catch erts_debug:set_internal_state(not_running_optimization, true) - end. - -exit_op_test(TestFun, WorkFun) -> - Opts = case {erlang:system_info(run_queues), - erlang:system_info(schedulers_online)} of - {RQ, SO} when RQ =:= 1; SO =:= 1 -> []; - _ -> - process_flag(scheduler, 1), - [{scheduler, 2}] - end, - Master = self(), - Going = make_ref(), - P = spawn_opt(fun () -> - loop(10, WorkFun), - Master ! Going, - loop(infinity, WorkFun) - end, Opts), - receive Going -> ok end, - loop(10, WorkFun), - erlang:yield(), - exit(P, bang), - PE0 = have_pending_exit(P), - TestFun(P), - PE = case PE0 of - true -> true; - _ -> false - end, - case {PE, get(no_pending_exit_success), get(no_pending_exit_tries)} of - {true, undefined, undefined} -> - put(no_pending_exit_success, 1), - put(no_pending_exit_tries, 1); - {false, undefined, undefined} -> - put(no_pending_exit_success, 0), - put(no_pending_exit_tries, 1); - {true, S, T} -> - put(no_pending_exit_success, S+1), - put(no_pending_exit_tries, T+1); - {false, _S, T} -> - put(no_pending_exit_tries, T+1) - end, - ok. - -loop(infinity, WorkFun) -> - do_loop(infinity, WorkFun); -loop(0, _WorkFun) -> - ok; -loop(N, WorkFun) when is_integer(N) -> - do_loop(N-1, WorkFun). - -do_loop(N, WorkFun) -> - WorkFun(), - loop(N, WorkFun). repeat(_Fun, N) when is_integer(N), N =< 0 -> ok; @@ -491,30 +109,3 @@ start_node(Config) -> stop_node(Node) -> test_server:stop_node(Node). - -have_pending_exit() -> - have_pending_exit(self()). - -have_pending_exit(Pid) -> - erts_debug:get_internal_state({have_pending_exit, Pid}). - -force_gc() -> - erts_debug:set_internal_state(force_gc, self()). - -fake_exit(From, To, Reason) -> - erts_debug:set_internal_state(send_fake_exit_signal, {From, To, Reason}). - -available_internal_state(Bool) when Bool == true; Bool == false -> - case {Bool, - (catch erts_debug:get_internal_state(available_internal_state))} of - {true, true} -> - true; - {false, true} -> - erts_debug:set_internal_state(available_internal_state, false), - true; - {true, _} -> - erts_debug:set_internal_state(available_internal_state, true), - false; - {false, _} -> - false - end. |