diff options
4 files changed, 131 insertions, 4 deletions
diff --git a/lib/common_test/src/ct_suite_callback.erl b/lib/common_test/src/ct_suite_callback.erl index 8372303737..508d3b5bd6 100644 --- a/lib/common_test/src/ct_suite_callback.erl +++ b/lib/common_test/src/ct_suite_callback.erl @@ -169,8 +169,9 @@ call(Fun, Config, Meta, NoChangeRet) when is_function(Fun) -> call([{CB, call_init, NextFun} | Rest], Config, Meta, CBs) -> try {Config, {NewId, _, {Mod,_State}} = NewCB} = call_init(CB, Config, Meta), - {NewCBs, NewRest} = case proplists:get_value(NewId, CBs, NextFun) of - undefined -> {CBs ++ [NewCB],Rest}; + {NewCBs, NewRest} = case lists:keyfind(NewId, 1, CBs) of + false when NextFun == undefined -> + {CBs ++ [NewCB],Rest}; ExistingCB when is_tuple(ExistingCB) -> {CBs, Rest}; _ -> diff --git a/lib/common_test/test/ct_suite_callback_SUITE.erl b/lib/common_test/test/ct_suite_callback_SUITE.erl index 88ce5e0e51..6d61fbb21d 100644 --- a/lib/common_test/test/ct_suite_callback_SUITE.erl +++ b/lib/common_test/test/ct_suite_callback_SUITE.erl @@ -80,7 +80,7 @@ all(suite) -> scope_suite_state_scb, fail_pre_suite_scb, fail_post_suite_scb, skip_pre_suite_scb, skip_post_suite_scb, recover_post_suite_scb, update_config_scb, - state_update_scb, options_scb + state_update_scb, options_scb, same_id_scb ] ) . @@ -182,6 +182,10 @@ options_scb(Config) when is_list(Config) -> do_test(options_scb, "ct_scb_empty_SUITE.erl", [{empty_scb,[test]}],Config). +same_id_scb(Config) when is_list(Config) -> + do_test(same_id_scb, "ct_scb_empty_SUITE.erl", + [same_id_scb,same_id_scb],Config). + %%%----------------------------------------------------------------- %%% HELP FUNCTIONS @@ -876,6 +880,46 @@ test_events(options_scb) -> {?eh,stop_logging,[]} ]; +test_events(same_id_scb) -> + [ + {?eh,start_logging,{'DEF','RUNDIR'}}, + {?eh,scb,{'_',init,[[]]}}, + {?eh,scb,{'_',init,[[]]}}, + {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}, + {?eh,tc_start,{ct_scb_empty_SUITE,init_per_suite}}, + {?eh,scb,{'_',pre_init_per_suite,[ct_scb_empty_SUITE,'$proplist',[]]}}, + {negative, + {?eh,scb,{'_',pre_init_per_suite,[ct_scb_empty_SUITE,'$proplist',[]]}}, + {?eh,scb,{'_',post_init_per_suite, + [ct_scb_empty_SUITE,'$proplist','$proplist',[]]}}}, + {negative, + {?eh,scb,{'_',post_init_per_suite, + [ct_scb_empty_SUITE,'$proplist','$proplist',[]]}}, + {?eh,tc_done,{ct_scb_empty_SUITE,init_per_suite,ok}}}, + + {?eh,tc_start,{ct_scb_empty_SUITE,test_case}}, + {?eh,scb,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}}, + {negative, + {?eh,scb,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}}, + {?eh,scb,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}}}, + {negative, + {?eh,scb,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}}, + {?eh,tc_done,{ct_scb_empty_SUITE,test_case,ok}}}, + + {?eh,tc_start,{ct_scb_empty_SUITE,end_per_suite}}, + {?eh,scb,{'_',pre_end_per_suite,[ct_scb_empty_SUITE,'$proplist',[]]}}, + {negative, + {?eh,scb,{'_',pre_end_per_suite,[ct_scb_empty_SUITE,'$proplist',[]]}}, + {?eh,scb,{'_',post_end_per_suite,[ct_scb_empty_SUITE,'$proplist','_',[]]}}}, + {negative, + {?eh,scb,{'_',post_end_per_suite, + [ct_scb_empty_SUITE,'$proplist','_',[]]}}, + {?eh,tc_done,{ct_scb_empty_SUITE,end_per_suite,ok}}}, + {?eh,test_done,{'DEF','STOP_TIME'}}, + {?eh,scb,{'_',terminate,[[]]}}, + {?eh,stop_logging,[]} + ]; + test_events(ok) -> ok. diff --git a/lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/same_id_scb.erl b/lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/same_id_scb.erl new file mode 100644 index 0000000000..6853aa52e8 --- /dev/null +++ b/lib/common_test/test/ct_suite_callback_SUITE_data/scb/tests/same_id_scb.erl @@ -0,0 +1,72 @@ +%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(same_id_scb).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% Suite Callbacks
+-compile(export_all).
+
+init(Opts) ->
+ {_,State} = empty_scb:init(Opts),
+ {?MODULE,State}.
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_scb:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_scb:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_scb:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_scb:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_scb:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_scb:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_scb:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_scb:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_scb:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_scb:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_scb:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_scb:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_scb:terminate(State).
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 5009741f59..981504b660 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -876,6 +876,16 @@ locate({TEH,tc_done,{undefined,undefined,{testcase_aborted, nomatch end; +%% Negative matching: Given two events, the first should not be present before +%% the other is matched. +locate({negative,NotMatch, Match} = Neg, Node, Evs, Config) -> + case locate(NotMatch, Node, Evs, Config) of + nomatch -> + locate(Match, Node, Evs, Config); + _ -> + exit({found_negative_event,Neg}) + end; + %% matches any event of type Name locate({TEH,Name,Data}, Node, [{TEH,#event{name=Name, data = EvData, @@ -888,7 +898,7 @@ locate({TEH,Name,Data}, Node, [{TEH,#event{name=Name, nomatch end; -locate({TEH,Name,Data}, Node, [_|Evs], Config) -> +locate({_TEH,_Name,_Data}, _Node, [_|_Evs], _Config) -> nomatch. match_data(D,D) -> |