summaryrefslogtreecommitdiff
path: root/lib/stdlib
diff options
context:
space:
mode:
authorRaimo Niskanen <raimo@erlang.org>2023-02-15 11:01:12 +0100
committerRaimo Niskanen <raimo@erlang.org>2023-02-15 12:25:23 +0100
commit193cda6958ce2c94eba670ca7372c83625b7fc58 (patch)
tree621432330ba8a02d73c1e1ad624df72d7b2a1c16 /lib/stdlib
parent2b397d7e5580480dc32fa9751db95f4b89ff029e (diff)
downloaderlang-193cda6958ce2c94eba670ca7372c83625b7fc58.tar.gz
Test looping over gen_server init failure
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl65
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl60
2 files changed, 121 insertions, 4 deletions
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index dc0ee98b01..618deffc9d 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -26,7 +26,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([start/1, crash/1, call/1, send_request/1,
+-export([start/1, crash/1, loop_start_fail/1, call/1, send_request/1,
send_request_receive_reqid_collection/1,
send_request_wait_reqid_collection/1,
send_request_check_reqid_collection/1,
@@ -84,7 +84,7 @@ suite() ->
{timetrap,{minutes,1}}].
all() ->
- [start, {group,stop}, crash, call, send_request,
+ [start, {group,stop}, crash, loop_start_fail, call, send_request,
send_request_receive_reqid_collection, send_request_wait_reqid_collection,
send_request_check_reqid_collection, cast, cast_fast, info, abcast,
continue,
@@ -518,6 +518,55 @@ crash(Config) when is_list(Config) ->
ok.
+
+loop_start_fail(Config) ->
+ _ = process_flag(trap_exit, true),
+ loop_start_fail(
+ Config,
+ [{start, []}, {start, [link]},
+ {start_link, []},
+ {start_monitor, [link]}, {start_monitor, []}]).
+
+loop_start_fail(_Config, []) ->
+ ok;
+loop_start_fail(Config, [{Start, Opts} | Start_Opts]) ->
+ loop_start_fail(
+ fun gen_server:Start/3,
+ {ets, {return, {stop, failed_to_start}}}, Opts,
+ fun ({error, failed_to_start}) -> ok end),
+ loop_start_fail(
+ fun gen_server:Start/3,
+ {ets, {return, ignore}}, Opts,
+ fun (ignore) -> ok end),
+ loop_start_fail(
+ fun gen_server:Start/3,
+ {ets, {return, 4711}}, Opts,
+ fun ({error, {bad_return_value, 4711}}) -> ok end),
+ loop_start_fail(
+ fun gen_server:Start/3,
+ {ets, {crash, error, bailout}}, Opts,
+ fun ({error, {bailout, ST}}) when is_list(ST) -> ok end),
+ loop_start_fail(
+ fun gen_server:Start/3,
+ {ets, {crash, exit, bailout}}, Opts,
+ fun ({error, bailout}) -> ok end),
+ loop_start_fail(
+ fun gen_server:Start/3,
+ {ets, {wait, 1000, void}}, [{timeout, 200} | Opts],
+ fun ({error, timeout}) -> ok end),
+ loop_start_fail(Config, Start_Opts).
+
+loop_start_fail(GenStartFun, Arg, Opts, ValidateFun) ->
+ loop_start_fail(GenStartFun, Arg, Opts, ValidateFun, 5).
+%%
+loop_start_fail(_GenStartFun, _Arg, _Opts, _ValidateFun, 0) ->
+ ok;
+loop_start_fail(GenStartFun, Arg, Opts, ValidateFun, N) ->
+ ok = ValidateFun(GenStartFun(?MODULE, Arg, Opts)),
+ loop_start_fail(GenStartFun, Arg, Opts, ValidateFun, N - 1).
+
+
+
%% --------------------------------------
%% Test gen_server:call and handle_call.
%% Test all different return values from
@@ -2782,7 +2831,17 @@ init({continue, Pid}) ->
{ok, [], {continue, {message, Pid}}};
init({state,State}) ->
io:format("init(state) -> ~p~n", [State]),
- {ok,State}.
+ {ok,State};
+init({ets,InitResult}) ->
+ ?MODULE = ets:new(?MODULE, [named_table]),
+ case InitResult of
+ {return, Value} ->
+ Value;
+ {crash, Class, Reason} ->
+ erlang:Class(Reason);
+ {wait, Time, Value} ->
+ receive after Time -> Value end
+ end.
handle_call(started_p, _From, State) ->
io:format("FROZ"),
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index 8f18c42dc1..6bff254b0b 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -37,7 +37,7 @@ all() ->
{group, stop_handle_event},
{group, abnormal},
{group, abnormal_handle_event},
- shutdown, stop_and_reply, state_enter, event_order,
+ shutdown, loop_start_fail, stop_and_reply, state_enter, event_order,
state_timeout, timeout_cancel_and_update,
event_types, generic_timers, code_change,
{group, sys},
@@ -686,6 +686,53 @@ shutdown(Config) ->
end.
+loop_start_fail(Config) ->
+ _ = process_flag(trap_exit, true),
+ loop_start_fail(
+ Config,
+ [{start, []}, {start, [link]},
+ {start_link, []},
+ {start_monitor, [link]}, {start_monitor, []}]).
+
+loop_start_fail(_Config, []) ->
+ ok;
+loop_start_fail(Config, [{Start, Opts} | Start_Opts]) ->
+ loop_start_fail(
+ fun gen_statem:Start/3,
+ {ets, {return, {stop, failed_to_start}}}, Opts,
+ fun ({error, failed_to_start}) -> ok end),
+ loop_start_fail(
+ fun gen_statem:Start/3,
+ {ets, {return, ignore}}, Opts,
+ fun (ignore) -> ok end),
+ loop_start_fail(
+ fun gen_statem:Start/3,
+ {ets, {return, 4711}}, Opts,
+ fun ({error, {bad_return_from_init, 4711}}) -> ok end),
+ loop_start_fail(
+ fun gen_statem:Start/3,
+ {ets, {crash, error, bailout}}, Opts,
+ fun ({error, bailout}) -> ok end),
+ loop_start_fail(
+ fun gen_statem:Start/3,
+ {ets, {crash, exit, bailout}}, Opts,
+ fun ({error, bailout}) -> ok end),
+ loop_start_fail(
+ fun gen_statem:Start/3,
+ {ets, {wait, 1000, void}}, [{timeout, 200} | Opts],
+ fun ({error, timeout}) -> ok end),
+ loop_start_fail(Config, Start_Opts).
+
+loop_start_fail(GenStartFun, Arg, Opts, ValidateFun) ->
+ loop_start_fail(GenStartFun, Arg, Opts, ValidateFun, 5).
+%%
+loop_start_fail(_GenStartFun, _Arg, _Opts, _ValidateFun, 0) ->
+ ok;
+loop_start_fail(GenStartFun, Arg, Opts, ValidateFun, N) ->
+ ok = ValidateFun(GenStartFun(?MODULE, Arg, Opts)),
+ loop_start_fail(GenStartFun, Arg, Opts, ValidateFun, N - 1).
+
+
stop_and_reply(_Config) ->
process_flag(trap_exit, true),
@@ -2804,6 +2851,17 @@ init({map_statem,#{init := Init}=Machine,Modes}) ->
Other ->
init_sup(Other)
end;
+init({ets, InitResult}) ->
+ ?MODULE = ets:new(?MODULE, [named_table]),
+ init_sup(
+ case InitResult of
+ {return, Value} ->
+ Value;
+ {crash, Class, Reason} ->
+ erlang:Class(Reason);
+ {wait, Time, Value} ->
+ receive after Time -> Value end
+ end);
init([]) ->
io:format("init~n", []),
init_sup({ok,idle,data}).