aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/common_test/test/Makefile3
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/empty_scb.erl187
-rw-r--r--lib/common_test/test/ct_suite_callback_SUITE.erl150
-rw-r--r--lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/ct_scb_empty_SUITE.erl110
4 files changed, 449 insertions, 1 deletions
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index f2fe3390cf..28be9f56f1 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -40,7 +40,8 @@ MODULES= \
ct_test_server_if_1_SUITE \
ct_config_SUITE \
ct_master_SUITE \
- ct_misc_1_SUITE
+ ct_misc_1_SUITE \
+ ct_suite_callback_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/common_test/test/ct_error_SUITE_data/error/test/empty_scb.erl b/lib/common_test/test/ct_error_SUITE_data/error/test/empty_scb.erl
new file mode 100644
index 0000000000..41808b4f1d
--- /dev/null
+++ b/lib/common_test/test/ct_error_SUITE_data/error/test/empty_scb.erl
@@ -0,0 +1,187 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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 Example Suite Callback module.
+%%%
+%%% <p>This module gives an example of a common test SCB (Suite CallBack).
+%%% There are many ways to add a SCB to a test run, you can do it either in
+%%% the command line using -suite_callback, in a test spec using
+%%% {suite_callback,M} or in the suite it self by returning suite_callback
+%%% from either suite/0, init_per_suite/1, init_per_group/2 and
+%%% init_per_testcase/2. The scope of the SCB is determined by where is it
+%%% started. If it is started in the command line or test spec then it will
+%%% be stopped at the end of all tests. If it is started in init_per_suite,
+%%% it will be stopped after end_per_suite and so on. See terminate
+%%% documentation for a table describing the scoping machanics.
+%%%
+%%% All of callbacks except init/1 in a SCB are optional.</p>
+
+-module(empty_scb).
+
+%% Suite Callbacks
+-export([init/1]).
+
+-export([pre_init_suite/3]).
+-export([post_init_suite/3]).
+-export([pre_end_suite/3]).
+-export([post_end_suite/3]).
+
+-export([pre_init_group/3]).
+-export([post_init_group/3]).
+-export([pre_end_group/3]).
+-export([post_end_group/3]).
+
+-export([pre_init_tc/3]).
+-export([post_end_tc/3]).
+
+-export([on_tc_fail/3]).
+
+-export([terminate/2]).
+
+-type proplist() :: list({atom(),term()}).
+-type config() :: proplist().
+-type reason() :: term().
+-type skip_or_fail() :: {skip, reason()} |
+ {auto_skip, reason()} |
+ {fail, reason()}.
+
+-record(state, { id = ?MODULE :: term()}).
+
+%% @doc Always called before any other callback function. Use this to initiate
+%% any common state. It should return an ID for this SCB and a state. The ID
+%% is used to uniquly identify an SCB instance, if two SCB's return the same
+%% ID the seconds SCB is ignored. This function should NOT have any side
+%% effects as it might be called multiple times by common test.
+-spec init(Opts :: proplist()) ->
+ {Id :: term(), State :: #state{}}.
+init(Opts) ->
+ {?MODULE, #state{ }}.
+
+%% @doc Called before init_per_suite is called. Note that this callback is
+%% only called if the SCB is added before init_per_suite is run (eg. in a test
+%% specification, suite/0 function etc).
+%% You can change the config in the this function.
+-spec pre_init_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_suite(Suite,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after init_per_suite.
+%% you can change the config in this function.
+-spec post_init_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_suite(Suite,Config,State) ->
+ {Config, State}.
+
+%% @doc Called before end_per_suite. Note that the config cannot be
+%% changed here, only the status of the suite.
+-spec pre_end_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_suite(Suite,Config,State) -> {Config, State}.
+
+%% @doc Called after end_per_suite. Note that the config cannot be
+%% changed here, only the status of the suite.
+-spec post_end_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_suite(Suite,Config,State) -> {Config, State}.
+
+%% @doc Called before each init_per_group.
+%% You can change the config in this function.
+-spec pre_init_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_group(Group,Config,State) -> {Config, State}.
+
+%% @doc Called after each init_per_group.
+%% You can change the config in this function.
+-spec post_init_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_group(Group,Config,State) -> {Config, State}.
+
+%% @doc Called after each end_per_group. Note that the config cannot be
+%% changed here, only the status of the group.
+-spec pre_end_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_group(Group,Config,State) -> {Config, State}.
+
+%% @doc Called after each end_per_group. Note that the config cannot be
+%% changed here, only the status of the group.
+-spec post_end_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_group(Group,Config,State) -> {Config, State}.
+
+%% @doc Called before each test case.
+%% You can change the config in this function.
+-spec pre_init_tc(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_tc(TC,Config,State) -> {Config, State}.
+
+%% @doc Called after each test case. Note that the config cannot be
+%% changed here, only the status of the test case.
+-spec post_end_tc(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_tc(TC,Config,State) -> {Config, State}.
+
+%% @doc Called after post_init_suite, post_end_suite, post_init_group,
+%% post_end_group and post_end_tc if the suite, group or test case failed.
+%% This function should be used for extra cleanup which might be needed.
+%% It is not possible to modify the config or the status of the test run.
+-spec on_tc_fail(TC :: init_per_suite | end_per_suite |
+ init_per_group | end_per_group | atom(),
+ Config :: config(), State :: #state{}) ->
+ ok.
+on_tc_fail(_TC, _Config, _State) ->
+ ok.
+
+%% @doc Called when the scope of the SCB is done, this depends on
+%% when the SCB was specified. This translation table describes when this
+%% function is called.
+%%
+%% | Started in | terminate called |
+%% |---------------------|-------------------------|
+%% | command_line | after all tests are run |
+%% | test spec | after all tests are run |
+%% | suite/0 | after SUITE is done |
+%% | init_per_suite/1 | after SUITE is done |
+%% | init_per_group/2 | after group is done |
+%% | init_per_testcase/2 | after test case is done |
+%% |-----------------------------------------------|
+%%
+-spec terminate(Config :: proplist(), State :: #state{}) ->
+ term().
+terminate(Config,State) -> {Config, State}.
diff --git a/lib/common_test/test/ct_suite_callback_SUITE.erl b/lib/common_test/test/ct_suite_callback_SUITE.erl
new file mode 100644
index 0000000000..7a8ad9a82e
--- /dev/null
+++ b/lib/common_test/test/ct_suite_callback_SUITE.erl
@@ -0,0 +1,150 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-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%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_error_SUITE
+%%%
+%%% Description:
+%%% Test various errors in Common Test suites.
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_suite_callback_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ DataDir = ?config(data_dir, Config),
+ TestDir = filename:join(DataDir,"scb/tests/"),
+ SCBs = filelib:wildcard(filename:join(TestDir,"*_scb.erl")),
+ io:format("SCBs: ~p",[SCBs]),
+ [io:format("Compiling ~p: ~p",
+ [FileName,compile:file(FileName,[{outdir,TestDir},debug_info])]) ||
+ FileName <- SCBs],
+ ct_test_support:init_per_suite([{path_dirs,[TestDir]} | Config]).
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+
+suite() ->
+ [{timetrap,{minutes,1}}].
+
+all() ->
+ all(suite).
+
+all(suite) ->
+ [
+ empty
+ ].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+empty(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suites = [filename:join(DataDir,"scb/tests/ct_scb_empty_SUITE.erl")],
+ {Opts,ERPid} = setup([{suite,Suites},
+ {suite_callbacks,[empty_scb]}], Config),
+ ok = ct_test_support:run(Opts, Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(empty_scb,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = events_to_check(empty),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+events_to_check(Test) ->
+ %% 2 tests (ct:run_test + script_start) is default
+ events_to_check(Test, 2).
+
+events_to_check(_, 0) ->
+ [];
+events_to_check(Test, N) ->
+ test_events(Test) ++ events_to_check(Test, N-1).
+
+test_events(empty) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,scb,{empty_scb,init,[[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scb_empty_SUITE,init_per_suite}},
+ {?eh,scb,{empty_scb,pre_init_per_suite,[ct_scb_empty_SUITE,[]]}},
+ {?eh,scb,{empty_scb,post_init_per_suite,[ct_scb_empty_SUITE,[]]}},
+ {?eh,tc_done,{ct_scb_empty_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_scb_empty_SUITE,test_case}},
+ {?eh,scb,{empty_scb,pre_init_per_testcase,[test_case,[]]}},
+ {?eh,scb,{empty_scb,post_end_per_testcase,[test_case,[]]}},
+ {?eh,tc_done,{ct_scb_empty_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scb_empty_SUITE,end_per_suite}},
+ {?eh,scb,{empty_scb,pre_end_per_suite,[ct_scb_empty_SUITE,[]]}},
+ {?eh,scb,{empty_scb,post_end_per_suite,[ct_scb_empty_SUITE,[]]}},
+ {?eh,tc_done,{ct_scb_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,scb,{empty_scb,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ].
diff --git a/lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/ct_scb_empty_SUITE.erl b/lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/ct_scb_empty_SUITE.erl
new file mode 100644
index 0000000000..2c62379be3
--- /dev/null
+++ b/lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/ct_scb_empty_SUITE.erl
@@ -0,0 +1,110 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+
+-module(ct_scb_empty_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% @doc
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Initiation before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%
+%% @spec init_per_suite(Config) -> Config
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Cleanup after the whole suite
+%%
+%% @spec end_per_suite(Config) -> _
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Initiation before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Initiation before each test case
+%%
+%% @spec init_per_testcase(TestCase, Config) -> Config
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Cleanup after each test case
+%%
+%% @spec end_per_testcase(TestCase, Config) -> _
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%%
+%% Returns a list of all test cases in this test suite
+%%
+%% @spec all() -> TestCases
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+test_case(Config) when is_list(Config) ->
+ ok.