aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/src/ct_hooks_lock.erl
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-02-17 17:07:05 +0100
committerLukas Larsson <[email protected]>2011-02-17 17:09:38 +0100
commit53974a3517268389ae18fabee509ebf4bbfce747 (patch)
tree208575bf9ac4916c6b60e052c6f712986c3f0de9 /lib/common_test/src/ct_hooks_lock.erl
parentb83388e78e72e66f4e0dae42083a6bcd9709922e (diff)
parentd87708bf18d29c0a66f6654368b4553067e62394 (diff)
downloadotp-53974a3517268389ae18fabee509ebf4bbfce747.tar.gz
otp-53974a3517268389ae18fabee509ebf4bbfce747.tar.bz2
otp-53974a3517268389ae18fabee509ebf4bbfce747.zip
Merge branch 'lukas/common_test/suite_callback/OTP-8851' into dev
* lukas/common_test/suite_callback/OTP-8851: (54 commits) Update example cth spec to reflect the implementation Cleanup code to fix dialyzer warning Rename Suite Callback to Common Test hook in documentation Rename Suite Callback to Common Test Hook in code and testcases Fix bug where the state of an SCB was altered when no on_tc_* existed Update SCBs to use a specific id/1 function for SCb overriding instead of returning it from init/1. Add documentation for SCBs Update suite callback test timeout so that beam debug test runs do not timeout Update test support so that if common test fails to be stopped in a suite, the ct node is restarted and the test case fails Add tests for SCB's with same id and fixed bug relating to it Add test suites for failing in init/1 function Added tests for starting SCB's with arguments and fixed a bug with how SCB's are parsed from the command line Add so that failures in SCB:init/1 causes the entire scb scope to fail Fix bug which caused scb to be added too much when initiated in the suite info function Started work on documenting suite callbacks, this is a partial commit Add locking mechanism for scb state when using parallel groups Add state update tests for suite callbacks Update ct_framework calls to allow manipulation of test results in end_tc without breaking backwards compatability (I hope) Add test case for init_per_suite recover scenario Add testcase for config updates ...
Diffstat (limited to 'lib/common_test/src/ct_hooks_lock.erl')
-rw-r--r--lib/common_test/src/ct_hooks_lock.erl132
1 files changed, 132 insertions, 0 deletions
diff --git a/lib/common_test/src/ct_hooks_lock.erl b/lib/common_test/src/ct_hooks_lock.erl
new file mode 100644
index 0000000000..98794201bb
--- /dev/null
+++ b/lib/common_test/src/ct_hooks_lock.erl
@@ -0,0 +1,132 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%% @doc Common Test Framework test execution control module.
+%%%
+%%% <p>This module is a proxy for calling and handling locks in
+%%% common test hooks.</p>
+
+-module(ct_hooks_lock).
+
+-behaviour(gen_server).
+
+%% API
+-export([start/1, stop/1, request/0, release/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-define(SERVER, ?MODULE).
+
+-record(state, { id, locked = false, requests = [] }).
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+
+%% @doc Starts the server
+start(Id) ->
+ case gen_server:start({local, ?SERVER}, ?MODULE, Id, []) of
+ {error,{already_started, Pid}} ->
+ {ok,Pid};
+ Else ->
+ Else
+ end.
+
+stop(Id) ->
+ try
+ gen_server:call(?SERVER, {stop,Id})
+ catch exit:{noproc,_} ->
+ stopped
+ end.
+
+request() ->
+ try
+ gen_server:call(?SERVER,{request,self()},infinity)
+ catch exit:{noproc,_} ->
+ locked
+ end.
+
+release() ->
+ try
+ gen_server:call(?SERVER,{release,self()})
+ catch exit:{noproc,_} ->
+ unlocked
+ end.
+
+%%%===================================================================
+%%% gen_server callbacks
+%%%===================================================================
+
+%% @doc Initiates the server
+init(Id) ->
+ {ok, #state{ id = Id }}.
+
+%% @doc Handling call messages
+handle_call({stop,Id}, _From, #state{ id = Id, requests = Reqs } = State) ->
+ [gen_server:reply(Req, locker_stopped) || {Req,_ReqId} <- Reqs],
+ {stop, normal, stopped, State};
+handle_call({stop,_Id}, _From, State) ->
+ {reply, stopped, State};
+handle_call({request, Pid}, _From, #state{ locked = false,
+ requests = [] } = State) ->
+ Ref = monitor(process, Pid),
+ {reply, locked, State#state{ locked = {true, Pid, Ref}} };
+handle_call({request, Pid}, From, #state{ requests = Reqs } = State) ->
+ {noreply, State#state{ requests = Reqs ++ [{From,Pid}] }};
+handle_call({release, Pid}, _From, #state{ locked = {true, Pid, Ref},
+ requests = []} = State) ->
+ demonitor(Ref,[flush]),
+ {reply, unlocked, State#state{ locked = false }};
+handle_call({release, Pid}, _From,
+ #state{ locked = {true, Pid, Ref},
+ requests = [{NextFrom,NextPid}|Rest]} = State) ->
+ demonitor(Ref,[flush]),
+ gen_server:reply(NextFrom,locked),
+ NextRef = monitor(process, NextPid),
+ {reply,unlocked,State#state{ locked = {true, NextPid, NextRef},
+ requests = Rest } };
+handle_call({release, _Pid}, _From, State) ->
+ {reply, not_locked, State}.
+
+%% @doc Handling cast messages
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+%% @doc Handling all non call/cast messages
+handle_info({'DOWN',Ref,process,Pid,_},
+ #state{ locked = {true, Pid, Ref},
+ requests = [{NextFrom,NextPid}|Rest] } = State) ->
+ gen_server:reply(NextFrom, locked),
+ NextRef = monitor(process, NextPid),
+ {noreply,State#state{ locked = {true, NextPid, NextRef},
+ requests = Rest } }.
+
+%% @doc This function is called by a gen_server when it is about to terminate.
+terminate(_Reason, _State) ->
+ ok.
+
+%% @doc Convert process state when code is changed
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%% -------------------------------------------------------------------------
+%% Internal Functions
+%% -------------------------------------------------------------------------