From 701315c4fabb5cefc377533198588a85a0fd1417 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Mon, 27 Aug 2012 16:37:16 +0200 Subject: Make sure the test can never hang when ct:break/1/2 is called --- lib/common_test/src/ct.erl | 85 ++++++++++++++++++++-------- lib/common_test/src/ct_run.erl | 15 +++-- lib/common_test/src/ct_testspec.erl | 6 +- lib/common_test/src/ct_util.hrl | 2 +- lib/common_test/test/ct_testspec_2_SUITE.erl | 10 ++-- 5 files changed, 79 insertions(+), 39 deletions(-) (limited to 'lib/common_test') diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index e369c9f4ef..aa8813c391 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -157,7 +157,7 @@ run(TestDirs) -> %%% {refresh_logs,LogDir} | {logopts,LogOpts} | %%% {verbosity,VLevels} | {basic_html,Bool} | %%% {ct_hooks, CTHs} | {enable_builtin_hooks,Bool} | -%%% {noinput,Bool} +%%% {release_shell,Bool} %%% TestDirs = [string()] | string() %%% Suites = [string()] | [atom()] | string() | atom() %%% Cases = [atom()] | atom() @@ -194,15 +194,24 @@ run(TestDirs) -> %%% CTHs = [CTHModule | {CTHModule, CTHInitArgs}] %%% CTHModule = atom() %%% CTHInitArgs = term() -%%% Result = [TestResult] | {error,Reason} -%%% @doc Run tests as specified by the combination of options in Opts. +%%% Result = {Ok,Failed,{UserSkipped,AutoSkipped}} | TestRunnerPid | {error,Reason} +%%% Ok = integer() +%%% Failed = integer() +%%% UserSkipped = integer() +%%% AutoSkipped = integer() +%%% TestRunnerPid = pid() +%%% Reason = term() +%%% @doc

Run tests as specified by the combination of options in Opts. %%% The options are the same as those used with the %%% ct_run program. %%% Note that here a TestDir can be used to point out the path to %%% a Suite. Note also that the option testcase %%% corresponds to the -case option in the ct_run %%% program. Configuration files specified in Opts will be -%%% installed automatically at startup. +%%% installed automatically at startup.

+%%%

