diff options
Diffstat (limited to 'lib/stdlib/test')
| -rw-r--r-- | lib/stdlib/test/io_SUITE.erl | 24 | ||||
| -rw-r--r-- | lib/stdlib/test/supervisor_SUITE.erl | 52 | ||||
| -rw-r--r-- | lib/stdlib/test/supervisor_deadlock.erl | 14 | ||||
| -rw-r--r-- | lib/stdlib/test/win32reg_SUITE.erl | 49 |
4 files changed, 107 insertions, 32 deletions
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl index 0e897631ff..bb1ed2a4fc 100644 --- a/lib/stdlib/test/io_SUITE.erl +++ b/lib/stdlib/test/io_SUITE.erl @@ -2125,12 +2125,24 @@ rpc_call_max(Node, M, F, Args) -> %% Make sure that a bad specification for a printable range is rejected. bad_printable_range(Config) when is_list(Config) -> Cmd = lists:concat([lib:progname()," +pcunnnnnicode -run erlang halt"]), - case os:cmd(Cmd) of - "bad range of printable characters" ++ _ -> - ok; - String -> - io:format("~s\n", [String]), - ?t:fail() + P = open_port({spawn, Cmd}, [stderr_to_stdout, {line, 200}]), + ok = receive + {P, {data, {eol , "bad range of printable characters" ++ _}}} -> + ok; + Other -> + Other + after 1000 -> + timeout + end, + catch port_close(P), + flush_from_port(P), + ok. + +flush_from_port(P) -> + receive {P, _} -> + flush_from_port(P) + after 0 -> + ok end. io_lib_print_binary_depth_one(doc) -> diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl index 8cb2a5194a..903ca76575 100644 --- a/lib/stdlib/test/supervisor_SUITE.erl +++ b/lib/stdlib/test/supervisor_SUITE.erl @@ -67,6 +67,7 @@ %% Misc tests -export([child_unlink/1, tree/1, count_children/1, + count_restarting_children/1, do_not_save_start_parameters_for_temporary_children/1, do_not_save_child_specs_for_temporary_children/1, simple_one_for_one_scale_many_temporary_children/1, @@ -90,7 +91,8 @@ all() -> {group, normal_termination}, {group, shutdown_termination}, {group, abnormal_termination}, child_unlink, tree, - count_children, do_not_save_start_parameters_for_temporary_children, + count_children, count_restarting_children, + do_not_save_start_parameters_for_temporary_children, do_not_save_child_specs_for_temporary_children, simple_one_for_one_scale_many_temporary_children, temporary_bystander, simple_global_supervisor, hanging_restart_loop, hanging_restart_loop_simple, @@ -1459,6 +1461,54 @@ count_children(Config) when is_list(Config) -> [1,0,0,0] = get_child_counts(sup_test). %%------------------------------------------------------------------------- +%% Test count_children when some children are restarting +count_restarting_children(Config) when is_list(Config) -> + process_flag(trap_exit, true), + Child = {child, {supervisor_deadlock, start_child_noreg, []}, + permanent, brutal_kill, worker, []}, + %% 2 sek delay on failing restart (see supervisor_deadlock.erl) -> + %% MaxR=20, MaxT=10 should ensure a restart loop when starting and + %% restarting 3 instances of the child (as below) + {ok, SupPid} = start_link({ok, {{simple_one_for_one, 20, 10}, [Child]}}), + + %% Ets table with state read by supervisor_deadlock.erl + ets:new(supervisor_deadlock,[set,named_table,public]), + ets:insert(supervisor_deadlock,{fail_start,false}), + + [1,0,0,0] = get_child_counts(SupPid), + {ok, Ch1_1} = supervisor:start_child(SupPid, []), + [1,1,0,1] = get_child_counts(SupPid), + {ok, Ch1_2} = supervisor:start_child(SupPid, []), + [1,2,0,2] = get_child_counts(SupPid), + {ok, Ch1_3} = supervisor:start_child(SupPid, []), + [1,3,0,3] = get_child_counts(SupPid), + + supervisor_deadlock:restart_child(Ch1_1), + supervisor_deadlock:restart_child(Ch1_2), + supervisor_deadlock:restart_child(Ch1_3), + test_server:sleep(400), + [1,3,0,3] = get_child_counts(SupPid), + [Ch2_1, Ch2_2, Ch2_3] = [C || {_,C,_,_} <- supervisor:which_children(SupPid)], + + ets:insert(supervisor_deadlock,{fail_start,true}), + supervisor_deadlock:restart_child(Ch2_1), + supervisor_deadlock:restart_child(Ch2_2), + test_server:sleep(4000), % allow restart to happen before proceeding + [1,1,0,3] = get_child_counts(SupPid), + + ets:insert(supervisor_deadlock,{fail_start,false}), + test_server:sleep(4000), % allow restart to happen before proceeding + [1,3,0,3] = get_child_counts(SupPid), + + ok = supervisor:terminate_child(SupPid, Ch2_3), + [1,2,0,2] = get_child_counts(SupPid), + [Ch3_1, Ch3_2] = [C || {_,C,_,_} <- supervisor:which_children(SupPid)], + ok = supervisor:terminate_child(SupPid, Ch3_1), + [1,1,0,1] = get_child_counts(SupPid), + ok = supervisor:terminate_child(SupPid, Ch3_2), + [1,0,0,0] = get_child_counts(SupPid). + +%%------------------------------------------------------------------------- %% Temporary children shall not be restarted so they should not save %% start parameters, as it potentially can take up a huge amount of %% memory for no purpose. diff --git a/lib/stdlib/test/supervisor_deadlock.erl b/lib/stdlib/test/supervisor_deadlock.erl index 288547a972..8d3d1c6f30 100644 --- a/lib/stdlib/test/supervisor_deadlock.erl +++ b/lib/stdlib/test/supervisor_deadlock.erl @@ -11,9 +11,11 @@ init([child]) -> %% terminates immediately {ok, []}; [{fail_start, true}] -> - %% Restart frequency is MaxR=8, MaxT=10, so this will - %% ensure that restart intensity is not reached -> restart - %% loop + %% A restart frequency of MaxR=8, MaxT=10 should ensure + %% that restart intensity is not reached -> restart loop. + %% (Note that if we use simple_one_for_one, and start + %% 'many' child instances, the restart frequency must be + %% ajusted accordingly.) timer:sleep(2000), % NOTE: this could be a gen_server call timeout {stop, error} @@ -41,5 +43,11 @@ code_change(_OldVsn, State, _Extra) -> start_child() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [child], []). +start_child_noreg() -> + gen_server:start_link(?MODULE, [child], []). + restart_child() -> gen_server:cast(supervisor_deadlock, restart). + +restart_child(Pid) -> + gen_server:cast(Pid, restart). diff --git a/lib/stdlib/test/win32reg_SUITE.erl b/lib/stdlib/test/win32reg_SUITE.erl index 82baa43318..6d27ac6387 100644 --- a/lib/stdlib/test/win32reg_SUITE.erl +++ b/lib/stdlib/test/win32reg_SUITE.erl @@ -49,48 +49,53 @@ init_per_suite(Config) when is_list(Config) -> end_per_suite(Config) when is_list(Config) -> Config. + long(doc) -> "Test long keys and entries (OTP-3446)."; long(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), + Dog = test_server:timetrap(test_server:seconds(10)), - ?line LongKey = "software\\" ++ + LongKey = "software\\" ++ lists:flatten(lists:duplicate(10, "..\\software\\")) ++ "Ericsson\\Erlang", - ?line {ok,Reg} = win32reg:open([read,write]), - ?line ok = win32reg:change_key(Reg, "\\hklm"), - ?line ok = win32reg:change_key(Reg, LongKey), - ?line {ok,ErlangKey} = win32reg:current_key(Reg), - io:format("Erlang key: ~s", [ErlangKey]), + {ok,Read} = win32reg:open([read]), + ok = win32reg:change_key(Read, "\\hklm"), + + ok = win32reg:change_key(Read, LongKey), + {ok,ErlangKey} = win32reg:current_key(Read), + io:format("Erlang key: ~s~n", [ErlangKey]), + ok = win32reg:close(Read), + {ok,Reg} = win32reg:open([read, write]), %% Write a long value and read it back. - ?line TestKey = "test_key", - ?line LongValue = lists:concat(["This is a long value generated by the test case ",?MODULE,":long/1. "|lists:duplicate(128, "a")]), - ?line ok = win32reg:set_value(Reg, TestKey, LongValue), - ?line {ok,LongValue} = win32reg:value(Reg, TestKey), + TestKey = "test_key", + LongValue = lists:concat(["This is a long value generated by the test case ",?MODULE,":long/1. "|lists:duplicate(128, "a")]), + ok = win32reg:set_value(Reg, TestKey, LongValue), + {ok,LongValue} = win32reg:value(Reg, TestKey), + io:format("Where ~p Key ~s Value ~s ~n", [win32reg:current_key(Reg), TestKey, LongValue]), %% Done. - ?line ok = win32reg:close(Reg), - ?line test_server:timetrap_cancel(Dog), + ok = win32reg:close(Reg), + test_server:timetrap_cancel(Dog), ok. evil_write(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), + Dog = test_server:timetrap(test_server:seconds(10)), - ?line Key = "Software\\Ericsson\\Erlang", - ?line {ok,Reg} = win32reg:open([read,write]), - ?line ok = win32reg:change_key(Reg, "\\hklm"), - ?line ok = win32reg:change_key(Reg, Key), - ?line {ok,ErlangKey} = win32reg:current_key(Reg), + Key = "Software\\Ericsson\\Erlang", + {ok,Reg} = win32reg:open([read,write]), + ok = win32reg:change_key(Reg, "\\hkcu"), + ok = win32reg:change_key_create(Reg, Key), + {ok,ErlangKey} = win32reg:current_key(Reg), io:format("Erlang key: ~s", [ErlangKey]), %% Write keys with different length and read it back. - ?line TestKey = "test_key " ++ lists:duplicate(128, $a), + TestKey = "test_key " ++ lists:duplicate(128, $a), evil_write_1(Reg, TestKey), %% Done. - ?line ok = win32reg:close(Reg), - ?line test_server:timetrap_cancel(Dog), + ok = win32reg:close(Reg), + test_server:timetrap_cancel(Dog), ok. evil_write_1(Reg, [_|[_|_]=Key]=Key0) -> |
