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