aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2016-09-30 18:00:38 +0200
committerRaimo Niskanen <[email protected]>2016-10-12 11:27:34 +0200
commit77e175589b0ee3c1a4c94aef3cdcdf54cd84c53c (patch)
treec1f5fa31d25e4e3f8974448f131f980a798bfbeb /lib/stdlib/test
parent800265f49f912dcf66846b13aa8032bf2f380caf (diff)
downloadotp-77e175589b0ee3c1a4c94aef3cdcdf54cd84c53c.tar.gz
otp-77e175589b0ee3c1a4c94aef3cdcdf54cd84c53c.tar.bz2
otp-77e175589b0ee3c1a4c94aef3cdcdf54cd84c53c.zip
Implement state timeouts
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl80
1 files changed, 79 insertions, 1 deletions
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index 48f93b1de7..28f9ab81fe 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -37,7 +37,8 @@ all() ->
{group, stop_handle_event},
{group, abnormal},
{group, abnormal_handle_event},
- shutdown, stop_and_reply, state_enter, event_order, code_change,
+ shutdown, stop_and_reply, state_enter, event_order,
+ state_timeout, code_change,
{group, sys},
hibernate, enter_loop].
@@ -709,6 +710,83 @@ event_order(_Config) ->
+state_timeout(_Config) ->
+ process_flag(trap_exit, true),
+
+ Machine =
+ #{init =>
+ fun () ->
+ {ok,start,0}
+ end,
+ start =>
+ fun
+ ({call,From}, {go,Time}, 0) ->
+ self() ! message_to_self,
+ {next_state, state1, {Time,From},
+ %% Verify that internal events goes before external
+ [{state_timeout,Time,1},
+ {next_event,internal,1}]}
+ end,
+ state1 =>
+ fun
+ (internal, 1, Data) ->
+ %% Verify that a state change cancels timeout 1
+ {next_state, state2, Data,
+ [{timeout,0,2},
+ {state_timeout,0,2},
+ {next_event,internal,2}]}
+ end,
+ state2 =>
+ fun
+ (internal, 2, Data) ->
+ %% Verify that {state_timeout,0,_}
+ %% comes after next_event and that
+ %% {timeout,0,_} is cancelled by
+ %% {state_timeout,0,_}
+ {keep_state, {ok,2,Data},
+ [{timeout,0,3}]};
+ (state_timeout, 2, {ok,2,{Time,From}}) ->
+ {next_state, state3, 3,
+ [{reply,From,ok},
+ {state_timeout,Time,3}]}
+ end,
+ state3 =>
+ fun
+ (info, message_to_self, 3) ->
+ {keep_state, '3'};
+ ({call,From}, check, '3') ->
+ {keep_state, From};
+ (state_timeout, 3, From) ->
+ {stop_and_reply, normal,
+ {reply,From,ok}}
+ end},
+
+ {ok,STM} = gen_statem:start_link(?MODULE, {map_statem,Machine,[]}, []),
+ TRef = erlang:start_timer(1000, self(), kull),
+ ok = gen_statem:call(STM, {go,500}),
+ ok = gen_statem:call(STM, check),
+ receive
+ {timeout,TRef,kull} ->
+ ct:fail(late_timeout)
+ after 0 ->
+ receive
+ {timeout,TRef,kull} ->
+ ok
+ after 1000 ->
+ ct:fail(no_check_timeout)
+ end
+ end,
+ receive
+ {'EXIT',STM,normal} ->
+ ok
+ after 500 ->
+ ct:fail(did_not_stop)
+ end,
+
+ verify_empty_msgq().
+
+
+
sys1(Config) ->
{ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []),
{status, Pid, {module,gen_statem}, _} = sys:get_status(Pid),