From 063bebc88358f66cea17e3cf777b8b561a5f14c0 Mon Sep 17 00:00:00 2001 From: Anton N Ryabkov Date: Mon, 24 Apr 2017 12:54:09 +0700 Subject: Added support of auto_hibernate_timeout option for gen_statem. --- lib/stdlib/test/gen_statem_SUITE.erl | 59 +++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'lib/stdlib/test/gen_statem_SUITE.erl') diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl index 05934b3953..f05fc19555 100644 --- a/lib/stdlib/test/gen_statem_SUITE.erl +++ b/lib/stdlib/test/gen_statem_SUITE.erl @@ -40,7 +40,7 @@ all() -> shutdown, stop_and_reply, state_enter, event_order, state_timeout, event_types, generic_timers, code_change, {group, sys}, - hibernate, enter_loop, {group, undef_callbacks}, + hibernate, auto_hibernate, enter_loop, {group, undef_callbacks}, undef_in_terminate]. groups() -> @@ -1284,6 +1284,55 @@ hibernate(Config) -> end, ok = verify_empty_msgq(). +%% Auto-hibernation timeout +auto_hibernate(Config) -> + OldFl = process_flag(trap_exit, true), + AutoHibernateTimeout = 100, + + {ok,Pid} = + gen_statem:start_link( + ?MODULE, start_arg(Config, []), [{auto_hibernate_timeout, AutoHibernateTimeout}]), + %% After init test + is_not_in_erlang_hibernate(Pid), + timer:sleep(AutoHibernateTimeout), + is_in_erlang_hibernate(Pid), + %% After info test + Pid ! {hping, self()}, + receive + {Pid, hpong} -> + ok + after 1000 -> + ct:fail(info) + end, + is_not_in_erlang_hibernate(Pid), + timer:sleep(AutoHibernateTimeout), + is_in_erlang_hibernate(Pid), + %% After cast test + ok = gen_statem:cast(Pid, {hping, self()}), + receive + {Pid, hpong} -> + ok + after 1000 -> + ct:fail(cast) + end, + is_not_in_erlang_hibernate(Pid), + timer:sleep(AutoHibernateTimeout), + is_in_erlang_hibernate(Pid), + %% After call test + hpong = gen_statem:call(Pid, hping), + is_not_in_erlang_hibernate(Pid), + timer:sleep(AutoHibernateTimeout), + is_in_erlang_hibernate(Pid), + + stop_it(Pid), + process_flag(trap_exit, OldFl), + receive + {'EXIT',Pid,normal} -> ok + after 5000 -> + ct:fail(gen_statem_did_not_die) + end, + ok = verify_empty_msgq(). + is_in_erlang_hibernate(Pid) -> receive after 1 -> ok end, is_in_erlang_hibernate_1(200, Pid). @@ -1704,6 +1753,14 @@ terminate(_Reason, _State, _Data) -> %% State functions +idle(info, {hping,Pid}, _Data) -> + Pid ! {self(), hpong}, + keep_state_and_data; +idle(cast, {hping,Pid}, Data) -> + Pid ! {self(), hpong}, + {keep_state, Data}; +idle({call, From}, hping, _Data) -> + {keep_state_and_data, [{reply, From, hpong}]}; idle(cast, {connect,Pid}, Data) -> Pid ! accept, {next_state,wfor_conf,Data,infinity}; % NoOp timeout just to test API -- cgit v1.2.3 From 38294da512781e44b44b9331bf613003397d529b Mon Sep 17 00:00:00 2001 From: Anton N Ryabkov Date: Mon, 24 Apr 2017 13:41:59 +0700 Subject: "auto_hibernate_timeout" option renamed to "hibernate_after". It was done because "hibernate_after" option already used in ssl for the same reason. --- lib/stdlib/test/gen_statem_SUITE.erl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/stdlib/test/gen_statem_SUITE.erl') diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl index f05fc19555..33441c75e0 100644 --- a/lib/stdlib/test/gen_statem_SUITE.erl +++ b/lib/stdlib/test/gen_statem_SUITE.erl @@ -1287,14 +1287,14 @@ hibernate(Config) -> %% Auto-hibernation timeout auto_hibernate(Config) -> OldFl = process_flag(trap_exit, true), - AutoHibernateTimeout = 100, + HibernateAfterTimeout = 100, {ok,Pid} = gen_statem:start_link( - ?MODULE, start_arg(Config, []), [{auto_hibernate_timeout, AutoHibernateTimeout}]), + ?MODULE, start_arg(Config, []), [{hibernate_after, HibernateAfterTimeout}]), %% After init test is_not_in_erlang_hibernate(Pid), - timer:sleep(AutoHibernateTimeout), + timer:sleep(HibernateAfterTimeout), is_in_erlang_hibernate(Pid), %% After info test Pid ! {hping, self()}, @@ -1305,7 +1305,7 @@ auto_hibernate(Config) -> ct:fail(info) end, is_not_in_erlang_hibernate(Pid), - timer:sleep(AutoHibernateTimeout), + timer:sleep(HibernateAfterTimeout), is_in_erlang_hibernate(Pid), %% After cast test ok = gen_statem:cast(Pid, {hping, self()}), @@ -1316,12 +1316,12 @@ auto_hibernate(Config) -> ct:fail(cast) end, is_not_in_erlang_hibernate(Pid), - timer:sleep(AutoHibernateTimeout), + timer:sleep(HibernateAfterTimeout), is_in_erlang_hibernate(Pid), %% After call test hpong = gen_statem:call(Pid, hping), is_not_in_erlang_hibernate(Pid), - timer:sleep(AutoHibernateTimeout), + timer:sleep(HibernateAfterTimeout), is_in_erlang_hibernate(Pid), stop_it(Pid), -- cgit v1.2.3 From bf3ead6cdb3a5c7556831b9684574845101f4f36 Mon Sep 17 00:00:00 2001 From: Anton N Ryabkov Date: Tue, 25 Apr 2017 18:27:15 +0700 Subject: Rolled back loop_receive function. HibernateAfterTimeout timeout used even in case of active timers exists. Added unit tests for hibernate_after functionality combined with gen_statem timers. --- lib/stdlib/test/gen_statem_SUITE.erl | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'lib/stdlib/test/gen_statem_SUITE.erl') diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl index 33441c75e0..5b9daecfd3 100644 --- a/lib/stdlib/test/gen_statem_SUITE.erl +++ b/lib/stdlib/test/gen_statem_SUITE.erl @@ -1323,7 +1323,36 @@ auto_hibernate(Config) -> is_not_in_erlang_hibernate(Pid), timer:sleep(HibernateAfterTimeout), is_in_erlang_hibernate(Pid), - + %% Timer test 1 + TimerTimeout1 = 50, + ok = gen_statem:call(Pid, {arm_htimer, self(), TimerTimeout1}), + is_not_in_erlang_hibernate(Pid), + timer:sleep(TimerTimeout1), + is_not_in_erlang_hibernate(Pid), + receive + {Pid, htimer_armed} -> + ok + after 1000 -> + ct:fail(timer1) + end, + is_not_in_erlang_hibernate(Pid), + timer:sleep(HibernateAfterTimeout), + is_in_erlang_hibernate(Pid), + %% Timer test 2 + TimerTimeout2 = 150, + ok = gen_statem:call(Pid, {arm_htimer, self(), TimerTimeout2}), + is_not_in_erlang_hibernate(Pid), + timer:sleep(HibernateAfterTimeout), + is_in_erlang_hibernate(Pid), + receive + {Pid, htimer_armed} -> + ok + after 1000 -> + ct:fail(timer2) + end, + is_not_in_erlang_hibernate(Pid), + timer:sleep(HibernateAfterTimeout), + is_in_erlang_hibernate(Pid), stop_it(Pid), process_flag(trap_exit, OldFl), receive @@ -1761,6 +1790,11 @@ idle(cast, {hping,Pid}, Data) -> {keep_state, Data}; idle({call, From}, hping, _Data) -> {keep_state_and_data, [{reply, From, hpong}]}; +idle({call, From}, {arm_htimer, Pid, Timeout}, _Data) -> + {keep_state_and_data, [{reply, From, ok}, {timeout, Timeout, {arm_htimer, Pid}}]}; +idle(timeout, {arm_htimer, Pid}, _Data) -> + Pid ! {self(), htimer_armed}, + keep_state_and_data; idle(cast, {connect,Pid}, Data) -> Pid ! accept, {next_state,wfor_conf,Data,infinity}; % NoOp timeout just to test API -- cgit v1.2.3