diff options
Diffstat (limited to 'lib/common_test/src')
-rw-r--r-- | lib/common_test/src/ct.erl | 3 | ||||
-rw-r--r-- | lib/common_test/src/ct_framework.erl | 70 | ||||
-rw-r--r-- | lib/common_test/src/ct_repeat.erl | 38 | ||||
-rw-r--r-- | lib/common_test/src/ct_run.erl | 14 | ||||
-rw-r--r-- | lib/common_test/src/ct_slave.erl | 78 | ||||
-rw-r--r-- | lib/common_test/src/ct_util.erl | 4 | ||||
-rw-r--r-- | lib/common_test/src/unix_telnet.erl | 36 |
7 files changed, 153 insertions, 90 deletions
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 04a95a53fa..e6732f7fc7 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -153,7 +153,7 @@ run(TestDirs) -> %%% {auto_compile,Bool} | {create_priv_dir,CreatePrivDir} | %%% {multiply_timetraps,M} | {scale_timetraps,Bool} | %%% {repeat,N} | {duration,DurTime} | {until,StopTime} | -%%% {force_stop,Bool} | {decrypt,DecryptKeyOrFile} | +%%% {force_stop,ForceStop} | {decrypt,DecryptKeyOrFile} | %%% {refresh_logs,LogDir} | {logopts,LogOpts} | %%% {verbosity,VLevels} | {basic_html,Bool} | %%% {ct_hooks, CTHs} | {enable_builtin_hooks,Bool} | @@ -184,6 +184,7 @@ run(TestDirs) -> %%% N = integer() %%% DurTime = string(HHMMSS) %%% StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS) +%%% ForceStop = skip_rest | Bool %%% DecryptKeyOrFile = {key,DecryptKey} | {file,DecryptFile} %%% DecryptKey = string() %%% DecryptFile = string() diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 5fe4eaf511..b92fe1555f 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -64,38 +64,46 @@ init_tc(Mod,Func,Config) -> ok end, - case ct_util:get_testdata(curr_tc) of - {Suite,{suite0_failed,{require,Reason}}} -> - {skip,{require_failed_in_suite0,Reason}}; - {Suite,{suite0_failed,_}=Failure} -> - {skip,Failure}; + case Func=/=end_per_suite + andalso Func=/=end_per_group + andalso ct_util:get_testdata(skip_rest) of + true -> + {skip,"Repeated test stopped by force_stop option"}; _ -> - ct_util:update_testdata(curr_tc, - fun(undefined) -> - [{Suite,Func}]; - (Running) -> - [{Suite,Func}|Running] - end, [create]), - case ct_util:read_suite_data({seq,Suite,Func}) of - undefined -> - init_tc1(Mod,Suite,Func,Config); - Seq when is_atom(Seq) -> - case ct_util:read_suite_data({seq,Suite,Seq}) of - [Func|TCs] -> % this is the 1st case in Seq - %% make sure no cases in this seq are - %% marked as failed from an earlier execution - %% in the same suite - lists:foreach( - fun(TC) -> - ct_util:save_suite_data({seq,Suite,TC}, - Seq) - end, TCs); - _ -> - ok - end, - init_tc1(Mod,Suite,Func,Config); - {failed,Seq,BadFunc} -> - {skip,{sequence_failed,Seq,BadFunc}} + case ct_util:get_testdata(curr_tc) of + {Suite,{suite0_failed,{require,Reason}}} -> + {skip,{require_failed_in_suite0,Reason}}; + {Suite,{suite0_failed,_}=Failure} -> + {skip,Failure}; + _ -> + ct_util:update_testdata(curr_tc, + fun(undefined) -> + [{Suite,Func}]; + (Running) -> + [{Suite,Func}|Running] + end, [create]), + case ct_util:read_suite_data({seq,Suite,Func}) of + undefined -> + init_tc1(Mod,Suite,Func,Config); + Seq when is_atom(Seq) -> + case ct_util:read_suite_data({seq,Suite,Seq}) of + [Func|TCs] -> % this is the 1st case in Seq + %% make sure no cases in this seq are + %% marked as failed from an earlier execution + %% in the same suite + lists:foreach( + fun(TC) -> + ct_util:save_suite_data( + {seq,Suite,TC}, + Seq) + end, TCs); + _ -> + ok + end, + init_tc1(Mod,Suite,Func,Config); + {failed,Seq,BadFunc} -> + {skip,{sequence_failed,Seq,BadFunc}} + end end end. diff --git a/lib/common_test/src/ct_repeat.erl b/lib/common_test/src/ct_repeat.erl index a47309c6ee..f4d9949776 100644 --- a/lib/common_test/src/ct_repeat.erl +++ b/lib/common_test/src/ct_repeat.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -23,7 +23,7 @@ %%% start flags (or equivalent ct:run_test/1 options) are supported: %%% -until <StopTime>, StopTime = YYMoMoDDHHMMSS | HHMMSS %%% -duration <DurTime>, DurTime = HHMMSS -%%% -force_stop +%%% -force_stop [skip_rest] %%% -repeat <N>, N = integer()</p> -module(ct_repeat). @@ -62,12 +62,15 @@ loop_test(If,Args) when is_list(Args) -> io:format("\nCommon Test: " "Will repeat tests for ~s.\n\n",[ts(Secs)]), TPid = - case lists:keymember(force_stop,1,Args) of - true -> + case proplists:get_value(force_stop,Args) of + False when False==false; False==undefined -> + undefined; + ForceStop -> CtrlPid = self(), - spawn(fun() -> stop_after(CtrlPid,Secs) end); - false -> - undefined + spawn( + fun() -> + stop_after(CtrlPid,Secs,ForceStop) + end) end, Args1 = [{loop_info,[{stop_time,Secs,StopTime,1}]} | Args], loop(If,stop_time,0,Secs,StopTime,Args1,TPid,[]) @@ -212,7 +215,7 @@ get_stop_time(until,[Y1,Y2,Mo1,Mo2,D1,D2,H1,H2,Mi1,Mi2,S1,S2]) -> list_to_integer([S1,S2])}, calendar:datetime_to_gregorian_seconds({Date,Time}); -get_stop_time(until,Time) -> +get_stop_time(until,Time=[_,_,_,_,_,_]) -> get_stop_time(until,"000000"++Time); get_stop_time(duration,[H1,H2,Mi1,Mi2,S1,S2]) -> @@ -227,10 +230,17 @@ cancel(Pid) -> %% After Secs, abort will make the test_server finish the current %% job, then empty the job queue and stop. -stop_after(_CtrlPid,Secs) -> +stop_after(_CtrlPid,Secs,ForceStop) -> timer:sleep(Secs*1000), + case ForceStop of + SkipRest when SkipRest==skip_rest; SkipRest==["skip_rest"] -> + ct_util:set_testdata({skip_rest,true}); + _ -> + ok + end, test_server_ctrl:abort(). + %% Callback from ct_run to print loop info to system log. log_loop_info(Args) -> case lists:keysearch(loop_info,1,Args) of @@ -259,11 +269,11 @@ log_loop_info(Args) -> io_lib:format("Test time remaining: ~w secs (~w%)\n", [Secs,trunc((Secs/Secs0)*100)]), LogStr4 = - case lists:keymember(force_stop,1,Args) of - true -> - io_lib:format("force_stop is enabled",[]); - _ -> - "" + case proplists:get_value(force_stop,Args) of + False when False==false; False==undefined -> + ""; + ForceStop -> + io_lib:format("force_stop is set to: ~w",[ForceStop]) end, ct_logs:log("Test loop info",LogStr1++LogStr2++LogStr3++LogStr4,[]) end. diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 49f00429ae..57cfab532e 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -771,9 +771,9 @@ script_usage() -> "\n\t[-scale_timetraps]" "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" "\n\t[-basic_html]" - "\n\t[-repeat N [-force_stop]] |" - "\n\t[-duration HHMMSS [-force_stop]] |" - "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"), + "\n\t[-repeat N] |" + "\n\t[-duration HHMMSS [-force_stop [skip_rest]]] |" + "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"), io:format("Run tests using test specification:\n\n" "\tct_run -spec TestSpec1 TestSpec2 .. TestSpecN" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" @@ -795,9 +795,9 @@ script_usage() -> "\n\t[-scale_timetraps]" "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" "\n\t[-basic_html]" - "\n\t[-repeat N [-force_stop]] |" - "\n\t[-duration HHMMSS [-force_stop]] |" - "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"), + "\n\t[-repeat N] |" + "\n\t[-duration HHMMSS [-force_stop [skip_rest]]] |" + "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"), io:format("Refresh the HTML index files:\n\n" "\tct_run -refresh_logs [LogDir]" "[-logdir LogDir] " @@ -2933,6 +2933,8 @@ opts2args(EnvStartOpts) -> []; ({create_priv_dir,PD}) when is_atom(PD) -> [{create_priv_dir,[atom_to_list(PD)]}]; + ({force_stop,skip_rest}) -> + [{force_stop,["skip_rest"]}]; ({force_stop,true}) -> [{force_stop,[]}]; ({force_stop,false}) -> diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl index 1fd8c04f8b..872c39de04 100644 --- a/lib/common_test/src/ct_slave.erl +++ b/lib/common_test/src/ct_slave.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -43,12 +43,13 @@ %%% @spec start(Node) -> Result %%% Node = atom() %%% Result = {ok, NodeName} | -%%% {error, already_started, NodeName} | -%%% {error, started_not_connected, NodeName} | -%%% {error, boot_timeout, NodeName} | -%%% {error, init_timeout, NodeName} | -%%% {error, startup_timeout, NodeName} | -%%% {error, not_alive, NodeName} +%%% {error, Reason, NodeName} +%%% Reason = already_started | +%%% started_not_connected | +%%% boot_timeout | +%%% init_timeout | +%%% startup_timeout | +%%% not_alive %%% NodeName = atom() %%% @doc Starts an Erlang node with name <code>Node</code> on the local host. %%% @see start/3 @@ -56,20 +57,28 @@ start(Node) -> start(gethostname(), Node). %%%----------------------------------------------------------------- -%%% @spec start(Host, Node) -> Result -%%% Node = atom() -%%% Host = atom() +%%% @spec start(HostOrNode, NodeOrOpts) -> Result +%%% HostOrNode = atom() +%%% NodeOrOpts = atom() | list() %%% Result = {ok, NodeName} | -%%% {error, already_started, NodeName} | -%%% {error, started_not_connected, NodeName} | -%%% {error, boot_timeout, NodeName} | -%%% {error, init_timeout, NodeName} | -%%% {error, startup_timeout, NodeName} | -%%% {error, not_alive, NodeName} +%%% {error, Reason, NodeName} +%%% Reason = already_started | +%%% started_not_connected | +%%% boot_timeout | +%%% init_timeout | +%%% startup_timeout | +%%% not_alive %%% NodeName = atom() -%%% @doc Starts an Erlang node with name <code>Node</code> on host -%%% <code>Host</code> with the default options. +%%% @doc Starts an Erlang node with default options on a specified +%%% host, or on the local host with specified options. That is, +%%% the call is interpreted as <code>start(Host, Node)</code> when the +%%% second argument is atom-valued and <code>start(Node, Opts)</code> +%%% when it's list-valued. %%% @see start/3 +start(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc + when is_list(Opts) -> + start(gethostname(), Node, Opts); + start(Host, Node) -> start(Host, Node, []). @@ -102,12 +111,14 @@ start(Host, Node) -> %%% ErlangFlags = string() %%% EnvVar = string() %%% Value = string() -%%% Result = {ok, NodeName} | {error, already_started, NodeName} | -%%% {error, started_not_connected, NodeName} | -%%% {error, boot_timeout, NodeName} | -%%% {error, init_timeout, NodeName} | -%%% {error, startup_timeout, NodeName} | -%%% {error, not_alive, NodeName} +%%% Result = {ok, NodeName} | +%%% {error, Reason, NodeName} +%%% Reason = already_started | +%%% started_not_connected | +%%% boot_timeout | +%%% init_timeout | +%%% startup_timeout | +%%% not_alive %%% NodeName = atom() %%% @doc Starts an Erlang node with name <code>Node</code> on host %%% <code>Host</code> as specified by the combination of options in @@ -169,7 +180,7 @@ start(Host, Node) -> %%% <code>NodeName</code> is the name of current node in this case.</item> %%% </list></p> %%% -start(Host, Node, Options) -> +start(Host, Node, Opts) -> ENode = enodename(Host, Node), case erlang:is_alive() of false-> @@ -177,7 +188,7 @@ start(Host, Node, Options) -> true-> case is_started(ENode) of false-> - OptionsRec = fetch_options(Options), + OptionsRec = fetch_options(Opts), do_start(Host, Node, OptionsRec); {true, not_connected}-> {error, started_not_connected, ENode}; @@ -189,9 +200,11 @@ start(Host, Node, Options) -> %%% @spec stop(Node) -> Result %%% Node = atom() %%% Result = {ok, NodeName} | -%%% {error, not_started, NodeName} | -%%% {error, not_connected, NodeName} | -%%% {error, stop_timeout, NodeName} +%%% {error, Reason, NodeName} +%%% Reason = not_started | +%%% not_connected | +%%% stop_timeout + %%% NodeName = atom() %%% @doc Stops the running Erlang node with name <code>Node</code> on %%% the localhost. @@ -202,9 +215,10 @@ stop(Node) -> %%% Host = atom() %%% Node = atom() %%% Result = {ok, NodeName} | -%%% {error, not_started, NodeName} | -%%% {error, not_connected, NodeName} | -%%% {error, stop_timeout, NodeName} +%%% {error, Reason, NodeName} +%%% Reason = not_started | +%%% not_connected | +%%% stop_timeout %%% NodeName = atom() %%% @doc Stops the running Erlang node with name <code>Node</code> on %%% host <code>Host</code>. diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index 2e7e731595..02e58d0786 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -940,7 +940,9 @@ ct_make_ref_loop(N) -> From ! {self(),N}, ct_make_ref_loop(N+1) end. - + +abs_name("/") -> + "/"; abs_name(Dir0) -> Abs = filename:absname(Dir0), Dir = case lists:reverse(Abs) of diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl index 99ce92e9f1..71df2ab44e 100644 --- a/lib/common_test/src/unix_telnet.erl +++ b/lib/common_test/src/unix_telnet.erl @@ -94,11 +94,16 @@ connect(Ip,Port,Timeout,KeepAlive,Extra) -> {Username,Password} -> connect1(Ip,Port,Timeout,KeepAlive,Username,Password); Name -> - case get_username_and_password(Name) of - {ok,{Username,Password}} -> - connect1(Ip,Port,Timeout,KeepAlive,Username,Password); - Error -> - Error + case not_require_user_and_pass(Name) of + true -> + connect_without_username_and_pass(Ip,Port,Timeout,KeepAlive); + _ -> + case get_username_and_password(Name) of + {ok,{Username,Password}} -> + connect1(Ip,Port,Timeout,KeepAlive,Username,Password); + Error -> + Error + end end end. @@ -144,6 +149,27 @@ connect1(Ip,Port,Timeout,KeepAlive,Username,Password) -> end_log(), Result. +connect_without_username_and_pass(Ip,Port,Timeout,KeepAlive) -> + start_log("unix_telnet:connect"), + Result = + case ct_telnet_client:open(Ip,Port,Timeout,KeepAlive) of + {ok,Pid} -> + {ok, Pid}; + Error -> + cont_log("Could not open telnet connection\n~p\n",[Error]), + Error + end, + end_log(), + Result. + +not_require_user_and_pass(Name) -> + case ct:get_config({Name, not_require_user_and_pass}) of + undefined -> + false; + _ -> + true + end. + get_username_and_password(Name) -> case ct:get_config({Name,username}) of undefined -> |