From ea23dbfba71bf4bc17fb9c61b19dc3973ccc30f1 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 15 Mar 2012 00:01:13 +0100 Subject: Run hooks for non-existing config functions --- lib/common_test/src/ct_framework.erl | 43 +++++--- lib/common_test/src/ct_hooks.erl | 22 +++-- lib/common_test/src/ct_run.erl | 3 +- lib/test_server/src/test_server_ctrl.erl | 163 ++++++++++++++++++++++++------- 4 files changed, 175 insertions(+), 56 deletions(-) diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index cdd8a6a596..1536a5591e 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -29,7 +29,8 @@ -export([get_logopts/0, format_comment/1, get_html_wrapper/3]). --export([error_in_suite/1, ct_init_per_group/2, ct_end_per_group/2]). +-export([error_in_suite/1, init_per_suite/1, end_per_suite/1, + ct_init_per_group/2, ct_end_per_group/2]). -export([make_all_conf/3, make_conf/5]). @@ -69,14 +70,16 @@ init_tc(Mod,Func,Config) -> case ct_util:get_testdata(curr_tc) of {Suite,{suite0_failed,_}=Failure} -> {Failure,false}; - {?MODULE,_} -> % should not really happen - {false,false}; - {Suite,_} -> % Func is not 1st case in suite - {false,false}; - _ when Func == init_per_suite -> % defaults will be added anyway - {false,false}; - _ -> % first case in suite - {false,true} + {?MODULE,_} when Func == init_per_suite -> + {false,true}; % no init_per_suite in Mod + {?MODULE,_} -> + {false,false}; % should not really happen + {Suite,_} -> + {false,false}; % Func is not 1st case in suite + _ when Func == init_per_suite -> + {false,false}; % defaults will be added anyway + _ -> + {false,true} % first case in suite end, case InitFailed of false -> @@ -123,8 +126,9 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> {{Mod,LastFunc},SavedConfig} -> % last testcase [{saved_config,{LastFunc,SavedConfig}} | lists:keydelete(saved_config,1,Config0)]; - {{LastSuite,InitOrEnd},SavedConfig} when InitOrEnd == init_per_suite ; - InitOrEnd == end_per_suite -> + {{LastSuite,InitOrEnd}, + SavedConfig} when InitOrEnd == init_per_suite ; + InitOrEnd == end_per_suite -> %% last suite [{saved_config,{LastSuite,SavedConfig}} | lists:keydelete(saved_config,1,Config0)]; @@ -259,7 +263,11 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> end. ct_suite_init(Mod, Func, [Config]) when is_list(Config) -> - case ct_hooks:init_tc( Mod, Func, Config) of + +%%! --- Thu Mar 15 15:16:17 2012 --- peppe was here! +%%!io:format(user, "+++ ct_suite_init ~p:~p -- ~p~n", [Mod,Func,Config]), + + case ct_hooks:init_tc(Mod, Func, Config) of NewConfig when is_list(NewConfig) -> {ok, [NewConfig]}; Else -> @@ -1470,6 +1478,16 @@ error_in_suite(Config) -> Reason = test_server:lookup_config(error,Config), exit(Reason). +%% if init_per_suite and end_per_suite are missing in the suite, +%% these will be called instead (without any trace of them in the +%% log files), only so that it's possible to call hook functions +%% for configuration +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + %% if the group config functions are missing in the suite, %% use these instead ct_init_per_group(GroupName, Config) -> @@ -1485,7 +1503,6 @@ ct_end_per_group(GroupName, _) -> "in suite, using default.", [GroupName]), ok. - %%%----------------------------------------------------------------- %%% @spec report(What,Data) -> ok diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index c42adbbdd9..026f86c8a7 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -70,8 +70,7 @@ terminate(Hooks) -> {skip, Reason :: term()} | {auto_skip, Reason :: term()} | {fail, Reason :: term()}. -init_tc(ct_framework, _Func, Args) -> - Args; + init_tc(Mod, init_per_suite, Config) -> Info = try proplists:get_value(ct_hooks, Mod:suite(),[]) of List when is_list(List) -> @@ -89,6 +88,11 @@ init_tc(Mod, {init_per_group, GroupName, Opts}, Config) -> call(fun call_generic/3, Config, [pre_init_per_group, GroupName]); init_tc(_Mod, {end_per_group, GroupName, _}, Config) -> call(fun call_generic/3, Config, [pre_end_per_group, GroupName]); +init_tc(Mod, {ct_init_per_group, GroupName, Opts}, Config) -> + maybe_start_locker(Mod, GroupName, Opts), + call(fun call_generic/3, Config, [pre_init_per_group, GroupName]); +init_tc(_Mod, {ct_end_per_group, GroupName, _}, Config) -> + call(fun call_generic/3, Config, [pre_end_per_group, GroupName]); init_tc(_Mod, TC, Config) -> call(fun call_generic/3, Config, [pre_init_per_testcase, TC]). @@ -104,27 +108,29 @@ init_tc(_Mod, TC, Config) -> {auto_skip, Reason :: term()} | {fail, Reason :: term()} | ok | '$ct_no_change'. -end_tc(ct_framework, _Func, _Args, Result, _Return) -> - Result; end_tc(Mod, init_per_suite, Config, _Result, Return) -> call(fun call_generic/3, Return, [post_init_per_suite, Mod, Config], '$ct_no_change'); - end_tc(Mod, end_per_suite, Config, Result, _Return) -> call(fun call_generic/3, Result, [post_end_per_suite, Mod, Config], '$ct_no_change'); - end_tc(_Mod, {init_per_group, GroupName, _}, Config, _Result, Return) -> call(fun call_generic/3, Return, [post_init_per_group, GroupName, Config], '$ct_no_change'); - end_tc(Mod, {end_per_group, GroupName, Opts}, Config, Result, _Return) -> Res = call(fun call_generic/3, Result, [post_end_per_group, GroupName, Config], '$ct_no_change'), maybe_stop_locker(Mod, GroupName,Opts), Res; - +end_tc(_Mod, {ct_init_per_group, GroupName, _}, Config, _Result, Return) -> + call(fun call_generic/3, Return, [post_init_per_group, GroupName, Config], + '$ct_no_change'); +end_tc(Mod, {ct_end_per_group, GroupName, Opts}, Config, Result, _Return) -> + Res = call(fun call_generic/3, Result, + [post_end_per_group, GroupName, Config], '$ct_no_change'), + maybe_stop_locker(Mod, GroupName,Opts), + Res; end_tc(_Mod, TC, Config, Result, _Return) -> call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config], '$ct_no_change'). diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 666eb3c988..d142bdaa81 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -1413,7 +1413,8 @@ do_run(Tests, Skip, Opts, Args) when is_record(Opts, opts) -> %% which framework it runs under. case os:getenv("TEST_SERVER_FRAMEWORK") of false -> - os:putenv("TEST_SERVER_FRAMEWORK", "ct_framework"); + os:putenv("TEST_SERVER_FRAMEWORK", "ct_framework"), + os:putenv("TEST_SERVER_FRAMEWORK_NAME", "common_test"); "ct_framework" -> ok; Other -> diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 50720a45c8..91e469ed95 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -650,8 +650,8 @@ init([Param]) -> contact_main_target(local) -> %% When used by a general framework, global registration of %% test_server should not be required. - case os:getenv("TEST_SERVER_FRAMEWORK") of - FW when FW =:= false; FW =:= "undefined" -> + case get_fw_mod(undefined) of + undefined -> %% Local target! The global test_server process implemented by %% test_server.erl will not be started, so we simulate it by %% globally registering this process instead. @@ -1381,6 +1381,18 @@ init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev}, put(test_server_create_priv_dir, CreatePrivDir), put(test_server_random_seed, proplists:get_value(random_seed, ExtraTools)), put(test_server_testcase_callback, TCCallback), + case os:getenv("TEST_SERVER_FRAMEWORK") of + FW when FW =:= false; FW =:= "undefined" -> + put(test_server_framework, '$none'); + FW -> + put(test_server_framework_name, list_to_atom(FW)), + case os:getenv("TEST_SERVER_FRAMEWORK_NAME") of + FWName when FWName =:= false; FWName =:= "undefined" -> + put(test_server_framework_name, '$none'); + FWName -> + put(test_server_framework_name, list_to_atom(FWName)) + end + end, %% before first print, read and set logging options LogOpts = test_server_sup:framework_call(get_logopts, [], []), put(test_server_logopts, LogOpts), @@ -1700,11 +1712,7 @@ do_test_cases(TopCases, SkipCases, Config, TimetrapData) when is_list(TopCases), is_tuple(TimetrapData) -> {ok,TestDir} = start_log_file(), - FwMod = - case os:getenv("TEST_SERVER_FRAMEWORK") of - FW when FW =:= false; FW =:= "undefined" -> ?MODULE; - FW -> list_to_atom(FW) - end, + FwMod = get_fw_mod(?MODULE), case collect_all_cases(TopCases, SkipCases) of {error,Why} -> print(1, "Error starting: ~p", [Why]), @@ -2129,17 +2137,17 @@ add_init_and_end_per_suite([{make,_,_}=Case|Cases], LastMod, LastRef, FwMod) -> add_init_and_end_per_suite([{skip_case,{{Mod,all},_}}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod -> {PreCases, NextMod, NextRef} = - do_add_end_per_suite_and_skip(LastMod, LastRef, Mod), + do_add_end_per_suite_and_skip(LastMod, LastRef, Mod, FwMod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([{skip_case,{{Mod,_},_}}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod -> {PreCases, NextMod, NextRef} = - do_add_init_and_end_per_suite(LastMod, LastRef, Mod), + do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([{skip_case,{conf,_,{Mod,_},_}}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod -> {PreCases, NextMod, NextRef} = - do_add_init_and_end_per_suite(LastMod, LastRef, Mod), + do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([{skip_case,_}=Case|Cases], LastMod, LastRef, FwMod) -> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; @@ -2151,7 +2159,7 @@ add_init_and_end_per_suite([{conf,Ref,Props,{FwMod,Func}}=Case|Cases], LastMod, case proplists:get_value(suite, Props) of Suite when Suite =/= undefined, Suite =/= LastMod -> {PreCases, NextMod, NextRef} = - do_add_init_and_end_per_suite(LastMod, LastRef, Suite), + do_add_init_and_end_per_suite(LastMod, LastRef, Suite, FwMod), Case1 = {conf,Ref,proplists:delete(suite,Props),{FwMod,Func}}, PreCases ++ [Case1|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; @@ -2161,19 +2169,19 @@ add_init_and_end_per_suite([{conf,Ref,Props,{FwMod,Func}}=Case|Cases], LastMod, add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = - do_add_init_and_end_per_suite(LastMod, LastRef, Mod), + do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([{conf,_,_,_}=Case|Cases], LastMod, LastRef, FwMod) -> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; add_init_and_end_per_suite([{Mod,_}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = - do_add_init_and_end_per_suite(LastMod, LastRef, Mod), + do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([{Mod,_,_}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = - do_add_init_and_end_per_suite(LastMod, LastRef, Mod), + do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod), PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([Case|Cases], LastMod, LastRef, FwMod)-> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; @@ -2181,10 +2189,23 @@ add_init_and_end_per_suite([], _LastMod, undefined, _FwMod) -> []; add_init_and_end_per_suite([], _LastMod, skipped_suite, _FwMod) -> []; -add_init_and_end_per_suite([], LastMod, LastRef, _FwMod) -> - [{conf,LastRef,[],{LastMod,end_per_suite}}]. +add_init_and_end_per_suite([], LastMod, LastRef, FwMod) -> + %% we'll add end_per_suite here even if it's not exported + %% (and simply let the call fail if it's missing) + case erlang:function_exported(LastMod, end_per_suite, 1) of + true -> + [{conf,LastRef,[],{LastMod,end_per_suite}}]; + false -> + %% let's call a "fake" end_per_suite if it exists + case erlang:function_exported(FwMod, end_per_suite, 1) of + true -> + [{conf,LastRef,[],{FwMod,end_per_suite}}]; + false -> + [{conf,LastRef,[],{LastMod,end_per_suite}}] + end + end. -do_add_init_and_end_per_suite(LastMod, LastRef, Mod) -> +do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) -> case code:is_loaded(Mod) of false -> code:load_file(Mod); _ -> ok @@ -2195,7 +2216,15 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod) -> Ref = make_ref(), {[{conf,Ref,[],{Mod,init_per_suite}}],Mod,Ref}; false -> - {[],Mod,undefined} + %% let's call a "fake" init_per_suite if it exists + case erlang:function_exported(FwMod, init_per_suite, 1) of + true -> + Ref = make_ref(), + {[{conf,Ref,[],{FwMod,init_per_suite}}],Mod,Ref}; + false -> + {[],Mod,undefined} + end + end, Cases = if LastRef==undefined -> @@ -2203,20 +2232,43 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod) -> LastRef==skipped_suite -> Init; true -> - %% Adding end_per_suite here without checking if the - %% function is actually exported. This is because a - %% conf case must have an end case - so if it doesn't - %% exist, it will only fail... - [{conf,LastRef,[],{LastMod,end_per_suite}}|Init] + %% we'll add end_per_suite here even if it's not exported + %% (and simply let the call fail if it's missing) + case erlang:function_exported(LastMod, end_per_suite, 1) of + true -> + [{conf,LastRef,[],{LastMod,end_per_suite}}|Init]; + false -> + %% let's call a "fake" end_per_suite if it exists + case erlang:function_exported(FwMod, end_per_suite, 1) of + true -> + [{conf,LastRef,[],{FwMod,end_per_suite}}|Init]; + false -> + [{conf,LastRef,[],{LastMod,end_per_suite}}|Init] + end + end end, {Cases,NextMod,NextRef}. -do_add_end_per_suite_and_skip(LastMod, LastRef, Mod) -> +do_add_end_per_suite_and_skip(LastMod, LastRef, Mod, FwMod) -> case LastRef of No when No==undefined ; No==skipped_suite -> {[],Mod,skipped_suite}; _Ref -> - {[{conf,LastRef,[],{LastMod,end_per_suite}}],Mod,skipped_suite} + case erlang:function_exported(LastMod, end_per_suite, 1) of + true -> + {[{conf,LastRef,[],{LastMod,end_per_suite}}], + Mod,skipped_suite}; + false -> + case erlang:function_exported(FwMod, end_per_suite, 1) of + true -> + %% let's call "fake" end_per_suite if it exists + {[{conf,LastRef,[],{FwMod,end_per_suite}}], + Mod,skipped_suite}; + false -> + {[{conf,LastRef,[],{LastMod,end_per_suite}}], + Mod,skipped_suite} + end + end end. @@ -3289,7 +3341,7 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) -> print(major, "=started ~s", [lists:flatten(timestamp_get(""))]), print(major, "=result skipped: ~s", [Comment1]), print(2,"*** Skipping test case #~w ~p ***", [CaseNum,{Mod,Func}]), - TR = xhtml("", [""]), + TR = xhtml("", [""]), GroupName = case get_name(Mode) of undefined -> ""; Name -> cast_to_list(Name) @@ -3303,7 +3355,7 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) -> "" ++ Col0 ++ "0.000s" ++ Col1 ++ "" "SKIPPED" "~s\n", - [num2str(CaseNum),Mod,GroupName,Func,ResultCol,Comment1]), + [num2str(CaseNum),fw_name(Mod),GroupName,Func,ResultCol,Comment1]), if CaseNum > 0 -> {US,AS} = get(test_server_skipped), case Type of @@ -3742,7 +3794,8 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, "" ++ Col0 ++ "~s" ++ Col1 ++ "" "~p" "< >", - [num2str(Num),Mod,GroupName,MinorBase,Func,MinorBase,MinorBase]), + [num2str(Num),fw_name(Mod),GroupName,MinorBase,Func, + MinorBase,MinorBase]), do_if_parallel(Main, ok, fun erlang:yield/0), %% run the test case @@ -4189,6 +4242,46 @@ progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time, %%-------------------------------------------------------------------- %% various help functions +get_fw_mod(Mod) -> + case get(test_server_framework) of + undefined -> + case os:getenv("TEST_SERVER_FRAMEWORK") of + FW when FW =:= false; FW =:= "undefined" -> + Mod; + FW -> + list_to_atom(FW) + end; + '$none' -> Mod; + FW -> FW + end. + +fw_name(?MODULE) -> + test_server; +fw_name(Mod) -> + case get(test_server_framework_name) of + undefined -> + case get_fw_mod(undefined) of + undefined -> + Mod; + Mod -> + case os:getenv("TEST_SERVER_FRAMEWORK_NAME") of + FWName when FWName =:= false; FWName =:= "undefined" -> + Mod; + FWName -> + list_to_atom(FWName) + end; + _ -> + Mod + end; + '$none' -> + Mod; + FWName -> + case get_fw_mod(Mod) of + Mod -> FWName; + _ -> Mod + end + end. + if_auto_skip(Reason={failed,{_,init_per_testcase,_}}, True, _False) -> {Reason,True()}; if_auto_skip({_T,{skip,Reason={failed,{_,init_per_testcase,_}}},_Opts}, True, _False) -> @@ -4292,8 +4385,8 @@ get_font_style1(default) -> %% set to false. format_exception(Reason={_Error,Stack}) when is_list(Stack) -> - case os:getenv("TEST_SERVER_FRAMEWORK") of - FW when FW =:= false; FW =:= "undefined" -> + case get_fw_mod(undefined) of + undefined -> case application:get_env(test_server, format_exception) of {ok,false} -> {"~p",Reason}; @@ -4301,7 +4394,7 @@ format_exception(Reason={_Error,Stack}) when is_list(Stack) -> do_format_exception(Reason) end; FW -> - case application:get_env(list_to_atom(FW), format_exception) of + case application:get_env(FW, format_exception) of {ok,false} -> {"~p",Reason}; _ -> @@ -4897,8 +4990,8 @@ collect_case([Case | Cases], St, Acc) -> collect_case(Cases, NewSt, Acc ++ FlatCases). collect_case_invoke(Mod, Case, MFA, St) -> - case os:getenv("TEST_SERVER_FRAMEWORK") of - FW when FW =:= false; FW =:= "undefined" -> + case get_fw_mod(undefined) of + undefined -> case catch apply(Mod, Case, [suite]) of {'EXIT',_} -> {ok,[MFA],St}; @@ -4906,7 +4999,9 @@ collect_case_invoke(Mod, Case, MFA, St) -> collect_subcases(Mod, Case, MFA, St, Suite) end; _ -> - Suite = test_server_sup:framework_call(get_suite, [?pl2a(Mod),Case], []), + Suite = test_server_sup:framework_call(get_suite, + [?pl2a(Mod),Case], + []), collect_subcases(Mod, Case, MFA, St, Suite) end. -- cgit v1.2.3 From b411aa5d4e953d719d21f0108edfe20bde08c916 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 15 Mar 2012 16:34:49 +0100 Subject: Change ct_init/end_per_group to init/end_per_group OTP-9986 --- lib/common_test/src/ct_framework.erl | 32 ++--- lib/common_test/src/ct_hooks.erl | 13 -- lib/common_test/src/vts.erl | 4 - lib/common_test/test/ct_group_info_SUITE.erl | 172 ++++++++++++------------ lib/common_test/test/ct_groups_test_2_SUITE.erl | 8 +- 5 files changed, 101 insertions(+), 128 deletions(-) diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 1536a5591e..3b46768c8b 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -30,7 +30,7 @@ -export([get_logopts/0, format_comment/1, get_html_wrapper/3]). -export([error_in_suite/1, init_per_suite/1, end_per_suite/1, - ct_init_per_group/2, ct_end_per_group/2]). + init_per_group/2, end_per_group/2]). -export([make_all_conf/3, make_conf/5]). @@ -333,8 +333,7 @@ add_defaults1(Mod,Func, GroupPath, SuiteInfo, DoInit) -> _ -> [] end end, GroupPath), - Args = if Func == init_per_group; Func == ct_init_per_group; - Func == end_per_group; Func == ct_end_per_group -> + Args = if Func == init_per_group ; Func == end_per_group -> [?val(name, hd(GroupPath))]; true -> [] @@ -433,7 +432,7 @@ add_defaults2(Mod,init_per_suite, IPSInfo, SuiteInfo,SuiteReqs, false) -> add_defaults2(Mod,init_per_suite, IPSInfo, SuiteInfo,SuiteReqs, true); add_defaults2(_Mod,IPG, IPGAndGroupInfo, SuiteInfo,SuiteReqs, DoInit) when - IPG == init_per_group ; IPG == ct_init_per_group -> + IPG == init_per_group -> %% If DoInit == true, we have to process the suite() list, otherwise %% it has already been handled (see clause for init_per_suite) case DoInit of @@ -476,7 +475,7 @@ add_defaults2(_Mod,_Func, TCAndGroupInfo, SuiteInfo,SuiteReqs, false) -> add_defaults2(_Mod,_Func, TCInfo, SuiteInfo,SuiteReqs, true) -> %% Here we have to process the suite info list also (no call to %% init_per_suite before this first test case). This TC can't belong - %% to a group, or the clause for (ct_)init_per_group would've caught this. + %% to a group, or the clause for init_per_group would've caught this. Info = lists:flatten([TCInfo, SuiteReqs]), lists:flatten([Info,remove_info_in_prev(Info, [SuiteInfo])]). @@ -577,8 +576,6 @@ required_default(Name,Key,Info,_,{init_per_suite,_}) -> try_set_default(Name,Key,Info,suite); required_default(Name,Key,Info,_,{{init_per_group,GrName,_},_}) -> try_set_default(Name,Key,Info,{group,GrName}); -required_default(Name,Key,Info,_,{{ct_init_per_group,GrName,_},_}) -> - try_set_default(Name,Key,Info,{group,GrName}); required_default(Name,Key,Info,_,_FuncSpec) -> try_set_default(Name,Key,Info,testcase). @@ -647,7 +644,7 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> FuncSpec = case group_or_func(Func,Args) of {_,GroupName,_Props} = Group -> - if Func == end_per_group; Func == ct_end_per_group -> + if Func == end_per_group -> ct_config:delete_default_config({group,GroupName}); true -> ok end, @@ -872,9 +869,7 @@ mark_as_failed1(_,_,_,[]) -> ok. group_or_func(Func, Config) when Func == init_per_group; - Func == end_per_group; - Func == ct_init_per_group; - Func == ct_end_per_group -> + Func == end_per_group -> case ?val(tc_group_properties, Config) of undefined -> {Func,unknown,[]}; @@ -1217,8 +1212,8 @@ make_conf(Mod, Name, Props, TestSpec) -> "end_per_group/2 missing for group " "~p in ~p, using default.", [Name,Mod]), - {{?MODULE,ct_init_per_group}, - {?MODULE,ct_end_per_group}, + {{?MODULE,init_per_group}, + {?MODULE,end_per_group}, [{suite,Mod}]} end, {conf,[{name,Name}|Props++ExtraProps],InitConf,TestSpec,EndConf}. @@ -1490,14 +1485,14 @@ end_per_suite(_Config) -> %% if the group config functions are missing in the suite, %% use these instead -ct_init_per_group(GroupName, Config) -> +init_per_group(GroupName, Config) -> ct:comment(io_lib:format("start of ~p", [GroupName])), ct_logs:log("TEST INFO", "init_per_group/2 for ~w missing " "in suite, using default.", [GroupName]), Config. -ct_end_per_group(GroupName, _) -> +end_per_group(GroupName, _) -> ct:comment(io_lib:format("end of ~p", [GroupName])), ct_logs:log("TEST INFO", "end_per_group/2 for ~w missing " "in suite, using default.", @@ -1579,10 +1574,6 @@ report(What,Data) -> ok; {end_per_group,_} -> ok; - {ct_init_per_group,_} -> - ok; - {ct_end_per_group,_} -> - ok; {_,ok} -> add_to_stats(ok); {_,{skipped,{failed,{_,init_per_testcase,_}}}} -> @@ -1619,8 +1610,7 @@ report(What,Data) -> data=Data}), ct_hooks:on_tc_skip(What, Data), if Case /= end_per_suite, - Case /= end_per_group, - Case /= ct_end_per_group -> + Case /= end_per_group -> add_to_stats(auto_skipped); true -> ok diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index 026f86c8a7..2a23cd992b 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -88,11 +88,6 @@ init_tc(Mod, {init_per_group, GroupName, Opts}, Config) -> call(fun call_generic/3, Config, [pre_init_per_group, GroupName]); init_tc(_Mod, {end_per_group, GroupName, _}, Config) -> call(fun call_generic/3, Config, [pre_end_per_group, GroupName]); -init_tc(Mod, {ct_init_per_group, GroupName, Opts}, Config) -> - maybe_start_locker(Mod, GroupName, Opts), - call(fun call_generic/3, Config, [pre_init_per_group, GroupName]); -init_tc(_Mod, {ct_end_per_group, GroupName, _}, Config) -> - call(fun call_generic/3, Config, [pre_end_per_group, GroupName]); init_tc(_Mod, TC, Config) -> call(fun call_generic/3, Config, [pre_init_per_testcase, TC]). @@ -123,14 +118,6 @@ end_tc(Mod, {end_per_group, GroupName, Opts}, Config, Result, _Return) -> [post_end_per_group, GroupName, Config], '$ct_no_change'), maybe_stop_locker(Mod, GroupName,Opts), Res; -end_tc(_Mod, {ct_init_per_group, GroupName, _}, Config, _Result, Return) -> - call(fun call_generic/3, Return, [post_init_per_group, GroupName, Config], - '$ct_no_change'); -end_tc(Mod, {ct_end_per_group, GroupName, Opts}, Config, Result, _Return) -> - Res = call(fun call_generic/3, Result, - [post_end_per_group, GroupName, Config], '$ct_no_change'), - maybe_stop_locker(Mod, GroupName,Opts), - Res; end_tc(_Mod, TC, Config, Result, _Return) -> call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config], '$ct_no_change'). diff --git a/lib/common_test/src/vts.erl b/lib/common_test/src/vts.erl index cc8a932887..9dfb0bd6b8 100644 --- a/lib/common_test/src/vts.erl +++ b/lib/common_test/src/vts.erl @@ -766,10 +766,6 @@ report1(tc_done,{_Suite,init_per_group,_},State) -> State; report1(tc_done,{_Suite,end_per_group,_},State) -> State; -report1(tc_done,{_Suite,ct_init_per_group,_},State) -> - State; -report1(tc_done,{_Suite,ct_end_per_group,_},State) -> - State; report1(tc_done,{_Suite,_Case,ok},State) -> State#state{ok=State#state.ok+1}; report1(tc_done,{_Suite,_Case,{failed,_Reason}},State) -> diff --git a/lib/common_test/test/ct_group_info_SUITE.erl b/lib/common_test/test/ct_group_info_SUITE.erl index 2da8219196..18016c4979 100644 --- a/lib/common_test/test/ct_group_info_SUITE.erl +++ b/lib/common_test/test/ct_group_info_SUITE.erl @@ -440,72 +440,72 @@ test_events(timetrap_all_no_ipg) -> {?eh,tc_done,{group_timetrap_3_SUITE,t1,{failed,{timetrap_timeout,1000}}}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g1,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g1,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g1,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g1,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t11,{failed,{timetrap_timeout,500}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g1,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g1,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g1,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g1,[{suite,group_timetrap_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g2,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g2,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g2,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g2,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t21,{failed,{timetrap_timeout,1500}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g2,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g2,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g2,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g2,[{suite,group_timetrap_3_SUITE}]},ok}}], {?eh,tc_done,{group_timetrap_3_SUITE,t2,{failed,{timetrap_timeout,1000}}}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g3,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g3,[{suite,group_timetrap_3_SUITE}]},ok}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g4,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g4,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g3,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g3,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g4,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g4,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t41,{failed,{timetrap_timeout,250}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g4,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g4,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g4,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g4,[{suite,group_timetrap_3_SUITE}]},ok}}], {?eh,tc_done,{group_timetrap_3_SUITE,t31,{failed,{timetrap_timeout,500}}}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g5,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g5,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g5,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g5,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t51,{failed,{timetrap_timeout,1500}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g5,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g5,[{suite,group_timetrap_3_SUITE}]},ok}}], - {?eh,tc_start,{ct_framework,{ct_end_per_group,g3,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g3,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g5,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g5,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g3,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g3,[{suite,group_timetrap_3_SUITE}]},ok}}], {?eh,tc_done,{group_timetrap_3_SUITE,t3,{failed,{timetrap_timeout,250}}}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g6,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g6,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g6,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g6,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t61,{failed,{timetrap_timeout,500}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g6,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g6,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g6,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g6,[{suite,group_timetrap_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g7,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g7,[{suite,group_timetrap_3_SUITE}]},ok}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g8,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g8,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g7,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g7,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g8,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g8,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t81,{failed,{timetrap_timeout,750}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g8,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g8,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g8,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g8,[{suite,group_timetrap_3_SUITE}]},ok}}], {?eh,tc_done,{group_timetrap_3_SUITE,t71,{failed,{timetrap_timeout,500}}}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g9,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g9,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g9,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g9,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t91,{failed,{timetrap_timeout,250}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g9,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g9,[{suite,group_timetrap_3_SUITE}]},ok}}], - {?eh,tc_start,{ct_framework,{ct_end_per_group,g7,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g7,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g9,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g9,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g7,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g7,[{suite,group_timetrap_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g10,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g10,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g10,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g10,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t101,{failed,{timetrap_timeout,1000}}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g10,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g10,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g10,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g10,[{suite,group_timetrap_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g11,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g11,[{suite,group_timetrap_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g11,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g11,[{suite,group_timetrap_3_SUITE}]},ok}}, {?eh,tc_done,{group_timetrap_3_SUITE,t111,{failed,{timetrap_timeout,1000}}}}, {?eh,test_stats,{0,14,{0,0}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g11,[{suite,group_timetrap_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g11,[{suite,group_timetrap_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g11,[{suite,group_timetrap_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g11,[{suite,group_timetrap_3_SUITE}]},ok}}], {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]} @@ -779,78 +779,78 @@ test_events(require_no_ipg) -> {?eh,start_info,{1,1,13}}, {?eh,tc_done,{group_require_3_SUITE,t1,ok}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g1,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g1,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g1,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g1,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t11,ok}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g1,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g1,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g1,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g1,[{suite,group_require_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g2,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g2,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g2,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g2,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t21,ok}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g2,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g2,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g2,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g2,[{suite,group_require_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g3,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g3,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g3,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g3,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t31,ok}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g3,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g3,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g3,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g3,[{suite,group_require_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g4,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g4,[{suite,group_require_3_SUITE}]}, + [{?eh,tc_start,{ct_framework,{init_per_group,g4,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g4,[{suite,group_require_3_SUITE}]}, {skipped,{require_failed,{name_in_use,common2_alias,common2}}}}}, {?eh,tc_auto_skip,{group_require_3_SUITE,t41, {require_failed,{name_in_use,common2_alias,common2}}}}, {?eh,test_stats,{4,0,{0,1}}}, - {?eh,tc_auto_skip,{ct_framework,ct_end_per_group, + {?eh,tc_auto_skip,{ct_framework,end_per_group, {require_failed,{name_in_use,common2_alias,common2}}}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g5,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g5,[{suite,group_require_3_SUITE}]},ok}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g6,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g6,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g5,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g5,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g6,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g6,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t61,ok}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g6,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g6,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g6,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g6,[{suite,group_require_3_SUITE}]},ok}}], {?eh,tc_done,{group_require_3_SUITE,t51,ok}}, - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g7,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g7,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g7,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g7,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t71,ok}}, {?eh,tc_done,{group_require_3_SUITE,t72,ok}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g7,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g7,[{suite,group_require_3_SUITE}]},ok}}], - {?eh,tc_start,{ct_framework,{ct_end_per_group,g5,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g5,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g7,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g7,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g5,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g5,[{suite,group_require_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g8,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g8,[{suite,group_require_3_SUITE}]}, + [{?eh,tc_start,{ct_framework,{init_per_group,g8,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g8,[{suite,group_require_3_SUITE}]}, {skipped,{require_failed,{not_available,non_existing}}}}}, {?eh,tc_auto_skip,{group_require_3_SUITE,t81, {require_failed,{not_available,non_existing}}}}, {?eh,test_stats,{8,0,{0,2}}}, - {?eh,tc_auto_skip,{ct_framework,ct_end_per_group, + {?eh,tc_auto_skip,{ct_framework,end_per_group, {require_failed,{not_available,non_existing}}}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g9,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g9,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g9,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g9,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t91, {skipped,{require_failed,{not_available,non_existing}}}}}, {?eh,test_stats,{8,0,{0,3}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g9,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g9,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g9,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g9,[{suite,group_require_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g10,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g10,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g10,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g10,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t101,ok}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g10,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g10,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g10,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g10,[{suite,group_require_3_SUITE}]},ok}}], - [{?eh,tc_start,{ct_framework,{ct_init_per_group,g11,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,g11,[{suite,group_require_3_SUITE}]},ok}}, + [{?eh,tc_start,{ct_framework,{init_per_group,g11,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,g11,[{suite,group_require_3_SUITE}]},ok}}, {?eh,tc_done,{group_require_3_SUITE,t111,ok}}, {?eh,test_stats,{10,0,{0,3}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,g11,[{suite,group_require_3_SUITE}]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,g11,[{suite,group_require_3_SUITE}]},ok}}], + {?eh,tc_start,{ct_framework,{end_per_group,g11,[{suite,group_require_3_SUITE}]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,g11,[{suite,group_require_3_SUITE}]},ok}}], {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]} diff --git a/lib/common_test/test/ct_groups_test_2_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE.erl index 2392b0b850..c3601ba0ce 100644 --- a/lib/common_test/test/ct_groups_test_2_SUITE.erl +++ b/lib/common_test/test/ct_groups_test_2_SUITE.erl @@ -171,16 +171,16 @@ test_events(missing_conf) -> {?eh,start_logging,{'DEF','RUNDIR'}}, {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, {?eh,start_info,{1,1,2}}, - {?eh,tc_start,{ct_framework,{ct_init_per_group,group1,[]}}}, - {?eh,tc_done,{ct_framework,{ct_init_per_group,group1,[]},ok}}, + {?eh,tc_start,{ct_framework,{init_per_group,group1,[]}}}, + {?eh,tc_done,{ct_framework,{init_per_group,group1,[]},ok}}, {?eh,tc_start,{missing_conf_SUITE,tc1}}, {?eh,tc_done,{missing_conf_SUITE,tc1,ok}}, {?eh,test_stats,{1,0,{0,0}}}, {?eh,tc_start,{missing_conf_SUITE,tc2}}, {?eh,tc_done,{missing_conf_SUITE,tc2,ok}}, {?eh,test_stats,{2,0,{0,0}}}, - {?eh,tc_start,{ct_framework,{ct_end_per_group,group1,[]}}}, - {?eh,tc_done,{ct_framework,{ct_end_per_group,group1,[]},ok}}, + {?eh,tc_start,{ct_framework,{end_per_group,group1,[]}}}, + {?eh,tc_done,{ct_framework,{end_per_group,group1,[]},ok}}, {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]} ]; -- cgit v1.2.3 From 2409000567436f33fd912e9a809cc9dda3e9172f Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Fri, 16 Mar 2012 01:35:21 +0100 Subject: Use calls to ct_framework:init/end_per_suite for configuration Now that calls to ct_framework:init/end_per_suite take place whenever init/end_per_suite is missing in the test suite, these calls should trigger init/end_tc to perform configuration (such as calling calling CTH functions, suite/0, etc). --- lib/common_test/src/ct_framework.erl | 185 ++++++++------------- lib/common_test/src/ct_hooks.erl | 19 ++- lib/common_test/test/ct_test_server_if_1_SUITE.erl | 17 +- lib/test_server/src/test_server_ctrl.erl | 11 +- 4 files changed, 100 insertions(+), 132 deletions(-) diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 3b46768c8b..1d81b19fe1 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -55,6 +55,7 @@ init_tc(Mod,Func,Config) -> %% in case Mod == ct_framework, lookup the suite name Suite = get_suite_name(Mod, Config), + %% check if previous testcase was interpreted and has left %% a "dead" trace window behind - if so, kill it case ct_util:get_testdata(interpret) of @@ -64,29 +65,17 @@ init_tc(Mod,Func,Config) -> _ -> ok end, - %% check if we need to add defaults explicitly because - %% there's no init_per_suite exported from Mod - {InitFailed,DoInit} = - case ct_util:get_testdata(curr_tc) of - {Suite,{suite0_failed,_}=Failure} -> - {Failure,false}; - {?MODULE,_} when Func == init_per_suite -> - {false,true}; % no init_per_suite in Mod - {?MODULE,_} -> - {false,false}; % should not really happen - {Suite,_} -> - {false,false}; % Func is not 1st case in suite - _ when Func == init_per_suite -> - {false,false}; % defaults will be added anyway - _ -> - {false,true} % first case in suite - end, - case InitFailed of - false -> + + case ct_util:get_testdata(curr_tc) of + {Suite,{suite0_failed,{require,Reason}}} -> + {skip,{require_failed_in_suite0,Reason}}; + {Suite,{suite0_failed,_}=Failure} -> + {skip,Failure}; + _ -> ct_util:set_testdata({curr_tc,{Suite,Func}}), case ct_util:read_suite_data({seq,Suite,Func}) of undefined -> - init_tc1(Mod,Func,Config,DoInit); + init_tc1(Mod,Suite,Func,Config); Seq when is_atom(Seq) -> case ct_util:read_suite_data({seq,Suite,Seq}) of [Func|TCs] -> % this is the 1st case in Seq @@ -99,17 +88,13 @@ init_tc(Mod,Func,Config) -> _ -> ok end, - init_tc1(Mod,Func,Config,DoInit); + init_tc1(Mod,Suite,Func,Config); {failed,Seq,BadFunc} -> {skip,{sequence_failed,Seq,BadFunc}} - end; - {_,{require,Reason}} -> - {skip,{require_failed_in_suite0,Reason}}; - _ -> - {skip,InitFailed} + end end. -init_tc1(?MODULE,error_in_suite,[Config0],_) when is_list(Config0) -> +init_tc1(?MODULE,_,error_in_suite,[Config0]) when is_list(Config0) -> ct_logs:init_tc(false), ct_event:notify(#event{name=tc_start, node=node(), @@ -120,10 +105,11 @@ init_tc1(?MODULE,error_in_suite,[Config0],_) when is_list(Config0) -> Reason -> {skip,Reason} end; -init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> + +init_tc1(Mod,Suite,Func,[Config0]) when is_list(Config0) -> Config1 = case ct_util:read_suite_data(last_saved_config) of - {{Mod,LastFunc},SavedConfig} -> % last testcase + {{Suite,LastFunc},SavedConfig} -> % last testcase [{saved_config,{LastFunc,SavedConfig}} | lists:keydelete(saved_config,1,Config0)]; {{LastSuite,InitOrEnd}, @@ -137,13 +123,14 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> end, ct_util:delete_suite_data(last_saved_config), Config = lists:keydelete(watchdog,1,Config1), - if Func /= init_per_suite, DoInit /= true -> - ok; - true -> + + if Func == init_per_suite -> %% delete all default values used in previous suite ct_config:delete_default_config(suite), %% release all name -> key bindings (once per suite) - ct_config:release_allocated() + ct_config:release_allocated(); + Func /= init_per_suite -> + ok end, GroupPath = ?val(tc_group_path, Config, []), @@ -158,9 +145,7 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> true -> ct_config:delete_default_config(testcase) end, - %% in case Mod == ct_framework, lookup the suite name - Suite = get_suite_name(Mod, Config), - case add_defaults(Mod,Func,AllGroups,DoInit) of + case add_defaults(Mod,Func,AllGroups) of Error = {suite0_failed,_} -> ct_logs:init_tc(false), ct_event:notify(#event{name=tc_start, @@ -170,35 +155,25 @@ init_tc1(Mod,Func,[Config0],DoInit) when is_list(Config0) -> {error,Error}; {SuiteInfo,MergeResult} -> case MergeResult of - {error,Reason} when DoInit == false -> + {error,Reason} -> ct_logs:init_tc(false), ct_event:notify(#event{name=tc_start, node=node(), data={Mod,FuncSpec}}), {skip,Reason}; _ -> - init_tc2(Mod,Func,SuiteInfo,MergeResult, - Config,DoInit) + init_tc2(Mod,Suite,Func,SuiteInfo,MergeResult,Config) end end; -init_tc1(_Mod,_Func,Args,_DoInit) -> - {ok,Args}. -init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> - %% if first testcase fails when there's no init_per_suite - %% we must do suite/0 configurations before skipping test - MergedInfo = - case MergeResult of - {error,_} when DoInit == true -> - SuiteInfo; - _ -> - MergeResult - end, +init_tc1(_Mod,_Suite,_Func,Args) -> + {ok,Args}. +init_tc2(Mod,Suite,Func,SuiteInfo,MergeResult,Config) -> %% timetrap must be handled before require - MergedInfo1 = timetrap_first(MergedInfo, [], []), + MergedInfo = timetrap_first(MergeResult, [], []), %% tell logger to use specified style sheet - case lists:keysearch(stylesheet,1,MergedInfo++Config) of + case lists:keysearch(stylesheet,1,MergeResult++Config) of {value,{stylesheet,SSFile}} -> ct_logs:set_stylesheet(Func,add_data_dir(SSFile,Config)); _ -> @@ -213,7 +188,7 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> %% list of {Type,Bool} tuples, e.g. {telnet,true}), case ct_util:get_overridden_silenced_connections() of undefined -> - case lists:keysearch(silent_connections,1,MergedInfo++Config) of + case lists:keysearch(silent_connections,1,MergeResult++Config) of {value,{silent_connections,Conns}} -> ct_util:silence_connections(Conns); _ -> @@ -222,18 +197,14 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> Conns -> ct_util:silence_connections(Conns) end, - if Func /= init_per_suite, DoInit /= true -> - ct_logs:init_tc(false); - true -> - ct_logs:init_tc(true) - end, + ct_logs:init_tc(Func == init_per_suite), FuncSpec = group_or_func(Func,Config), ct_event:notify(#event{name=tc_start, node=node(), data={Mod,FuncSpec}}), - case catch configure(MergedInfo1,MergedInfo1,SuiteInfo, - {FuncSpec,DoInit},Config) of + case catch configure(MergedInfo,MergedInfo,SuiteInfo, + FuncSpec,Config) of {suite0_failed,Reason} -> ct_util:set_testdata({curr_tc,{Mod,{suite0_failed,{require,Reason}}}}), {skip,{require_failed_in_suite0,Reason}}; @@ -250,7 +221,7 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> _ -> case get('$test_server_framework_test') of undefined -> - ct_suite_init(Mod, FuncSpec, FinalConfig); + ct_suite_init(Suite, FuncSpec, FinalConfig); Fun -> case Fun(init_tc, FinalConfig) of NewConfig when is_list(NewConfig) -> @@ -262,25 +233,21 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) -> end end. -ct_suite_init(Mod, Func, [Config]) when is_list(Config) -> - -%%! --- Thu Mar 15 15:16:17 2012 --- peppe was here! -%%!io:format(user, "+++ ct_suite_init ~p:~p -- ~p~n", [Mod,Func,Config]), - - case ct_hooks:init_tc(Mod, Func, Config) of +ct_suite_init(Suite, Func, [Config]) when is_list(Config) -> + case ct_hooks:init_tc(Suite, Func, Config) of NewConfig when is_list(NewConfig) -> {ok, [NewConfig]}; Else -> Else end. -add_defaults(Mod,Func, GroupPath, DoInit) -> +add_defaults(Mod,Func, GroupPath) -> Suite = get_suite_name(Mod, GroupPath), case (catch Suite:suite()) of {'EXIT',{undef,_}} -> SuiteInfo = merge_with_suite_defaults(Suite,[]), SuiteInfoNoCTH = [I || I <- SuiteInfo, element(1,I) =/= ct_hooks], - case add_defaults1(Mod,Func, GroupPath, SuiteInfoNoCTH, DoInit) of + case add_defaults1(Mod,Func, GroupPath, SuiteInfoNoCTH) of Error = {error,_} -> {SuiteInfo,Error}; MergedInfo -> {SuiteInfo,MergedInfo} end; @@ -300,7 +267,7 @@ add_defaults(Mod,Func, GroupPath, DoInit) -> SuiteInfoNoCTH = [I || I <- SuiteInfo1, element(1,I) =/= ct_hooks], case add_defaults1(Mod,Func, GroupPath, - SuiteInfoNoCTH, DoInit) of + SuiteInfoNoCTH) of Error = {error,_} -> {SuiteInfo1,Error}; MergedInfo -> {SuiteInfo1,MergedInfo} end; @@ -321,7 +288,7 @@ add_defaults(Mod,Func, GroupPath, DoInit) -> {suite0_failed,bad_return_value} end. -add_defaults1(Mod,Func, GroupPath, SuiteInfo, DoInit) -> +add_defaults1(Mod,Func, GroupPath, SuiteInfo) -> Suite = get_suite_name(Mod, GroupPath), %% GroupPathInfo (for subgroup on level X) = %% [LevelXGroupInfo, LevelX-1GroupInfo, ..., TopLevelGroupInfo] @@ -354,7 +321,7 @@ add_defaults1(Mod,Func, GroupPath, SuiteInfo, DoInit) -> (default_config == element(1,SDDef)))], case check_for_clashes(TestCaseInfo, GroupPathInfo, SuiteReqs) of [] -> - add_defaults2(Mod,Func, TCAndGroupInfo,SuiteInfo,SuiteReqs, DoInit); + add_defaults2(Mod,Func, TCAndGroupInfo,SuiteInfo,SuiteReqs); Clashes -> {error,{config_name_already_in_use,Clashes}} end. @@ -428,34 +395,25 @@ keysmember([Key,Pos|Next], List) -> keysmember([], _) -> true. -add_defaults2(Mod,init_per_suite, IPSInfo, SuiteInfo,SuiteReqs, false) -> - add_defaults2(Mod,init_per_suite, IPSInfo, SuiteInfo,SuiteReqs, true); +add_defaults2(_Mod,init_per_suite, IPSInfo, SuiteInfo,SuiteReqs) -> + Info = lists:flatten([IPSInfo, SuiteReqs]), + lists:flatten([Info,remove_info_in_prev(Info, [SuiteInfo])]); -add_defaults2(_Mod,IPG, IPGAndGroupInfo, SuiteInfo,SuiteReqs, DoInit) when - IPG == init_per_group -> - %% If DoInit == true, we have to process the suite() list, otherwise - %% it has already been handled (see clause for init_per_suite) - case DoInit of - true -> - %% note: we know for sure this is a top level group - Info = lists:flatten([IPGAndGroupInfo, SuiteReqs]), - Info ++ remove_info_in_prev(Info, [SuiteInfo]); - false -> - SuiteInfo1 = - remove_info_in_prev(lists:flatten([IPGAndGroupInfo, - SuiteReqs]), [SuiteInfo]), - %% don't require terms in prev groups (already processed) - case IPGAndGroupInfo of - [IPGInfo] -> - lists:flatten([IPGInfo,SuiteInfo1]); - [IPGInfo | [CurrGroupInfo | PrevGroupInfo]] -> - PrevGroupInfo1 = delete_require_terms(PrevGroupInfo), - lists:flatten([IPGInfo,CurrGroupInfo,PrevGroupInfo1, - SuiteInfo1]) - end +add_defaults2(_Mod,init_per_group, IPGAndGroupInfo, SuiteInfo,SuiteReqs) -> + SuiteInfo1 = + remove_info_in_prev(lists:flatten([IPGAndGroupInfo, + SuiteReqs]), [SuiteInfo]), + %% don't require terms in prev groups (already processed) + case IPGAndGroupInfo of + [IPGInfo] -> + lists:flatten([IPGInfo,SuiteInfo1]); + [IPGInfo | [CurrGroupInfo | PrevGroupInfo]] -> + PrevGroupInfo1 = delete_require_terms(PrevGroupInfo), + lists:flatten([IPGInfo,CurrGroupInfo,PrevGroupInfo1, + SuiteInfo1]) end; -add_defaults2(_Mod,_Func, TCAndGroupInfo, SuiteInfo,SuiteReqs, false) -> +add_defaults2(_Mod,_Func, TCAndGroupInfo, SuiteInfo,SuiteReqs) -> %% Include require elements from test case info and current group, %% but not from previous groups or suite/0 (since we've already required %% those vars). Let test case info elements override group and suite @@ -470,14 +428,7 @@ add_defaults2(_Mod,_Func, TCAndGroupInfo, SuiteInfo,SuiteReqs, false) -> PrevGroupInfo1 = delete_require_terms(PrevGroupInfo), lists:flatten([TCInfo,CurrGroupInfo,PrevGroupInfo1, SuiteInfo1]) - end; - -add_defaults2(_Mod,_Func, TCInfo, SuiteInfo,SuiteReqs, true) -> - %% Here we have to process the suite info list also (no call to - %% init_per_suite before this first test case). This TC can't belong - %% to a group, or the clause for init_per_group would've caught this. - Info = lists:flatten([TCInfo, SuiteReqs]), - lists:flatten([Info,remove_info_in_prev(Info, [SuiteInfo])]). + end. delete_require_terms([Info | Prev]) -> Info1 = [T || T <- Info, @@ -565,16 +516,9 @@ configure([],_,_,_,Config) -> %% function and be scoped 'group', or come from the testcase %% info function and then be scoped 'testcase' -required_default(Name,Key,Info,SuiteInfo,{FuncSpec,true}) -> - case try_set_default(Name,Key,SuiteInfo,suite) of - ok -> - ok; - _ -> - required_default(Name,Key,Info,[],{FuncSpec,false}) - end; -required_default(Name,Key,Info,_,{init_per_suite,_}) -> +required_default(Name,Key,Info,_,init_per_suite) -> try_set_default(Name,Key,Info,suite); -required_default(Name,Key,Info,_,{{init_per_group,GrName,_},_}) -> +required_default(Name,Key,Info,_,{init_per_group,GrName,_}) -> try_set_default(Name,Key,Info,{group,GrName}); required_default(Name,Key,Info,_,_FuncSpec) -> try_set_default(Name,Key,Info,testcase). @@ -626,6 +570,9 @@ end_tc(Mod,Func,{Result,[Args]}, Return) -> end_tc(Mod,Func,self(),Result,Args,Return). end_tc(Mod,Func,TCPid,Result,Args,Return) -> + %% in case Mod == ct_framework, lookup the suite name + Suite = get_suite_name(Mod, Args), + case lists:keysearch(watchdog,1,Args) of {value,{watchdog,Dog}} -> test_server:timetrap_cancel(Dog); false -> ok @@ -652,7 +599,7 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> {value,{save_config,SaveConfig}} -> ct_util:save_suite_data( last_saved_config, - {Mod,{group,GroupName}}, + {Suite,{group,GroupName}}, SaveConfig), Group; false -> @@ -662,7 +609,7 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> case lists:keysearch(save_config,1,Args) of {value,{save_config,SaveConfig}} -> ct_util:save_suite_data(last_saved_config, - {Mod,Func},SaveConfig), + {Suite,Func},SaveConfig), Func; false -> Func @@ -674,7 +621,7 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> undefined -> {FinalResult,FinalNotify} = case ct_hooks:end_tc( - Mod, FuncSpec, Args, Result, Return) of + Suite, FuncSpec, Args, Result, Return) of '$ct_no_change' -> {ok,Result}; FinalResult1 -> @@ -711,7 +658,7 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> end, case Func of end_per_suite -> - ct_util:match_delete_suite_data({seq,Mod,'_'}); + ct_util:match_delete_suite_data({seq,Suite,'_'}); _ -> ok end, diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index 2a23cd992b..8f452ef5e3 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -213,10 +213,25 @@ call([{HookId, Fun} | Rest], Config, Meta, Hooks) -> try Hook = lists:keyfind(HookId, #ct_hook_config.id, Hooks), {NewConf, NewHook} = Fun(Hook, Config, Meta), - NewCalls = get_new_hooks(NewConf, Fun), + + %%! --- Fri Mar 16 17:27:25 2012 --- peppe was here! + %%!!?? + NewConf1 = + if is_tuple(NewConf) -> + if element(1, NewConf) == skip; + element(1, NewConf) == fail -> + Config; + true -> + NewConf + end; + true -> + NewConf + end, + + NewCalls = get_new_hooks(NewConf1, Fun), NewHooks = lists:keyreplace(HookId, #ct_hook_config.id, Hooks, NewHook), call(resort(NewCalls ++ Rest,NewHooks,Meta), %% Resort if call_init changed prio - remove(?config_name, NewConf), Meta, + remove(?config_name, NewConf1), Meta, terminate_if_scope_ends(HookId, Meta, NewHooks)) catch throw:{error_in_cth_call,Reason} -> call(Rest, {fail, Reason}, Meta, diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE.erl index efc0309781..8825d84884 100644 --- a/lib/common_test/test/ct_test_server_if_1_SUITE.erl +++ b/lib/common_test/test/ct_test_server_if_1_SUITE.erl @@ -242,25 +242,28 @@ test_events(ts_if_1) -> {?eh,tc_auto_skip,{ts_if_5_SUITE,end_per_suite, {require_failed_in_suite0,{not_available,undef_variable}}}}, - {?eh,tc_start,{ts_if_6_SUITE,tc1}}, - {?eh,tc_done,{ts_if_6_SUITE,tc1,{failed,{error,{suite0_failed,{exited,suite0_byebye}}}}}}, - {?eh,test_stats,{3,5,{6,8}}}, + {?eh,tc_start,{ct_framework,init_per_suite}}, + {?eh,tc_done,{ct_framework,init_per_suite, + {failed,{error,{suite0_failed,{exited,suite0_byebye}}}}}}, + {?eh,tc_auto_skip,{ts_if_6_SUITE,tc1, + {failed,{error,{suite0_failed,{exited,suite0_byebye}}}}}}, + {?eh,test_stats,{3,5,{5,9}}}, {?eh,tc_start,{ts_if_7_SUITE,tc1}}, {?eh,tc_done,{ts_if_7_SUITE,tc1,ok}}, - {?eh,test_stats,{4,5,{6,8}}}, + {?eh,test_stats,{4,5,{5,9}}}, {?eh,tc_start,{ts_if_8_SUITE,tc1}}, {?eh,tc_done,{ts_if_8_SUITE,tc1,{failed,{error,failed_on_purpose}}}}, - {?eh,test_stats,{4,6,{6,8}}}, + {?eh,test_stats,{4,6,{5,9}}}, {?eh,tc_user_skip,{skipped_by_spec_1_SUITE,all,"should be skipped"}}, - {?eh,test_stats,{4,6,{7,8}}}, + {?eh,test_stats,{4,6,{6,9}}}, {?eh,tc_start,{skipped_by_spec_2_SUITE,init_per_suite}}, {?eh,tc_done,{skipped_by_spec_2_SUITE,init_per_suite,ok}}, {?eh,tc_user_skip,{skipped_by_spec_2_SUITE,tc1,"should be skipped"}}, - {?eh,test_stats,{4,6,{8,8}}}, + {?eh,test_stats,{4,6,{7,9}}}, {?eh,tc_start,{skipped_by_spec_2_SUITE,end_per_suite}}, {?eh,tc_done,{skipped_by_spec_2_SUITE,end_per_suite,ok}}, diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 91e469ed95..79c45de071 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -2199,7 +2199,7 @@ add_init_and_end_per_suite([], LastMod, LastRef, FwMod) -> %% let's call a "fake" end_per_suite if it exists case erlang:function_exported(FwMod, end_per_suite, 1) of true -> - [{conf,LastRef,[],{FwMod,end_per_suite}}]; + [{conf,LastRef,[{suite,LastMod}],{FwMod,end_per_suite}}]; false -> [{conf,LastRef,[],{LastMod,end_per_suite}}] end @@ -2220,7 +2220,8 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) -> case erlang:function_exported(FwMod, init_per_suite, 1) of true -> Ref = make_ref(), - {[{conf,Ref,[],{FwMod,init_per_suite}}],Mod,Ref}; + {[{conf,Ref,[{suite,Mod}], + {FwMod,init_per_suite}}],Mod,Ref}; false -> {[],Mod,undefined} end @@ -2241,7 +2242,8 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) -> %% let's call a "fake" end_per_suite if it exists case erlang:function_exported(FwMod, end_per_suite, 1) of true -> - [{conf,LastRef,[],{FwMod,end_per_suite}}|Init]; + [{conf,LastRef,[{suite,Mod}], + {FwMod,end_per_suite}}|Init]; false -> [{conf,LastRef,[],{LastMod,end_per_suite}}|Init] end @@ -2846,7 +2848,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0, end, Mode0), update_config(hd(Config), TSDirs ++ [{tc_group_path,GroupPath} | CfgProps]) - end, + end, + CurrMode = curr_mode(Ref, Mode0, Mode), ConfCaseResult = run_test_case(Ref, 0, Mod, Func, [ActualCfg], skip_init, target, TimetrapData, CurrMode), -- cgit v1.2.3 From 86acf3b0515628e645f1641c3b0542071a87d05d Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Sun, 18 Mar 2012 01:56:40 +0100 Subject: Fix bug in handling ct_hooks start arguments --- lib/common_test/src/ct_hooks.erl | 19 ++----------------- lib/common_test/src/ct_run.erl | 2 +- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index 8f452ef5e3..2a23cd992b 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -213,25 +213,10 @@ call([{HookId, Fun} | Rest], Config, Meta, Hooks) -> try Hook = lists:keyfind(HookId, #ct_hook_config.id, Hooks), {NewConf, NewHook} = Fun(Hook, Config, Meta), - - %%! --- Fri Mar 16 17:27:25 2012 --- peppe was here! - %%!!?? - NewConf1 = - if is_tuple(NewConf) -> - if element(1, NewConf) == skip; - element(1, NewConf) == fail -> - Config; - true -> - NewConf - end; - true -> - NewConf - end, - - NewCalls = get_new_hooks(NewConf1, Fun), + NewCalls = get_new_hooks(NewConf, Fun), NewHooks = lists:keyreplace(HookId, #ct_hook_config.id, Hooks, NewHook), call(resort(NewCalls ++ Rest,NewHooks,Meta), %% Resort if call_init changed prio - remove(?config_name, NewConf1), Meta, + remove(?config_name, NewConf), Meta, terminate_if_scope_ends(HookId, Meta, NewHooks)) catch throw:{error_in_cth_call,Reason} -> call(Rest, {fail, Reason}, Meta, diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index d142bdaa81..72124f6f21 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -2329,7 +2329,7 @@ ct_hooks_args2opts(Args) -> Acc end,[],Args). -ct_hooks_args2opts([CTH,Arg,Prio,"and"| Rest],Acc) -> +ct_hooks_args2opts([CTH,Arg,Prio,"and"| Rest],Acc) when Arg /= "and" -> ct_hooks_args2opts(Rest,[{list_to_atom(CTH), parse_cth_args(Arg), parse_cth_args(Prio)}|Acc]); -- cgit v1.2.3 From d4d4792d2706ae81ca190edc3636079e31b2b084 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Sun, 18 Mar 2012 16:32:57 +0100 Subject: Introduce new test suite for CTHs --- lib/common_test/src/ct_framework.erl | 1 - lib/common_test/test/ct_hooks_SUITE.erl | 12 +- .../cth/tests/ct_no_config_SUITE.erl | 64 +++ .../ct_hooks_SUITE_data/cth/tests/empty_cth.erl | 548 ++++++++++----------- .../cth/tests/verify_config_cth.erl | 131 +++++ 5 files changed, 478 insertions(+), 278 deletions(-) create mode 100644 lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl create mode 100644 lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 1d81b19fe1..0f1bec7f9b 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -641,7 +641,6 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> data={Mod,FuncSpec,tag(Result)}}), FinalResult = Fun(end_tc, Return) end, - case FinalResult of {skip,{sequence_failed,_,_}} -> diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl index 2c519f08b5..be07ea7fd6 100644 --- a/lib/common_test/test/ct_hooks_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE.erl @@ -83,10 +83,9 @@ all(suite) -> fail_post_suite_cth, skip_pre_suite_cth, skip_post_suite_cth, recover_post_suite_cth, update_config_cth, state_update_cth, options_cth, same_id_cth, - fail_n_skip_with_minimal_cth, prio_cth + fail_n_skip_with_minimal_cth, prio_cth, no_config ] - ) - . + ). %%-------------------------------------------------------------------- @@ -214,6 +213,10 @@ prio_cth(Config) when is_list(Config) -> [{empty_cth,[1000],1000},{empty_cth,[900],900}, {prio_cth,[1100,100],100},{prio_cth,[1100]}],Config). +no_config(Config) when is_list(Config) -> + do_test(no_config, "ct_no_config_SUITE.erl", + [verify_config_cth],Config). + %%%----------------------------------------------------------------- %%% HELP FUNCTIONS %%%----------------------------------------------------------------- @@ -1078,6 +1081,9 @@ test_events(prio_cth) -> {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]}]; +test_events(no_config) -> + []; + test_events(ok) -> ok. diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl new file mode 100644 index 0000000000..2ad80aa1e7 --- /dev/null +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_config_SUITE.erl @@ -0,0 +1,64 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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_no_config_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("ct.hrl"). + +%%% This suite is used to verify 2 things: +%%% +%%% 1) All hook pre/post functions get called, even if no init/end +%%% config functions exist in the suite (new from ver 1.6.1, R15B01). +%%% +%%% 2) The hook functions can read Config list elements, as well as +%%% required config variables, even if no init/end config +%%% functions exist. + +suite() -> + [{timetrap, {seconds,1}}, + {ct_hooks, [verify_config_cth]}, + {require,suite_cfg}, + {default_config,suite_cfg,?MODULE}]. + +group(test_group) -> + [{require,group_cfg}, + {default_config,group_cfg,test_group}]. + +test_case_1() -> + [{require,test_case_1_cfg}, + {default_config,test_case_1_cfg,test_case_1}]. + +test_case_2() -> + [{require,test_case_2_cfg}, + {default_config,test_case_2_cfg,test_case_2}]. + +all() -> + [test_case_1, {group,test_group}]. + +groups() -> + [{test_group,[],[test_case_2]}]. + +test_case_1(Config) -> + ok. + +test_case_2(Config) -> + ok. diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl index 7befcfa57c..2529e806ea 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl @@ -1,277 +1,277 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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. -%%% -%%%

This module gives an example of a common test CTH (Common Test Hook). -%%% There are many ways to add a CTH to a test run, you can do it either in -%%% the command line using -ct_hook, in a test spec using -%%% {ct_hook,M} or in the suite it self by returning ct_hook -%%% from either suite/0, init_per_suite/1, init_per_group/2 and -%%% init_per_testcase/2. The scope of the CTH 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 CTH are optional.

- --module(empty_cth). - -%% CT Hooks --export([id/1]). --export([init/2]). - --export([pre_init_per_suite/3]). --export([post_init_per_suite/4]). --export([pre_end_per_suite/3]). --export([post_end_per_suite/4]). - --export([pre_init_per_group/3]). --export([post_init_per_group/4]). --export([pre_end_per_group/3]). --export([post_end_per_group/4]). - --export([pre_init_per_testcase/3]). --export([post_end_per_testcase/4]). - --export([on_tc_fail/3]). --export([on_tc_skip/3]). - --export([terminate/1]). - --include_lib("common_test/src/ct_util.hrl"). --include_lib("common_test/include/ct_event.hrl"). - +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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. +%%% +%%%

This module gives an example of a common test CTH (Common Test Hook). +%%% There are many ways to add a CTH to a test run, you can do it either in +%%% the command line using -ct_hook, in a test spec using +%%% {ct_hook,M} or in the suite it self by returning ct_hook +%%% from either suite/0, init_per_suite/1, init_per_group/2 and +%%% init_per_testcase/2. The scope of the CTH 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 CTH are optional.

+ +-module(empty_cth). + +%% CT Hooks +-export([id/1]). +-export([init/2]). + +-export([pre_init_per_suite/3]). +-export([post_init_per_suite/4]). +-export([pre_end_per_suite/3]). +-export([post_end_per_suite/4]). + +-export([pre_init_per_group/3]). +-export([post_init_per_group/4]). +-export([pre_end_per_group/3]). +-export([post_end_per_group/4]). + +-export([pre_init_per_testcase/3]). +-export([post_end_per_testcase/4]). + +-export([on_tc_fail/3]). +-export([on_tc_skip/3]). + +-export([terminate/1]). + +-include_lib("common_test/src/ct_util.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + -type config() :: proplists:proplist(). --type reason() :: term(). --type skip_or_fail() :: {skip, reason()} | - {auto_skip, reason()} | - {fail, reason()} | - {'EXIT',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 state for this CTH. +-type reason() :: term(). +-type skip_or_fail() :: {skip, reason()} | + {auto_skip, reason()} | + {fail, reason()} | + {'EXIT',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 state for this CTH. -spec init(Id :: term(), Opts :: proplists:proplist()) -> - {ok, State :: #state{}}. -init(Id, Opts) -> - gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, init, [Id, Opts]}}), - {ok,Opts}. - -%% @doc The ID is used to uniquly identify an CTH instance, if two CTH's -%% return the same ID the seconds CTH is ignored. This function should NOT -%% have any side effects as it might be called multiple times by common test. + {ok, State :: #state{}}. +init(Id, Opts) -> + gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, init, [Id, Opts]}}), + {ok,Opts}. + +%% @doc The ID is used to uniquly identify an CTH instance, if two CTH's +%% return the same ID the seconds CTH is ignored. This function should NOT +%% have any side effects as it might be called multiple times by common test. -spec id(Opts :: proplists:proplist()) -> - Id :: term(). -id(Opts) -> - gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, id, [Opts]}}), - now(). - -%% @doc Called before init_per_suite is called. Note that this callback is -%% only called if the CTH 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_per_suite(Suite :: atom(), - Config :: config(), - State :: #state{}) -> - {config() | skip_or_fail(), NewState :: #state{}}. -pre_init_per_suite(Suite,Config,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, pre_init_per_suite, - [Suite,Config,State]}}), - {Config, State}. - -%% @doc Called after init_per_suite. -%% you can change the return value in this function. --spec post_init_per_suite(Suite :: atom(), - Config :: config(), - Return :: config() | skip_or_fail(), - State :: #state{}) -> - {config() | skip_or_fail(), NewState :: #state{}}. -post_init_per_suite(Suite,Config,Return,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, post_init_per_suite, - [Suite,Config,Return,State]}}), - {Return, State}. - -%% @doc Called before end_per_suite. The config/state can be changed here, -%% though it will only affect the *end_per_suite function. --spec pre_end_per_suite(Suite :: atom(), - Config :: config() | skip_or_fail(), - State :: #state{}) -> - {ok | skip_or_fail(), NewState :: #state{}}. -pre_end_per_suite(Suite,Config,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, pre_end_per_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_per_suite(Suite :: atom(), - Config :: config(), - Return :: term(), - State :: #state{}) -> - {ok | skip_or_fail(), NewState :: #state{}}. -post_end_per_suite(Suite,Config,Return,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, post_end_per_suite, - [Suite,Config,Return,State]}}), - {Return, State}. - -%% @doc Called before each init_per_group. -%% You can change the config in this function. --spec pre_init_per_group(Group :: atom(), - Config :: config(), - State :: #state{}) -> - {config() | skip_or_fail(), NewState :: #state{}}. -pre_init_per_group(Group,Config,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, pre_init_per_group, - [Group,Config,State]}}), - {Config, State}. - -%% @doc Called after each init_per_group. -%% You can change the return value in this function. --spec post_init_per_group(Group :: atom(), - Config :: config(), - Return :: config() | skip_or_fail(), - State :: #state{}) -> - {config() | skip_or_fail(), NewState :: #state{}}. -post_init_per_group(Group,Config,Return,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, post_init_per_group, - [Group,Config,Return,State]}}), - {Return, State}. - -%% @doc Called after each end_per_group. The config/state can be changed here, -%% though it will only affect the *end_per_group functions. --spec pre_end_per_group(Group :: atom(), - Config :: config() | skip_or_fail(), - State :: #state{}) -> - {ok | skip_or_fail(), NewState :: #state{}}. -pre_end_per_group(Group,Config,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, pre_end_per_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_per_group(Group :: atom(), - Config :: config(), - Return :: term(), - State :: #state{}) -> - {ok | skip_or_fail(), NewState :: #state{}}. -post_end_per_group(Group,Config,Return,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, post_end_per_group, - [Group,Config,Return,State]}}), - {Return, State}. - -%% @doc Called before each test case. -%% You can change the config in this function. --spec pre_init_per_testcase(TC :: atom(), - Config :: config(), - State :: #state{}) -> - {config() | skip_or_fail(), NewState :: #state{}}. -pre_init_per_testcase(TC,Config,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, pre_init_per_testcase, - [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_per_testcase(TC :: atom(), - Config :: config(), - Return :: term(), - State :: #state{}) -> - {ok | skip_or_fail(), NewState :: #state{}}. -post_end_per_testcase(TC,Config,Return,State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, post_end_per_testcase, - [TC,Config,Return,State]}}), - {Return, State}. - -%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, -%% post_end_per_group and post_end_per_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(), - Reason :: term(), State :: #state{}) -> - NewState :: #state{}. -on_tc_fail(TC, Reason, State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, on_tc_fail, - [TC,Reason,State]}}), - State. - -%% @doc Called when a test case is skipped by either user action -%% or due to an init function failing. Test case can be -%% end_per_suite, init_per_group, end_per_group and the actual test cases. --spec on_tc_skip(TC :: end_per_suite | - init_per_group | end_per_group | atom(), - {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} | - {tc_user_skip, {skipped, Reason :: term()}}, - State :: #state{}) -> - NewState :: #state{}. -on_tc_skip(TC, Reason, State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, on_tc_skip, - [TC,Reason,State]}}), - State. - -%% @doc Called when the scope of the CTH is done, this depends on -%% when the CTH 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 | -%% |-----------------------------------------------| -%% --spec terminate(State :: #state{}) -> - term(). -terminate(State) -> - gen_event:notify( - ?CT_EVMGR_REF, #event{ name = cth, node = node(), - data = {?MODULE, terminate, [State]}}), - ok. + Id :: term(). +id(Opts) -> + gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, id, [Opts]}}), + now(). + +%% @doc Called before init_per_suite is called. Note that this callback is +%% only called if the CTH 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_per_suite(Suite :: atom(), + Config :: config(), + State :: #state{}) -> + {config() | skip_or_fail(), NewState :: #state{}}. +pre_init_per_suite(Suite,Config,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, pre_init_per_suite, + [Suite,Config,State]}}), + {Config, State}. + +%% @doc Called after init_per_suite. +%% you can change the return value in this function. +-spec post_init_per_suite(Suite :: atom(), + Config :: config(), + Return :: config() | skip_or_fail(), + State :: #state{}) -> + {config() | skip_or_fail(), NewState :: #state{}}. +post_init_per_suite(Suite,Config,Return,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, post_init_per_suite, + [Suite,Config,Return,State]}}), + {Return, State}. + +%% @doc Called before end_per_suite. The config/state can be changed here, +%% though it will only affect the *end_per_suite function. +-spec pre_end_per_suite(Suite :: atom(), + Config :: config() | skip_or_fail(), + State :: #state{}) -> + {ok | skip_or_fail(), NewState :: #state{}}. +pre_end_per_suite(Suite,Config,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, pre_end_per_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_per_suite(Suite :: atom(), + Config :: config(), + Return :: term(), + State :: #state{}) -> + {ok | skip_or_fail(), NewState :: #state{}}. +post_end_per_suite(Suite,Config,Return,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, post_end_per_suite, + [Suite,Config,Return,State]}}), + {Return, State}. + +%% @doc Called before each init_per_group. +%% You can change the config in this function. +-spec pre_init_per_group(Group :: atom(), + Config :: config(), + State :: #state{}) -> + {config() | skip_or_fail(), NewState :: #state{}}. +pre_init_per_group(Group,Config,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, pre_init_per_group, + [Group,Config,State]}}), + {Config, State}. + +%% @doc Called after each init_per_group. +%% You can change the return value in this function. +-spec post_init_per_group(Group :: atom(), + Config :: config(), + Return :: config() | skip_or_fail(), + State :: #state{}) -> + {config() | skip_or_fail(), NewState :: #state{}}. +post_init_per_group(Group,Config,Return,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, post_init_per_group, + [Group,Config,Return,State]}}), + {Return, State}. + +%% @doc Called after each end_per_group. The config/state can be changed here, +%% though it will only affect the *end_per_group functions. +-spec pre_end_per_group(Group :: atom(), + Config :: config() | skip_or_fail(), + State :: #state{}) -> + {ok | skip_or_fail(), NewState :: #state{}}. +pre_end_per_group(Group,Config,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, pre_end_per_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_per_group(Group :: atom(), + Config :: config(), + Return :: term(), + State :: #state{}) -> + {ok | skip_or_fail(), NewState :: #state{}}. +post_end_per_group(Group,Config,Return,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, post_end_per_group, + [Group,Config,Return,State]}}), + {Return, State}. + +%% @doc Called before each test case. +%% You can change the config in this function. +-spec pre_init_per_testcase(TC :: atom(), + Config :: config(), + State :: #state{}) -> + {config() | skip_or_fail(), NewState :: #state{}}. +pre_init_per_testcase(TC,Config,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, pre_init_per_testcase, + [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_per_testcase(TC :: atom(), + Config :: config(), + Return :: term(), + State :: #state{}) -> + {ok | skip_or_fail(), NewState :: #state{}}. +post_end_per_testcase(TC,Config,Return,State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, post_end_per_testcase, + [TC,Config,Return,State]}}), + {Return, State}. + +%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, +%% post_end_per_group and post_end_per_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(), + Reason :: term(), State :: #state{}) -> + NewState :: #state{}. +on_tc_fail(TC, Reason, State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, on_tc_fail, + [TC,Reason,State]}}), + State. + +%% @doc Called when a test case is skipped by either user action +%% or due to an init function failing. Test case can be +%% end_per_suite, init_per_group, end_per_group and the actual test cases. +-spec on_tc_skip(TC :: end_per_suite | + init_per_group | end_per_group | atom(), + {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} | + {tc_user_skip, {skipped, Reason :: term()}}, + State :: #state{}) -> + NewState :: #state{}. +on_tc_skip(TC, Reason, State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, on_tc_skip, + [TC,Reason,State]}}), + State. + +%% @doc Called when the scope of the CTH is done, this depends on +%% when the CTH 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 | +%% |-----------------------------------------------| +%% +-spec terminate(State :: #state{}) -> + term(). +terminate(State) -> + gen_event:notify( + ?CT_EVMGR_REF, #event{ name = cth, node = node(), + data = {?MODULE, terminate, [State]}}), + ok. diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl new file mode 100644 index 0000000000..f86e1a8b01 --- /dev/null +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl @@ -0,0 +1,131 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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(verify_config_cth). + +-include_lib("common_test/src/ct_util.hrl"). + +%% CT Hooks +-compile(export_all). + +-define(val(K, L), proplists:get_value(K, L)). + +id(Opts) -> + empty_cth:id(Opts). + +init(Id, Opts) -> + {ok, State} = empty_cth:init(Id, Opts), + {ok, State}. + +pre_init_per_suite(Suite, Config, State) -> + ct_no_config_SUITE = ct:get_config(suite_cfg), + empty_cth:pre_init_per_suite(Suite, + [{pre_init_per_suite,true} | Config], + State). + +post_init_per_suite(Suite,Config,Return,State) -> + true = ?val(pre_init_per_suite, Return), + ct_no_config_SUITE = ct:get_config(suite_cfg), + empty_cth:post_init_per_suite(Suite, + Config, + [{post_init_per_suite,true} | Return], + State). + +pre_end_per_suite(Suite,Config,State) -> + true = ?val(post_init_per_suite, Config), + ct_no_config_SUITE = ct:get_config(suite_cfg), + empty_cth:pre_end_per_suite(Suite, + [{pre_end_per_suite,true} | Config], + State). + +post_end_per_suite(Suite,Config,Return,State) -> + true = ?val(pre_end_per_suite, Config), + ct_no_config_SUITE = ct:get_config(suite_cfg), + empty_cth:post_end_per_suite(Suite,Config,Return,State). + +pre_init_per_group(Group,Config,State) -> + true = ?val(post_init_per_suite, Config), + ct_no_config_SUITE = ct:get_config(suite_cfg), + test_group = ct:get_config(group_cfg), + empty_cth:pre_init_per_group(Group, + [{pre_init_per_group,true} | Config], + State). + +post_init_per_group(Group,Config,Return,State) -> + true = ?val(pre_init_per_group, Return), + test_group = ct:get_config(group_cfg), + empty_cth:post_init_per_group(Group, + Config, + [{post_init_per_group,true} | Return], + State). + +pre_end_per_group(Group,Config,State) -> + true = ?val(post_init_per_group, Config), + ct_no_config_SUITE = ct:get_config(suite_cfg), + test_group = ct:get_config(group_cfg), + empty_cth:pre_end_per_group(Group, + [{pre_end_per_group,true} | Config], + State). + +post_end_per_group(Group,Config,Return,State) -> + true = ?val(pre_end_per_group, Config), + ct_no_config_SUITE = ct:get_config(suite_cfg), + %%! BUG! SHOULD WORK: + %%! test_group = ct:get_config(group_cfg), + empty_cth:post_end_per_group(Group,Config,Return,State). + +pre_init_per_testcase(TC,Config,State) -> + true = ?val(post_init_per_suite, Config), + case ?val(name, ?val(tc_group_properties, Config)) of + undefined -> + ok; + _ -> + true = ?val(post_init_per_group, Config), + test_group = ct:get_config(group_cfg) + end, + ct_no_config_SUITE = ct:get_config(suite_cfg), + CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"), + TC = ct:get_config(CfgKey), + empty_cth:pre_init_per_testcase(TC, + [{pre_init_per_testcase,true} | Config], + State). + +post_end_per_testcase(TC,Config,Return,State) -> + true = ?val(post_init_per_suite, Config), + true = ?val(pre_init_per_testcase, Config), + case ?val(name, ?val(tc_group_properties, Config)) of + undefined -> + ok; + _ -> + true = ?val(post_init_per_group, Config), + test_group = ct:get_config(group_cfg) + end, + ct_no_config_SUITE = ct:get_config(suite_cfg), + CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"), + TC = ct:get_config(CfgKey), + empty_cth:post_end_per_testcase(TC,Config,Return,State). + +on_tc_fail(TC, Reason, State) -> + empty_cth:on_tc_fail(TC,Reason,State). + +on_tc_skip(TC, Reason, State) -> + empty_cth:on_tc_skip(TC,Reason,State). + +terminate(State) -> + empty_cth:terminate(State). -- cgit v1.2.3 From 7b16f86fb5933a94b21a11391dc37562283991da Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Mon, 19 Mar 2012 12:28:11 +0100 Subject: Fix error with group config deleted before post_end_per_group OTP-9989 Also improve ct_hooks test suite. --- lib/common_test/src/ct_framework.erl | 69 +++++++++++----------- lib/common_test/test/ct_hooks_SUITE.erl | 49 ++++++++++++++- .../cth/tests/verify_config_cth.erl | 5 +- 3 files changed, 86 insertions(+), 37 deletions(-) diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 0f1bec7f9b..187794e78b 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -588,59 +588,62 @@ end_tc(Mod,Func,TCPid,Result,Args,Return) -> end, ct_util:delete_testdata(comment), ct_util:delete_suite_data(last_saved_config), - FuncSpec = - case group_or_func(Func,Args) of - {_,GroupName,_Props} = Group -> - if Func == end_per_group -> - ct_config:delete_default_config({group,GroupName}); - true -> ok - end, - case lists:keysearch(save_config,1,Args) of - {value,{save_config,SaveConfig}} -> - ct_util:save_suite_data( - last_saved_config, - {Suite,{group,GroupName}}, - SaveConfig), - Group; - false -> - Group - end; - _ -> - case lists:keysearch(save_config,1,Args) of - {value,{save_config,SaveConfig}} -> - ct_util:save_suite_data(last_saved_config, - {Suite,Func},SaveConfig), - Func; - false -> - Func - end - end, - ct_util:reset_silent_connections(), + + FuncSpec = case group_or_func(Func,Args) of + {_,_GroupName,_} = Group -> Group; + _ -> Func + end, case get('$test_server_framework_test') of undefined -> {FinalResult,FinalNotify} = case ct_hooks:end_tc( - Suite, FuncSpec, Args, Result, Return) of + Suite, FuncSpec, Args, Result, Return) of '$ct_no_change' -> {ok,Result}; FinalResult1 -> {FinalResult1,FinalResult1} end, - % send sync notification so that event handlers may print - % in the log file before it gets closed + %% send sync notification so that event handlers may print + %% in the log file before it gets closed ct_event:sync_notify(#event{name=tc_done, node=node(), data={Mod,FuncSpec, tag_cth(FinalNotify)}}); Fun -> - % send sync notification so that event handlers may print - % in the log file before it gets closed + %% send sync notification so that event handlers may print + %% in the log file before it gets closed ct_event:sync_notify(#event{name=tc_done, node=node(), data={Mod,FuncSpec,tag(Result)}}), FinalResult = Fun(end_tc, Return) + end, + + case FuncSpec of + {_,GroupName,_Props} -> + if Func == end_per_group -> + ct_config:delete_default_config({group,GroupName}); + true -> ok + end, + case lists:keysearch(save_config,1,Args) of + {value,{save_config,SaveConfig}} -> + ct_util:save_suite_data(last_saved_config, + {Suite,{group,GroupName}}, + SaveConfig); + false -> + ok + end; + _ -> + case lists:keysearch(save_config,1,Args) of + {value,{save_config,SaveConfig}} -> + ct_util:save_suite_data(last_saved_config, + {Suite,Func},SaveConfig); + false -> + ok + end end, + + ct_util:reset_silent_connections(), case FinalResult of {skip,{sequence_failed,_,_}} -> diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl index be07ea7fd6..efe57a7d0b 100644 --- a/lib/common_test/test/ct_hooks_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE.erl @@ -1082,7 +1082,54 @@ test_events(prio_cth) -> {?eh,stop_logging,[]}]; test_events(no_config) -> - []; + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,cth,{empty_cth,init,[verify_config_cth,[]]}}, + {?eh,start_info,{1,1,2}}, + {?eh,tc_start,{ct_framework,init_per_suite}}, + {?eh,cth,{empty_cth,pre_init_per_suite, + [ct_no_config_SUITE,'$proplist',[]]}}, + {?eh,cth,{empty_cth,post_init_per_suite, + [ct_no_config_SUITE,'$proplist','$proplist',[]]}}, + {?eh,tc_done,{ct_framework,init_per_suite,ok}}, + {?eh,tc_start,{ct_no_config_SUITE,test_case_1}}, + {?eh,cth,{empty_cth,pre_init_per_testcase, + [test_case_1,'$proplist',[]]}}, + {?eh,cth,{empty_cth,post_end_per_testcase, + [test_case_1,'$proplist',ok,[]]}}, + {?eh,tc_done,{ct_no_config_SUITE,test_case_1,ok}}, + {?eh,test_stats,{1,0,{0,0}}}, + [{?eh,tc_start,{ct_framework,{init_per_group,test_group,'$proplist'}}}, + {?eh,cth,{empty_cth,pre_init_per_group, + [test_group,'$proplist',[]]}}, + {?eh,cth,{empty_cth,post_init_per_group, + [test_group,'$proplist','$proplist',[]]}}, + {?eh,tc_done,{ct_framework, + {init_per_group,test_group,'$proplist'},ok}}, + {?eh,tc_start,{ct_no_config_SUITE,test_case_2}}, + {?eh,cth,{empty_cth,pre_init_per_testcase, + [test_case_2,'$proplist',[]]}}, + {?eh,cth,{empty_cth,post_end_per_testcase, + [test_case_2,'$proplist',ok,[]]}}, + {?eh,tc_done,{ct_no_config_SUITE,test_case_2,ok}}, + {?eh,test_stats,{2,0,{0,0}}}, + {?eh,tc_start,{ct_framework,{end_per_group,test_group,'$proplist'}}}, + {?eh,cth,{empty_cth,pre_end_per_group, + [test_group,'$proplist',[]]}}, + {?eh,cth,{empty_cth,post_end_per_group, + [test_group,'$proplist',ok,[]]}}, + {?eh,tc_done,{ct_framework,{end_per_group,test_group,'$proplist'},ok}}], + {?eh,tc_start,{ct_framework,end_per_suite}}, + {?eh,cth,{empty_cth,pre_end_per_suite, + [ct_no_config_SUITE,'$proplist',[]]}}, + {?eh,cth,{empty_cth,post_end_per_suite, + [ct_no_config_SUITE,'$proplist',ok,[]]}}, + {?eh,tc_done,{ct_framework,end_per_suite,ok}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,cth,{empty_cth,terminate,[[]]}}, + {?eh,stop_logging,[]} + ]; test_events(ok) -> ok. diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl index f86e1a8b01..99ea261e14 100644 --- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl +++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl @@ -27,7 +27,7 @@ -define(val(K, L), proplists:get_value(K, L)). id(Opts) -> - empty_cth:id(Opts). + ?MODULE. init(Id, Opts) -> {ok, State} = empty_cth:init(Id, Opts), @@ -86,8 +86,7 @@ pre_end_per_group(Group,Config,State) -> post_end_per_group(Group,Config,Return,State) -> true = ?val(pre_end_per_group, Config), ct_no_config_SUITE = ct:get_config(suite_cfg), - %%! BUG! SHOULD WORK: - %%! test_group = ct:get_config(group_cfg), + test_group = ct:get_config(group_cfg), empty_cth:post_end_per_group(Group,Config,Return,State). pre_init_per_testcase(TC,Config,State) -> -- cgit v1.2.3