TestRunnerPid is returned if release_shell == true +%%% (see the User's Guide for details).

+%%%

Reason indicates what type of error has been encountered.

run_test(Opts) -> ct_run:run_test(Opts). @@ -960,6 +969,8 @@ get_testdata(Key) -> Error; {'EXIT',_Reason} -> no_tests_running; + undefined -> + {error,no_testdata}; [CurrTC] when Key == curr_tc -> {ok,CurrTC}; Data -> @@ -1159,7 +1170,8 @@ sync_notify(Name,Data) -> %%%----------------------------------------------------------------- %%% @spec break(Comment) -> ok | {error,Reason} %%% Comment = string() -%%% Reason = {multiple_cases_running,TestCases} +%%% Reason = {multiple_cases_running,TestCases} | +%%% 'enable break with release_shell option' %%% TestCases = [atom()] %%% %%% @doc

This function will cancel all timetraps and pause the @@ -1170,21 +1182,33 @@ sync_notify(Name,Data) -> %%% test case. If a parallel group is executing, break/2 %%% should be called instead.

break(Comment) -> - case get_testdata(curr_tc) of - {ok,{_,TestCase}} -> - test_server:break(?MODULE, Comment); - {ok,Cases} when is_list(Cases) -> - {error,{multiple_cases_running, - [TC || {_,TC} <- Cases]}}; - Error -> - {error,Error} + case {ct_util:get_testdata(starter), + ct_util:get_testdata(release_shell)} of + {ct,ReleaseSh} when ReleaseSh /= true -> + Warning = "ct:break/1 can only be used if release_shell == true.\n", + ct_logs:log("Warning!", Warning, []), + io:format(user, "Warning! " ++ Warning, []), + {error,'enable break with release_shell option'}; + _ -> + case get_testdata(curr_tc) of + {ok,{_,TestCase}} -> + test_server:break(?MODULE, Comment); + {ok,Cases} when is_list(Cases) -> + {error,{'multiple cases running', + [TC || {_,TC} <- Cases]}}; + Error = {error,_} -> + Error; + Error -> + {error,Error} + end end. %%%----------------------------------------------------------------- %%% @spec break(TestCase, Comment) -> ok | {error,Reason} %%% TestCase = atom() %%% Comment = string() -%%% Reason = test_case_not_running +%%% Reason = 'test case not running' | +%%% 'enable break with release_shell option' %%% %%% @doc

This function works the same way as break/1, %%% only the TestCase argument makes it possible to @@ -1192,18 +1216,29 @@ break(Comment) -> %%% continue/1 function should be used to resume %%% execution of TestCase.

break(TestCase, Comment) -> - case get_testdata(curr_tc) of - {ok,Cases} when is_list(Cases) -> - case lists:keymember(TestCase, 2, Cases) of - true -> + case {ct_util:get_testdata(starter), + ct_util:get_testdata(release_shell)} of + {ct,ReleaseSh} when ReleaseSh /= true -> + Warning = "ct:break/2 can only be used if release_shell == true.\n", + ct_logs:log("Warning!", Warning, []), + io:format(user, "Warning! " ++ Warning, []), + {error,'enable break with release_shell option'}; + _ -> + case get_testdata(curr_tc) of + {ok,Cases} when is_list(Cases) -> + case lists:keymember(TestCase, 2, Cases) of + true -> + test_server:break(?MODULE, TestCase, Comment); + false -> + {error,'test case not running'} + end; + {ok,{_,TestCase}} -> test_server:break(?MODULE, TestCase, Comment); - false -> - {error,test_case_not_running} - end; - {ok,{_,TestCase}} -> - test_server:break(?MODULE, TestCase, Comment); - Error -> - {error,Error} + Error = {error,_} -> + Error; + Error -> + {error,Error} + end end. %%%----------------------------------------------------------------- diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index faf5786a54..d80d216f9e 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -76,7 +76,8 @@ scale_timetraps = false, create_priv_dir, testspecs = [], - tests}). + tests, + starter}). %%%----------------------------------------------------------------- %%% @spec script_start() -> void() @@ -334,7 +335,8 @@ script_start1(Parent, Args) -> stylesheet = Stylesheet, multiply_timetraps = MultTT, scale_timetraps = ScaleTT, - create_priv_dir = CreatePrivDir}, + create_priv_dir = CreatePrivDir, + starter = script}, %% check if log files should be refreshed or go on to run tests... Result = run_or_refresh(StartOpts, Args), @@ -1003,7 +1005,8 @@ run_test2(StartOpts) -> stylesheet = Stylesheet, multiply_timetraps = MultiplyTT, scale_timetraps = ScaleTT, - create_priv_dir = CreatePrivDir}, + create_priv_dir = CreatePrivDir, + starter = ct}, %% test specification case proplists:get_value(spec, StartOpts) of @@ -1632,6 +1635,7 @@ do_run(Tests, Skip, Opts, Args) when is_record(Opts, opts) -> "run ct:start_interactive()\n\n",[]), {error,interactive_mode}; _Pid -> + ct_util:set_testdata({starter,Opts#opts.starter}), compile_and_run(Tests, Skip, Opts1#opts{verbosity=Verbosity}, Args) end @@ -1677,8 +1681,9 @@ compile_and_run(Tests, Skip, Opts, Args) -> {Tests1,Skip1} = final_tests(Tests,Skip,SavedErrors), - possibly_spawn(true == proplists:get_value(noinput, Args), - Tests1, Skip1, Opts); + ReleaseSh = proplists:get_value(release_shell, Args), + ct_util:set_testdata({release_shell,ReleaseSh}), + possibly_spawn(ReleaseSh == true, Tests1, Skip1, Opts); false -> io:nl(), ct_util:stop(clean), diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl index de63ac3b75..a8b67d0329 100644 --- a/lib/common_test/src/ct_testspec.erl +++ b/lib/common_test/src/ct_testspec.erl @@ -779,8 +779,8 @@ add_tests([{event_handler,Node,HOrHs,Args}|Ts],Spec) -> add_tests([{enable_builtin_hooks,Bool}|Ts],Spec) -> add_tests(Ts, Spec#testspec{enable_builtin_hooks = Bool}); -add_tests([{noinput,Bool}|Ts],Spec) -> - add_tests(Ts, Spec#testspec{noinput = Bool}); +add_tests([{release_shell,Bool}|Ts],Spec) -> + add_tests(Ts, Spec#testspec{release_shell = Bool}); %% --- handled/errors --- add_tests([{define,_,_}|Ts],Spec) -> % handled @@ -1283,7 +1283,7 @@ valid_terms() -> {ct_hooks,2}, {ct_hooks,3}, {enable_builtin_hooks,2}, - {noinput,2}, + {release_shell,2}, {multiply_timetraps,2}, {multiply_timetraps,3}, {scale_timetraps,2}, diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl index 7b08e78433..196b5e46d0 100644 --- a/lib/common_test/src/ct_util.hrl +++ b/lib/common_test/src/ct_util.hrl @@ -43,7 +43,7 @@ event_handler=[], ct_hooks=[], enable_builtin_hooks=true, - noinput=false, + release_shell=false, include=[], auto_compile=[], stylesheet=[], diff --git a/lib/common_test/test/ct_testspec_2_SUITE.erl b/lib/common_test/test/ct_testspec_2_SUITE.erl index 681387c745..411529b52a 100644 --- a/lib/common_test/test/ct_testspec_2_SUITE.erl +++ b/lib/common_test/test/ct_testspec_2_SUITE.erl @@ -91,7 +91,7 @@ all() -> %% {ct_hooks,2} %% {ct_hooks,3} %% {enable_builtin_hooks,2} -%% {noinput,2} +%% {release_shell,2} %% {multiply_timetraps,2} %% {multiply_timetraps,3} %% {scale_timetraps,2} @@ -198,7 +198,7 @@ basic_compatible_no_nodes(_Config) -> ct_hooks = [{Node,{cth_mod1,[]}}, {Node,{cth_mod2,[]}}], enable_builtin_hooks = true, - noinput = false, + release_shell = false, include = Incls, auto_compile = [], stylesheet = [], @@ -325,7 +325,7 @@ basic_compatible_nodes(_Config) -> {Node1,{cth_mod2,[]}}, {Node2,{cth_mod2,[]}}], enable_builtin_hooks = true, - noinput = false, + release_shell = false, include = Incls, auto_compile = [], stylesheet = [], @@ -542,7 +542,7 @@ misc_config_terms(_Config) -> {enable_builtin_hooks,false}, - {noinput,true}, + {release_shell,true}, {auto_compile,false}, {auto_compile,n1@h1,true}, @@ -590,7 +590,7 @@ misc_config_terms(_Config) -> {n1@h1,CfgD}, {n2@h2,CfgD}], enable_builtin_hooks = false, - noinput = true, + release_shell = true, auto_compile = [{Node,false}, {n1@h1,true}, {n2@h2,false}], -- cgit v1.2.3