diff options
author | Raimo Niskanen <[email protected]> | 2016-02-16 17:54:15 +0100 |
---|---|---|
committer | Raimo Niskanen <[email protected]> | 2016-02-18 08:27:55 +0100 |
commit | 99d48f5921f95073c8e46280494746b0e1a2c375 (patch) | |
tree | b58a5fe5f5c4c6d701d66879fa25e2e68abbde93 /lib/stdlib/test | |
parent | 3815de0c7337058991066454c246587c0dbaa664 (diff) | |
download | otp-99d48f5921f95073c8e46280494746b0e1a2c375.tar.gz otp-99d48f5921f95073c8e46280494746b0e1a2c375.tar.bz2 otp-99d48f5921f95073c8e46280494746b0e1a2c375.zip |
Implement option callback_mode
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r-- | lib/stdlib/test/gen_statem_SUITE.erl | 242 |
1 files changed, 174 insertions, 68 deletions
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl index 51e08f5ec1..8a96f0e8e2 100644 --- a/lib/stdlib/test/gen_statem_SUITE.erl +++ b/lib/stdlib/test/gen_statem_SUITE.erl @@ -19,7 +19,7 @@ %% -module(gen_statem_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -compile(export_all). -behaviour(gen_statem). @@ -30,7 +30,11 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [{group, start}, + {group, start_handle_event}, + {group, stop}, + {group, stop_handle_event}, {group, abnormal}, + {group, abnormal_handle_event}, shutdown, {group, sys}, hibernate, enter_loop]. @@ -38,13 +42,24 @@ groups() -> [{start, [], [start1, start2, start3, start4, start5, start6, start7, start8, start9, start10, start11, start12]}, + {start_handle_event, [], + [start1, start2, start3, start4, start5, start6, start7, + start8, start9, start10, start11, start12]}, {stop, [], [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]}, + {stop_handle_event, [], + [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]}, {abnormal, [], [abnormal1, abnormal2]}, + {abnormal_handle_event, [], [abnormal1, abnormal2]}, {sys, [], [sys1, call_format_status, error_format_status, terminate_crash_format, + get_state, replace_state]}, + {sys_handle_event, [], + [sys1, + call_format_status, + error_format_status, terminate_crash_format, get_state, replace_state]}]. init_per_suite(Config) -> @@ -53,6 +68,12 @@ init_per_suite(Config) -> end_per_suite(_Config) -> ok. +init_per_group(GroupName, Config) + when GroupName =:= start_handle_event; + GroupName =:= stop_handle_event; + GroupName =:= abnormal_handle_event; + GroupName =:= sys_handle_event -> + [{init_ops,[{callback_mode,handle_event_function}]}|Config]; init_per_group(_GroupName, Config) -> Config. @@ -65,6 +86,7 @@ init_per_testcase(_CaseName, Config) -> %%% dbg:tracer(), %%% dbg:p(all, c), %%% dbg:tpl(gen_statem, cx), +%%% dbg:tpl(sys, cx), [{watchdog, Dog} | Config]. end_per_testcase(_CaseName, Config) -> @@ -88,7 +110,7 @@ end_per_testcase(_CaseName, Config) -> start1(Config) when is_list(Config) -> %%OldFl = process_flag(trap_exit, true), - {ok,Pid0} = gen_statem:start_link(?MODULE, [], []), + {ok,Pid0} = gen_statem:start_link(?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid0), ok = do_sync_func_test(Pid0), stop_it(Pid0), @@ -102,7 +124,7 @@ start1(Config) when is_list(Config) -> %% anonymous w. shutdown start2(Config) when is_list(Config) -> %% Dont link when shutdown - {ok,Pid0} = gen_statem:start(?MODULE, [], []), + {ok,Pid0} = gen_statem:start(?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid0), ok = do_sync_func_test(Pid0), stopped = gen_statem:call(Pid0, {stop,shutdown}), @@ -113,13 +135,15 @@ start2(Config) when is_list(Config) -> start3(Config) when is_list(Config) -> %%OldFl = process_flag(trap_exit, true), - {ok,Pid0} = gen_statem:start(?MODULE, [], [{timeout,5}]), + {ok,Pid0} = + gen_statem:start(?MODULE, start_arg(Config, []), [{timeout,5}]), ok = do_func_test(Pid0), ok = do_sync_func_test(Pid0), stop_it(Pid0), - {error,timeout} = gen_statem:start(?MODULE, sleep, - [{timeout,5}]), + {error,timeout} = + gen_statem:start( + ?MODULE, start_arg(Config, sleep), [{timeout,5}]), %%process_flag(trap_exit, OldFl), ok = verify_empty_msgq(). @@ -128,7 +152,7 @@ start3(Config) when is_list(Config) -> start4(Config) when is_list(Config) -> OldFl = process_flag(trap_exit, true), - ignore = gen_statem:start(?MODULE, ignore, []), + ignore = gen_statem:start(?MODULE, start_arg(Config, ignore), []), process_flag(trap_exit, OldFl), ok = verify_empty_msgq(). @@ -138,14 +162,14 @@ start5(suite) -> []; start5(Config) when is_list(Config) -> OldFl = process_flag(trap_exit, true), - {error,stopped} = gen_statem:start(?MODULE, stop, []), + {error,stopped} = gen_statem:start(?MODULE, start_arg(Config, stop), []), process_flag(trap_exit, OldFl), ok = verify_empty_msgq(). %% anonymous linked start6(Config) when is_list(Config) -> - {ok,Pid} = gen_statem:start_link(?MODULE, [], []), + {ok,Pid} = gen_statem:start_link(?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid), ok = do_sync_func_test(Pid), stop_it(Pid), @@ -157,11 +181,11 @@ start7(Config) when is_list(Config) -> STM = {global,my_stm}, {ok,Pid} = - gen_statem:start_link(STM, ?MODULE, [], []), + gen_statem:start_link(STM, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start_link(STM, ?MODULE, [], []), + gen_statem:start_link(STM, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start(STM, ?MODULE, [], []), + gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid), ok = do_sync_func_test(Pid), @@ -179,9 +203,9 @@ start8(Config) when is_list(Config) -> STM = {local,Name}, {ok,Pid} = - gen_statem:start(STM, ?MODULE, [], []), + gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start(STM, ?MODULE, [], []), + gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid), ok = do_sync_func_test(Pid), @@ -199,9 +223,9 @@ start9(Config) when is_list(Config) -> STM = {local,Name}, {ok,Pid} = - gen_statem:start_link(STM, ?MODULE, [], []), + gen_statem:start_link(STM, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start(STM, ?MODULE, [], []), + gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid), ok = do_sync_func_test(Pid), @@ -217,11 +241,11 @@ start10(Config) when is_list(Config) -> STM = {global,my_stm}, {ok,Pid} = - gen_statem:start(STM, ?MODULE, [], []), + gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start(STM, ?MODULE, [], []), + gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start_link(STM, ?MODULE, [], []), + gen_statem:start_link(STM, ?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid), ok = do_sync_func_test(Pid), @@ -238,19 +262,19 @@ start11(Config) when is_list(Config) -> GlobalSTM = {global,Name}, {ok,Pid} = - gen_statem:start_link(LocalSTM, ?MODULE, [], []), + gen_statem:start_link(LocalSTM, ?MODULE, start_arg(Config, []), []), stop_it(Pid), {ok,_Pid1} = - gen_statem:start_link(LocalSTM, ?MODULE, [], []), + gen_statem:start_link(LocalSTM, ?MODULE, start_arg(Config, []), []), stop_it(Name), {ok,Pid2} = - gen_statem:start(GlobalSTM, ?MODULE, [], []), + gen_statem:start(GlobalSTM, ?MODULE, start_arg(Config, []), []), stop_it(Pid2), receive after 1 -> true end, Result = - gen_statem:start(GlobalSTM, ?MODULE, [], []), + gen_statem:start(GlobalSTM, ?MODULE, start_arg(Config, []), []), io:format("Result = ~p~n",[Result]), {ok,_Pid3} = Result, stop_it(GlobalSTM), @@ -263,11 +287,11 @@ start12(Config) when is_list(Config) -> VIA = {via,dummy_via,my_stm}, {ok,Pid} = - gen_statem:start_link(VIA, ?MODULE, [], []), + gen_statem:start_link(VIA, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start_link(VIA, ?MODULE, [], []), + gen_statem:start_link(VIA, ?MODULE, start_arg(Config, []), []), {error,{already_started,Pid}} = - gen_statem:start(VIA, ?MODULE, [], []), + gen_statem:start(VIA, ?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid), ok = do_sync_func_test(Pid), @@ -279,23 +303,23 @@ start12(Config) when is_list(Config) -> %% Anonymous, reason 'normal' -stop1(_Config) -> - {ok,Pid} = gen_statem:start(?MODULE, [], []), +stop1(Config) -> + {ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []), ok = gen_statem:stop(Pid), false = erlang:is_process_alive(Pid), noproc = ?EXPECT_FAILURE(gen_statem:stop(Pid), Reason). %% Anonymous, other reason -stop2(_Config) -> - {ok,Pid} = gen_statem:start(?MODULE, [], []), +stop2(Config) -> + {ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []), ok = gen_statem:stop(Pid, other_reason, infinity), false = erlang:is_process_alive(Pid), ok. %% Anonymous, invalid timeout -stop3(_Config) -> - {ok,Pid} = gen_statem:start(?MODULE, [], []), +stop3(Config) -> + {ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []), _ = ?EXPECT_FAILURE( gen_statem:stop(Pid, other_reason, invalid_timeout), @@ -306,8 +330,10 @@ stop3(_Config) -> ok. %% Registered name -stop4(_Config) -> - {ok,Pid} = gen_statem:start({local,to_stop},?MODULE, [], []), +stop4(Config) -> + {ok,Pid} = + gen_statem:start( + {local,to_stop},?MODULE, start_arg(Config, []), []), ok = gen_statem:stop(to_stop), false = erlang:is_process_alive(Pid), noproc = @@ -315,9 +341,11 @@ stop4(_Config) -> ok. %% Registered name and local node -stop5(_Config) -> +stop5(Config) -> Name = to_stop, - {ok,Pid} = gen_statem:start({local,Name},?MODULE, [], []), + {ok,Pid} = + gen_statem:start( + {local,Name},?MODULE, start_arg(Config, []), []), ok = gen_statem:stop({Name,node()}), false = erlang:is_process_alive(Pid), noproc = @@ -325,9 +353,9 @@ stop5(_Config) -> ok. %% Globally registered name -stop6(_Config) -> +stop6(Config) -> STM = {global,to_stop}, - {ok,Pid} = gen_statem:start(STM, ?MODULE, [], []), + {ok,Pid} = gen_statem:start(STM, ?MODULE, start_arg(Config, []), []), ok = gen_statem:stop(STM), false = erlang:is_process_alive(Pid), noproc = @@ -335,11 +363,10 @@ stop6(_Config) -> ok. %% 'via' registered name -stop7(_Config) -> +stop7(Config) -> VIA = {via,dummy_via,to_stop}, dummy_via:reset(), - {ok,Pid} = gen_statem:start(VIA, - ?MODULE, [], []), + {ok,Pid} = gen_statem:start(VIA, ?MODULE, start_arg(Config, []), []), ok = gen_statem:stop(VIA), false = erlang:is_process_alive(Pid), noproc = @@ -347,46 +374,55 @@ stop7(_Config) -> ok. %% Anonymous on remote node -stop8(_Config) -> +stop8(Config) -> {ok,Node} = ?t:start_node(gen_statem_stop8, slave, []), Dir = filename:dirname(code:which(?MODULE)), rpc:call(Node, code, add_path, [Dir]), - {ok,Pid} = rpc:call(Node, gen_statem,start, [?MODULE,[],[]]), + {ok,Pid} = + rpc:call( + Node, gen_statem,start, + [?MODULE,start_arg(Config, []),[]]), ok = gen_statem:stop(Pid), false = rpc:call(Node, erlang, is_process_alive, [Pid]), noproc = ?EXPECT_FAILURE(gen_statem:stop(Pid), Reason1), true = ?t:stop_node(Node), - {nodedown,Node} = + {{nodedown,Node},{sys,terminate,_}} = ?EXPECT_FAILURE(gen_statem:stop(Pid), Reason2), ok. %% Registered name on remote node -stop9(_Config) -> +stop9(Config) -> Name = to_stop, LocalSTM = {local,Name}, {ok,Node} = ?t:start_node(gen_statem__stop9, slave, []), STM = {Name,Node}, Dir = filename:dirname(code:which(?MODULE)), rpc:call(Node, code, add_path, [Dir]), - {ok,Pid} = rpc:call(Node, gen_statem, start, [LocalSTM,?MODULE,[],[]]), + {ok,Pid} = + rpc:call( + Node, gen_statem, start, + [LocalSTM,?MODULE,start_arg(Config, []),[]]), ok = gen_statem:stop(STM), undefined = rpc:call(Node,erlang,whereis,[Name]), false = rpc:call(Node,erlang,is_process_alive,[Pid]), noproc = ?EXPECT_FAILURE(gen_statem:stop(STM), Reason1), true = ?t:stop_node(Node), - {nodedown,Node} = + {{nodedown,Node},{sys,terminate,_}} = ?EXPECT_FAILURE(gen_statem:stop(STM), Reason2), ok. %% Globally registered name on remote node -stop10(_Config) -> +stop10(Config) -> STM = {global,to_stop}, {ok,Node} = ?t:start_node(gen_statem_stop10, slave, []), Dir = filename:dirname(code:which(?MODULE)), rpc:call(Node,code,add_path,[Dir]), - {ok,Pid} = rpc:call(Node, gen_statem, start, [STM,?MODULE,[],[]]), + {ok,Pid} = + rpc:call( + Node, gen_statem, start, + [STM,?MODULE,start_arg(Config, []),[]]), global:sync(), ok = gen_statem:stop(STM), false = rpc:call(Node, erlang, is_process_alive, [Pid]), @@ -402,7 +438,8 @@ abnormal1(Config) when is_list(Config) -> Name = abnormal1, LocalSTM = {local,Name}, - {ok, _Pid} = gen_statem:start(LocalSTM, ?MODULE, [], []), + {ok, _Pid} = + gen_statem:start(LocalSTM, ?MODULE, start_arg(Config, []), []), %% timeout call. delayed = gen_statem:call(Name, {delayed_answer,1}, 100), @@ -410,13 +447,14 @@ abnormal1(Config) when is_list(Config) -> ?EXPECT_FAILURE( gen_statem:call(Name, {delayed_answer,1000}, 10), Reason), + ok = gen_statem:stop(Name), ok = verify_empty_msgq(). %% Check that bad return values makes the stm crash. Note that we must %% trap exit since we must link to get the real bad_return_ error abnormal2(Config) when is_list(Config) -> OldFl = process_flag(trap_exit, true), - {ok,Pid} = gen_statem:start_link(?MODULE, [], []), + {ok,Pid} = gen_statem:start_link(?MODULE, start_arg(Config, []), []), %% bad return value in the gen_statem loop {{bad_return_value,badreturn},_} = @@ -433,7 +471,7 @@ abnormal2(Config) when is_list(Config) -> shutdown(Config) when is_list(Config) -> process_flag(trap_exit, true), - {ok,Pid0} = gen_statem:start_link(?MODULE, [], []), + {ok,Pid0} = gen_statem:start_link(?MODULE, start_arg(Config, []), []), ok = do_func_test(Pid0), ok = do_sync_func_test(Pid0), stopped = gen_statem:call(Pid0, {stop,{shutdown,reason}}), @@ -454,7 +492,7 @@ shutdown(Config) when is_list(Config) -> sys1(Config) when is_list(Config) -> - {ok,Pid} = gen_statem:start(?MODULE, [], []), + {ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []), {status, Pid, {module,gen_statem}, _} = sys:get_status(Pid), sys:suspend(Pid), Parent = self(), @@ -477,7 +515,7 @@ sys1(Config) when is_list(Config) -> stop_it(Pid). call_format_status(Config) when is_list(Config) -> - {ok,Pid} = gen_statem:start(?MODULE, [], []), + {ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []), Status = sys:get_status(Pid), {status,Pid,_Mod,[_PDict,running,_,_, Data]} = Status, [format_status_called|_] = lists:reverse(Data), @@ -485,7 +523,9 @@ call_format_status(Config) when is_list(Config) -> %% check that format_status can handle a name being an atom (pid is %% already checked by the previous test) - {ok, Pid2} = gen_statem:start({local, gstm}, ?MODULE, [], []), + {ok, Pid2} = + gen_statem:start( + {local, gstm}, ?MODULE, start_arg(Config, []), []), Status2 = sys:get_status(gstm), {status,Pid2,_Mod,[_PDict2,running,_,_,Data2]} = Status2, [format_status_called|_] = lists:reverse(Data2), @@ -494,13 +534,17 @@ call_format_status(Config) when is_list(Config) -> %% check that format_status can handle a name being a term other than a %% pid or atom GlobalName1 = {global,"CallFormatStatus"}, - {ok,Pid3} = gen_statem:start(GlobalName1, ?MODULE, [], []), + {ok,Pid3} = + gen_statem:start( + GlobalName1, ?MODULE, start_arg(Config, []), []), Status3 = sys:get_status(GlobalName1), {status,Pid3,_Mod,[_PDict3,running,_,_,Data3]} = Status3, [format_status_called|_] = lists:reverse(Data3), stop_it(Pid3), GlobalName2 = {global,{name, "term"}}, - {ok,Pid4} = gen_statem:start(GlobalName2, ?MODULE, [], []), + {ok,Pid4} = + gen_statem:start( + GlobalName2, ?MODULE, start_arg(Config, []), []), Status4 = sys:get_status(GlobalName2), {status,Pid4,_Mod,[_PDict4,running,_,_, Data4]} = Status4, [format_status_called|_] = lists:reverse(Data4), @@ -510,13 +554,15 @@ call_format_status(Config) when is_list(Config) -> %% pid or atom dummy_via:reset(), ViaName1 = {via,dummy_via,"CallFormatStatus"}, - {ok,Pid5} = gen_statem:start(ViaName1, ?MODULE, [], []), + {ok,Pid5} = gen_statem:start(ViaName1, ?MODULE, start_arg(Config, []), []), Status5 = sys:get_status(ViaName1), {status,Pid5,_Mod, [_PDict5,running,_,_, Data5]} = Status5, [format_status_called|_] = lists:reverse(Data5), stop_it(Pid5), ViaName2 = {via,dummy_via,{name,"term"}}, - {ok, Pid6} = gen_statem:start(ViaName2, ?MODULE, [], []), + {ok, Pid6} = + gen_statem:start( + ViaName2, ?MODULE, start_arg(Config, []), []), Status6 = sys:get_status(ViaName2), {status,Pid6,_Mod,[_PDict6,running,_,_,Data6]} = Status6, [format_status_called|_] = lists:reverse(Data6), @@ -528,7 +574,9 @@ error_format_status(Config) when is_list(Config) -> error_logger_forwarder:register(), OldFl = process_flag(trap_exit, true), StateData = "called format_status", - {ok,Pid} = gen_statem:start(?MODULE, {state_data,StateData}, []), + {ok,Pid} = + gen_statem:start( + ?MODULE, start_arg(Config, {state_data,StateData}), []), %% bad return value in the gen_statem loop {{bad_return_value,badreturn},_} = ?EXPECT_FAILURE(gen_statem:call(Pid, badreturn), Reason), @@ -562,7 +610,9 @@ terminate_crash_format(Config) when is_list(Config) -> error_logger_forwarder:register(), OldFl = process_flag(trap_exit, true), StateData = crash_terminate, - {ok,Pid} = gen_statem:start(?MODULE, {state_data,StateData}, []), + {ok,Pid} = + gen_statem:start( + ?MODULE, start_arg(Config, {state_data,StateData}), []), stop_it(Pid), Self = self(), receive @@ -595,7 +645,9 @@ terminate_crash_format(Config) when is_list(Config) -> get_state(Config) when is_list(Config) -> State = self(), - {ok,Pid} = gen_statem:start(?MODULE, {state_data,State}, []), + {ok,Pid} = + gen_statem:start( + ?MODULE, start_arg(Config, {state_data,State}), []), {idle,State} = sys:get_state(Pid), {idle,State} = sys:get_state(Pid, 5000), stop_it(Pid), @@ -603,13 +655,16 @@ get_state(Config) when is_list(Config) -> %% check that get_state can handle a name being an atom (pid is %% already checked by the previous test) {ok,Pid2} = - gen_statem:start({local,gstm}, ?MODULE, {state_data,State}, []), + gen_statem:start( + {local,gstm}, ?MODULE, start_arg(Config, {state_data,State}), []), {idle,State} = sys:get_state(gstm), {idle,State} = sys:get_state(gstm, 5000), stop_it(Pid2), %% check that get_state works when pid is sys suspended - {ok,Pid3} = gen_statem:start(?MODULE, {state_data,State}, []), + {ok,Pid3} = + gen_statem:start( + ?MODULE, start_arg(Config, {state_data,State}), []), {idle,State} = sys:get_state(Pid3), ok = sys:suspend(Pid3), {idle,State} = sys:get_state(Pid3, 5000), @@ -619,7 +674,9 @@ get_state(Config) when is_list(Config) -> replace_state(Config) when is_list(Config) -> State = self(), - {ok, Pid} = gen_statem:start(?MODULE, {state_data,State}, []), + {ok, Pid} = + gen_statem:start( + ?MODULE, start_arg(Config, {state_data,State}), []), {idle,State} = sys:get_state(Pid), NState1 = "replaced", Replace1 = fun({StateName, _}) -> {StateName,NState1} end, @@ -650,7 +707,9 @@ replace_state(Config) when is_list(Config) -> hibernate(Config) when is_list(Config) -> OldFl = process_flag(trap_exit, true), - {ok,Pid0} = gen_statem:start_link(?MODULE, hiber_now, []), + {ok,Pid0} = + gen_statem:start_link( + ?MODULE, start_arg(Config, hiber_now), []), is_in_erlang_hibernate(Pid0), stop_it(Pid0), receive @@ -659,7 +718,8 @@ hibernate(Config) when is_list(Config) -> ?t:fail(gen_statem_did_not_die) end, - {ok,Pid} = gen_statem:start_link(?MODULE, hiber, []), + {ok,Pid} = + gen_statem:start_link(?MODULE, start_arg(Config, hiber), []), true = ({current_function,{erlang,hibernate,3}} =/= erlang:process_info(Pid,current_function)), hibernating = gen_statem:call(Pid, hibernate_sync), @@ -1031,6 +1091,14 @@ verify_empty_msgq() -> [] = ?t:messages_get(), ok. +start_arg(Config, Arg) -> + case lists:keyfind(init_ops, 1, Config) of + {_,Ops} -> + {init_ops,Arg,Ops}; + false -> + Arg + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% The State Machine @@ -1052,7 +1120,16 @@ init(hiber_now) -> {ok,hiber_idle,[],[hibernate]}; init({state_data, StateData}) -> {ok,idle,StateData}; -init(_) -> +init({init_ops,Arg,InitOps}) -> + case init(Arg) of + {ok,State,Data,Ops} -> + {ok,State,Data,InitOps++Ops}; + {ok,State,Data} -> + {ok,State,Data,InitOps}; + Other -> + Other + end; +init([]) -> {ok,idle,state_data}. terminate(_, _State, crash_terminate) -> @@ -1247,6 +1324,35 @@ handle_common_events(cast, {'alive?',Pid}, _, State, Data) -> handle_common_events(_, _, _, _, _) -> undefined. +%% Dispatcher to test callback_mode handle_event_function +%% +%% Wrap the state in a 1 element list just to test non-atom +%% states. Note that the state from init/1 is not wrapped +%% so both atom and non-atom states are tested. +handle_event(Type, Event, PrevState, State, Data) -> + PrevStateName = unwrap(PrevState), + StateName = unwrap(State), + case + ?MODULE:StateName( + Type, Event, PrevStateName, StateName, Data) of + {next_state,NewState,NewStateData} -> + {next_state,wrap(NewState),NewStateData}; + {next_state,NewState,NewStateData,StateOps} -> + {next_state,wrap(NewState),NewStateData,StateOps}; + Other -> + Other + end. + +unwrap([State]) -> + State; +unwrap(State) -> + State. + +wrap(State) -> + [State]. + + + code_change(_OldVsn, State, StateData, _Extra) -> {ok,State,StateData}. |