aboutsummaryrefslogblamecommitdiffstats
path: root/lib/common_test/test/ct_hooks_SUITE.erl
blob: 9c477c8c7712bdc2ffba8a9b986668ed2e6defed (plain) (tree)
1
2
3
4
5
6
7
8
9


                   
                                                        
  


                                                                   
  






                                                                           















                                                                      
                                           

































                                                                               
                             



               
             

                  


                                                                          

                                                                   

                                                        
                                                                 
                                  
                                                            
                             
                                                     
                                                                 
                                                   
                                                                      
                                                                     
                                                         
                                                           

                                                        
       
      







                                                                      
                                       

                                                                         
                                       


















                                                                             
 




                                                                   
                                                






















                                                                    




                                                          



















                                                                                




                                                                                







                                                          



                                                                 



                                                          



                                                           



                                                               











                                                                      



                                                                            


                                                  
 







                                                                               

                                              

                                                                  
 



                                                









                                                                              



                                              
                                       

                                                    
                              






















                                                                           





                                                                             
 
















                                                                             
                                           


                                                                        































































                                                                                      



                                                                    





                                                   
 


                                                                                      
                                        



                                                                               
 


                                                       
                                   


                                                         

                                          

                                                                   













                                                          






                                                                   














                                                                    
                                                      

                                                   



                                                                        





                                                                 
                                                   



                                                                                                    
                                                     
 












                                                                                      
                                                      
                             

                                   
                                   







                                                                                         



                                                                                            
                                                     
 






















                                                                                
                                                      
                             







                                           
                                                      

                                           




                                                          
 








                                                         
                                                      
                             

                                           
                                   





                                                                                         

                                                                                            
                                                     
 














                                                                                
                                                      
                                   







                                                        
 


                                                         
 






























                                                                 
                                                      
                                         




                                          
                                                      
                                   














                                                                                                   

                                                                                                      
                                                               
 













                                                                                          

                                                                       

                                                                   
                                          





                                                                






                                                                                               

                                                                                                  
                                                           
 








                                                                                      



























                                                                                 









                                                                               
                                                                                                            
                                                                                 
 
                                                              

                                                                                                       
                                                                
 
                                                                              

                                                                                                  

                                                                                 
 
















                                                                                                             

                                                                                                                
                                                                     
 













                                                                                                    

                                           







                                                                                                         

                                                                                                            
                                                                 
 


















                                                                                                
                                                                                                                     
                                                                                       
 
                                                                    

                                                                                                                 
                                                                      
 
                                                                                    

                                                                                                            

                                                                                       
 








                                                                         
                                                      
                                   
 






                                                                            
                                                                       
 
 



                                                                   
                                                            


                                                                         
 



                                                                      
                                                                


                                                                             
 




                                         
















                                                                    


                                          
                                                      
                                   




                                                                                         
                                                                                        



                                                                   
                                                                                     
 


                                                                      
                                                                                         








                                          
                                                      
                                   




                                                                                                
                                                                                   
 
                                                                   
                                                                                             
 
                                                                         





                                         





                                                                    
 


                                                                               
                                                                                                           
                                                                                 
 
                                                              

                                                                                                       
                                                                
 
                                                                              

                                                                                                  

                                                                           

                                                             
                                                           



                                                                 

                                                            
                                                          





                                         


                                          
                                                      
                                   
 




                                                                                         
                                                                                   
 
                                                                   
                                                                                             
 
                                                                         
 




                                         





















                                                                                  
                                                                  











                                                                                 





































                                                                                     



                                        
                                                      
                                   







                                                                        
                                                                 
                                         
                                                                 
                                        
 













                                                          
                                                      
                                   
 













                                                                         

                                       




                                               

                                       














                                                                          

                                       







                                                  

                                       












                                                                        

                                       







                                               

                                       









                                                                         
 



























                                                               
                                                      

                                   
                                         
 





























                                                                               



































































































                                                                                     


                                          
                                                      
                                             







                                                                     

                                                                                                       
                                                     
 












                                                                                          
                                                      
                             
                             
                                           











                                                                              
                                                                                         
               

                                                                                              
               
                                                                                             
                                                       
 















                                                                                  
                                                      
                                   
                                         















                                                                                       

                                                                        
                                                                  
                                               

                                                                        
                                                                  









                                                                               




                                          
                        






                                                                 

                 








                                                                      
 
                                          








                                                                            
 









                                                                              
 





                                                                      



                                                                         


                                                                           
                                      



                                                                        
                                        



                                                                         



                                                                           


                                                                          
                                   


                                                                           


                                                            
 
                         












                                                                 
                                                                 
                                               
                                                                    



                                                                            
                                                                 
                                              
                                                                             



                                                                 
                                                                  
                                                
                                                                     



                                                                           
                                                                 
                                             
                                                                    










                                                                              
 














                                                                    
                                                       





















































                                                                               
                                                        











































































                                                                                 
                                                         











                                                             













                                                                                                        
                                                                                                        
                                               
                                                                                                           



                                                                            
                                                                                                        
                                              
                                                                                                                    



                                                                 
                                                                                                         
                                                
                                                                                                            



                                                                           
                                                                                                        
                                             
                                                                                                           










                                                                                               





                                                      



                                                                          
                                     



                                                                            
 




                                                    

















































                                                                              



                                                                
                                                                












                                                               










                                                               
                                   

























                                                                             
                                                                 






















                                                                                      

                                                              


























                                                                                  
                                                                        





































                                                                                
                                                                              





























                                                                              
                                                                     






























                                                                           
                                                                  




































































                                                                             
                                                                    


















                                                                  
                                                


                                      















                                                                  
                                                






























































                                                                                 






















                                                                      
                                                                   
                          
                                      







                                                                                  
                                                                             
                          
                                      







                                                                            
                                                                       
                          
                                      














































                                                                                  
                                                                  
                                      
                                                



                                                                           
                                                                      








































                                                                                
                                                   




                                                                        
                                                                                




































                                                                               
                                                      














                                                            






























































































































































































































                                                                                                        


                  




































                                             
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%%     http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%

%%%-------------------------------------------------------------------
%%% File: ct_error_SUITE
%%%
%%% Description: 
%%% Test various errors in Common Test suites.
%%%
%%% The suites used for the test are located in the data directory.
%%%-------------------------------------------------------------------
-module(ct_hooks_SUITE).

-compile(export_all).

-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").

-define(eh, ct_test_support_eh).

%%--------------------------------------------------------------------
%% TEST SERVER CALLBACK FUNCTIONS
%%--------------------------------------------------------------------

%%--------------------------------------------------------------------
%% Description: Since Common Test starts another Test Server
%% instance, the tests need to be performed on a separate node (or
%% there will be clashes with logging processes etc).
%%--------------------------------------------------------------------
init_per_suite(Config) ->
    DataDir = ?config(data_dir, Config),
    TestDir = filename:join(DataDir,"cth/tests/"),
    CTHs = filelib:wildcard(filename:join(TestDir,"*_cth.erl")),
    io:format("CTHs: ~p",[CTHs]),
    [io:format("Compiling ~p: ~p",
	    [FileName,compile:file(FileName,[{outdir,TestDir},debug_info])]) ||
	FileName <- CTHs],
    ct_test_support:init_per_suite([{path_dirs,[TestDir]} | Config]).

end_per_suite(Config) ->
    ct_test_support:end_per_suite(Config).

init_per_testcase(TestCase, Config) ->
    ct_test_support:init_per_testcase(TestCase, Config).

end_per_testcase(TestCase, Config) ->
    ct_test_support:end_per_testcase(TestCase, Config).


suite() ->
    [{timetrap,{minutes,1}}].

all() ->
    all(suite).

all(suite) ->
    lists:reverse(
      [
       crash_groups, crash_all, bad_return_groups, bad_return_all,
       illegal_values_groups, illegal_values_all, alter_groups, alter_all,
       alter_all_to_skip, alter_all_from_skip,
       one_cth, two_cth, faulty_cth_no_init, faulty_cth_id_no_init,
       faulty_cth_exit_in_init, faulty_cth_exit_in_id,
       faulty_cth_exit_in_init_scope_suite, minimal_cth,
       minimal_and_maximal_cth, faulty_cth_undef,
       scope_per_suite_cth, scope_per_group_cth, scope_suite_cth,
       scope_suite_group_only_cth,
       scope_per_suite_state_cth, scope_per_group_state_cth,
       scope_suite_state_cth,
       fail_pre_suite_cth, double_fail_pre_suite_cth,
       fail_post_suite_cth, skip_pre_suite_cth, skip_pre_end_cth,
       skip_pre_init_tc_cth, fail_post_init_tc_cth,
       skip_post_suite_cth, recover_post_suite_cth, update_config_cth,
       state_update_cth, update_result_cth, options_cth, same_id_cth,
       fail_n_skip_with_minimal_cth, prio_cth, no_config,
       no_init_suite_config, no_init_config, no_end_config,
       failed_sequence, repeat_force_stop, config_clash,
       callbacks_on_skip, fallback, data_dir, cth_log
      ]
    ).


%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------

%%%-----------------------------------------------------------------
%%% 
one_cth(Config) when is_list(Config) ->
    do_test(one_empty_cth, "ct_cth_empty_SUITE.erl",[empty_cth], Config).

two_cth(Config) when is_list(Config) ->
    do_test(two_empty_cth, "ct_cth_empty_SUITE.erl",[empty_cth,empty_cth],
	    Config).

faulty_cth_no_init(Config) when is_list(Config) ->
    do_test(faulty_cth_no_init, "ct_cth_empty_SUITE.erl",[askjhdkljashdkaj],
	    Config,{error,"Failed to start CTH, see the "
		   "CT Log for details"}).

faulty_cth_id_no_init(Config) when is_list(Config) ->
    do_test(faulty_cth_id_no_init, "ct_cth_empty_SUITE.erl",[id_no_init_cth],
	    Config,{error,"Failed to start CTH, see the "
		   "CT Log for details"}).

minimal_cth(Config) when is_list(Config) ->
    do_test(minimal_cth, "ct_cth_empty_SUITE.erl",[minimal_cth],Config).

minimal_and_maximal_cth(Config) when is_list(Config) ->
    do_test(minimal_and_maximal_cth, "ct_cth_empty_SUITE.erl",
	    [minimal_cth, empty_cth],Config).

faulty_cth_undef(Config) when is_list(Config) ->
    do_test(faulty_cth_undef, "ct_cth_empty_SUITE.erl",
	    [undef_cth],Config).

faulty_cth_exit_in_init_scope_suite(Config) when is_list(Config) ->
    do_test(faulty_cth_exit_in_init_scope_suite,
	    "ct_exit_in_init_scope_suite_cth_SUITE.erl",
	    [],Config).

faulty_cth_exit_in_init(Config) when is_list(Config) ->
    do_test(faulty_cth_exit_in_init, "ct_cth_empty_SUITE.erl",
	    [crash_init_cth], Config,
	    {error,"Failed to start CTH, see the "
	     "CT Log for details"}).

faulty_cth_exit_in_id(Config) when is_list(Config) ->
    do_test(faulty_cth_exit_in_id, "ct_cth_empty_SUITE.erl",
	    [crash_id_cth], Config,
	    {error,"Failed to start CTH, see the "
	     "CT Log for details"}).

scope_per_suite_cth(Config) when is_list(Config) ->
    do_test(scope_per_suite_cth, "ct_scope_per_suite_cth_SUITE.erl",
	    [],Config).

scope_suite_cth(Config) when is_list(Config) ->
    do_test(scope_suite_cth, "ct_scope_suite_cth_SUITE.erl",
	    [],Config).

scope_suite_group_only_cth(Config) when is_list(Config) ->
    do_test(scope_suite_group_only_cth,
            "ct_scope_suite_group_only_cth_SUITE.erl",
	    [],Config,ok,2,[{group,g1}]).

scope_per_group_cth(Config) when is_list(Config) ->
    do_test(scope_per_group_cth, "ct_scope_per_group_cth_SUITE.erl",
	    [],Config).

scope_per_suite_state_cth(Config) when is_list(Config) ->
    do_test(scope_per_suite_state_cth, "ct_scope_per_suite_state_cth_SUITE.erl",
	    [],Config).

