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_logs.erl9
-rw-r--r--lib/common_test/src/ct_master.erl2
-rw-r--r--lib/common_test/src/ct_master_event.erl22
-rw-r--r--lib/common_test/src/ct_run.erl71
-rw-r--r--lib/common_test/src/ct_testspec.erl15
-rw-r--r--lib/common_test/src/ct_util.erl23
-rw-r--r--lib/common_test/src/ct_util.hrl1
7 files changed, 99 insertions, 44 deletions
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index 5924930072..0b204a681a 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -397,9 +397,9 @@ tc_print(Category,Format,Args) ->
%%% <p>This function is called by <code>ct</code> when printing
%%% stuff from a testcase on the user console.</p>
tc_print(Category,Importance,Format,Args) ->
- VLvl = case ct_util:get_testdata({verbosity,Category}) of
+ VLvl = case ct_util:get_verbosity(Category) of
undefined ->
- ct_util:get_testdata({verbosity,'$unspecified'});
+ ct_util:get_verbosity('$unspecified');
{error,bad_invocation} ->
?MAX_VERBOSITY;
Val ->
@@ -1475,8 +1475,9 @@ count_cases(Dir) ->
write_summary(SumFile, Summary),
Summary
end;
- {error, _Reason} ->
- io:format("\nFailed to read ~p (skipped)\n", [LogFile]),
+ {error, Reason} ->
+ io:format("\nFailed to read ~p: ~p (skipped)\n",
+ [LogFile,Reason]),
error
end
end.
diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl
index e516f635d2..b42ff73846 100644
--- a/lib/common_test/src/ct_master.erl
+++ b/lib/common_test/src/ct_master.erl
@@ -428,7 +428,7 @@ master_loop(#state{node_ctrl_pids=[],
log(all,"TEST RESULTS",Str,[]),
log(all,"Info","Updating log files",[]),
refresh_logs(LogDirs,[]),
-
+
ct_master_event:stop(),
ct_master_logs:stop(),
ok;
diff --git a/lib/common_test/src/ct_master_event.erl b/lib/common_test/src/ct_master_event.erl
index 5877b7c6f2..fd97ab16f7 100644
--- a/lib/common_test/src/ct_master_event.erl
+++ b/lib/common_test/src/ct_master_event.erl
@@ -66,16 +66,30 @@ add_handler(Args) ->
%% Description: Stops the event manager
%%--------------------------------------------------------------------
stop() ->
- flush(),
- gen_event:stop(?CT_MEVMGR_REF).
+ case flush() of
+ {error,Reason} ->
+ ct_master_logs:log("Error",
+ "No response from CT Master Event.\n"
+ "Reason = ~p\n"
+ "Terminating now!\n",[Reason]),
+ %% communication with event manager fails, kill it
+ catch exit(whereis(?CT_MEVMGR_REF), kill);
+ _ ->
+ gen_event:stop(?CT_MEVMGR_REF)
+ end.
flush() ->
- case gen_event:call(?CT_MEVMGR_REF,?MODULE,flush) of
+ try gen_event:call(?CT_MEVMGR_REF,?MODULE,flush,1800000) of
flushing ->
timer:sleep(1),
flush();
done ->
- ok
+ ok;
+ Error = {error,_} ->
+ Error
+ catch
+ _:Reason ->
+ {error,Reason}
end.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index c0bdbb2a09..49f00429ae 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -2291,8 +2291,12 @@ add_jobs([{TestDir,all,_}|Tests], Skip, Opts, CleanUp) ->
{'EXIT',_} ->
CleanUp;
_ ->
- wait_for_idle(),
- add_jobs(Tests, Skip, Opts, CleanUp)
+ case wait_for_idle() of
+ ok ->
+ add_jobs(Tests, Skip, Opts, CleanUp);
+ _ ->
+ CleanUp
+ end
end;
add_jobs([{TestDir,[Suite],all}|Tests], Skip,
Opts, CleanUp) when is_atom(Suite) ->
@@ -2305,8 +2309,12 @@ add_jobs([{TestDir,Suites,all}|Tests], Skip,
{'EXIT',_} ->
CleanUp;
_ ->
- wait_for_idle(),
- add_jobs(Tests, Skip, Opts, CleanUp)
+ case wait_for_idle() of
+ ok ->
+ add_jobs(Tests, Skip, Opts, CleanUp);
+ _ ->
+ CleanUp
+ end
end;
add_jobs([{TestDir,Suite,all}|Tests], Skip, Opts, CleanUp) ->
case maybe_interpret(Suite, all, Opts) of
@@ -2318,8 +2326,12 @@ add_jobs([{TestDir,Suite,all}|Tests], Skip, Opts, CleanUp) ->
{'EXIT',_} ->
CleanUp;
_ ->
- wait_for_idle(),
- add_jobs(Tests, Skip, Opts, [Suite|CleanUp])
+ case wait_for_idle() of
+ ok ->
+ add_jobs(Tests, Skip, Opts, [Suite|CleanUp]);
+ _ ->
+ CleanUp
+ end
end;
Error ->
Error
@@ -2358,8 +2370,12 @@ add_jobs([{TestDir,Suite,Confs}|Tests], Skip, Opts, CleanUp) when
{'EXIT',_} ->
CleanUp;
_ ->
- wait_for_idle(),
- add_jobs(Tests, Skip, Opts, [Suite|CleanUp])
+ case wait_for_idle() of
+ ok ->
+ add_jobs(Tests, Skip, Opts, [Suite|CleanUp]);
+ _ ->
+ CleanUp
+ end
end;
Error ->
Error
@@ -2384,8 +2400,12 @@ add_jobs([{TestDir,Suite,Cases}|Tests],
{'EXIT',_} ->
CleanUp;
_ ->
- wait_for_idle(),
- add_jobs(Tests, Skip, Opts, [Suite|CleanUp])
+ case wait_for_idle() of
+ ok ->
+ add_jobs(Tests, Skip, Opts, [Suite|CleanUp]);
+ _ ->
+ CleanUp
+ end
end;
Error ->
Error
@@ -2401,8 +2421,12 @@ add_jobs([{TestDir,Suite,Case}|Tests], Skip, Opts, CleanUp) when is_atom(Case) -
{'EXIT',_} ->
CleanUp;
_ ->
- wait_for_idle(),
- add_jobs(Tests, Skip, Opts, [Suite|CleanUp])
+ case wait_for_idle() of
+ ok ->
+ add_jobs(Tests, Skip, Opts, [Suite|CleanUp]);
+ _ ->
+ CleanUp
+ end
end;
Error ->
Error
@@ -2412,7 +2436,13 @@ add_jobs([], _, _, CleanUp) ->
wait_for_idle() ->
ct_util:update_last_run_index(),
- Notify = fun(Me) -> Me ! idle end,
+ Notify = fun(Me,IdleState) -> Me ! {idle,IdleState},
+ receive
+ {Me,proceed} -> ok
+ after
+ 30000 -> ok
+ end
+ end,
case catch test_server_ctrl:idle_notify(Notify) of
{'EXIT',_} ->
error;
@@ -2420,11 +2450,14 @@ wait_for_idle() ->
%% so we don't hang forever if test_server dies
Ref = erlang:monitor(process, TSPid),
Result = receive
- idle -> ok;
+ {idle,abort} -> aborted;
+ {idle,_} -> ok;
{'DOWN', Ref, _, _, _} -> error
end,
erlang:demonitor(Ref, [flush]),
ct_util:update_last_run_index(),
+ %% let test_server_ctrl proceed (and possibly shut down) now
+ TSPid ! {self(),proceed},
Result
end.
@@ -2921,11 +2954,11 @@ opts2args(EnvStartOpts) ->
[{event_handler_init,[atom_to_list(EH),ArgStr]}];
({event_handler,{EHs,Arg}}) when is_list(EHs) ->
ArgStr = lists:flatten(io_lib:format("~p", [Arg])),
- Strs = lists:map(fun(EH) ->
- [atom_to_list(EH),
- ArgStr,"and"]
- end, EHs),
- [_LastAnd|StrsR] = lists:reverse(lists:flatten(Strs)),
+ Strs = lists:flatmap(fun(EH) ->
+ [atom_to_list(EH),
+ ArgStr,"and"]
+ end, EHs),
+ [_LastAnd | StrsR] = lists:reverse(Strs),
[{event_handler_init,lists:reverse(StrsR)}];
({logopts,LOs}) when is_list(LOs) ->
[{logopts,[atom_to_list(LO) || LO <- LOs]}];
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index e341391a91..71b03c0ea6 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -1020,17 +1020,6 @@ add_tests([],Spec) -> % done
%% check if it's a CT term that has bad format or if the user seems to
%% have added something of his/her own, which we'll let pass if relaxed
%% mode is enabled.
-check_term(Atom) when is_atom(Atom) ->
- Valid = valid_terms(),
- case lists:member(Atom,Valid) of
- true ->
- valid;
- false -> % ignore
- case get(relaxed) of
- true -> invalid;
- false -> throw({error,{undefined_term_in_spec,Atom}})
- end
- end;
check_term(Term) when is_tuple(Term) ->
Size = size(Term),
[Name|_] = tuple_to_list(Term),
@@ -1059,9 +1048,7 @@ check_term(Term) when is_tuple(Term) ->
throw({error,{undefined_term_in_spec,Term}})
end
end
- end;
-check_term(Other) ->
- throw({error,{undefined_term_in_spec,Other}}).
+ end.
%% specific data handling before saving in testspec record, e.g.
%% converting relative paths to absolute for directories and files
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 0f2b2081d9..2e7e731595 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -39,7 +39,8 @@
delete_suite_data/0, delete_suite_data/1, match_delete_suite_data/1,
delete_testdata/0, delete_testdata/1,
set_testdata/1, get_testdata/1, get_testdata/2,
- set_testdata_async/1, update_testdata/2, update_testdata/3]).
+ set_testdata_async/1, update_testdata/2, update_testdata/3,
+ set_verbosity/1, get_verbosity/1]).
-export([override_silence_all_connections/0, override_silence_connections/1,
get_overridden_silenced_connections/0,
@@ -128,6 +129,10 @@ do_start(Parent, Mode, LogDir, Verbosity) ->
create_table(?conn_table,#conn.handle),
create_table(?board_table,2),
create_table(?suite_table,#suite_data.key),
+
+ create_table(?verbosity_table,1),
+ [ets:insert(?verbosity_table,{Cat,Lvl}) || {Cat,Lvl} <- Verbosity],
+
{ok,StartDir} = file:get_cwd(),
case file:set_cwd(LogDir) of
ok -> ok;
@@ -202,7 +207,7 @@ do_start(Parent, Mode, LogDir, Verbosity) ->
self() ! {{stop,{self(),{user_error,CTHReason}}},
{Parent,make_ref()}}
end,
- loop(Mode, [{{verbosity,Cat},Lvl} || {Cat,Lvl} <- Verbosity], StartDir).
+ loop(Mode, [], StartDir).
create_table(TableName,KeyPos) ->
create_table(TableName,set,KeyPos).
@@ -278,6 +283,19 @@ reset_cwd() ->
get_start_dir() ->
call(get_start_dir).
+%% handle verbosity outside ct_util_server (let the client read
+%% the verbosity table) to avoid possible deadlock situations
+set_verbosity(Elem = {_Category,_Level}) ->
+ ets:insert(?verbosity_table, Elem),
+ ok.
+get_verbosity(Category) ->
+ case ets:lookup(?verbosity_table, Category) of
+ [{Category,Level}] ->
+ Level;
+ _ ->
+ undefined
+ end.
+
loop(Mode,TestData,StartDir) ->
receive
{update_last_run_index,From} ->
@@ -377,6 +395,7 @@ loop(Mode,TestData,StartDir) ->
ets:delete(?conn_table),
ets:delete(?board_table),
ets:delete(?suite_table),
+ ets:delete(?verbosity_table),
ct_logs:close(Info, StartDir),
ct_event:stop(),
ct_config:stop(),
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index c9c6514fa4..7c2e31f40c 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -21,6 +21,7 @@
-define(conn_table,ct_connections).
-define(board_table,ct_boards).
-define(suite_table,ct_suite_data).
+-define(verbosity_table,ct_verbosity_table).
-record(conn, {handle,
targetref,