1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%% Common Test Example Suite Callback module.
22%%%
23%%% This module gives an example of a common test CTH (Common Test Hook).
24%%% There are many ways to add a CTH to a test run, you can do it either in
25%%% the command line using -ct_hook, in a test spec using
26%%% {ct_hook,M} or in the suite it self by returning ct_hook
27%%% from either suite/0, init_per_suite/1, init_per_group/2 and
28%%% init_per_testcase/2. The scope of the CTH is determined by where is it
29%%% started. If it is started in the command line or test spec then it will
30%%% be stopped at the end of all tests. If it is started in init_per_suite,
31%%% it will be stopped after end_per_suite and so on. See terminate
32%%% documentation for a table describing the scoping machanics.
33%%%
34%%% All of callbacks except init/1 in a CTH are optional.
35
36-module(empty_cth).
37
38%% CT Hooks
39-export([id/1]).
40-export([init/2]).
41
42-export([post_all/3]).
43-export([post_groups/2]).
44
45-export([pre_init_per_suite/3]).
46-export([post_init_per_suite/4]).
47-export([pre_end_per_suite/3]).
48-export([post_end_per_suite/4]).
49
50-export([pre_init_per_group/4]).
51-export([post_init_per_group/5]).
52-export([pre_end_per_group/4]).
53-export([post_end_per_group/5]).
54
55-export([pre_init_per_testcase/4]).
56-export([post_init_per_testcase/5]).
57-export([pre_end_per_testcase/4]).
58-export([post_end_per_testcase/5]).
59
60-export([on_tc_fail/4]).
61-export([on_tc_skip/4]).
62
63-export([terminate/1]).
64
65-include_lib("common_test/src/ct_util.hrl").
66-include_lib("common_test/include/ct_event.hrl").
67
68-type config() :: proplists:proplist().
69-type reason() :: term().
70-type skip_or_fail() :: {skip, reason()} |
71                        {auto_skip, reason()} |
72                        {fail, reason()} |
73			{'EXIT',reason()}.
74
75-record(state, { id = ?MODULE :: term()}).
76
77%% Called after groups/0.
78%% You can change the return value in this function.
79-spec post_groups(Suite :: atom(), Groups :: list()) -> list().
80post_groups(Suite,Groups) ->
81    gen_event:notify(
82      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
83			     data = {?MODULE, post_groups,
84				     [Suite,Groups]}}),
85    ct:log("~w:post_groups(~w) called", [?MODULE,Suite]),
86    Groups.
87
88%% Called after all/0.
89%% You can change the return value in this function.
90-spec post_all(Suite :: atom(),
91               Tests :: list(),
92               Groups :: term()) ->
93    list().
94post_all(Suite,Tests,Groups) ->
95    gen_event:notify(
96      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
97			     data = {?MODULE, post_all,
98				     [Suite,Tests,Groups]}}),
99    ct:log("~w:post_all(~w) called", [?MODULE,Suite]),
100    Tests.
101
102%% Always called before any other callback function. Use this to initiate
103%% any common state. It should return an state for this CTH.
104-spec init(Id :: term(), Opts :: proplists:proplist()) ->
105    {ok, State :: #state{}}.
106init(Id, Opts) ->
107    gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(),
108					    data = {?MODULE, init, [Id, Opts]}}),
109    ct:log("~w:init called", [?MODULE]),
110    {ok,Opts}.
111
112%% The ID is used to uniquly identify an CTH instance, if two CTH's
113%% return the same ID the seconds CTH is ignored. This function should NOT
114%% have any side effects as it might be called multiple times by common test.
115-spec id(Opts :: proplists:proplist()) ->
116    Id :: term().
117id(Opts) ->
118    gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(),
119					    data = {?MODULE, id, [Opts]}}),
120    ct:log("~w:id called", [?MODULE]),
121    ct_test_support:unique_timestamp().
122
123%% Called before init_per_suite is called. Note that this callback is
124%% only called if the CTH is added before init_per_suite is run (eg. in a test
125%% specification, suite/0 function etc).
126%% You can change the config in the this function.
127-spec pre_init_per_suite(Suite :: atom(),
128		     Config :: config(),
129		     State :: #state{}) ->
130    {config() | skip_or_fail(), NewState :: #state{}}.
131pre_init_per_suite(Suite,Config,State) ->
132    gen_event:notify(
133      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
134			     data = {?MODULE, pre_init_per_suite,
135				     [Suite,Config,State]}}),
136    ct:log("~w:pre_init_per_suite(~w) called", [?MODULE,Suite]),
137    {Config, State}.
138
139%% Called after init_per_suite.
140%% you can change the return value in this function.
141-spec post_init_per_suite(Suite :: atom(),
142			  Config :: config(),
143			  Return :: config() | skip_or_fail(),
144			  State :: #state{}) ->
145    {config() | skip_or_fail(), NewState :: #state{}}.
146post_init_per_suite(Suite,Config,Return,State) ->
147    gen_event:notify(
148      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
149			     data = {?MODULE, post_init_per_suite,
150				     [Suite,Config,Return,State]}}),
151    ct:log("~w:post_init_per_suite(~w) called", [?MODULE,Suite]),
152    {Return, State}.
153
154%% Called before end_per_suite. The config/state can be changed here,
155%% though it will only affect the *end_per_suite function.
156-spec pre_end_per_suite(Suite :: atom(),
157		    Config :: config() | skip_or_fail(),
158		    State :: #state{}) ->
159    {ok | skip_or_fail(), NewState :: #state{}}.
160pre_end_per_suite(Suite,Config,State) ->
161    gen_event:notify(
162      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
163			     data = {?MODULE, pre_end_per_suite,
164				     [Suite,Config,State]}}),
165    ct:log("~w:pre_end_per_suite(~w) called", [?MODULE,Suite]),
166    {Config, State}.
167
168%% Called after end_per_suite. Note that the config cannot be
169%% changed here, only the status of the suite.
170-spec post_end_per_suite(Suite :: atom(),
171			 Config :: config(),
172			 Return :: term(),
173			 State :: #state{}) ->
174    {ok | skip_or_fail(), NewState :: #state{}}.
175post_end_per_suite(Suite,Config,Return,State) ->
176    gen_event:notify(
177      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
178			     data = {?MODULE, post_end_per_suite,
179				     [Suite,Config,Return,State]}}),
180    ct:log("~w:post_end_per_suite(~w) called", [?MODULE,Suite]),
181    {Return, State}.
182
183%% Called before each init_per_group.
184%% You can change the config in this function.
185-spec pre_init_per_group(Suite :: atom(),
186                         Group :: atom(),
187                         Config :: config(),
188                         State :: #state{}) ->
189    {config() | skip_or_fail(), NewState :: #state{}}.
190pre_init_per_group(Suite,Group,Config,State) ->
191    gen_event:notify(
192      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
193			     data = {?MODULE, pre_init_per_group,
194				     [Suite,Group,Config,State]}}),
195    ct:log("~w:pre_init_per_group(~w,~w) called", [?MODULE,Suite,Group]),
196    {Config, State}.
197
198%% Called after each init_per_group.
199%% You can change the return value in this function.
200-spec post_init_per_group(Suite :: atom(),
201                          Group :: atom(),
202			  Config :: config(),
203			  Return :: config() | skip_or_fail(),
204			  State :: #state{}) ->
205    {config() | skip_or_fail(), NewState :: #state{}}.
206post_init_per_group(Suite,Group,Config,Return,State) ->
207    gen_event:notify(
208      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
209			     data = {?MODULE, post_init_per_group,
210				     [Suite,Group,Config,Return,State]}}),
211    ct:log("~w:post_init_per_group(~w,~w) called", [?MODULE,Suite,Group]),
212    {Return, State}.
213
214%% Called after each end_per_group. The config/state can be changed here,
215%% though it will only affect the *end_per_group functions.
216-spec pre_end_per_group(Suite :: atom(),
217                        Group :: atom(),
218			Config :: config() | skip_or_fail(),
219			State :: #state{}) ->
220    {ok | skip_or_fail(), NewState :: #state{}}.
221pre_end_per_group(Suite,Group,Config,State) ->
222    gen_event:notify(
223      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
224			     data = {?MODULE, pre_end_per_group,
225				     [Suite,Group,Config,State]}}),
226    ct:log("~w:pre_end_per_group(~w~w) called", [?MODULE,Suite,Group]),
227    {Config, State}.
228
229%% Called after each end_per_group. Note that the config cannot be
230%% changed here, only the status of the group.
231-spec post_end_per_group(Suite :: atom(),
232                         Group :: atom(),
233			 Config :: config(),
234			 Return :: term(),
235			 State :: #state{}) ->
236    {ok | skip_or_fail(), NewState :: #state{}}.
237post_end_per_group(Suite,Group,Config,Return,State) ->
238    gen_event:notify(
239      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
240			     data = {?MODULE, post_end_per_group,
241				     [Suite,Group,Config,Return,State]}}),
242    ct:log("~w:post_end_per_group(~w,~w) called", [?MODULE,Suite,Group]),
243    {Return, State}.
244
245%% Called before init_per_testcase/2 for each test case.
246%% You can change the config in this function.
247-spec pre_init_per_testcase(Suite :: atom(),
248                            TC :: atom(),
249                            Config :: config(),
250                            State :: #state{}) ->
251    {config() | skip_or_fail(), NewState :: #state{}}.
252pre_init_per_testcase(Suite,TC,Config,State) ->
253    gen_event:notify(
254      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
255			     data = {?MODULE, pre_init_per_testcase,
256				     [Suite,TC,Config,State]}}),
257    ct:log("~w:pre_init_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
258    {Config, State}.
259
260%% Called after init_per_testcase/2, and before the test case.
261-spec post_init_per_testcase(Suite :: atom(),
262                             TC :: atom(),
263			     Config :: config(),
264			     Return :: config() | skip_or_fail(),
265			     State :: #state{}) ->
266				    {config() | skip_or_fail(), NewState :: #state{}}.
267post_init_per_testcase(Suite,TC,Config,Return,State) ->
268    gen_event:notify(
269      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
270			     data = {?MODULE, post_init_per_testcase,
271				     [Suite,TC,Config,Return,State]}}),
272    ct:log("~w:post_init_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
273    {Return, State}.
274
275%% Called before end_per_testacse/2. No skip or fail allowed here,
276%% only config additions.
277-spec pre_end_per_testcase(Suite :: atom(),
278                           TC :: atom(),
279                           Config :: config(),
280                           State :: #state{}) ->
281    {config(), NewState :: #state{}}.
282pre_end_per_testcase(Suite,TC,Config,State) ->
283    gen_event:notify(
284      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
285			     data = {?MODULE, pre_end_per_testcase,
286				     [Suite,TC,Config,State]}}),
287    ct:log("~w:pre_end_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
288    {Config, State}.
289
290%% Called after end_per_testcase/2 for each test case. Note that
291%% the config cannot be changed here, only the status of the test case.
292-spec post_end_per_testcase(Suite :: atom(),
293                            TC :: atom(),
294			    Config :: config(),
295			    Return :: term(),
296			    State :: #state{}) ->
297    {ok | skip_or_fail(), NewState :: #state{}}.
298post_end_per_testcase(Suite,TC,Config,Return,State) ->
299    gen_event:notify(
300      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
301			     data = {?MODULE, post_end_per_testcase,
302				     [Suite,TC,Config,Return,State]}}),
303    ct:log("~w:post_end_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
304    {Return, State}.
305
306%% Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
307%% post_end_per_group and post_end_per_tc if the suite, group or test case failed.
308%% This function should be used for extra cleanup which might be needed.
309%% It is not possible to modify the config or the status of the test run.
310-spec on_tc_fail(Suite :: atom(),
311                 TC :: init_per_suite | end_per_suite |
312		       init_per_group | end_per_group | atom() |
313		       {Function :: atom(), GroupName :: atom()},
314		 Reason :: term(), State :: #state{}) -> NewState :: #state{}.
315on_tc_fail(Suite, TC, Reason, State) ->
316    gen_event:notify(
317      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
318			     data = {?MODULE, on_tc_fail,
319				     [Suite,TC,Reason,State]}}),
320    ct:log("~w:on_tc_fail(~w,~w) called", [?MODULE,Suite,TC]),
321    State.
322
323%% Called when a test case is skipped by either user action
324%% or due to an init function failing. Test case can be
325%% end_per_suite, init_per_group, end_per_group and the actual test cases.
326-spec on_tc_skip(Suite :: atom(),
327                 TC :: end_per_suite |
328		       init_per_group | end_per_group | atom() |
329		       {Function :: atom(), GroupName :: atom()},
330		 {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} |
331		 {tc_user_skip, {skipped, Reason :: term()}},
332		 State :: #state{}) -> NewState :: #state{}.
333on_tc_skip(Suite, TC, Reason, State) ->
334    gen_event:notify(
335      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
336			     data = {?MODULE, on_tc_skip,
337				     [Suite,TC,Reason,State]}}),
338    ct:log("~w:on_tc_skip(~w,~w) called", [?MODULE,Suite,TC]),
339    State.
340
341%% Called when the scope of the CTH is done, this depends on
342%% when the CTH was specified. This translation table describes when this
343%% function is called.
344%%
345%%  | Started in          |     terminate called    |
346%%  |---------------------|-------------------------|
347%%  | command_line        | after all tests are run |
348%%  | test spec           | after all tests are run |
349%%  | suite/0             | after SUITE is done     |
350%%  | init_per_suite/1    | after SUITE is done     |
351%%  | init_per_group/2    | after group is done     |
352%%  |-----------------------------------------------|
353%%
354-spec terminate(State :: #state{}) ->
355    term().
356terminate(State) ->
357    gen_event:notify(
358      ?CT_EVMGR_REF, #event{ name = cth, node = node(),
359			     data = {?MODULE, terminate, [State]}}),
360    ct:log("~w:terminate called", [?MODULE]),
361    ok.
362