scope_suite_state_cth(Config) when is_list(Config) ->
    do_test(scope_suite_state_cth, "ct_scope_suite_state_cth_SUITE.erl",
	    [],Config).

scope_per_group_state_cth(Config) when is_list(Config) ->
    do_test(scope_per_group_state_cth, "ct_scope_per_group_state_cth_SUITE.erl",
	    [],Config).

fail_pre_suite_cth(Config) when is_list(Config) ->
    do_test(fail_pre_suite_cth, "ct_cth_empty_SUITE.erl",
	    [fail_pre_suite_cth],Config).

double_fail_pre_suite_cth(Config) when is_list(Config) ->
    do_test(double_fail_pre_suite_cth, "{ct_scope_suite_crash_in_cth_SUITE.erl,"
	    "ct_scope_suite_cth_SUITE.erl}",
	    [],Config).

fail_post_suite_cth(Config) when is_list(Config) ->
    do_test(fail_post_suite_cth, "ct_cth_empty_SUITE.erl",
	    [fail_post_suite_cth],Config).

skip_pre_suite_cth(Config) when is_list(Config) ->
    do_test(skip_pre_suite_cth, "ct_cth_empty_SUITE.erl",
	    [skip_pre_suite_cth],Config).

skip_pre_end_cth(Config) when is_list(Config) ->
    do_test(skip_pre_end_cth, "ct_scope_per_group_cth_SUITE.erl",
	    [skip_pre_end_cth],Config).

skip_post_suite_cth(Config) when is_list(Config) ->
    do_test(skip_post_suite_cth, "ct_cth_empty_SUITE.erl",
	    [skip_post_suite_cth],Config).

skip_pre_init_tc_cth(Config) ->
    do_test(skip_pre_init_tc_cth, "ct_cth_empty_SUITE.erl",
	    [skip_pre_init_tc_cth],Config).

fail_post_init_tc_cth(Config) ->
    do_test(fail_post_init_tc_cth, "ct_fail_init_tc_SUITE.erl",
	    [fail_post_init_tc_cth],Config).

recover_post_suite_cth(Config) when is_list(Config) ->
    do_test(recover_post_suite_cth, "ct_cth_fail_per_suite_SUITE.erl",
	    [recover_post_suite_cth],Config).

update_config_cth(Config) when is_list(Config) ->
    do_test(update_config_cth, "ct_update_config_SUITE.erl",
	    [update_config_cth],Config).

state_update_cth(Config) when is_list(Config) ->
    do_test(state_update_cth, "ct_cth_fail_one_skip_one_SUITE.erl",
	    [state_update_cth,state_update_cth],Config).

update_result_cth(Config) ->
    do_test(update_result_cth, "ct_cth_update_result_post_end_tc_SUITE.erl",
            [update_result_post_end_tc_cth],Config).

options_cth(Config) when is_list(Config) ->
    do_test(options_cth, "ct_cth_empty_SUITE.erl",
	    [{empty_cth,[test]}],Config).

same_id_cth(Config) when is_list(Config) ->
    do_test(same_id_cth, "ct_cth_empty_SUITE.erl",
	    [same_id_cth,same_id_cth],Config).

fail_n_skip_with_minimal_cth(Config) when is_list(Config) ->
    do_test(fail_n_skip_with_minimal_cth, "ct_cth_fail_one_skip_one_SUITE.erl",
	    [minimal_terminate_cth],Config).

