aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPeter Andersson <peppe@erlang.org>2012-01-18 15:45:40 +0100
committerPeter Andersson <peppe@erlang.org>2012-03-13 14:57:35 +0100
commit4aabf295e7b11d5ae03553aab1ba83a2657fa7aa (patch)
treefcb2c6b03a63af56a00da21b53aa536e4170d0fc /lib
parent24cb87703d919598d5b95268d868432c8ada3232 (diff)
downloadotp-4aabf295e7b11d5ae03553aab1ba83a2657fa7aa.tar.gz
otp-4aabf295e7b11d5ae03553aab1ba83a2657fa7aa.tar.bz2
otp-4aabf295e7b11d5ae03553aab1ba83a2657fa7aa.zip
Make it possible to use unique priv_dir names
Introduce the optional feature to have Test Server generate priv_dir directory names that are unique for each test case or config function. The name of the option/flag is 'unique_priv_dir' and it can be set to value 'auto' or 'manual'. If auto, Test Server creates each priv_dir automatically (can be expensive in case of many and/or repeated cases). If manual, the user needs to create the priv_dir explicitly by calling ct:make_priv_dir/0.
Diffstat (limited to 'lib')
-rw-r--r--lib/common_test/src/ct.erl11
-rw-r--r--lib/common_test/src/ct_logs.erl12
-rw-r--r--lib/common_test/src/ct_run.erl57
-rw-r--r--lib/common_test/src/ct_util.hrl3
-rw-r--r--lib/common_test/test/Makefile1
-rw-r--r--lib/test_server/src/test_server.erl48
-rw-r--r--lib/test_server/src/test_server_ctrl.erl95
7 files changed, 181 insertions, 46 deletions
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index 0a77527b2f..83ed0a66d7 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 unique_priv_dir
+%%% option set to manual, 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 bb30cafbeb..0cd9b5f7cb 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -1665,10 +1665,6 @@ make_all_suites_index(When) when is_atom(When) ->
notify_and_lock_file(AbsIndexName),
LogDirs = filelib:wildcard(logdir_prefix()++".*/*"++?logdir_ext),
Sorted = sort_logdirs(LogDirs, []),
-
- %%! --- Tue Jan 17 16:30:44 2012 --- peppe was here!
- io:format(user, "~nLOGDIRS = ~p~nSORTED: ~p~n~n", [LogDirs,Sorted]),
-
Result = make_all_suites_index1(When, AbsIndexName, Sorted),
notify_and_unlock_file(AbsIndexName),
Result;
@@ -1690,10 +1686,6 @@ make_all_suites_index(NewTestData = {_TestName,DirName}) ->
_ -> "..."
end,
notify_and_lock_file(AbsIndexName),
-
- %%! --- Mon Jan 16 23:37:33 2012 --- peppe was here!
- io:format(user, "ALL SUITES CACHED: ~p, ~p, ~p~n", [AbsIndexName,NewTestData,LogDirData]),
-
Result =
case catch make_all_suites_ix_cached(AbsIndexName,
NewTestData,
@@ -1781,10 +1773,6 @@ make_all_suites_index1(When, AbsIndexName, AllLogDirs) ->
end.
make_all_suites_index2(IndexName, AllTestLogDirs) ->
-
-%%! --- Mon Jan 16 23:40:08 2012 --- peppe was here!
- io:format(user, "ALL SUITES (~p): ~p~n", [IndexName,AllTestLogDirs]),
-
{ok,Index0,_Totals,CacheData} =
make_all_suites_index3(AllTestLogDirs,
all_suites_index_header(),
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index 05b10bca32..7798d369d2 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,
+ unique_priv_dir = false,
testspecs = [],
tests}).
@@ -178,6 +179,10 @@ script_start1(Parent, Args) ->
fun([CT]) -> list_to_atom(CT);
([]) -> true
end, false, Args),
+ UniquePrivDir = get_start_opt(unique_priv_dir,
+ fun([UPD]) -> list_to_atom(UPD);
+ ([]) -> auto
+ end, false, 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,
+ unique_priv_dir = UniquePrivDir},
%% 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),
+
+ UniquePrivDir =
+ choose_val(StartOpts#opts.unique_priv_dir,
+ SpecStartOpts#opts.unique_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,
+ unique_priv_dir = UniquePrivDir}}
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[-unique_priv_dir [auto | manual]]"
"\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[-unique_priv_dir [auto | manual]]"
"\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[-unique_priv_dir [auto | manual]]"
"\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
+ UniquePrivDir = get_start_opt(unique_priv_dir, value, false, 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,
+ unique_priv_dir = UniquePrivDir},
%% 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),
+ UniquePrivDir = choose_val(Opts#opts.unique_priv_dir,
+ SpecOpts#opts.unique_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,
+ unique_priv_dir = UniquePrivDir,
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,
+ unique_priv_dir = UPDs}, 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),
+ UniquePrivDir = proplists:get_value(Node, UPDs),
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,
+ unique_priv_dir = UniquePrivDir}.
refresh_logs(LogDir) ->
{ok,Cwd} = file:get_cwd(),
@@ -1842,6 +1871,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:unique_priv_dir(Opts#opts.unique_priv_dir),
+
ct_event:notify(#event{name=start_info,
node=node(),
data={NoOfTests,NoOfSuites,NoOfCases}}),
@@ -2419,6 +2450,10 @@ opts2args(EnvStartOpts) ->
[{scale_timetraps,[]}];
({scale_timetraps,false}) ->
[];
+ ({unique_priv_dir,false}) ->
+ [];
+ ({unique_priv_dir,UPD}) when is_atom(UPD) ->
+ [{unique_priv_dir,[UPD]}];
({force_stop,true}) ->
[{force_stop,[]}];
({force_stop,false}) ->
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index bde832811a..da96743732 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=[],
+ unique_priv_dir=[],
alias=[],
tests=[],
- merge_tests = true }).
+ merge_tests=true}).
-record(cover, {app=none,
level=details,
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index 284612b8f7..6d09a28634 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -29,6 +29,7 @@ MODULES= \
ct_test_support_eh \
ct_userconfig_callback \
ct_smoke_test_SUITE \
+ ct_bugs_SUITE \
ct_event_handler_SUITE \
ct_config_info_SUITE \
ct_groups_test_1_SUITE \
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 08197ee36e..091c46ca74 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -44,7 +44,7 @@
-export([start_node/3, stop_node/1, wait_for_node/1, is_release_available/1]).
-export([app_test/1, app_test/2]).
-export([is_native/1]).
--export([comment/1]).
+-export([comment/1, make_priv_dir/0]).
-export([os_type/0]).
-export([run_on_shielded_node/2]).
-export([is_cover/0,is_debug/0,is_commercial/0]).
@@ -754,6 +754,25 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
{set_curr_conf,From,NewCurrConf} ->
From ! {self(),set_curr_conf,ok},
run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,NewCurrConf);
+ {make_priv_dir,From} when CurrConf == undefined ->
+ From ! {self(),make_priv_dir,{error,no_priv_dir_in_config}};
+ {make_priv_dir,From} ->
+ Result =
+ case proplists:get_value(priv_dir, element(2, CurrConf)) of
+ undefined ->
+ {error,no_priv_dir_in_config};
+ PrivDir ->
+ case file:make_dir(PrivDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ MkDirError ->
+ {error,{MkDirError,PrivDir}}
+ end
+ end,
+ From ! {self(),make_priv_dir,Result},
+ run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf);
{'EXIT',Pid,{Ref,Time,Value,Loc,Opts}} ->
RetVal = {Time/1000000,Value,mod_loc(Loc),Opts,Comment},
run_test_case_msgloop(Ref,Pid,CaptureStdout,{true,RetVal},Comment,undefined);
@@ -1176,6 +1195,9 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
exit({Ref,Time,Value,Loc,Opts}).
run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
+ %% save current state in controller loop
+ sync_send(group_leader(),set_curr_conf,{{Mod,Func},hd(Args)},
+ 5000, fun() -> exit(no_answer_from_group_leader) end),
case RunInit of
run_init ->
put(test_server_init_or_end_conf,{init_per_testcase,Func}),
@@ -1234,8 +1256,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
%% call user callback function if defined
EndConf1 = user_callback(TCCallback, Mod, Func, 'end', EndConf),
%% update current state in controller loop
- sync_send(group_leader(),set_curr_conf,EndConf1,
- 5000, fun() -> exit(no_answer_from_group_leader) end),
+ sync_send(group_leader(),set_curr_conf,EndConf1, 5000,
+ fun() -> exit(no_answer_from_group_leader) end),
{FWReturn1,TSReturn1,EndConf2} =
case end_per_testcase(Mod, Func, EndConf1) of
SaveCfg1={save_config,_} ->
@@ -2575,11 +2597,23 @@ read_comment() ->
MsgLooper = group_leader(),
MsgLooper ! {read_comment,self()},
receive
- {MsgLooper,read_comment,Comment} ->
- Comment
+ {MsgLooper,read_comment,Comment} -> Comment
+ after
+ 5000 -> ""
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% make_priv_dir() -> ok
+%%
+%% Order test server to create the private directory
+%% for the current test case.
+make_priv_dir() ->
+ MsgLooper = group_leader(),
+ group_leader() ! {make_priv_dir,self()},
+ receive
+ {MsgLooper,make_priv_dir,Result} -> Result
after
- 5000 ->
- ""
+ 5000 -> error
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 5466ab2cfa..ecb1125b1e 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -164,6 +164,7 @@
-export([start_get_totals/1, stop_get_totals/0]).
-export([get_levels/0, set_levels/3]).
-export([multiply_timetraps/1, scale_timetraps/1, get_timetrap_parameters/0]).
+-export([unique_priv_dir/1]).
-export([cover/2, cover/3, cover/7,
cross_cover_analyse/1, cross_cover_analyse/2, trc/1, stop_trace/0]).
-export([testcase_callback/1]).
@@ -219,8 +220,8 @@
-define(user_skip_color, "#FF8000").
-record(state,{jobs=[],levels={1,19,10},
- multiply_timetraps=1,scale_timetraps=true,
- finish=false,
+ multiply_timetraps=1, scale_timetraps=true,
+ unique_priv_dir=false, finish=false,
target_info, trc=false, cover=false, wait_for_node=[],
testcase_callback=undefined, idle_notify=[],
get_totals=false, random_seed=undefined}).
@@ -506,6 +507,9 @@ scale_timetraps(Bool) ->
get_timetrap_parameters() ->
controller_call(get_timetrap_parameters).
+unique_priv_dir(Value) ->
+ controller_call({unique_priv_dir,Value}).
+
trc(TraceFile) ->
controller_call({trace,TraceFile}, 2*?ACCEPT_TIMEOUT).
@@ -811,6 +815,7 @@ handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) ->
[SpecName,{State#state.multiply_timetraps,
State#state.scale_timetraps}],
LogDir, Name, State#state.levels,
+ State#state.unique_priv_dir,
State#state.testcase_callback, ExtraTools1),
NewJobs = [{Name,Pid}|State#state.jobs],
{reply, ok, State#state{jobs=NewJobs}};
@@ -820,6 +825,7 @@ handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) ->
[SpecList,{State#state.multiply_timetraps,
State#state.scale_timetraps}],
LogDir, Name, State#state.levels,
+ State#state.unique_priv_dir,
State#state.testcase_callback, ExtraTools1),
NewJobs = [{Name,Pid}|State#state.jobs],
{reply, ok, State#state{jobs=NewJobs}};
@@ -837,6 +843,7 @@ handle_call({add_job,Dir,Name,TopCase,Skip}, _From, State) ->
{State#state.multiply_timetraps,
State#state.scale_timetraps}],
LogDir, Name, State#state.levels,
+ State#state.unique_priv_dir,
State#state.testcase_callback, ExtraTools1),
NewJobs = [{Name,Pid}|State#state.jobs],
{reply, ok, State#state{jobs=NewJobs}}
@@ -1045,6 +1052,18 @@ handle_call({cover,App,Analyse}, _From, State) ->
{reply,ok,State#state{cover={App,Analyse}}};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% handle_call({unique_priv_dir,Value}, _, State) -> ok | {error,Reason}
+%%
+%% Set unique_priv_dir to either false (create common priv dir once
+%% per test run), manual (the priv dir name will be unique for each test
+%% case, but the user has to call test_server:make_priv_dir/0 to create
+%% it), or auto (unique priv dir created automatically for each test
+%% case).
+
+handle_call({unique_priv_dir,Value}, _From, State) ->
+ {reply,ok,State#state{unique_priv_dir=Value}};
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% handle_call({testcase_callback,{Mod,Func}}, _, State) -> ok | {error,Reason}
%%
%% Add a callback function that will be called before and after every
@@ -1321,7 +1340,7 @@ kill_all_jobs([]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% spawn_tester(Mod, Func, Args, Dir, Name, Levels,
+%% spawn_tester(Mod, Func, Args, Dir, Name, Levels, UniquePrivDir,
%% TestCaseCallback, ExtraTools) -> Pid
%% Mod = atom()
%% Func = atom()
@@ -1329,6 +1348,7 @@ kill_all_jobs([]) ->
%% Dir = string()
%% Name = string()
%% Levels = {integer(),integer(),integer()}
+%% UniquePrivDir = false | manual | auto
%% TestCaseCallback = {CBMod,CBFunc} | undefined
%% ExtraTools = [ExtraTool,...]
%% ExtraTool = CoverInfo | TraceInfo | RandomSeed
@@ -1339,14 +1359,15 @@ kill_all_jobs([]) ->
%% When the named function is done executing, a summary of the results
%% is printed to the log files.
-spawn_tester(Mod, Func, Args, Dir, Name, Levels, TCCallback, ExtraTools) ->
+spawn_tester(Mod, Func, Args, Dir, Name, Levels,
+ UniquePrivDir, TCCallback, ExtraTools) ->
spawn_link(
fun() -> init_tester(Mod, Func, Args, Dir, Name, Levels,
- TCCallback, ExtraTools)
+ UniquePrivDir, TCCallback, ExtraTools)
end).
init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev},
- TCCallback, ExtraTools) ->
+ UniquePrivDir, TCCallback, ExtraTools) ->
process_flag(trap_exit, true),
put(test_server_name, Name),
put(test_server_dir, Dir),
@@ -1357,6 +1378,7 @@ init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev},
put(test_server_summary_level, SumLev),
put(test_server_major_level, MajLev),
put(test_server_minor_level, MinLev),
+ put(test_server_unique_priv_dir, UniquePrivDir),
put(test_server_random_seed, proplists:get_value(random_seed, ExtraTools)),
put(test_server_testcase_callback, TCCallback),
%% before first print, read and set logging options
@@ -2754,7 +2776,15 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
{skipped,TcSkip},
{failed,TcFail}]}]
end,
- TSDirs = [{priv_dir,get(test_server_priv_dir)},{data_dir,get_data_dir(Mod)}],
+
+ case get(test_server_unique_priv_dir) of
+ false -> % use common priv_dir
+ TSDirs = [{priv_dir,get(test_server_priv_dir)},
+ {data_dir,get_data_dir(Mod)}];
+ _ ->
+ TSDirs = [{data_dir,get_data_dir(Mod)}]
+ end,
+
ActualCfg =
if not StartConf ->
update_config(hd(Config), TSDirs ++ CfgProps);
@@ -2916,8 +2946,13 @@ run_test_cases_loop([{conf,_Ref,_Props,_X}=Conf|_Cases0],
run_test_cases_loop([{Mod,Case}|Cases], Config, TimetrapData, Mode, Status) ->
ActualCfg =
- update_config(hd(Config), [{priv_dir,get(test_server_priv_dir)},
- {data_dir,get_data_dir(Mod)}]),
+ case get(test_server_unique_priv_dir) of
+ false ->
+ update_config(hd(Config), [{priv_dir,get(test_server_priv_dir)},
+ {data_dir,get_data_dir(Mod)}]);
+ _ ->
+ update_config(hd(Config), [{data_dir,get_data_dir(Mod)}])
+ end,
run_test_cases_loop([{Mod,Case,[ActualCfg]}|Cases], Config,
TimetrapData, Mode, Status);
@@ -3638,9 +3673,14 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
%% if this runs on a parallel test case process,
%% copy the dictionary from the main process
do_if_parallel(Main, fun() -> process_flag(trap_exit, true) end, ok),
- CopyDict = fun() -> lists:foreach(fun({Key,Val}) -> put(Key, Val) end, State) end,
+ CopyDict = fun() -> lists:foreach(fun({Key,Val}) ->
+ put(Key, Val)
+ end, State)
+ end,
do_if_parallel(Main, CopyDict, ok),
- do_if_parallel(Main, fun() -> put(test_server_common_io_handler, {tc,Main}) end, ok),
+ do_if_parallel(Main, fun() ->
+ put(test_server_common_io_handler, {tc,Main})
+ end, ok),
%% if io is being buffered, send start io session message
%% (no matter if case runs on parallel or main process)
case get(test_server_common_io_handler) of
@@ -3660,8 +3700,35 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
MinorBase = filename:basename(MinorName),
print(major, "=logfile ~s", [filename:basename(MinorName)]),
- Args1 = [[{tc_logfile,MinorName} | proplists:delete(tc_logfile,hd(Args))]],
- test_server_sup:framework_call(report, [tc_start,{{?pl2a(Mod),Func},MinorName}]),
+ UpdatedArgs =
+ %% maybe create unique private directory for test case or config func
+ case get(test_server_unique_priv_dir) of
+ false ->
+ update_config(hd(Args), [{tc_logfile,MinorName}]);
+ PrivDirMode ->
+ RunDir = filename:dirname(MinorName),
+ Ext =
+ if Num == 0 ->
+ {_,S,Us} = now(),
+ lists:flatten(io_lib:format(".~w.~w", [S,Us]));
+ true ->
+ %% create unique private directory for test case
+ RunDir = filename:dirname(MinorName),
+ lists:flatten(io_lib:format(".~w", [Num]))
+ end,
+ PrivDir = filename:join(RunDir, ?priv_dir) ++ Ext,
+ if PrivDirMode == auto ->
+ ok = file:make_dir(PrivDir);
+ PrivDirMode == manual ->
+ ok
+ end,
+ update_config(hd(Args), [{priv_dir,PrivDir++"/"},
+ {tc_logfile,MinorName}])
+ end,
+
+ test_server_sup:framework_call(report,
+ [tc_start,{{?pl2a(Mod),Func},MinorName}]),
+
print_props((RunInit==skip_init), get_props(Mode)),
GroupName = case get_name(Mode) of
undefined -> "";
@@ -3680,7 +3747,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
do_if_parallel(Main, ok, fun erlang:yield/0),
%% run the test case
{Result,DetectedFail,ProcsBefore,ProcsAfter} =
- run_test_case_apply(Num, Mod, Func, Args1, get_name(Mode),
+ run_test_case_apply(Num, Mod, Func, [UpdatedArgs], get_name(Mode),
RunInit, Where, TimetrapData),
{Time,RetVal,Loc,Opts,Comment} =
case Result of