aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common_test/src')
-rw-r--r--lib/common_test/src/ct.erl11
-rw-r--r--lib/common_test/src/ct_logs.erl85
-rw-r--r--lib/common_test/src/ct_run.erl57
-rw-r--r--lib/common_test/src/ct_testspec.erl18
-rw-r--r--lib/common_test/src/ct_util.hrl3
5 files changed, 126 insertions, 48 deletions
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index 0a77527b2f..63a8adbc63 100644
--- a/lib/common_test/src/ct.erl
+++ b/lib/common_test/src/ct.erl
@@ -64,7 +64,7 @@
print/1, print/2, print/3,
pal/1, pal/2, pal/3,
capture_start/0, capture_stop/0, capture_get/0, capture_get/1,
- fail/1, fail/2, comment/1, comment/2,
+ fail/1, fail/2, comment/1, comment/2, make_priv_dir/0,
testcases/2, userdata/2, userdata/3,
timetrap/1, get_timetrap_info/0, sleep/1]).
@@ -673,6 +673,15 @@ send_html_comment(Comment) ->
ct_util:set_testdata({comment,Html}),
test_server:comment(Html).
+%%%-----------------------------------------------------------------
+%%% @spec make_priv_dir() -> ok | {error,Reason}
+%%% Reason = term()
+%%% @doc If the test has been started with the create_priv_dir
+%%% option set to manual_per_tc, in order for the test case to use
+%%% the private directory, it must first create it by calling
+%%% this function.
+make_priv_dir() ->
+ test_server:make_priv_dir().
%%%-----------------------------------------------------------------
%%% @spec get_target_name(Handle) -> {ok,TargetName} | {error,Reason}
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index b2f669fefe..0cd9b5f7cb 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -920,33 +920,48 @@ insert_dir(D,[D1|Ds]) ->
insert_dir(D,[]) ->
[D].
-make_last_run_index([Name|Rest], Result, TotSucc, TotFail, UserSkip, AutoSkip,
- TotNotBuilt, Missing) ->
- case last_test(Name) of
+make_last_run_index([Name|Rest], Result, TotSucc, TotFail,
+ UserSkip, AutoSkip, TotNotBuilt, Missing) ->
+ case get_run_dirs(Name) of
false ->
%% Silently skip.
- make_last_run_index(Rest, Result, TotSucc, TotFail, UserSkip, AutoSkip,
- TotNotBuilt, Missing);
- LastLogDir ->
+ make_last_run_index(Rest, Result, TotSucc, TotFail,
+ UserSkip, AutoSkip, TotNotBuilt, Missing);
+ LogDirs ->
SuiteName = filename:rootname(filename:basename(Name)),
- case make_one_index_entry(SuiteName, LastLogDir, "-", false, Missing) of
- {Result1,Succ,Fail,USkip,ASkip,NotBuilt} ->
- %% for backwards compatibility
- AutoSkip1 = case catch AutoSkip+ASkip of
- {'EXIT',_} -> undefined;
- Res -> Res
- end,
- make_last_run_index(Rest, [Result|Result1], TotSucc+Succ,
- TotFail+Fail, UserSkip+USkip, AutoSkip1,
- TotNotBuilt+NotBuilt, Missing);
- error ->
- make_last_run_index(Rest, Result, TotSucc, TotFail, UserSkip, AutoSkip,
- TotNotBuilt, Missing)
- end
+ {Result1,TotSucc1,TotFail1,UserSkip1,AutoSkip1,TotNotBuilt1} =
+ make_last_run_index1(SuiteName, LogDirs, Result,
+ TotSucc, TotFail,
+ UserSkip, AutoSkip,
+ TotNotBuilt, Missing),
+ make_last_run_index(Rest, Result1, TotSucc1, TotFail1,
+ UserSkip1, AutoSkip1,
+ TotNotBuilt1, Missing)
end;
+
make_last_run_index([], Result, TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt, _) ->
{ok, [Result|total_row(TotSucc, TotFail, UserSkip, AutoSkip, TotNotBuilt, false)],
{TotSucc,TotFail,UserSkip,AutoSkip,TotNotBuilt}}.
+
+make_last_run_index1(SuiteName, [LogDir | LogDirs], Result, TotSucc, TotFail,
+ UserSkip, AutoSkip, TotNotBuilt, Missing) ->
+ case make_one_index_entry(SuiteName, LogDir, "-", false, Missing) of
+ {Result1,Succ,Fail,USkip,ASkip,NotBuilt} ->
+ %% for backwards compatibility
+ AutoSkip1 = case catch AutoSkip+ASkip of
+ {'EXIT',_} -> undefined;
+ Res -> Res
+ end,
+ make_last_run_index1(SuiteName, LogDirs, [Result|Result1], TotSucc+Succ,
+ TotFail+Fail, UserSkip+USkip, AutoSkip1,
+ TotNotBuilt+NotBuilt, Missing);
+ error ->
+ make_last_run_index1(SuiteName, LogDirs, Result, TotSucc, TotFail,
+ UserSkip, AutoSkip, TotNotBuilt, Missing)
+ end;
+make_last_run_index1(_, [], Result, TotSucc, TotFail,
+ UserSkip, AutoSkip, TotNotBuilt, _) ->
+ {Result,TotSucc,TotFail,UserSkip,AutoSkip,TotNotBuilt}.
make_one_index_entry(SuiteName, LogDir, Label, All, Missing) ->
case count_cases(LogDir) of
@@ -1698,8 +1713,8 @@ make_all_suites_index(NewTestData = {_TestName,DirName}) ->
sort_logdirs([Dir|Dirs],Groups) ->
TestName = filename:rootname(filename:basename(Dir)),
case filelib:wildcard(filename:join(Dir,"run.*")) of
- [RunDir] ->
- Groups1 = insert_test(TestName,{filename:basename(RunDir),RunDir},Groups),
+ RunDirs = [_|_] ->
+ Groups1 = sort_logdirs1(TestName,RunDirs,Groups),
sort_logdirs(Dirs,Groups1);
_ -> % ignore missing run directory
sort_logdirs(Dirs,Groups)
@@ -1707,6 +1722,12 @@ sort_logdirs([Dir|Dirs],Groups) ->
sort_logdirs([],Groups) ->
lists:keysort(1,sort_each_group(Groups)).
+sort_logdirs1(TestName,[RunDir|RunDirs],Groups) ->
+ Groups1 = insert_test(TestName,{filename:basename(RunDir),RunDir},Groups),
+ sort_logdirs1(TestName,RunDirs,Groups1);
+sort_logdirs1(_,[],Groups) ->
+ Groups.
+
insert_test(Test,IxDir,[{Test,IxDirs}|Groups]) ->
[{Test,[IxDir|IxDirs]}|Groups];
insert_test(Test,IxDir,[]) ->
@@ -1998,21 +2019,17 @@ notify_and_unlock_file(File) ->
end.
%%%-----------------------------------------------------------------
-%%% @spec last_test(Dir) -> string() | false
+%%% @spec get_run_dirs(Dir) -> [string()] | false
%%%
%%% @doc
%%%
-last_test(Dir) ->
- last_test(filelib:wildcard(filename:join(Dir, "run.[1-2]*")), false).
-
-last_test([Run|Rest], false) ->
- last_test(Rest, Run);
-last_test([Run|Rest], Latest) when Run > Latest ->
- last_test(Rest, Run);
-last_test([_|Rest], Latest) ->
- last_test(Rest, Latest);
-last_test([], Latest) ->
- Latest.
+get_run_dirs(Dir) ->
+ case filelib:wildcard(filename:join(Dir, "run.[1-2]*")) of
+ [] ->
+ false;
+ RunDirs ->
+ lists:sort(RunDirs)
+ end.
%%%-----------------------------------------------------------------
%%% @spec xhtml(HTML, XHTML) -> HTML | XHTML
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index 45436392d8..666eb3c988 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -63,6 +63,7 @@
stylesheet,
multiply_timetraps = 1,
scale_timetraps = false,
+ create_priv_dir,
testspecs = [],
tests}).
@@ -178,6 +179,10 @@ script_start1(Parent, Args) ->
fun([CT]) -> list_to_atom(CT);
([]) -> true
end, false, Args),
+ CreatePrivDir = get_start_opt(create_priv_dir,
+ fun([PD]) -> list_to_atom(PD);
+ ([]) -> auto_per_tc
+ end, Args),
EvHandlers = event_handler_args2opts(Args),
CTHooks = ct_hooks_args2opts(Args),
EnableBuiltinHooks = get_start_opt(enable_builtin_hooks,
@@ -255,7 +260,8 @@ script_start1(Parent, Args) ->
silent_connections = SilentConns,
stylesheet = Stylesheet,
multiply_timetraps = MultTT,
- scale_timetraps = ScaleTT},
+ scale_timetraps = ScaleTT,
+ create_priv_dir = CreatePrivDir},
%% check if log files should be refreshed or go on to run tests...
Result = run_or_refresh(StartOpts, Args),
@@ -322,12 +328,21 @@ script_start2(StartOpts = #opts{vts = undefined,
Cover = choose_val(StartOpts#opts.cover,
SpecStartOpts#opts.cover),
- MultTT = choose_val(StartOpts#opts.multiply_timetraps,
- SpecStartOpts#opts.multiply_timetraps),
- ScaleTT = choose_val(StartOpts#opts.scale_timetraps,
- SpecStartOpts#opts.scale_timetraps),
- AllEvHs = merge_vals([StartOpts#opts.event_handlers,
- SpecStartOpts#opts.event_handlers]),
+ MultTT =
+ choose_val(StartOpts#opts.multiply_timetraps,
+ SpecStartOpts#opts.multiply_timetraps),
+ ScaleTT =
+ choose_val(StartOpts#opts.scale_timetraps,
+ SpecStartOpts#opts.scale_timetraps),
+
+ CreatePrivDir =
+ choose_val(StartOpts#opts.create_priv_dir,
+ SpecStartOpts#opts.create_priv_dir),
+
+ AllEvHs =
+ merge_vals([StartOpts#opts.event_handlers,
+ SpecStartOpts#opts.event_handlers]),
+
AllCTHooks = merge_vals(
[StartOpts#opts.ct_hooks,
SpecStartOpts#opts.ct_hooks]),
@@ -354,7 +369,8 @@ script_start2(StartOpts = #opts{vts = undefined,
EnableBuiltinHooks,
include = AllInclude,
multiply_timetraps = MultTT,
- scale_timetraps = ScaleTT}}
+ scale_timetraps = ScaleTT,
+ create_priv_dir = CreatePrivDir}}
end;
_ ->
{undefined,StartOpts}
@@ -567,6 +583,7 @@ script_usage() ->
"\n\t[-no_auto_compile]"
"\n\t[-multiply_timetraps N]"
"\n\t[-scale_timetraps]"
+ "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]"
"\n\t[-basic_html]\n\n"),
io:format("Run tests from command line:\n\n"
"\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |"
@@ -586,6 +603,7 @@ script_usage() ->
"\n\t[-no_auto_compile]"
"\n\t[-multiply_timetraps N]"
"\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]] |"
@@ -606,6 +624,7 @@ script_usage() ->
"\n\t[-no_auto_compile]"
"\n\t[-multiply_timetraps N]"
"\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]] |"
@@ -782,6 +801,9 @@ run_test2(StartOpts) ->
MultiplyTT = get_start_opt(multiply_timetraps, value, 1, StartOpts),
ScaleTT = get_start_opt(scale_timetraps, value, false, StartOpts),
+ %% create unique priv dir names
+ CreatePrivDir = get_start_opt(create_priv_dir, value, StartOpts),
+
%% auto compile & include files
Include =
case proplists:get_value(auto_compile, StartOpts) of
@@ -842,7 +864,8 @@ run_test2(StartOpts) ->
silent_connections = SilentConns,
stylesheet = Stylesheet,
multiply_timetraps = MultiplyTT,
- scale_timetraps = ScaleTT},
+ scale_timetraps = ScaleTT,
+ create_priv_dir = CreatePrivDir},
%% test specification
case proplists:get_value(spec, StartOpts) of
@@ -889,6 +912,8 @@ run_spec_file(Relaxed,
SpecOpts#opts.multiply_timetraps),
ScaleTT = choose_val(Opts#opts.scale_timetraps,
SpecOpts#opts.scale_timetraps),
+ CreatePrivDir = choose_val(Opts#opts.create_priv_dir,
+ SpecOpts#opts.create_priv_dir),
AllEvHs = merge_vals([Opts#opts.event_handlers,
SpecOpts#opts.event_handlers]),
AllInclude = merge_vals([Opts#opts.include,
@@ -912,6 +937,7 @@ run_spec_file(Relaxed,
testspecs = AbsSpecs,
multiply_timetraps = MultTT,
scale_timetraps = ScaleTT,
+ create_priv_dir = CreatePrivDir,
ct_hooks = AllCTHooks,
enable_builtin_hooks = EnableBuiltinHooks
},
@@ -1170,7 +1196,8 @@ get_data_for_node(#testspec{label = Labels,
enable_builtin_hooks = EnableBuiltinHooks,
include = Incl,
multiply_timetraps = MTs,
- scale_timetraps = STs}, Node) ->
+ scale_timetraps = STs,
+ create_priv_dir = PDs}, Node) ->
Label = proplists:get_value(Node, Labels),
Profile = proplists:get_value(Node, Profiles),
LogDir = case proplists:get_value(Node, LogDirs) of
@@ -1184,6 +1211,7 @@ get_data_for_node(#testspec{label = Labels,
Cover = proplists:get_value(Node, CoverFs),
MT = proplists:get_value(Node, MTs),
ST = proplists:get_value(Node, STs),
+ CreatePrivDir = proplists:get_value(Node, PDs),
ConfigFiles = [{?ct_config_txt,F} || {N,F} <- Cfgs, N==Node] ++
[CBF || {N,CBF} <- UsrCfgs, N==Node],
EvHandlers = [{H,A} || {N,H,A} <- EvHs, N==Node],
@@ -1200,7 +1228,8 @@ get_data_for_node(#testspec{label = Labels,
enable_builtin_hooks = EnableBuiltinHooks,
include = Include,
multiply_timetraps = MT,
- scale_timetraps = ST}.
+ scale_timetraps = ST,
+ create_priv_dir = CreatePrivDir}.
refresh_logs(LogDir) ->
{ok,Cwd} = file:get_cwd(),
@@ -1848,6 +1877,8 @@ do_run_test(Tests, Skip, Opts) ->
test_server_ctrl:multiply_timetraps(Opts#opts.multiply_timetraps),
test_server_ctrl:scale_timetraps(Opts#opts.scale_timetraps),
+ test_server_ctrl:create_priv_dir(choose_val(Opts#opts.create_priv_dir,
+ auto_per_run)),
ct_event:notify(#event{name=start_info,
node=node(),
data={NoOfTests,NoOfSuites,NoOfCases}}),
@@ -2447,6 +2478,10 @@ opts2args(EnvStartOpts) ->
[{scale_timetraps,[]}];
({scale_timetraps,false}) ->
[];
+ ({create_priv_dir,auto_per_run}) ->
+ [];
+ ({create_priv_dir,PD}) when is_atom(PD) ->
+ [{create_priv_dir,[atom_to_list(PD)]}];
({force_stop,true}) ->
[{force_stop,[]}];
({force_stop,false}) ->
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index b68cbd3aa1..5b197c0c81 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -568,6 +568,21 @@ add_tests([{scale_timetraps,Node,ST}|Ts],Spec) ->
add_tests([{scale_timetraps,ST}|Ts],Spec) ->
add_tests([{scale_timetraps,all_nodes,ST}|Ts],Spec);
+%% --- create_priv_dir ---
+add_tests([{create_priv_dir,all_nodes,PD}|Ts],Spec) ->
+ Tests = lists:map(fun(N) -> {create_priv_dir,N,PD} end, list_nodes(Spec)),
+ add_tests(Tests++Ts,Spec);
+add_tests([{create_priv_dir,Nodes,PD}|Ts],Spec) when is_list(Nodes) ->
+ Ts1 = separate(Nodes,create_priv_dir,[PD],Ts,Spec#testspec.nodes),
+ add_tests(Ts1,Spec);
+add_tests([{create_priv_dir,Node,PD}|Ts],Spec) ->
+ PDs = Spec#testspec.create_priv_dir,
+ PDs1 = [{ref2node(Node,Spec#testspec.nodes),PD} |
+ lists:keydelete(ref2node(Node,Spec#testspec.nodes),1,PDs)],
+ add_tests(Ts,Spec#testspec{create_priv_dir=PDs1});
+add_tests([{create_priv_dir,PD}|Ts],Spec) ->
+ add_tests([{create_priv_dir,all_nodes,PD}|Ts],Spec);
+
%% --- config ---
add_tests([{config,all_nodes,Files}|Ts],Spec) ->
Tests = lists:map(fun(N) -> {config,N,Files} end, list_nodes(Spec)),
@@ -1158,7 +1173,8 @@ valid_terms() ->
{skip_groups,6},
{skip_groups,7},
{skip_cases,5},
- {skip_cases,6}
+ {skip_cases,6},
+ {create_priv_dir,2}
].
%% this function "guesses" if the user has misspelled a term name
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index bde832811a..082599a9c6 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -43,9 +43,10 @@
include=[],
multiply_timetraps=[],
scale_timetraps=[],
+ create_priv_dir=[],
alias=[],
tests=[],
- merge_tests = true }).
+ merge_tests=true}).
-record(cover, {app=none,
level=details,