prio_cth(Config) when is_list(Config) ->
    do_test(prio_cth, "ct_cth_prio_SUITE.erl",
	    [{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).

no_init_suite_config(Config) when is_list(Config) ->
    do_test(no_init_suite_config, "ct_no_init_suite_config_SUITE.erl",
            [empty_cth],Config).

no_init_config(Config) when is_list(Config) ->
    do_test(no_init_config, "ct_no_init_config_SUITE.erl",[empty_cth],Config).

no_end_config(Config) when is_list(Config) ->
    do_test(no_end_config, "ct_no_end_config_SUITE.erl",[empty_cth],Config).

data_dir(Config) when is_list(Config) ->
    do_test(data_dir, "ct_data_dir_SUITE.erl",
	    [verify_data_dir_cth],Config).

cth_log(Config) when is_list(Config) ->
    %% test that cth_log_redirect writes properly to
    %% unexpected I/O log
    ct:timetrap({minutes,10}),
    StartOpts = do_test(cth_log, "cth_log_SUITE.erl", [], Config),
    Logdir = proplists:get_value(logdir, StartOpts),
    UnexpIoLogs =
	filelib:wildcard(
	  filename:join(Logdir,
			"ct_run*/cth.tests*/run*/unexpected_io.log.html")),
    lists:foreach(
      fun(UnexpIoLog) ->
	      {ok,Bin} = file:read_file(UnexpIoLog),
	      Ts = string:tokens(binary_to_list(Bin),[$\n]),
	      Matches = lists:foldl(fun([$=,$E,$R,$R,$O,$R|_],  N) ->
					    N+1;
				       ([$L,$o,$g,$g,$e,$r|_],  N) ->
					    N+1;
				       (_, N) -> N
				    end, 0, Ts),
	      ct:pal("~p matches in ~tp", [Matches,UnexpIoLog]),
	      if Matches > 10 -> ok;
		 true -> exit({no_unexpected_io_found,UnexpIoLog})
	      end
      end, UnexpIoLogs),
    ok.

%% OTP-10599 adds the Suite argument as first argument to all hook
%% callbacks that did not have a Suite argument from before. This test
%% checks that ct_hooks will fall back to old versions of callbacks if
%% new versions are not exported.
fallback(Config) ->
    do_test(fallback, "all_hook_callbacks_SUITE.erl",[fallback_cth], Config).

%% Test that expected callbacks, and only those, are called when tests
%% are skipped in different ways
callbacks_on_skip(Config) ->
    do_test(callbacks_on_skip, {spec,"skip.spec"},[skip_cth], Config).

%% Test that expected callbacks, and only those, are called when tests
%% are skipped due to failed sequence
failed_sequence(Config) ->
    do_test(failed_sequence, "seq_SUITE.erl", [skip_cth], Config).

%% Test that expected callbacks, and only those, are called when tests
%% are skipped due to {force_stop,skip_rest} option
repeat_force_stop(Config) ->
    do_test(repeat_force_stop, "repeat_SUITE.erl", [skip_cth], Config, ok, 2,
            [{force_stop,skip_rest},{duration,"000009"}]).

%% Test that expected callbacks, and only those, are called when a test
%% fails due to clash in config alias names
config_clash(Config) ->
    do_test(config_clash, "config_clash_SUITE.erl", [skip_cth], Config).

%% Test post_groups and post_all hook callbacks, introduced by OTP-14746
alter_groups(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,
                         [{post_groups_return,[{new_group,[tc1,tc2]}]},
                          {post_all_return,[{group,new_group}]}],Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

alter_all(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,[{post_all_return,[tc2]}],Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

alter_all_from_skip(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,[{all_return,{skip,"skipped by all/0"}},
                                         {post_all_return,[tc2]}],Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

alter_all_to_skip(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,
                         [{post_all_return,{skip,"skipped by post_all/3"}}],
                         Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

bad_return_groups(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,[{post_groups_return,not_a_list}],
                         Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

bad_return_all(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,[{post_all_return,not_a_list}],
                         Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

illegal_values_groups(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,
                         [{post_groups_return,[{new_group,[this_test_does_not_exist]},
                                          this_is_not_a_group_def]}],
                         Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

illegal_values_all(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,
                         [{post_all_return,[{group,this_group_does_not_exist},
                                       {this_is_not_a_valid_term}]}],
                         Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

crash_groups(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,[{post_groups_return,crash}],Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

crash_all(Config) ->
    CfgFile = gen_config(?FUNCTION_NAME,[{post_all_return,crash}],Config),
    do_test(?FUNCTION_NAME, "all_and_groups_SUITE.erl", [all_and_groups_cth],
            Config, ok, 2, [{config,CfgFile}]).

%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------

do_test(Tag, WTT, CTHs, Config) ->
    do_test(Tag, WTT, CTHs, Config, ok).
do_test(Tag, WTT, CTHs, Config, {error,_} = Res) ->
    do_test(Tag, WTT, CTHs, Config, Res, 1,[]);
do_test(Tag, WTT, CTHs, Config, Res) ->
    do_test(Tag, WTT, CTHs, Config, Res, 2,[]).

do_test(Tag, WhatToTest, CTHs, Config, Res, EC, ExtraOpts) when is_list(WhatToTest) ->
    do_test(Tag, {suite,WhatToTest}, CTHs, Config, Res, EC, ExtraOpts);
do_test(Tag, {WhatTag,Wildcard}, CTHs, Config, Res, EC, ExtraOpts) ->
    DataDir = ?config(data_dir, Config),
    Files = filelib:wildcard(
               filename:join([DataDir,"cth/tests",Wildcard])),
    {Opts,ERPid} =
        setup([{WhatTag,Files},{ct_hooks,CTHs},{label,Tag}|ExtraOpts], Config),

    Res = ct_test_support:run(Opts, Config),
    Events = ct_test_support:get_events(ERPid, Config),

    ct_test_support:log_events(Tag,
			       reformat(Events, ?eh),
			       ?config(priv_dir, Config),
			       Opts),

    TestEvents = events_to_check(Tag, EC),
    ok = ct_test_support:verify_events(TestEvents, Events, Config),
    Opts.

setup(Test, Config) ->
    Opts0 = ct_test_support:get_opts(Config),
    Level = ?config(trace_level, Config),
    EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
    Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test],
    ERPid = ct_test_support:start_event_receiver(Config),
    {Opts,ERPid}.

reformat(Events, EH) ->
    ct_test_support:reformat(Events, EH).
%reformat(Events, _EH) ->
%    Events.

gen_config(Name,KeyVals,Config) ->
    PrivDir = ?config(priv_dir,Config),
    File = filename:join(PrivDir,atom_to_list(Name)++".cfg"),
    ok = file:write_file(File,[io_lib:format("~p.~n",[{Key,Value}])
                               || {Key,Value} <- KeyVals]),
    File.

%%%-----------------------------------------------------------------
%%% TEST EVENTS
%%%-----------------------------------------------------------------
events_to_check(Test) ->
    %% 2 tests (ct:run_test + script_start) is default
    events_to_check(Test, 2).

events_to_check(_, 0) ->
    [];
events_to_check(Test, N) ->
    test_events(Test) ++ events_to_check(Test, N-1).

test_events(one_empty_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     %% check that post_groups and post_all comes after init when hook
     %% is installed with start flag/option.
     {?eh,cth,{empty_cth,post_groups,[ct_cth_empty_SUITE,[]]}},
     {?eh,cth,{empty_cth,post_all,[ct_cth_empty_SUITE,[test_case],[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist','_',[]]}},
     {?eh,cth,{empty_cth,pre_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist','_',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,
	       [ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(two_empty_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',id,[[]]}},
     {?eh,cth,{'_',id,[[]]}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(faulty_cth_no_init) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(faulty_cth_id_no_init) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',id,[[]]}},
     {negative,{?eh,tc_start,'_'},
      {?eh,test_done,{'DEF','STOP_TIME'}}},
     {?eh,stop_logging,[]}
    ];

test_events(minimal_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {negative,{?eh,cth,{'_',id,['_',[]]}},
      {?eh,cth,{'_',init,['_',[]]}}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(minimal_and_maximal_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',id,[[]]}},
     {negative,{?eh,cth,{'_',id,['_',[]]}},
      {?eh,cth,{'_',init,['_',[]]}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(faulty_cth_undef) ->
    FailReasonStr = "undef_cth:pre_init_per_suite/3 CTH call failed",
    FailReason = {ct_cth_empty_SUITE,init_per_suite,
		  {failed,FailReasonStr}},
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
		  {failed, {error,FailReasonStr}}}},
     {?eh,cth,{'_',on_tc_fail,'_'}},

     {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
			{failed, FailReason}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},

     {?eh,tc_auto_skip,{ct_cth_empty_SUITE,end_per_suite,
			{failed, FailReason}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},

     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(faulty_cth_exit_in_init_scope_suite) ->
    [{?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{'_',init_per_suite}},
     {?eh,cth,{empty_cth,init,['_',[]]}},
     {?eh,tc_done,
      {ct_exit_in_init_scope_suite_cth_SUITE,init_per_suite,
       {failed,
	{error,
	 "Failed to start CTH, see the CT Log for details"}}}},
     {?eh,tc_auto_skip,
      {ct_exit_in_init_scope_suite_cth_SUITE,test_case,
       {failed,
	{ct_exit_in_init_scope_suite_cth_SUITE,init_per_suite,
	 {failed,
	  "Failed to start CTH, see the CT Log for details"}}}}},
     {?eh,tc_auto_skip,
      {ct_exit_in_init_scope_suite_cth_SUITE,end_per_suite,
       {failed,
	{ct_exit_in_init_scope_suite_cth_SUITE,init_per_suite,
	 {failed,
	  "Failed to start CTH, see the CT Log for details"}}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}];

test_events(faulty_cth_exit_in_init) ->
    [{?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,['_',[]]}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}];

test_events(faulty_cth_exit_in_id) ->
    [{?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {negative, {?eh,tc_start,'_'},
      {?eh,test_done,{'DEF','STOP_TIME'}}},
     {?eh,stop_logging,[]}];

test_events(scope_per_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{ct_scope_per_suite_cth_SUITE,init_per_suite}},
     {?eh,cth,{'_',id,[[]]}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_scope_per_suite_cth_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_scope_per_suite_cth_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_scope_per_suite_cth_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_suite_cth_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_suite_cth_SUITE,test_case,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_scope_per_suite_cth_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_scope_per_suite_cth_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,
	       [ct_scope_per_suite_cth_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_scope_per_suite_cth_SUITE,'$proplist','_',[]]}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,tc_done,{ct_scope_per_suite_cth_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(scope_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     %% check that post_groups and post_all comes before init when hook
     %% is installed in suite/0
     %% And there should be no terminate after these, since init is
     %% not yet called.
     {?eh,cth,{'_',post_groups,['_',[]]}},
     {negative,
      {?eh,cth,{'_',terminate,['_']}},
      {?eh,cth,{'_',post_all,['_','_',[]]}}},
     {negative,
      {?eh,cth,{'_',terminate,['_']}},
      {?eh,tc_start,{ct_scope_suite_cth_SUITE,init_per_suite}}},
     {?eh,cth,{'_',id,[[]]}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_scope_suite_cth_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_scope_suite_cth_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_scope_suite_cth_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_scope_suite_cth_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_suite_cth_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_scope_suite_cth_SUITE,test_case,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_scope_suite_cth_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_scope_suite_cth_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,[ct_scope_suite_cth_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_scope_suite_cth_SUITE,'$proplist','_',[]]}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,tc_done,{ct_scope_suite_cth_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(scope_suite_group_only_cth) ->
    Suite = ct_scope_suite_group_only_cth_SUITE,
    CTH = empty_cth,
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,start_info,{1,1,1}},
     %% check that post_groups and post_all comes before init when hook
     %% is installed in suite/0
     {?eh,cth,{CTH,post_groups,['_',['_']]}},
     {negative,
      {?eh,cth,{CTH,post_all,['_','_','_']}},
      {?eh,tc_start,{Suite,init_per_suite}}},
     {?eh,cth,{CTH,id,[[]]}},
     {?eh,cth,{CTH,init,['_',[]]}},
     {?eh,cth,{CTH,pre_init_per_suite,[Suite,'$proplist',mystate]}},
     {?eh,cth,{CTH,post_init_per_suite,[Suite,'$proplist','$proplist',mystate]}},
     {?eh,tc_done,{Suite,init_per_suite,ok}},

     {?eh,tc_start,{Suite,end_per_suite}},
     {?eh,cth,{CTH,pre_end_per_suite,[Suite,'$proplist',mystate]}},
     {?eh,cth,{CTH,post_end_per_suite,[Suite,'$proplist','_',mystate]}},
     {?eh,cth,{CTH,terminate,[mystate]}},
     {?eh,tc_done,{Suite,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(scope_per_group_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{ct_scope_per_group_cth_SUITE,init_per_suite}},
     {?eh,tc_done,{ct_scope_per_group_cth_SUITE,init_per_suite,ok}},

     [{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]}}},
      {?eh,cth,{'_',id,[[]]}},
      {?eh,cth,{'_',init,['_',[]]}},
      {?eh,cth,{'_',post_init_per_group,[ct_scope_per_group_cth_SUITE,group1, '$proplist','$proplist',[]]}},
      {?eh,tc_done,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]},ok}},

      {?eh,tc_start,{ct_scope_per_group_cth_SUITE,test_case}},
      {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',[]]}},
      {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',ok,[]]}},
      {?eh,tc_done,{ct_scope_per_group_cth_SUITE,test_case,ok}},

      {?eh,tc_start,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]}}},
      {?eh,cth,{'_',pre_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist',[]]}},
      {?eh,cth,{'_',post_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist','_',[]]}},
      {?eh,cth,{'_',terminate,[[]]}},
      {?eh,tc_done,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]},ok}}],

     {?eh,tc_start,{ct_scope_per_group_cth_SUITE,end_per_suite}},
     {?eh,tc_done,{ct_scope_per_group_cth_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(scope_per_suite_state_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,init_per_suite}},
     {?eh,cth,{'_',id,[[test]]}},
     {?eh,cth,{'_',init,['_',[test]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_scope_per_suite_state_cth_SUITE,'$proplist','$proplist',[test]]}},
     {?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_suite_state_cth_SUITE,test_case,'$proplist',[test]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_suite_state_cth_SUITE,test_case,'$proplist',ok,[test]]}},
     {?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,
	       [ct_scope_per_suite_state_cth_SUITE,'$proplist',[test]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_scope_per_suite_state_cth_SUITE,'$proplist','_',[test]]}},
     {?eh,cth,{'_',terminate,[[test]]}},
     {?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(scope_suite_state_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',post_groups,['_',[]]}},
     {?eh,cth,{'_',post_all,['_','_',[]]}},
     {?eh,tc_start,{ct_scope_suite_state_cth_SUITE,init_per_suite}},
     {?eh,cth,{'_',id,[[test]]}},
     {?eh,cth,{'_',init,['_',[test]]}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist',[test]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist','$proplist',[test]]}},
     {?eh,tc_done,{ct_scope_suite_state_cth_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_scope_suite_state_cth_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_suite_state_cth_SUITE,test_case,'$proplist',[test]]}},
     {?eh,cth,{'_',post_end_per_testcase,[ct_scope_suite_state_cth_SUITE,test_case,'$proplist',ok,[test]]}},
     {?eh,tc_done,{ct_scope_suite_state_cth_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_scope_suite_state_cth_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist',[test]]}},
     {?eh,cth,{'_',post_end_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist','_',[test]]}},
     {?eh,cth,{'_',terminate,[[test]]}},
     {?eh,tc_done,{ct_scope_suite_state_cth_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(scope_per_group_state_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,init_per_suite}},
     {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,init_per_suite,ok}},

     [{?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,{init_per_group,group1,[]}}},
      {?eh,cth,{'_',id,[[test]]}},
      {?eh,cth,{'_',init,['_',[test]]}},
      {?eh,cth,{'_',post_init_per_group,[ct_scope_per_group_state_cth_SUITE,group1,'$proplist','$proplist',[test]]}},
      {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,{init_per_group,group1,[]},ok}},

      {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,test_case}},
      {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_group_state_cth_SUITE,test_case,'$proplist',[test]]}},
      {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_group_state_cth_SUITE,test_case,'$proplist',ok,[test]]}},
      {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,test_case,ok}},

      {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,{end_per_group,group1,[]}}},
      {?eh,cth,{'_',pre_end_per_group,[ct_scope_per_group_state_cth_SUITE,group1,'$proplist',[test]]}},
      {?eh,cth,{'_',post_end_per_group,[ct_scope_per_group_state_cth_SUITE,group1,'$proplist','_',[test]]}},
      {?eh,cth,{'_',terminate,[[test]]}},
      {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,{end_per_group,group1,[]},ok}}],

     {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,end_per_suite}},
     {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(fail_pre_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},

     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist',
					{fail,"Test failure"},[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
                   {failed, {error,"Test failure"}}}},
     {?eh,cth,{'_',on_tc_fail,
	       [ct_cth_empty_SUITE,init_per_suite,"Test failure",[]]}},


     {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
                        {failed,{ct_cth_empty_SUITE,init_per_suite,
				 {failed,"Test failure"}}}}},
     {?eh,cth,{'_',on_tc_skip,
	       [ct_cth_empty_SUITE,test_case, {tc_auto_skip,
			    {failed, {ct_cth_empty_SUITE, init_per_suite,
				     {failed, "Test failure"}}}},[]]}},


     {?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,
                         {failed, {ct_cth_empty_SUITE, init_per_suite,
				   {failed, "Test failure"}}}}},
     {?eh,cth,{'_',on_tc_skip,
	       [ct_cth_empty_SUITE,end_per_suite, {tc_auto_skip,
				{failed, {ct_cth_empty_SUITE, init_per_suite,
					  {failed, "Test failure"}}}},[]]}},


     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth, {'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(double_fail_pre_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{'_',init_per_suite}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,cth,{'_',pre_init_per_suite,['_','$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,['_','$proplist',
					{fail,"Test failure"},[]]}},
     {?eh,cth, {empty_cth,terminate,[[]]}},

     {?eh,tc_start,{'_',init_per_suite}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,cth, {empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(fail_post_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
		   {failed,{error,"Test failure"}}}},
     {?eh,cth,{'_',on_tc_fail,[ct_cth_empty_SUITE,init_per_suite, "Test failure", []]}},

     {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
                        {failed,{ct_cth_empty_SUITE,init_per_suite,
				 {failed,"Test failure"}}}}},
     {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,test_case,{tc_auto_skip,'_'},[]]}},

     {?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,
                         {failed, {ct_cth_empty_SUITE, init_per_suite,
				   {failed, "Test failure"}}}}},
     {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,end_per_suite,{tc_auto_skip,'_'},[]]}},

     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth, {'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(skip_pre_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist',{skip,"Test skip"},[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,{skipped,"Test skip"}}},
     {?eh,cth,{'_',on_tc_skip,
	       [ct_cth_empty_SUITE,init_per_suite,{tc_user_skip,"Test skip"},[]]}},

     {?eh,tc_user_skip,{ct_cth_empty_SUITE,test_case,"Test skip"}},
     {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,test_case,{tc_user_skip,"Test skip"},[]]}},

     {?eh,tc_user_skip, {ct_cth_empty_SUITE, end_per_suite,"Test skip"}},

     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth, {'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(skip_pre_end_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{ct_scope_per_group_cth_SUITE,init_per_suite}},
     {?eh,tc_done,{ct_scope_per_group_cth_SUITE,init_per_suite,ok}},

     [{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]}}},
      {?eh,cth,{'_',id,[[]]}},
      {?eh,cth,{'_',init,['_',[]]}},
      {?eh,cth,{'_',post_init_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist','$proplist',[]]}},
      {?eh,tc_done,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]},ok}},

      {?eh,tc_start,{ct_scope_per_group_cth_SUITE,test_case}},
      {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',[]]}},
      {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',ok,[]]}},
      {?eh,tc_done,{ct_scope_per_group_cth_SUITE,test_case,ok}},

      {?eh,tc_start,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]}}},
      {?eh,cth,{'_',pre_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist',[]]}},
      {?eh,cth,{'_',post_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist','_',[]]}},
      {?eh,tc_done,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]},
		    {skipped,"Test skip"}}}],
      {?eh,cth,{'_',on_tc_skip,[ct_scope_per_group_cth_SUITE,
                                {end_per_group,group1},
				{tc_user_skip,"Test skip"},
				[]]}},
     {?eh,tc_start,{ct_scope_per_group_cth_SUITE,end_per_suite}},
     {?eh,tc_done,{ct_scope_per_group_cth_SUITE,end_per_suite,
		   {skipped,"Test skip"}}},
     {?eh,cth,{'_',on_tc_skip,[ct_scope_per_group_cth_SUITE,
                               end_per_suite,
			       {tc_user_skip,"Test skip"},
			       []]}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(skip_post_suite_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},

     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,{skipped,"Test skip"}}},
     {?eh,cth,{'_',on_tc_skip,
	       [ct_cth_empty_SUITE,init_per_suite,{tc_user_skip,"Test skip"},[]]}},

     {?eh,tc_user_skip,{ct_cth_empty_SUITE,test_case,"Test skip"}},
     {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,test_case,{tc_user_skip,"Test skip"},[]]}},

     {?eh,tc_user_skip, {ct_cth_empty_SUITE, end_per_suite,"Test skip"}},

     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(skip_pre_init_tc_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,['_',[]]}},
     {?eh,start_info,{1,1,1}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
               [ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
               [ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_testcase,
               [ct_cth_empty_SUITE,test_case,'$proplist',
                {skip,"Skipped in pre_init_per_testcase"},
                []]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,test_case,
                   {skipped,"Skipped in pre_init_per_testcase"}}},
     {?eh,cth,{empty_cth,on_tc_skip,
               [ct_cth_empty_SUITE,test_case,
                {tc_user_skip,"Skipped in pre_init_per_testcase"},
                []]}},
     {?eh,test_stats,{0,0,{1,0}}},
     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,
               [ct_cth_empty_SUITE,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(fail_post_init_tc_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,['_',[]]}},
     {?eh,start_info,{1,1,1}},
     {?eh,tc_start,{ct_fail_init_tc_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,[ct_fail_init_tc_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
               [ct_fail_init_tc_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_fail_init_tc_SUITE,init_per_suite,ok}},
     {?eh,tc_start,{ct_fail_init_tc_SUITE,test_case}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
               [ct_fail_init_tc_SUITE,test_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_testcase,
               [ct_fail_init_tc_SUITE,test_case,'$proplist',
                {skip,
                 {failed,
                  {ct_fail_init_tc_SUITE,init_per_testcase,
                   {{test_case_failed,"Failed in init_per_testcase"},'_'}}}},
                []]}},
     {?eh,tc_done,{ct_fail_init_tc_SUITE,test_case,
                   {failed,"Changed skip to fail in post_init_per_testcase"}}},
     {?eh,cth,{empty_cth,on_tc_fail,
               [ct_fail_init_tc_SUITE,test_case,
                "Changed skip to fail in post_init_per_testcase",
                []]}},
     {?eh,test_stats,{0,1,{0,0}}},
     {?eh,tc_start,{ct_fail_init_tc_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,[ct_fail_init_tc_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,
               [ct_fail_init_tc_SUITE,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_fail_init_tc_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(recover_post_suite_cth) ->
    Suite = ct_cth_fail_per_suite_SUITE,
    [
     {?eh,start_logging,'_'},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{Suite,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[Suite,'$proplist','$proplist']}},
     {?eh,cth,{'_',post_init_per_suite,[Suite,contains([tc_status]),
					{'EXIT',{'_','_'}},[]]}},
     {?eh,tc_done,{Suite,init_per_suite,ok}},

     {?eh,tc_start,{Suite,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,
	       [Suite,test_case, not_contains([tc_status]),[]]}},
     {?eh,cth,{'_',post_end_per_testcase,
	       [Suite,test_case, contains([tc_status]),'_',[]]}},
     {?eh,tc_done,{Suite,test_case,ok}},

     {?eh,tc_start,{Suite,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,
	       [Suite,not_contains([tc_status]),[]]}},
     {?eh,cth,{'_',post_end_per_suite,
	       [Suite,not_contains([tc_status]),'_',[]]}},
     {?eh,tc_done,{Suite,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(update_config_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},

     {?eh,tc_start,{ct_update_config_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,
	       [ct_update_config_SUITE,contains([]),[]]}},
     {?eh,cth,{'_',post_init_per_suite,
	       [ct_update_config_SUITE,
		'$proplist',
		contains(
			  [init_per_suite,
			   pre_init_per_suite]),
		[]]}},
     {?eh,tc_done,{ct_update_config_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_update_config_SUITE, {init_per_group,group1,[]}}},
     {?eh,cth,{'_',pre_init_per_group,
	       [ct_update_config_SUITE,
                group1,contains(
			 [post_init_per_suite,
			  init_per_suite,
			  pre_init_per_suite]),
		[]]}},
     {?eh,cth,{'_',post_init_per_group,
	       [ct_update_config_SUITE,
                group1,
		contains(
		  [post_init_per_suite,
		   init_per_suite,
		   pre_init_per_suite]),
		contains(
		  [init_per_group,
		   pre_init_per_group,
		   post_init_per_suite,
		   init_per_suite,
		   pre_init_per_suite]),
	       []]}},
     {?eh,tc_done,{ct_update_config_SUITE,{init_per_group,group1,[]},ok}},

     {?eh,tc_start,{ct_update_config_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,
	       [ct_update_config_SUITE,
                test_case,contains(
			    [post_init_per_group,
			     init_per_group,
			     pre_init_per_group,
			     post_init_per_suite,
			     init_per_suite,
			     pre_init_per_suite]),
		[]]}},
     {?eh,cth,{'_',post_end_per_testcase,
	       [ct_update_config_SUITE,
                test_case,contains(
			    [init_per_testcase,
			     pre_init_per_testcase,
			     post_init_per_group,
			     init_per_group,
			     pre_init_per_group,
			     post_init_per_suite,
			     init_per_suite,
			     pre_init_per_suite]),
		ok,[]]}},
     {?eh,tc_done,{ct_update_config_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_update_config_SUITE, {end_per_group,group1,[]}}},
     {?eh,cth,{'_',pre_end_per_group,
	       [ct_update_config_SUITE,
                group1,contains(
			 [post_init_per_group,
			  init_per_group,
			  pre_init_per_group,
			  post_init_per_suite,
			  init_per_suite,
			  pre_init_per_suite]),
		[]]}},
     {?eh,cth,{'_',post_end_per_group,
	       [ct_update_config_SUITE,
                group1,
		contains(
		  [pre_end_per_group,
		   post_init_per_group,
		   init_per_group,
		   pre_init_per_group,
		   post_init_per_suite,
		   init_per_suite,
		   pre_init_per_suite]),
	       ok,[]]}},
     {?eh,tc_done,{ct_update_config_SUITE,{end_per_group,group1,[]},ok}},

     {?eh,tc_start,{ct_update_config_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,
	       [ct_update_config_SUITE,contains(
					 [post_init_per_suite,
					  init_per_suite,
					  pre_init_per_suite]),
		[]]}},
     {?eh,cth,{'_',post_end_per_suite,
	       [ct_update_config_SUITE,contains(
					 [pre_end_per_suite,
					  post_init_per_suite,
					  init_per_suite,
					  pre_init_per_suite]),
	       '_',[]]}},
     {?eh,tc_done,{ct_update_config_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[contains(
				[post_end_per_suite,
				 pre_end_per_suite,
				 post_init_per_suite,
				 init_per_suite,
				 pre_init_per_suite])]}},
     {?eh,stop_logging,[]}
    ];

test_events(state_update_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{'_',init_per_suite}},

     {?eh,tc_done,{'_',end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[contains(
				[post_end_per_suite,pre_end_per_suite,
				 post_end_per_group,pre_end_per_group,
				 {not_in_order,
				  [post_end_per_testcase,pre_init_per_testcase,
				   on_tc_skip,post_end_per_testcase,
				   pre_init_per_testcase,on_tc_fail,
				   post_end_per_testcase,pre_init_per_testcase]
				 },
				 post_init_per_group,pre_init_per_group,
				 post_init_per_suite,pre_init_per_suite,
				 init])]}},
     {?eh,cth,{'_',terminate,[contains(
				[post_end_per_suite,pre_end_per_suite,
				 post_end_per_group,pre_end_per_group,
				 {not_in_order,
				  [post_end_per_testcase,pre_init_per_testcase,
				   on_tc_skip,post_end_per_testcase,
				   pre_init_per_testcase,on_tc_fail,
				   post_end_per_testcase,pre_init_per_testcase]
				 },
				 post_init_per_group,pre_init_per_group,
				 post_init_per_suite,pre_init_per_suite,
				 init]
			       )]}},
     {?eh,stop_logging,[]}
    ];

test_events(update_result_cth) ->
    Suite = ct_cth_update_result_post_end_tc_SUITE,
    [
     {?eh,start_logging,'_'},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{Suite,init_per_suite}},
     {?eh,tc_done,{Suite,init_per_suite,ok}},

     {?eh,tc_start,{Suite,tc_ok_to_fail}},
     {?eh,cth,{'_',post_end_per_testcase,[Suite,tc_ok_to_fail,'_',ok,[]]}},
     {?eh,tc_done,{Suite,tc_ok_to_fail,{failed,{error,"Test failure"}}}},
     {?eh,cth,{'_',on_tc_fail,'_'}},
     {?eh,test_stats,{0,1,{0,0}}},

     {?eh,tc_start,{Suite,tc_ok_to_skip}},
     {?eh,cth,{'_',post_end_per_testcase,[Suite,tc_ok_to_skip,'_',ok,[]]}},
     {?eh,tc_done,{Suite,tc_ok_to_skip,{skipped,"Test skipped"}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},
     {?eh,test_stats,{0,1,{1,0}}},

     {?eh,tc_start,{Suite,tc_fail_to_ok}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,tc_fail_to_ok,'_',
                {error,{test_case_failed,"should be changed to ok"}},[]]}},
     {?eh,tc_done,{Suite,tc_fail_to_ok,ok}},
     {?eh,test_stats,{1,1,{1,0}}},

     {?eh,tc_start,{Suite,tc_fail_to_skip}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,tc_fail_to_skip,'_',
                {error,{test_case_failed,"should be changed to skip"}},[]]}},
     {?eh,tc_done,{Suite,tc_fail_to_skip,{skipped,"Test skipped"}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},
     {?eh,test_stats,{1,1,{2,0}}},

     {?eh,tc_start,{Suite,tc_timetrap_to_ok}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,tc_timetrap_to_ok,'_',{timetrap_timeout,3000},[]]}},
     {?eh,tc_done,{Suite,tc_timetrap_to_ok,ok}},
     {?eh,test_stats,{2,1,{2,0}}},

     {?eh,tc_start,{Suite,tc_timetrap_to_skip}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,tc_timetrap_to_skip,'_',{timetrap_timeout,3000},[]]}},
     {?eh,tc_done,{Suite,tc_timetrap_to_skip,{skipped,"Test skipped"}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},
     {?eh,test_stats,{2,1,{3,0}}},

     {?eh,tc_start,{Suite,tc_skip_to_fail}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,tc_skip_to_fail,'_',
                {skip,"should be changed to fail"},[]]}},
     {?eh,tc_done,{Suite,tc_skip_to_fail,{failed,{error,"Test failure"}}}},
     {?eh,cth,{'_',on_tc_fail,'_'}},
     {?eh,test_stats,{2,2,{3,0}}},

     {?eh,tc_start,{Suite,end_fail_to_fail}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,end_fail_to_fail,'_',
                {failed,
                 {Suite,end_per_testcase,
                  {'EXIT',{test_case_failed,"change result when end fails"}}}},[]]}},
     {?eh,tc_done,{Suite,end_fail_to_fail,{failed,{error,"Test failure"}}}},
     {?eh,cth,{'_',on_tc_fail,'_'}},
     {?eh,test_stats,{2,3,{3,0}}},

     {?eh,tc_start,{Suite,end_fail_to_skip}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,end_fail_to_skip,'_',
                {failed,
                 {Suite,end_per_testcase,
                  {'EXIT',{test_case_failed,"change result when end fails"}}}},[]]}},
     {?eh,tc_done,{Suite,end_fail_to_skip,{skipped,"Test skipped"}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},
     {?eh,test_stats,{2,3,{4,0}}},

     {?eh,tc_start,{Suite,end_timetrap_to_fail}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,end_timetrap_to_fail,'_',
                {failed,{Suite,end_per_testcase,{timetrap_timeout,3000}}},[]]}},
     {?eh,tc_done,{Suite,end_timetrap_to_fail,{failed,{error,"Test failure"}}}},
     {?eh,cth,{'_',on_tc_fail,'_'}},
     {?eh,test_stats,{2,4,{4,0}}},

     {?eh,tc_start,{Suite,end_timetrap_to_skip}},
     {?eh,cth,{'_',post_end_per_testcase,
               [Suite,end_timetrap_to_skip,'_',
                {failed,{Suite,end_per_testcase,{timetrap_timeout,3000}}},[]]}},
     {?eh,tc_done,{Suite,end_timetrap_to_skip,{skipped,"Test skipped"}}},
     {?eh,cth,{'_',on_tc_skip,'_'}},
     {?eh,test_stats,{2,4,{5,0}}},

     {?eh,tc_start,{Suite,end_per_suite}},
     {?eh,tc_done,{Suite,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(options_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,['_',[test]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [ct_cth_empty_SUITE,'$proplist',[test]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [ct_cth_empty_SUITE,'$proplist','$proplist',[test]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[test]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist','_',[test]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},

     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,
	       [ct_cth_empty_SUITE,'$proplist',[test]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[test]]}},
     {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[test]]}},
     {?eh,stop_logging,[]}
    ];

test_events(same_id_cth) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',id,[[]]}},
     {?eh,cth,{'_',id,[[]]}},
     {?eh,cth,{'_',init,[same_id_cth,[]]}},
     {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
     {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {negative,
       {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
      {?eh,cth,{'_',post_init_per_suite,
		[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}}},
     {negative,
      {?eh,cth,{'_',post_init_per_suite,
		[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
      {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}}},

     {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
     {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
     {negative,
      {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
      {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}}},
     {negative,
      {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
      {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}}},

     {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
     {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
     {negative,
      {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
      {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}}},
     {negative,
      {?eh,cth,{'_',post_end_per_suite,
		[ct_cth_empty_SUITE,'$proplist','_',[]]}},
      {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(fail_n_skip_with_minimal_cth) ->
    [{?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{'_',init,['_',[]]}},
     {?eh,tc_start,{'_',init_per_suite}},

     {parallel,
      [{?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{init_per_group,
						      group1,[parallel]}}},
       {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{init_per_group,
						     group1,[parallel]},ok}},
       {parallel,
	[{?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{init_per_group,
							group2,[parallel]}}},
	 {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{init_per_group,
						       group2,[parallel]},ok}},
	 %% Verify that 'skip' as well as 'skipped' works
	 {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,test_case2}},
	 {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,test_case2,{skipped,"skip it"}}},
	 {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,test_case3}},
	 {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,test_case3,{skipped,"skip it"}}},
	 {?eh,cth,{empty_cth,on_tc_skip,[ct_cth_fail_one_skip_one_SUITE,
                                         {test_case2,group2},
					 {tc_user_skip,"skip it"},
					 []]}},
	 {?eh,cth,{empty_cth,on_tc_skip,[ct_cth_fail_one_skip_one_SUITE,
                                         {test_case3,group2},
					 {tc_user_skip,"skip it"},
					 []]}},
	 {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{end_per_group,
							group2,[parallel]}}},
	 {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{end_per_group,group2,
						       [parallel]},ok}}]},
       {?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{end_per_group,
						      group1,[parallel]}}},
       {?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,{end_per_group,
						     group1,[parallel]},ok}}]},

     {?eh,tc_done,{'_',end_per_suite,ok}},
     {?eh,cth,{'_',terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(prio_cth) ->
    GenPre = fun(Func,States) when Func==pre_init_per_suite;
                                   Func==pre_end_per_suite ->
		     [{?eh,cth,{'_',Func,['_','_',State]}} ||
                         State <- States];
                (Func,States) ->
		     [{?eh,cth,{'_',Func,['_','_','_',State]}} ||
			 State <- States]
	     end,

    GenPost = fun(Func,States) when Func==post_init_per_suite;
                                    Func==post_end_per_suite ->
		      [{?eh,cth,{'_',Func,['_','_','_',State]}} ||
			  State <- States];
                 (Func,States) ->
		      [{?eh,cth,{'_',Func,['_','_','_','_',State]}} ||
			  State <- States]

              end,

    [{?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}] ++

	[{?eh,tc_start,{ct_cth_prio_SUITE,init_per_suite}}] ++
	GenPre(pre_init_per_suite,
	       [[1100,100],[800],[900],[1000],[1200,1050],[1100],[1200]]) ++
	GenPost(post_init_per_suite,
		[[1100,100],[600,200],[600,600],[700],[800],[900],[1000],
		 [1200,1050],[1100],[1200]]) ++
	[{?eh,tc_done,{ct_cth_prio_SUITE,init_per_suite,ok}},


	 [{?eh,tc_start,{ct_cth_prio_SUITE,{init_per_group,'_',[]}}}] ++
	     GenPre(pre_init_per_group,
		    [[1100,100],[600,200],[600,600],[700],[800],
		     [900],[1000],[1200,1050],[1100],[1200]]) ++
	     GenPost(post_init_per_group,
		     [[1100,100],[600,200],[600,600],[600],[700],[800],
		      [900],[900,900],[500,900],[1000],[1200,1050],
		      [1100],[1200]]) ++
	     [{?eh,tc_done,{ct_cth_prio_SUITE,{init_per_group,'_',[]},ok}}] ++

	     [{?eh,tc_start,{ct_cth_prio_SUITE,test_case}}] ++
	     GenPre(pre_init_per_testcase,
		    [[1100,100],[600,200],[600,600],[600],[700],[800],
		     [900],[900,900],[500,900],[1000],[1200,1050],
		     [1100],[1200]]) ++
	     GenPost(post_end_per_testcase,
		     lists:reverse(
		       [[1100,100],[600,200],[600,600],[600],[700],[800],
			[900],[900,900],[500,900],[1000],[1200,1050],
			[1100],[1200]])) ++
	     [{?eh,tc_done,{ct_cth_prio_SUITE,test_case,ok}},

	      {?eh,tc_start,{ct_cth_prio_SUITE,{end_per_group,'_',[]}}}] ++
	     GenPre(pre_end_per_group,
		    lists:reverse(
		      [[1100,100],[600,200],[600,600],[600],[700],[800],
		       [900],[900,900],[500,900],[1000],[1200,1050],
		       [1100],[1200]])) ++
	     GenPost(post_end_per_group,
		     lists:reverse(
		       [[1100,100],[600,200],[600,600],[600],[700],[800],
			[900],[900,900],[500,900],[1000],[1200,1050],
			[1100],[1200]])) ++
	     [{?eh,tc_done,{ct_cth_prio_SUITE,{end_per_group,'_',[]},ok}}],

	 {?eh,tc_start,{ct_cth_prio_SUITE,end_per_suite}}] ++
	GenPre(pre_end_per_suite,
	       lists:reverse(
		 [[1100,100],[600,200],[600,600],[700],[800],[900],[1000],
		  [1200,1050],[1100],[1200]])) ++
	GenPost(post_end_per_suite,
		lists:reverse(
		  [[1100,100],[600,200],[600,600],[700],[800],[900],[1000],
		   [1200,1050],[1100],[1200]])) ++
	[{?eh,tc_done,{ct_cth_prio_SUITE,end_per_suite,ok}},
	 {?eh,test_done,{'DEF','STOP_TIME'}},
	 {?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,
	       [ct_no_config_SUITE,test_case_1,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,
	       [ct_no_config_SUITE,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,
		[ct_no_config_SUITE,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_init_per_group,
		[ct_no_config_SUITE,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,
		[ct_no_config_SUITE,test_case_2,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_end_per_testcase,
		[ct_no_config_SUITE,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,
		[ct_no_config_SUITE,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_end_per_group,
		[ct_no_config_SUITE,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(no_init_suite_config) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,start_info,{1,1,1}},
     {?eh,tc_start,{ct_no_init_suite_config_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [ct_no_init_suite_config_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [ct_no_init_suite_config_SUITE,'$proplist','_',[]]}},
     {?eh,tc_done,{ct_no_init_suite_config_SUITE,init_per_suite,
                   {failed,{error,{undef,'_'}}}}},
     {?eh,cth,{empty_cth,on_tc_fail,[ct_no_init_suite_config_SUITE,
                                     init_per_suite,
                                     {undef,'_'},[]]}},
      {?eh,tc_auto_skip,{ct_no_init_suite_config_SUITE,test_case,
                         {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
                                  {'EXIT',{undef,'_'}}}}}},
     {?eh,cth,{empty_cth,on_tc_skip,
               [ct_no_init_suite_config_SUITE,
                test_case,
                {tc_auto_skip,
                 {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
                          {'EXIT',{undef,'_'}}}}},
                []]}},
     {?eh,test_stats,{0,0,{0,1}}},
     {?eh,tc_auto_skip,{ct_no_init_suite_config_SUITE,end_per_suite,
                        {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
                                 {'EXIT',{undef,'_'}}}}}},
     {?eh,cth,{empty_cth,on_tc_skip,
               [ct_no_init_suite_config_SUITE,
                end_per_suite,
                {tc_auto_skip,
                 {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
                          {'EXIT',{undef,'_'}}}}},
                []]}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(no_init_config) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,start_info,{1,1,2}},
     {?eh,tc_start,{ct_no_init_config_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [ct_no_init_config_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [ct_no_init_config_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_no_init_config_SUITE,init_per_suite,ok}},
     {?eh,tc_start,{ct_no_init_config_SUITE,test_case_1}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
	       [ct_no_init_config_SUITE,test_case_1,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,
	       [ct_no_init_config_SUITE,test_case_1,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_no_init_config_SUITE,test_case_1,ok}},
     {?eh,test_stats,{1,0,{0,0}}},
     [{?eh,tc_start,{ct_no_init_config_SUITE,{init_per_group,test_group,[]}}},
      {?eh,cth,{empty_cth,pre_init_per_group,
		[ct_no_init_config_SUITE,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_init_per_group,
		[ct_no_init_config_SUITE,test_group,'$proplist','_',[]]}},
      {?eh,tc_done,{ct_no_init_config_SUITE,{init_per_group,test_group,[]},
                    {failed,{error,{undef,'_'}}}}},
      {?eh,cth,{empty_cth,on_tc_fail,[ct_no_init_config_SUITE,
                                      {init_per_group,test_group},
                                      {undef,'_'},[]]}},
      {?eh,tc_auto_skip,{ct_no_init_config_SUITE,{test_case_2,test_group},
                         {failed,{ct_no_init_config_SUITE,init_per_group,
                                  {'EXIT',{undef,'_'}}}}}},
      {?eh,cth,{empty_cth,on_tc_skip,[ct_no_init_config_SUITE,
                                      {test_case_2,test_group},
                                      {tc_auto_skip,
                                       {failed,
                                        {ct_no_init_config_SUITE,init_per_group,
                                         {'EXIT',{undef,'_'}}}}},
                                       []]}},
      {?eh,test_stats,{1,0,{0,1}}},
      {?eh,tc_auto_skip,{ct_no_init_config_SUITE,{end_per_group,test_group},
                         {failed,{ct_no_init_config_SUITE,init_per_group,
                                  {'EXIT',{undef,'_'}}}}}},
      {?eh,cth,{empty_cth,on_tc_skip,[ct_no_init_config_SUITE,
                                      {end_per_group,test_group},
                                      {tc_auto_skip,
                                       {failed,
                                        {ct_no_init_config_SUITE,init_per_group,
                                         {'EXIT',{undef,'_'}}}}},
                                       []]}}],
     {?eh,tc_start,{ct_no_init_config_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,
	       [ct_no_init_config_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,
	       [ct_no_init_config_SUITE,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_no_init_config_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(no_end_config) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,start_info,{1,1,2}},
     {?eh,tc_start,{ct_no_end_config_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [ct_no_end_config_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [ct_no_end_config_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{ct_no_end_config_SUITE,init_per_suite,ok}},
     {?eh,tc_start,{ct_no_end_config_SUITE,test_case_1}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
	       [ct_no_end_config_SUITE,test_case_1,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,
	       [ct_no_end_config_SUITE,test_case_1,'$proplist',ok,[]]}},
     {?eh,tc_done,{ct_no_end_config_SUITE,test_case_1,ok}},
     {?eh,test_stats,{1,0,{0,0}}},
     [{?eh,tc_start,{ct_no_end_config_SUITE,
                     {init_per_group,test_group,'$proplist'}}},
      {?eh,cth,{empty_cth,pre_init_per_group,
		[ct_no_end_config_SUITE,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_init_per_group,
		[ct_no_end_config_SUITE,test_group,'$proplist','$proplist',[]]}},
      {?eh,tc_done,{ct_no_end_config_SUITE,
		    {init_per_group,test_group,'$proplist'},ok}},
      {?eh,tc_start,{ct_no_end_config_SUITE,test_case_2}},
      {?eh,cth,{empty_cth,pre_init_per_testcase,
		[ct_no_end_config_SUITE,test_case_2,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_end_per_testcase,
		[ct_no_end_config_SUITE,test_case_2,'$proplist',ok,[]]}},
      {?eh,tc_done,{ct_no_end_config_SUITE,test_case_2,ok}},
      {?eh,test_stats,{2,0,{0,0}}},
      {?eh,tc_start,{ct_no_end_config_SUITE,
                     {end_per_group,test_group,'$proplist'}}},
      {?eh,cth,{empty_cth,pre_end_per_group,
		[ct_no_end_config_SUITE,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_end_per_group,
		[ct_no_end_config_SUITE,test_group,'$proplist','_',[]]}},
      {?eh,tc_done,{ct_no_end_config_SUITE,{end_per_group,test_group,[]},
                    {failed,{error,{undef,'_'}}}}},
      {?eh,cth,{empty_cth,on_tc_fail,[ct_no_end_config_SUITE,
                                      {end_per_group,test_group},
                                      {undef,'_'},[]]}}],
     {?eh,tc_start,{ct_no_end_config_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,
	       [ct_no_end_config_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,
	       [ct_no_end_config_SUITE,'$proplist','_',[]]}},
     {?eh,tc_done,{ct_no_end_config_SUITE,end_per_suite,
                   {failed,{error,{undef,'_'}}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(data_dir) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,init,[verify_data_dir_cth,[]]}},
     {?eh,start_info,{1,1,2}},
     {?eh,tc_start,{ct_framework,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [ct_data_dir_SUITE,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [ct_data_dir_SUITE,'$proplist','$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
     {?eh,tc_done,{ct_framework,init_per_suite,ok}},
     {?eh,tc_start,{ct_data_dir_SUITE,test_case_1}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
	       [ct_data_dir_SUITE,test_case_1,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,
	       [ct_data_dir_SUITE,test_case_1,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
     {?eh,tc_done,{ct_data_dir_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,
		[ct_data_dir_SUITE,test_group,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
      {?eh,cth,{empty_cth,post_init_per_group,
		[ct_data_dir_SUITE,test_group,'$proplist','$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
      {?eh,tc_done,{ct_framework,
		    {init_per_group,test_group,'$proplist'},ok}},
      {?eh,tc_start,{ct_data_dir_SUITE,test_case_2}},
      {?eh,cth,{empty_cth,pre_init_per_testcase,
		[ct_data_dir_SUITE,test_case_2,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
      {?eh,cth,{empty_cth,post_end_per_testcase,
		[ct_data_dir_SUITE,test_case_2,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
      {?eh,tc_done,{ct_data_dir_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,
		[ct_data_dir_SUITE,test_group,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
      {?eh,cth,{empty_cth,post_end_per_group,
		[ct_data_dir_SUITE,test_group,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
      {?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_data_dir_SUITE,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,
	       [ct_data_dir_SUITE,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
     {?eh,tc_done,{ct_framework,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(cth_log) ->
    [{?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,tc_start,{cth_log_SUITE,init_per_suite}},

     {parallel,
      [{?eh,tc_start,{ct_framework,{init_per_group,g1,
				    [{suite,cth_log_SUITE},parallel]}}},
       {?eh,tc_done,{ct_framework,{init_per_group,g1,
				   [{suite,cth_log_SUITE},parallel]},ok}},
       {?eh,test_stats,{30,0,{0,0}}},
       {?eh,tc_start,{ct_framework,{end_per_group,g1,
				    [{suite,cth_log_SUITE},parallel]}}},
       {?eh,tc_done,{ct_framework,{end_per_group,g1,
				   [{suite,cth_log_SUITE},parallel]},ok}}]},

     {?eh,tc_done,{cth_log_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,stop_logging,[]}
    ];

test_events(fallback) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,tc_start,{all_hook_callbacks_SUITE,init_per_suite}},
     {?eh,cth,{empty_cth,pre_init_per_suite,
	       [all_hook_callbacks_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_suite,
	       [all_hook_callbacks_SUITE,'$proplist','$proplist',[]]}},
     {?eh,tc_done,{all_hook_callbacks_SUITE,init_per_suite,ok}},

     [{?eh,tc_start,{ct_framework,{init_per_group,test_group,'$proplist'}}},
      {?eh,cth,{empty_cth,pre_init_per_group,
		[fallback_nosuite,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_init_per_group,
		[fallback_nosuite,test_group,'$proplist','$proplist',[]]}},
      {?eh,tc_done,{ct_framework,
		    {init_per_group,test_group,'$proplist'},ok}},
      {?eh,tc_start,{all_hook_callbacks_SUITE,test_case}},
      {?eh,cth,{empty_cth,pre_init_per_testcase,
		[fallback_nosuite,test_case,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_end_per_testcase,
		[fallback_nosuite,test_case,'$proplist',ok,[]]}},
      {?eh,tc_done,{all_hook_callbacks_SUITE,test_case,ok}},
      {?eh,test_stats,{1,0,{0,0}}},
      {?eh,tc_start,{ct_framework,{end_per_group,test_group,'$proplist'}}},
      {?eh,cth,{empty_cth,pre_end_per_group,
		[fallback_nosuite,test_group,'$proplist',[]]}},
      {?eh,cth,{empty_cth,post_end_per_group,
		[fallback_nosuite,test_group,'$proplist',ok,[]]}},
      {?eh,tc_done,{ct_framework,{end_per_group,test_group,'$proplist'},ok}}],
     {?eh,tc_start,{all_hook_callbacks_SUITE,test_case}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
               [fallback_nosuite,test_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_testcase,
               [fallback_nosuite,test_case,'$proplist','_',[]]}},
     {?eh,cth,{empty_cth,pre_end_per_testcase,
               [fallback_nosuite,test_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_testcase,
               [fallback_nosuite,test_case,'$proplist','_',[]]}},
     {?eh,tc_done,{all_hook_callbacks_SUITE,test_case,ok}},
     {?eh,test_stats,{2,0,{0,0}}},
     {?eh,tc_start,{all_hook_callbacks_SUITE,skip_case}},
     {?eh,cth,{empty_cth,pre_init_per_testcase,
               [fallback_nosuite,skip_case,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_init_per_testcase,
               [fallback_nosuite,skip_case,'$proplist',
                {skip,"Skipped in init_per_testcase/2"},[]]}},
     {?eh,tc_done,{all_hook_callbacks_SUITE,skip_case,
                   {skipped,"Skipped in init_per_testcase/2"}}},
     {?eh,cth,{empty_cth,on_tc_skip,
               [fallback_nosuite,skip_case,
                {tc_user_skip,"Skipped in init_per_testcase/2"},
                []]}},
     {?eh,test_stats,{2,0,{1,0}}},
     {?eh,tc_start,{all_hook_callbacks_SUITE,end_per_suite}},
     {?eh,cth,{empty_cth,pre_end_per_suite,
	       [all_hook_callbacks_SUITE,'$proplist',[]]}},
     {?eh,cth,{empty_cth,post_end_per_suite,
               [all_hook_callbacks_SUITE,'$proplist','_',[]]}},
     {?eh,tc_done,{all_hook_callbacks_SUITE,end_per_suite,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(callbacks_on_skip) ->
    %% skip_cth.erl will send a 'cth_error' event if a hook is
    %% erroneously called. Therefore, all Events are changed to
    %% {negative,{?eh,cth_error,'_'},Event}
    %% at the end of this function.
    Events =
        [
         {?eh,start_logging,{'DEF','RUNDIR'}},
         {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
         {?eh,cth,{empty_cth,id,[[]]}},
         {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
         {?eh,start_info,{6,6,15}},

         %% all_hook_callbacks_SUITE is skipped in spec
         %% Only the on_tc_skip callback shall be called
         {?eh,tc_user_skip,{all_hook_callbacks_SUITE,all,"Skipped in spec"}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [all_hook_callbacks_SUITE,all,
                    {tc_user_skip,"Skipped in spec"},
                    []]}},
         {?eh,test_stats,{0,0,{1,0}}},

         %% skip_init_SUITE is skipped in its init_per_suite function
         %% No group- or testcase-functions shall be called.
         {?eh,tc_start,{skip_init_SUITE,init_per_suite}},
         {?eh,cth,{empty_cth,pre_init_per_suite,
                   [skip_init_SUITE,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_suite,
                   [skip_init_SUITE,
                    '$proplist',
                    {skip,"Skipped in init_per_suite/1"},
                    []]}},
         {?eh,tc_done,{skip_init_SUITE,init_per_suite,
                       {skipped,"Skipped in init_per_suite/1"}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_init_SUITE,init_per_suite,
                    {tc_user_skip,"Skipped in init_per_suite/1"},
                    []]}},
         {?eh,tc_user_skip,{skip_init_SUITE,test_case,"Skipped in init_per_suite/1"}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_init_SUITE,test_case,
                    {tc_user_skip,"Skipped in init_per_suite/1"},
                    []]}},
         {?eh,test_stats,{0,0,{2,0}}},
         {?eh,tc_user_skip,{skip_init_SUITE,end_per_suite,
                            "Skipped in init_per_suite/1"}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_init_SUITE,end_per_suite,
                    {tc_user_skip,"Skipped in init_per_suite/1"},
                    []]}},

         %% skip_req_SUITE is auto-skipped since a 'require' statement
         %% returned by suite/0 is not fulfilled.
         %% No group- or testcase-functions shall be called.
         {?eh,tc_start,{skip_req_SUITE,init_per_suite}},
         {?eh,tc_done,{skip_req_SUITE,init_per_suite,
                       {auto_skipped,{require_failed_in_suite0,
                                      {not_available,whatever}}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_req_SUITE,init_per_suite,
                    {tc_auto_skip,{require_failed_in_suite0,
                                   {not_available,whatever}}},
                    []]}},
         {?eh,tc_auto_skip,{skip_req_SUITE,test_case,{require_failed_in_suite0,
                                                      {not_available,whatever}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_req_SUITE,test_case,
                    {tc_auto_skip,{require_failed_in_suite0,
                                   {not_available,whatever}}},
                    []]}},
         {?eh,test_stats,{0,0,{2,1}}},
         {?eh,tc_auto_skip,{skip_req_SUITE,end_per_suite,
                            {require_failed_in_suite0,
                             {not_available,whatever}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_req_SUITE,end_per_suite,
                    {tc_auto_skip,{require_failed_in_suite0,
                                   {not_available,whatever}}},
                    []]}},

         %% skip_fail_SUITE is auto-skipped since the suite/0 function
         %% retuns a faluty format.
         %% No group- or testcase-functions shall be called.
         {?eh,tc_start,{skip_fail_SUITE,init_per_suite}},
         {?eh,tc_done,{skip_fail_SUITE,init_per_suite,
                       {failed,{error,{suite0_failed,bad_return_value}}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_fail_SUITE,init_per_suite,
                    {tc_auto_skip,
                     {failed,{error,{suite0_failed,bad_return_value}}}},
                    []]}},
         {?eh,tc_auto_skip,{skip_fail_SUITE,test_case,
                            {failed,{error,{suite0_failed,bad_return_value}}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_fail_SUITE,test_case,
                    {tc_auto_skip,
                     {failed,{error,{suite0_failed,bad_return_value}}}},
                    []]}},
         {?eh,test_stats,{0,0,{2,2}}},
         {?eh,tc_auto_skip,{skip_fail_SUITE,end_per_suite,
                            {failed,{error,{suite0_failed,bad_return_value}}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_fail_SUITE,end_per_suite,
                    {tc_auto_skip,
                     {failed,{error,{suite0_failed,bad_return_value}}}},
                    []]}},

         %% skip_group_SUITE
         {?eh,tc_start,{skip_group_SUITE,init_per_suite}},
         {?eh,cth,{empty_cth,pre_init_per_suite,
                   [skip_group_SUITE,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_suite,
                   [skip_group_SUITE,
                    '$proplist',
                    '_',
                    []]}},
         {?eh,tc_done,{skip_group_SUITE,init_per_suite,ok}},

         %% test_group_1 - auto_skip due to require failed
         [{?eh,tc_start,{skip_group_SUITE,{init_per_group,test_group_1,[]}}},
          {?eh,tc_done,
           {skip_group_SUITE,{init_per_group,test_group_1,[]},
            {auto_skipped,{require_failed,{not_available,whatever}}}}},
          {?eh,cth,{empty_cth,on_tc_skip,
                    [skip_group_SUITE,
                     {init_per_group,test_group_1},
                     {tc_auto_skip,{require_failed,{not_available,whatever}}},
                     []]}},
          {?eh,tc_auto_skip,{skip_group_SUITE,{test_case,test_group_1},
                             {require_failed,{not_available,whatever}}}},
          {?eh,cth,{empty_cth,on_tc_skip,
                    [skip_group_SUITE,
                     {test_case,test_group_1},
                     {tc_auto_skip,{require_failed,{not_available,whatever}}},
                     []]}},
          {?eh,test_stats,{0,0,{2,3}}},
          {?eh,tc_auto_skip,{skip_group_SUITE,{end_per_group,test_group_1},
                             {require_failed,{not_available,whatever}}}}],
         %% The following appears to be outside of the group, but
         %% that's only an implementation detail in
         %% ct_test_support.erl - it does not know about events from
         %% test suite specific hooks and regards the group ended with
         %% the above tc_auto_skip-event for end_per_group.
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_group_SUITE,
                    {end_per_group,test_group_1},
                    {tc_auto_skip,{require_failed,{not_available,whatever}}},
                    []]}},

         %% test_group_2 - auto_skip due to failed return from group/1
         [{?eh,tc_start,{skip_group_SUITE,{init_per_group,test_group_2,[]}}},
          {?eh,tc_done,
           {skip_group_SUITE,{init_per_group,test_group_2,[]},
            {auto_skipped,{group0_failed,bad_return_value}}}},
          {?eh,cth,{empty_cth,on_tc_skip,
                    [skip_group_SUITE,
                     {init_per_group,test_group_2},
                     {tc_auto_skip,{group0_failed,bad_return_value}},
                     []]}},
          {?eh,tc_auto_skip,{skip_group_SUITE,{test_case,test_group_2},
                             {group0_failed,bad_return_value}}},
          {?eh,cth,{empty_cth,on_tc_skip,
                    [skip_group_SUITE,
                     {test_case,test_group_2},
                     {tc_auto_skip,{group0_failed,bad_return_value}},
                     []]}},
          {?eh,test_stats,{0,0,{2,4}}},
          {?eh,tc_auto_skip,{skip_group_SUITE,{end_per_group,test_group_2},
                             {group0_failed,bad_return_value}}}],
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_group_SUITE,
                    {end_per_group,test_group_2},
                    {tc_auto_skip,{group0_failed,bad_return_value}},
                    []]}},
         %% test_group_3 - user_skip in init_per_group/2
         [{?eh,tc_start,
           {skip_group_SUITE,{init_per_group,test_group_3,[]}}},
          {?eh,cth,{empty_cth,pre_init_per_group,
                    [skip_group_SUITE,test_group_3,'$proplist',[]]}},
          {?eh,cth,{empty_cth,post_init_per_group,
                    [skip_group_SUITE,test_group_3,'$proplist',
                     {skip,"Skipped in init_per_group/2"},
                     []]}},
          {?eh,tc_done,{skip_group_SUITE,
                        {init_per_group,test_group_3,[]},
                        {skipped,"Skipped in init_per_group/2"}}},
          {?eh,cth,{empty_cth,on_tc_skip,
                    [skip_group_SUITE,
                     {init_per_group,test_group_3},
                     {tc_user_skip,"Skipped in init_per_group/2"},
                     []]}},
          {?eh,tc_user_skip,{skip_group_SUITE,
                             {test_case,test_group_3},
                             "Skipped in init_per_group/2"}},
          {?eh,cth,{empty_cth,on_tc_skip,
                    [skip_group_SUITE,
                     {test_case,test_group_3},
                     {tc_user_skip,"Skipped in init_per_group/2"},
                     []]}},
          {?eh,test_stats,{0,0,{3,4}}},
          {?eh,tc_user_skip,{skip_group_SUITE,
                             {end_per_group,test_group_3},
                             "Skipped in init_per_group/2"}}],
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_group_SUITE,
                    {end_per_group,test_group_3},
                    {tc_user_skip,"Skipped in init_per_group/2"},
                    []]}},

         {?eh,tc_start,{skip_group_SUITE,end_per_suite}},
         {?eh,cth,{empty_cth,pre_end_per_suite,
                   [skip_group_SUITE,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_end_per_suite,
                   [skip_group_SUITE,
                    '$proplist',
                    ok,[]]}},
         {?eh,tc_done,{skip_group_SUITE,end_per_suite,ok}},


         %% skip_case_SUITE has 4 test cases which are all skipped in
         %% different ways
         {?eh,tc_start,{skip_case_SUITE,init_per_suite}},
         {?eh,cth,{empty_cth,pre_init_per_suite,
                   [skip_case_SUITE,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_suite,
                   [skip_case_SUITE,
                    '$proplist',
                    '_',
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,init_per_suite,ok}},

         %% Skip in spec -> only on_tc_skip shall be called
         {?eh,tc_user_skip,{skip_case_SUITE,skip_in_spec,"Skipped in spec"}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,skip_in_spec,
                    {tc_user_skip,"Skipped in spec"},
                    []]}},
         {?eh,test_stats,{0,0,{4,4}}},

         %% Skip in init_per_testcase -> pre/post_end_per_testcase
         %% shall not be called
         {?eh,tc_start,{skip_case_SUITE,skip_in_init}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [skip_case_SUITE,skip_in_init,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [skip_case_SUITE,skip_in_init,
                    '$proplist',
                    {skip,"Skipped in init_per_testcase/2"},
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,skip_in_init,
                       {skipped,"Skipped in init_per_testcase/2"}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,skip_in_init,
                    {tc_user_skip,"Skipped in init_per_testcase/2"},
                    []]}},
         {?eh,test_stats,{0,0,{5,4}}},

         %% Fail in init_per_testcase -> pre/post_end_per_testcase
         %% shall not be called
         {?eh,tc_start,{skip_case_SUITE,fail_in_init}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [skip_case_SUITE,fail_in_init,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [skip_case_SUITE,fail_in_init,
                    '$proplist',
                    {skip,{failed,'_'}},
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,fail_in_init,
                       {auto_skipped,{failed,'_'}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,fail_in_init,
                    {tc_auto_skip,{failed,'_'}},
                    []]}},
         {?eh,test_stats,{0,0,{5,5}}},

         %% Exit in init_per_testcase -> pre/post_end_per_testcase
         %% shall not be called
         {?eh,tc_start,{skip_case_SUITE,exit_in_init}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [skip_case_SUITE,exit_in_init,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [skip_case_SUITE,exit_in_init,
                    '$proplist',
                    {skip,{failed,'_'}},
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,exit_in_init,
                       {auto_skipped,{failed,'_'}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,exit_in_init,
                    {tc_auto_skip,{failed,'_'}},
                    []]}},
         {?eh,test_stats,{0,0,{5,6}}},

         %% Fail in end_per_testcase -> all hooks shall be called and
         %% test shall succeed.
         {?eh,tc_start,{skip_case_SUITE,fail_in_end}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [skip_case_SUITE,fail_in_end,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [skip_case_SUITE,fail_in_end,
                    '$proplist',
                    ok,
                    []]}},
         {?eh,cth,{empty_cth,pre_end_per_testcase,
                   [skip_case_SUITE,fail_in_end,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_end_per_testcase,
                   [skip_case_SUITE,fail_in_end,
                    '$proplist',
                    {failed,
                     {skip_case_SUITE,end_per_testcase,
                      {'EXIT',
                       {test_case_failed,"Failed in end_per_testcase/2"}}}},
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,fail_in_end,
                       {failed,
                        {skip_case_SUITE,end_per_testcase,
                         {'EXIT',
                          {test_case_failed,"Failed in end_per_testcase/2"}}}}}},
         {?eh,test_stats,{1,0,{5,6}}},

         %% Exit in end_per_testcase -> all hooks shall be called and
         %% test shall succeed.
         {?eh,tc_start,{skip_case_SUITE,exit_in_end}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [skip_case_SUITE,exit_in_end,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [skip_case_SUITE,exit_in_end,
                    '$proplist',
                    ok,
                    []]}},
         {?eh,cth,{empty_cth,pre_end_per_testcase,
                   [skip_case_SUITE,exit_in_end,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_end_per_testcase,
                   [skip_case_SUITE,exit_in_end,
                    '$proplist',
                    {failed,
                     {skip_case_SUITE,end_per_testcase,
                      {'EXIT',"Exit in end_per_testcase/2"}}},
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,exit_in_end,
                       {failed,
                        {skip_case_SUITE,end_per_testcase,
                         {'EXIT',"Exit in end_per_testcase/2"}}}}},
         {?eh,test_stats,{2,0,{5,6}}},

         %% Skip in testcase function -> all callbacks shall be called
         {?eh,tc_start,{skip_case_SUITE,skip_in_case}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [skip_case_SUITE,skip_in_case,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [skip_case_SUITE,skip_in_case,
                    '$proplist',
                    ok,[]]}},
         {?eh,cth,{empty_cth,pre_end_per_testcase,
                   [skip_case_SUITE,skip_in_case,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_end_per_testcase,
                   [skip_case_SUITE,skip_in_case,
                    '$proplist',
                    {skip,"Skipped in test case function"},
                    []]}},
         {?eh,tc_done,{skip_case_SUITE,skip_in_case,
                       {skipped,"Skipped in test case function"}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,skip_in_case,
                    {tc_user_skip,"Skipped in test case function"},
                    []]}},
         {?eh,test_stats,{2,0,{6,6}}},

         %% Auto skip due to failed 'require' -> only the on_tc_skip
         %% callback shall be called
         {?eh,tc_start,{skip_case_SUITE,req_auto_skip}},
         {?eh,tc_done,{skip_case_SUITE,req_auto_skip,
                       {auto_skipped,{require_failed,{not_available,whatever}}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,req_auto_skip,
                    {tc_auto_skip,{require_failed,{not_available,whatever}}},
                    []]}},
         {?eh,test_stats,{2,0,{6,7}}},

         %% Auto skip due to failed testcase/0 function -> only the
         %% on_tc_skip callback shall be called
         {?eh,tc_start,{skip_case_SUITE,fail_auto_skip}},
         {?eh,tc_done,{skip_case_SUITE,fail_auto_skip,
                       {auto_skipped,{testcase0_failed,bad_return_value}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [skip_case_SUITE,fail_auto_skip,
                    {tc_auto_skip,{testcase0_failed,bad_return_value}},
                    []]}},
         {?eh,test_stats,{2,0,{6,8}}},

         {?eh,tc_start,{skip_case_SUITE,end_per_suite}},
         {?eh,cth,{empty_cth,pre_end_per_suite,
                   [skip_case_SUITE,
                    '$proplist',
                    []]}},
         {?eh,cth,{empty_cth,post_end_per_suite,
                   [skip_case_SUITE,
                    '$proplist',
                    ok,[]]}},
         {?eh,tc_done,{skip_case_SUITE,end_per_suite,ok}},
         {?eh,test_done,{'DEF','STOP_TIME'}},
         {?eh,cth,{empty_cth,terminate,[[]]}},
         {?eh,stop_logging,[]}
        ],
    %% Make sure no 'cth_error' events are received!
    [{negative,{?eh,cth_error,'_'},E} || E <- Events];

test_events(failed_sequence) ->
    %% skip_cth.erl will send a 'cth_error' event if a hook is
    %% erroneously called. Therefore, all Events are changed to
    %% {negative,{?eh,cth_error,'_'},Event}
    %% at the end of this function.
    Events =
        [
         {?eh,start_logging,{'DEF','RUNDIR'}},
         {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
         {?eh,cth,{empty_cth,id,[[]]}},
         {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
         {?eh,start_info,{1,1,2}},
         {?eh,tc_start,{ct_framework,init_per_suite}},
         {?eh,cth,{empty_cth,pre_init_per_suite,[seq_SUITE,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_init_per_suite,
                   [seq_SUITE,'$proplist','$proplist',[]]}},
         {?eh,tc_done,{ct_framework,init_per_suite,ok}},
         {?eh,tc_start,{seq_SUITE,test_case_1}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [seq_SUITE,test_case_1,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [seq_SUITE,test_case_1,'$proplist',ok,[]]}},
         {?eh,cth,{empty_cth,pre_end_per_testcase,
                   [seq_SUITE,test_case_1,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_end_per_testcase,
                   [seq_SUITE,test_case_1,'$proplist',
                    {error,failed_on_purpose},[]]}},
         {?eh,tc_done,{seq_SUITE,test_case_1,{failed,{error,failed_on_purpose}}}},
         {?eh,cth,{empty_cth,on_tc_fail,
                   [seq_SUITE,test_case_1,failed_on_purpose,[]]}},
         {?eh,test_stats,{0,1,{0,0}}},
         {?eh,tc_start,{seq_SUITE,test_case_2}},
         {?eh,tc_done,{seq_SUITE,test_case_2,
                       {auto_skipped,{sequence_failed,seq1,test_case_1}}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [seq_SUITE,test_case_2,
                    {tc_auto_skip,{sequence_failed,seq1,test_case_1}},
                    []]}},
         {?eh,test_stats,{0,1,{0,1}}},
         {?eh,tc_start,{ct_framework,end_per_suite}},
         {?eh,cth,{empty_cth,pre_end_per_suite,[seq_SUITE,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_end_per_suite,[seq_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,[]}
        ],
    %% Make sure no 'cth_error' events are received!
    [{negative,{?eh,cth_error,'_'},E} || E <- Events];

test_events(repeat_force_stop) ->
    %% skip_cth.erl will send a 'cth_error' event if a hook is
    %% erroneously called. Therefore, all Events are changed to
    %% {negative,{?eh,cth_error,'_'},Event}
    %% at the end of this function.
    Events=
        [
         {?eh,start_logging,{'DEF','RUNDIR'}},
         {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
         {?eh,cth,{empty_cth,id,[[]]}},
         {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
         {?eh,start_info,{1,1,2}},
         {?eh,tc_start,{ct_framework,init_per_suite}},
         {?eh,cth,{empty_cth,pre_init_per_suite,[repeat_SUITE,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_init_per_suite,
                   [repeat_SUITE,'$proplist','$proplist',[]]}},
         {?eh,tc_done,{ct_framework,init_per_suite,ok}},
         {?eh,tc_start,{repeat_SUITE,test_case_1}},
         {?eh,cth,{empty_cth,pre_init_per_testcase,
                   [repeat_SUITE,test_case_1,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_init_per_testcase,
                   [repeat_SUITE,test_case_1,'$proplist',ok,[]]}},
         {?eh,cth,{empty_cth,pre_end_per_testcase,
                   [repeat_SUITE,test_case_1,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_end_per_testcase,
                   [repeat_SUITE,test_case_1,'$proplist',ok,[]]}},
         {?eh,tc_done,{repeat_SUITE,test_case_1,ok}},
         {?eh,test_stats,{1,0,{0,0}}},
         {?eh,tc_start,{repeat_SUITE,test_case_2}},
         {?eh,tc_done,{repeat_SUITE,test_case_2,
                       {auto_skipped,
                        "Repeated test stopped by force_stop option"}}},
         {?eh,cth,{empty_cth,on_tc_skip,
                   [repeat_SUITE,test_case_2,
                    {tc_auto_skip,"Repeated test stopped by force_stop option"},
                    []]}},
         {?eh,test_stats,{1,0,{0,1}}},
         {?eh,tc_start,{ct_framework,end_per_suite}},
         {?eh,cth,{empty_cth,pre_end_per_suite,[repeat_SUITE,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_end_per_suite,
                   [repeat_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,[]}
        ],
    %% Make sure no 'cth_error' events are received!
    [{negative,{?eh,cth_error,'_'},E} || E <- Events];

test_events(config_clash) ->
    %% skip_cth.erl will send a 'cth_error' event if a hook is
    %% erroneously called. Therefore, all Events are changed to
    %% {negative,{?eh,cth_error,'_'},Event}
    %% at the end of this function.
    Events =
        [
         {?eh,start_logging,{'DEF','RUNDIR'}},
         {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
         {?eh,cth,{empty_cth,id,[[]]}},
         {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
         {?eh,start_info,{1,1,1}},
         {?eh,tc_start,{ct_framework,init_per_suite}},
         {?eh,cth,{empty_cth,pre_init_per_suite,
                   [config_clash_SUITE,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_init_per_suite,
                   [config_clash_SUITE,'$proplist','$proplist',[]]}},
         {?eh,tc_done,{ct_framework,init_per_suite,ok}},
         {?eh,tc_start,{config_clash_SUITE,test_case_1}},
         {?eh,tc_done,{config_clash_SUITE,test_case_1,
                       {failed,{error,{config_name_already_in_use,[aa]}}}}},
         {?eh,cth,{empty_cth,on_tc_fail,
                   [config_clash_SUITE,test_case_1,
                    {config_name_already_in_use,[aa]},
                    []]}},
         {?eh,test_stats,{0,1,{0,0}}},
         {?eh,tc_start,{ct_framework,end_per_suite}},
         {?eh,cth,{empty_cth,pre_end_per_suite,
                   [config_clash_SUITE,'$proplist',[]]}},
         {?eh,cth,{empty_cth,post_end_per_suite,
                   [config_clash_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,[]}
    ],
    %% Make sure no 'cth_error' events are received!
    [{negative,{?eh,cth_error,'_'},E} || E <- Events];

test_events(alter_groups) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,
                                      [{new_group,[tc1,tc2]}]]}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,[{group,new_group}],
                                   [{new_group,[tc1,tc2]}]]}},
     {?eh,start_info,{1,1,2}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,
                                      [{new_group,[tc1,tc2]}]]}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,[{group,new_group}],
                                   [{new_group,[tc1,tc2]}]]}},
     {?eh,tc_start,{all_and_groups_SUITE,{init_per_group,new_group,[]}}},
     {?eh,tc_done,{all_and_groups_SUITE,
                   {init_per_group,new_group,'$proplist'},ok}},
     {?eh,tc_start,{all_and_groups_SUITE,tc1}},
     {?eh,tc_done,{all_and_groups_SUITE,tc1,ok}},
     {?eh,tc_start,{all_and_groups_SUITE,tc2}},
     {?eh,tc_done,{all_and_groups_SUITE,tc2,ok}},
     {?eh,tc_start,{all_and_groups_SUITE,{end_per_group,new_group,[]}}},
     {?eh,tc_done,{all_and_groups_SUITE,
                   {end_per_group,new_group,'$proplist'},ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(alter_all) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,
                                      [{test_group,[tc1]}]]}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,[tc2],
                                   [{test_group,[tc1]}]]}},
     {?eh,start_info,{1,1,1}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,[tc2],'_']}},
     {?eh,tc_start,{all_and_groups_SUITE,tc2}},
     {?eh,tc_done,{all_and_groups_SUITE,tc2,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(alter_all_from_skip) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,
                                      [{test_group,[tc1]}]]}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,[tc2],
                                   [{test_group,[tc1]}]]}},
     {?eh,start_info,{1,1,1}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,[tc2],'_']}},
     {?eh,tc_start,{all_and_groups_SUITE,tc2}},
     {?eh,tc_done,{all_and_groups_SUITE,tc2,ok}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(alter_all_to_skip) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,
                                      [{test_group,[tc1]}]]}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,
                                   {skip,"skipped by post_all/3"},
                                   [{test_group,[tc1]}]]}},
     {?eh,start_info,{1,1,0}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,
                                   {skip,"skipped by post_all/3"},
                                   '_']}},
     {?eh,tc_user_skip,{all_and_groups_SUITE,all,"skipped by post_all/3"}},
     {?eh,cth,{'_',on_tc_skip,[all_and_groups_SUITE,all,
                               {tc_user_skip,"skipped by post_all/3"},
                               []]}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(illegal_values_groups) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,
               [all_and_groups_SUITE,
                [{new_group,[this_test_does_not_exist]},
                 this_is_not_a_group_def]]}},
     {?eh,start_info,{1,0,0}},
     {?eh,cth,{empty_cth,post_groups,
               [all_and_groups_SUITE,
                [{new_group,[this_test_does_not_exist]},
                 this_is_not_a_group_def]]}},
     {?eh,tc_start,{ct_framework,error_in_suite}},
     {?eh,tc_done,{ct_framework,error_in_suite,{failed,{error,'_'}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(illegal_values_all) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,
               [all_and_groups_SUITE,
                [{group,this_group_does_not_exist},
                 {this_is_not_a_valid_term}],'_']}},
     {?eh,start_info,{1,0,0}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,
               [all_and_groups_SUITE,
                [{group,this_group_does_not_exist},
                 {this_is_not_a_valid_term}],'_']}},
     {?eh,tc_start,{ct_framework,error_in_suite}},
     {?eh,tc_done,
      {ct_framework,error_in_suite,
       {failed,
        {error,'Invalid reference to group this_group_does_not_exist in all_and_groups_SUITE:all/0'}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(bad_return_groups) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,not_a_list]}},
     {?eh,start_info,{1,0,0}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,not_a_list]}},
     {?eh,tc_start,{ct_framework,error_in_suite}},
     {?eh,tc_done,
      {ct_framework,error_in_suite,
       {failed,
        {error,
         {'Bad return value from post_groups/2 hook function',not_a_list}}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(bad_return_all) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,not_a_list,'_']}},
     {?eh,start_info,{1,0,0}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,not_a_list,'_']}},
     {?eh,tc_start,{ct_framework,error_in_suite}},
     {?eh,tc_done,
      {ct_framework,error_in_suite,
       {failed,
        {error,{'Bad return value from post_all/3 hook function',not_a_list}}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(crash_groups) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,crash]}},
     {?eh,start_info,{1,0,0}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,crash]}},
     {?eh,tc_start,{ct_framework,error_in_suite}},
     {?eh,tc_done,{ct_framework,error_in_suite,
                   {failed,
                    {error,"all_and_groups_cth:post_groups/2 CTH call failed"}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(crash_all) ->
    [
     {?eh,start_logging,{'DEF','RUNDIR'}},
     {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
     {?eh,cth,{empty_cth,id,[[]]}},
     {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,crash,'_']}},
     {?eh,start_info,{1,0,0}},
     {?eh,cth,{empty_cth,post_groups,[all_and_groups_SUITE,'_']}},
     {?eh,cth,{empty_cth,post_all,[all_and_groups_SUITE,crash,'_']}},
     {?eh,tc_start,{ct_framework,error_in_suite}},
     {?eh,tc_done,{ct_framework,error_in_suite,
                   {failed,
                    {error,"all_and_groups_cth:post_all/3 CTH call failed"}}}},
     {?eh,test_done,{'DEF','STOP_TIME'}},
     {?eh,cth,{empty_cth,terminate,[[]]}},
     {?eh,stop_logging,[]}
    ];

test_events(ok) ->
    ok.

%% test events help functions
contains(List) ->
    fun(Proplist) when is_list(Proplist) ->
	    contains(List,Proplist)
    end.

contains([{not_in_order,List}|T],Rest) ->
    contains_parallel(List,Rest),
    contains(T,Rest);
contains([{Ele,Pos}|T] = L,[H|T2]) ->
    case element(Pos,H) of
	Ele ->
	    contains(T,T2);
	_ ->
	    contains(L,T2)
    end;
contains([Ele|T],[{Ele,_}|T2])->
    contains(T,T2);
contains([Ele|T],[Ele|T2])->
    contains(T,T2);
contains(List,[_|T]) ->
    contains(List,T);
contains([],_) ->
    match.

contains_parallel([Key | T], Elems) ->
    contains([Key],Elems),
    contains_parallel(T,Elems);
contains_parallel([],_Elems) ->
    match.

not_contains(List) ->
    fun(Proplist) when is_list(Proplist) ->
	    [] = [Ele || {Ele,_} <- Proplist,
			 Test <- List,
			 Test =:= Ele]
    end.