From e0440ea67e0b1ce05ca2305f7f4b52e4e23ce493 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 13 Jul 2011 10:45:39 +0200 Subject: Fix error with test_server not releasing SASL TTY handlers OTP-9311 --- lib/test_server/src/test_server_ctrl.erl | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index f3445b742b..24069946ef 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -1297,6 +1297,7 @@ terminate(_Reason, State) -> end, kill_all_jobs(State#state.jobs), test_server_node:stop(State#state.target_info), + test_server_h:restore(), ok. kill_all_jobs([{_Name,JobPid}|Jobs]) -> -- cgit v1.2.3 From d3b636f97ce36e106ac53beb4cba0db13cd5656f Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 13 Jul 2011 17:20:45 +0200 Subject: Fix problem with automatically generated init & end-config functions for groups OTP-9369 --- lib/test_server/src/test_server_ctrl.erl | 78 +++++++++++++++++--------------- 1 file changed, 41 insertions(+), 37 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 24069946ef..85686217f7 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -1665,6 +1665,11 @@ do_test_cases(TopCases, SkipCases, Config, TimetrapData) when is_list(TopCases), is_tuple(TimetrapData) -> start_log_file(), + FwMod = + case os:getenv("TEST_SERVER_FRAMEWORK") of + FW when FW =:= false; FW =:= "undefined" -> ?MODULE; + FW -> list_to_atom(FW) + end, case collect_all_cases(TopCases, SkipCases) of {error,Why} -> print(1, "Error starting: ~p", [Why]), @@ -1677,11 +1682,11 @@ do_test_cases(TopCases, SkipCases, put(test_server_cases, N), put(test_server_case_num, 0), TestSpec = - add_init_and_end_per_suite(TestSpec0, undefined, undefined), - + add_init_and_end_per_suite(TestSpec0, undefined, undefined, FwMod), TI = get_target_info(), - print(1, "Starting test~s", [print_if_known(N, {", ~w test cases",[N]}, - {" (with repeated test cases)",[]})]), + print(1, "Starting test~s", + [print_if_known(N, {", ~w test cases",[N]}, + {" (with repeated test cases)",[]})]), Test = get(test_server_name), test_server_sup:framework_call(report, [tests_start,{Test,N}]), @@ -1710,13 +1715,12 @@ do_test_cases(TopCases, SkipCases, print(html, "
Used Erlang ~s in ~s.\n", [erlang:system_info(version), code:root_dir()]), - case os:getenv("TEST_SERVER_FRAMEWORK") of - FW when FW =:= false; FW =:= "undefined" -> + if FwMod == ?MODULE -> print(html, "

Target:
\n"), print_who(TI#target_info.host, TI#target_info.username), print(html, "
Used Erlang ~s in ~s.\n", [TI#target_info.version, TI#target_info.root_dir]); - _ -> + true -> case test_server_sup:framework_call(target_info, []) of TargetInfo when is_list(TargetInfo), length(TargetInfo) > 0 -> @@ -2006,54 +2010,54 @@ copy_html_file(Src, DestDir) -> end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% add_init_and_end_per_suite(TestSpec, Mod, Ref) -> NewTestSpec +%% add_init_and_end_per_suite(TestSpec, Mod, Ref, FwMod) -> NewTestSpec %% %% Expands TestSpec with an initial init_per_suite, and a final %% end_per_suite element, per each discovered suite in the list. -add_init_and_end_per_suite([{make,_,_}=Case|Cases], LastMod, LastRef) -> - [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; -add_init_and_end_per_suite([{skip_case,{{Mod,all},_}}=Case|Cases], LastMod, LastRef) - when Mod =/= LastMod -> +add_init_and_end_per_suite([{make,_,_}=Case|Cases], LastMod, LastRef, FwMod) -> + [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; +add_init_and_end_per_suite([{skip_case,{{Mod,all},_}}=Case|Cases], LastMod, + LastRef, FwMod) when Mod =/= LastMod -> {PreCases, NextMod, NextRef} = do_add_end_per_suite_and_skip(LastMod, LastRef, Mod), - PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; -add_init_and_end_per_suite([{skip_case,{{Mod,_},_}}=Case|Cases], LastMod, LastRef) - when Mod =/= LastMod -> + PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; +add_init_and_end_per_suite([{skip_case,{{Mod,_},_}}=Case|Cases], LastMod, + LastRef, FwMod) when Mod =/= LastMod -> {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), - PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; -add_init_and_end_per_suite([{skip_case,{conf,_,{Mod,_},_}}=Case|Cases], LastMod, LastRef) - when Mod =/= LastMod -> + PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; +add_init_and_end_per_suite([{skip_case,{conf,_,{Mod,_},_}}=Case|Cases], LastMod, + LastRef, FwMod) when Mod =/= LastMod -> {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), - PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; -add_init_and_end_per_suite([{skip_case,_}=Case|Cases], LastMod, LastRef) -> - [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; -add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod, LastRef) - when Mod =/= LastMod -> + PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; +add_init_and_end_per_suite([{skip_case,_}=Case|Cases], LastMod, LastRef, FwMod) -> + [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; +add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod, + LastRef, FwMod) when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), - PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; -add_init_and_end_per_suite([{conf,_,_,_}=Case|Cases], LastMod, LastRef) -> - [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; -add_init_and_end_per_suite([{Mod,_}=Case|Cases], LastMod, LastRef) - when Mod =/= LastMod -> + PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; +add_init_and_end_per_suite([{conf,_,_,_}=Case|Cases], LastMod, LastRef, FwMod) -> + [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; +add_init_and_end_per_suite([{Mod,_}=Case|Cases], LastMod, LastRef, FwMod) + when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), - PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; -add_init_and_end_per_suite([{Mod,_,_}=Case|Cases], LastMod, LastRef) - when Mod =/= LastMod -> + PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; +add_init_and_end_per_suite([{Mod,_,_}=Case|Cases], LastMod, LastRef, FwMod) + when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = do_add_init_and_end_per_suite(LastMod, LastRef, Mod), - PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef)]; -add_init_and_end_per_suite([Case|Cases], LastMod, LastRef)-> - [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef)]; -add_init_and_end_per_suite([], _LastMod, undefined) -> + PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; +add_init_and_end_per_suite([Case|Cases], LastMod, LastRef, FwMod)-> + [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; +add_init_and_end_per_suite([], _LastMod, undefined, _FwMod) -> []; -add_init_and_end_per_suite([], _LastMod, skipped_suite) -> +add_init_and_end_per_suite([], _LastMod, skipped_suite, _FwMod) -> []; -add_init_and_end_per_suite([], LastMod, LastRef) -> +add_init_and_end_per_suite([], LastMod, LastRef, _FwMod) -> [{conf,LastRef,[],{LastMod,end_per_suite}}]. do_add_init_and_end_per_suite(LastMod, LastRef, Mod) -> -- cgit v1.2.3 From 021b0dcb2a3a86ec0e07b0de8dc7cde9be0924ba Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 14 Jul 2011 14:18:57 +0200 Subject: Introduce new 'logopts' flag Introduce new 'logopts' flag and make it possible to modify the default logging behaviour OTP-9372 OTP-9396 --- lib/test_server/src/test_server_ctrl.erl | 34 +++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 85686217f7..b7b25fcf72 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -1350,6 +1350,10 @@ init_tester(Mod, Func, Args, Dir, Name, {SumLev,MajLev,MinLev}, put(test_server_minor_level, MinLev), 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 + LogOpts = test_server_sup:framework_call(get_logopts, [], []), + put(test_server_logopts, LogOpts), + put(test_server_log_nl, not lists:member(no_nl, LogOpts)), StartedExtraTools = start_extra_tools(ExtraTools), {TimeMy,Result} = ts_tc(Mod, Func, Args), put(test_server_common_io_handler, undefined), @@ -1889,11 +1893,12 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName) -> []), SrcListing = downcase(cast_to_list(Mod)) ++ ?src_listing_ext, - case filelib:is_file(filename:join(LogDir, SrcListing)) of - true -> + case {filelib:is_file(filename:join(LogDir, SrcListing)), + lists:member(no_src, get(test_server_logopts))} of + {true,false} -> print(Lev, "source code for ~p:~p/1\n", [SrcListing,Func,Mod,Func]); - false -> ok + _ -> ok end, io:fwrite(Fd, "

\n", []),
@@ -2106,7 +2111,12 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
 
     maybe_open_job_sock(),
 
-    html_convert_modules(TestSpec, Config),
+    case lists:member(no_src, get(test_server_logopts)) of
+	true ->
+	    ok;
+	false ->
+	    html_convert_modules(TestSpec, Config)
+    end,
 
     run_test_cases_loop(TestSpec, [Config], TimetrapData, [], []),
 
@@ -2315,7 +2325,8 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
 		    handle_test_case_io_and_status(),
 		    set_io_buffering(undefined),
 		    {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, false, SkipMode),
-		    test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]),
+		    test_server_sup:framework_call(report, [tc_auto_skip,
+							    {?pl2a(Mod),Func,Comment}]),
 		    run_test_cases_loop(Cases, Config, TimetrapData, ParentMode,
 					delete_status(Ref, Status));
 		_ ->
@@ -2323,7 +2334,8 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
 		    %% parallel group (io buffering is active)
 		    wait_for_cases(Ref),
 		    {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, true, SkipMode),
-		    test_server_sup:framework_call(report, [tc_auto_skip,{?pl2a(Mod),Func,Comment}]),
+		    test_server_sup:framework_call(report, [tc_auto_skip,
+							    {?pl2a(Mod),Func,Comment}]),
 		    case CurrIOHandler of
 			{Ref,_} ->
 			    %% current_io_handler was set by start conf of this
@@ -4350,14 +4362,18 @@ output_to_fd(Fd, [$=|Msg], internal) ->
     io:put_chars(Fd, [$=]),
     io:put_chars(Fd, Msg),
     io:put_chars(Fd, "\n");
+
 output_to_fd(Fd, Msg, internal) ->
     io:put_chars(Fd, [$=,$=,$=,$ ]),
     io:put_chars(Fd, Msg),
     io:put_chars(Fd, "\n");
+
 output_to_fd(Fd, Msg, _Sender) ->
     io:put_chars(Fd, Msg),
-    io:put_chars(Fd, "\n").
-
+    case get(test_server_log_nl) of
+	false -> ok;
+	_     -> io:put_chars(Fd, "\n")
+    end.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% timestamp_filename_get(Leader) -> string()
@@ -4670,7 +4686,7 @@ collect_case_invoke(Mod, Case, MFA, St) ->
 		    collect_subcases(Mod, Case, MFA, St, Suite)
 	    end;
 	_ ->
-	    Suite = test_server_sup:framework_call(get_suite, [?pl2a(Mod),Case],[]),
+	    Suite = test_server_sup:framework_call(get_suite, [?pl2a(Mod),Case], []),
 	    collect_subcases(Mod, Case, MFA, St, Suite)
     end.
 
-- 
cgit v1.2.3


From 8618bb8eab726ab5652b40751bdca928b49eca7f Mon Sep 17 00:00:00 2001
From: Peter Andersson 
Date: Thu, 14 Jul 2011 16:10:31 +0200
Subject: Fix incorrect module name arg to FW:end_tc/3

OTP-9379
---
 lib/test_server/src/test_server.erl     | 4 ++--
 lib/test_server/src/test_server_sup.erl | 2 +-
 lib/test_server/src/ts_erl_config.erl   | 5 -----
 3 files changed, 3 insertions(+), 8 deletions(-)

(limited to 'lib/test_server/src')

diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 591329b361..d3fa3c8b87 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -1218,8 +1218,8 @@ do_end_tc_call(M,F,Res,Return) ->
 		    NewReturn
 	    end;
 	Other ->
-	    case test_server_sup:framework_call(
-		   end_tc, [Other,F,Res], Ref) of
+	    case test_server_sup:framework_call(Other, end_tc,
+						[?pl2a(M),F,Res], Ref) of
 		{fail,FWReason} ->
 		    {failed,FWReason};
 		_Else ->
diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl
index 53dfb45e3a..e846a4c14a 100644
--- a/lib/test_server/src/test_server_sup.erl
+++ b/lib/test_server/src/test_server_sup.erl
@@ -26,7 +26,7 @@
 	 cleanup_crash_dumps/0, crash_dump_dir/0, tar_crash_dumps/0,
 	 get_username/0, get_os_family/0, 
 	 hostatom/0, hostatom/1, hoststr/0, hoststr/1,
-	 framework_call/2,framework_call/3,
+	 framework_call/2,framework_call/3,framework_call/4,
 	 format_loc/1, package_str/1, package_atom/1,
 	 call_trace/1]).
 -include("test_server_internal.hrl").
diff --git a/lib/test_server/src/ts_erl_config.erl b/lib/test_server/src/ts_erl_config.erl
index 640c8ddc9f..3b41f90d55 100644
--- a/lib/test_server/src/ts_erl_config.erl
+++ b/lib/test_server/src/ts_erl_config.erl
@@ -222,7 +222,6 @@ erl_interface(Vars,OsType) ->
 		end,
     CrossCompile = case OsType of
 		       vxworks -> "true";
-		       ose ->     "true";
 		       _ ->       "false"
 		   end,
     [{erl_interface_libpath, filename:nativename(LibPath)},
@@ -329,8 +328,6 @@ sock_libraries({win32, _}) ->
 sock_libraries({unix, _}) ->
     "";	% Included in general libraries if needed.
 sock_libraries(vxworks) ->
-    "";
-sock_libraries(ose) ->
     "".
 
 link_library(LibName,{win32, _}) ->
@@ -339,8 +336,6 @@ link_library(LibName,{unix, _}) ->
     "lib" ++ LibName ++ ".a";
 link_library(LibName,vxworks) ->
     "lib" ++ LibName ++ ".a";
-link_library(_LibName,ose) ->
-    "";
 link_library(_LibName,_Other) ->
     exit({link_library, not_supported}).
 
-- 
cgit v1.2.3


From bd56af6214c451b9c7d0ab455b2597021299ecaa Mon Sep 17 00:00:00 2001
From: Peter Andersson 
Date: Thu, 14 Jul 2011 16:56:36 +0200
Subject: Introduce new framework callback function to read info about color of
 comments

OTP-9237
---
 lib/test_server/src/test_server.erl      | 9 ++++++---
 lib/test_server/src/test_server_ctrl.erl | 7 +++++--
 2 files changed, 11 insertions(+), 5 deletions(-)

(limited to 'lib/test_server/src')

diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index d3fa3c8b87..f5f795e082 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -733,14 +733,18 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 	    print(Detail,Format,Args),
 	    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf);
 	{comment,NewComment} ->
+	    NewComment1 = test_server_ctrl:to_string(NewComment),
+	    NewComment2 = test_server_sup:framework_call(format_comment,
+							 [NewComment1],
+							 NewComment1),
 	    Terminate1 =
 		case Terminate of
 		    {true,{Time,Value,Loc,Opts,_OldComment}} ->
-			{true,{Time,Value,mod_loc(Loc),Opts,NewComment}};
+			{true,{Time,Value,mod_loc(Loc),Opts,NewComment2}};
 		    Other ->
 			Other
 		end,
-	    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate1,NewComment,CurrConf);
+	    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate1,NewComment2,CurrConf);
 	{set_curr_conf,NewCurrConf} ->
 	    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,NewCurrConf);
 	{'EXIT',Pid,{Ref,Time,Value,Loc,Opts}} ->
@@ -2283,7 +2287,6 @@ comment(String) ->
     group_leader() ! {comment,String},
     ok.
 
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% os_type() -> OsType
 %%
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index b7b25fcf72..7554a31530 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -173,7 +173,7 @@
 %%% TEST_SERVER INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 -export([output/2, print/2, print/3, print_timestamp/2]).
 -export([start_node/3, stop_node/1, wait_for_node/1, is_release_available/1]).
--export([format/1, format/2, format/3]).
+-export([format/1, format/2, format/3, to_string/1]).
 -export([get_target_info/0]).
 -export([get_hosts/0]).
 -export([get_target_os_type/0]).
@@ -3976,8 +3976,11 @@ progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time,
 	case RetVal of
 	    {comment,RetComment} ->
 		String = to_string(RetComment),
+		HtmlCmt = test_server_sup:framework_call(format_comment,
+							 [String],
+							 String),
 		print(major, "=result        ok: ~s", [String]),
-		"" ++ String ++ "";
+		"" ++ HtmlCmt ++ "";
 	    _ ->
 		print(major, "=result        ok", []),
 		case Comment0 of
-- 
cgit v1.2.3


From f7ed0bf5212de281c4456f8ec7735ff22a06c371 Mon Sep 17 00:00:00 2001
From: Peter Andersson 
Date: Thu, 14 Jul 2011 17:55:53 +0200
Subject: Fix error with incorrect test case status when end_per_testcase times
 out

OTP-9397
---
 lib/test_server/src/test_server.erl | 117 +++++++++++++++++++++---------------
 1 file changed, 67 insertions(+), 50 deletions(-)

(limited to 'lib/test_server/src')

diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index f5f795e082..52fb4fba6b 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -757,7 +757,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 		    case mod_loc(Loc) of
 			{FwMod,FwFunc,framework} ->
 			    %% timout during framework call
-			    spawn_fw_call(FwMod,FwFunc,Pid,
+			    spawn_fw_call(FwMod,FwFunc,CurrConf,Pid,
 					  {framework_error,{timetrap,TVal}},
 					  unknown,self(),Comment),
 			    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,
@@ -783,7 +783,8 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 					%% group leader process or io will cause deadlock,
 					%% so we spawn a dedicated process for the operation
 					%% and let the group leader go back to handle io.
-					spawn_fw_call(Mod,Func,Pid,{timetrap_timeout,TVal},
+					spawn_fw_call(Mod,Func,CurrConf,Pid,
+						      {timetrap_timeout,TVal},
 						      Loc1,self(),Comment),
 					undefined
 				end,
@@ -794,12 +795,13 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 		    case mod_loc(Loc) of
 			{FwMod,FwFunc,framework} ->
 			    %% timout during framework call
-			    spawn_fw_call(FwMod,FwFunc,Pid,
+			    spawn_fw_call(FwMod,FwFunc,CurrConf,Pid,
 					  {framework_error,{timetrap,TVal}},
 					  unknown,self(),Comment);
 			Loc1 ->
 			    {Mod,_Func} = get_mf(Loc1),
-			    spawn_fw_call(Mod,InitOrEnd,Pid,{timetrap_timeout,TVal},
+			    spawn_fw_call(Mod,InitOrEnd,CurrConf,Pid,
+					  {timetrap_timeout,TVal},
 					  Loc1,self(),Comment)
 		    end,
 		    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf);
@@ -808,7 +810,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 		    case mod_loc(AbortLoc) of
 			{FwMod,FwFunc,framework} ->
 			    %% abort during framework call
-			    spawn_fw_call(FwMod,FwFunc,Pid,
+			    spawn_fw_call(FwMod,FwFunc,CurrConf,Pid,
 					  {framework_error,ErrorMsg},
 					  unknown,self(),Comment),
 			    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,
@@ -832,7 +834,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 							  TVal),
 					{EndConfPid,{Mod,Func},Conf};
 				    _ ->
-					spawn_fw_call(Mod,Func,Pid,ErrorMsg,
+					spawn_fw_call(Mod,Func,CurrConf,Pid,ErrorMsg,
 						      Loc1,self(),Comment),
 					undefined
 				end,
@@ -843,17 +845,18 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 		    %% result of an exit(TestCase,kill) call, which is the
 		    %% only way to abort a testcase process that traps exits
 		    %% (see abort_current_testcase)
-		    spawn_fw_call(undefined,undefined,Pid,testcase_aborted_or_killed,
+		    spawn_fw_call(undefined,undefined,CurrConf,Pid,
+				  testcase_aborted_or_killed,
 				  unknown,self(),Comment),
 		    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf);
 		{fw_error,{FwMod,FwFunc,FwError}} ->
-		    spawn_fw_call(FwMod,FwFunc,Pid,{framework_error,FwError},
+		    spawn_fw_call(FwMod,FwFunc,CurrConf,Pid,{framework_error,FwError},
 				  unknown,self(),Comment),
 		    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf);
 		_Other ->
 		    %% the testcase has terminated because of Reason (e.g. an exit
 		    %% because a linked process failed)
-		    spawn_fw_call(undefined,undefined,Pid,Reason,
+		    spawn_fw_call(undefined,undefined,CurrConf,Pid,Reason,
 				  unknown,self(),Comment),
 		    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf)
 	    end;
@@ -861,7 +864,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
 	    case CurrConf of
 		{EndConfPid,{Mod,Func},_Conf} ->
 		    {_Mod,_Func,TCPid,TCExitReason,Loc} = Data,
-		    spawn_fw_call(Mod,Func,TCPid,TCExitReason,Loc,self(),Comment),
+		    spawn_fw_call(Mod,Func,CurrConf,TCPid,TCExitReason,Loc,self(),Comment),
 		    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,undefined);
 		_ ->
 		    run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf)
@@ -932,7 +935,7 @@ call_end_conf(Mod,Func,TCPid,TCExitReason,Loc,Conf,TVal) ->
 				    ok
 			    end,
 			    Supervisor ! {self(),end_conf}
-		       end,
+		    end,
 		Pid = spawn_link(EndConfApply),
 		receive
 		    {Pid,end_conf} ->
@@ -945,50 +948,59 @@ call_end_conf(Mod,Func,TCPid,TCExitReason,Loc,Conf,TVal) ->
 	end,
     spawn_link(EndConfProc).
 
-spawn_fw_call(Mod,{init_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why,
+spawn_fw_call(Mod,{init_per_testcase,Func},_,Pid,{timetrap_timeout,TVal}=Why,
 	      Loc,SendTo,Comment) ->
     FwCall =
 	fun() ->
-	    Skip = {skip,{failed,{Mod,init_per_testcase,Why}}},
-	    %% if init_per_testcase fails, the test case
-	    %% should be skipped
-	    case catch do_end_tc_call(Mod,Func,{Pid,Skip,[[]]},Why) of
-		{'EXIT',FwEndTCErr} ->
-		    exit({fw_notify_done,end_tc,FwEndTCErr});
-		_ ->
-		    ok
-	    end,
-	    %% finished, report back
-	    SendTo ! {self(),fw_notify_done,
-		      {TVal/1000,Skip,Loc,[],Comment}}
+		Skip = {skip,{failed,{Mod,init_per_testcase,Why}}},
+		%% if init_per_testcase fails, the test case
+		%% should be skipped
+		case catch do_end_tc_call(Mod,Func,{Pid,Skip,[[]]},Why) of
+		    {'EXIT',FwEndTCErr} ->
+			exit({fw_notify_done,end_tc,FwEndTCErr});
+		    _ ->
+			ok
+		end,
+		%% finished, report back
+		SendTo ! {self(),fw_notify_done,
+			  {TVal/1000,Skip,Loc,[],Comment}}
 	end,
     spawn_link(FwCall);
 
-spawn_fw_call(Mod,{end_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why,
-	      Loc,SendTo,_Comment) ->
+spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid,
+	      {timetrap_timeout,TVal}=Why,_Loc,SendTo,Comment) ->
     FwCall =
 	fun() ->
-	    Conf = [{tc_status,ok}],
-	    %% if end_per_testcase fails, the test case should be
-	    %% reported successful with a warning printed as comment
-	    case catch do_end_tc_call(Mod,Func,{Pid,
-						{failed,{Mod,end_per_testcase,Why}},
-						[Conf]}, Why) of
-		{'EXIT',FwEndTCErr} ->
-		    exit({fw_notify_done,end_tc,FwEndTCErr});
-		_ ->
-		    ok
-	    end,
-	    %% finished, report back
-	    SendTo ! {self(),fw_notify_done,
-		      {TVal/1000,{error,{Mod,end_per_testcase,Why}},Loc,[],
-		       [""
-			"WARNING: end_per_testcase timed out!"
-			""]}}
+		%% if end_per_testcase fails a warning should be
+		%% printed as comment
+		case catch do_end_tc_call(Mod,Func,{Pid,
+						    {failed,{Mod,
+							     end_per_testcase,
+							     Why}},
+						    [EndConf]}, Why) of
+		    {'EXIT',FwEndTCErr} ->
+			exit({fw_notify_done,end_tc,FwEndTCErr});
+		    _ ->
+			ok
+		end,
+		RetVal = case proplists:get_value(tc_status, EndConf) of
+			     undefined -> {failed,{Mod,end_per_testcase,Why}};
+			     Result -> Result
+			 end,
+		FailLoc = proplists:get_value(tc_fail_loc, EndConf),
+		Comment1 = if Comment == "" -> "";
+			      true -> Comment ++ "
" + end, + %% finished, report back + SendTo ! {self(),fw_notify_done, + {TVal/1000,RetVal,FailLoc,[], + [Comment1,"" + "WARNING: end_per_testcase timed out!" + ""]}} end, spawn_link(FwCall); -spawn_fw_call(FwMod,FwFunc,_Pid,{framework_error,FwError},_,SendTo,_Comment) -> +spawn_fw_call(FwMod,FwFunc,_,_Pid,{framework_error,FwError},_,SendTo,_Comment) -> FwCall = fun() -> test_server_sup:framework_call(report, [framework_error, @@ -1003,7 +1015,7 @@ spawn_fw_call(FwMod,FwFunc,_Pid,{framework_error,FwError},_,SendTo,_Comment) -> end, spawn_link(FwCall); -spawn_fw_call(Mod,Func,Pid,Error,Loc,SendTo,Comment) -> +spawn_fw_call(Mod,Func,_,Pid,Error,Loc,SendTo,Comment) -> FwCall = fun() -> case catch fw_error_notify(Mod,Func,[], @@ -1140,25 +1152,28 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {EndConf,TSReturn,FWReturn} = case Return of {E,TCError} when E=='EXIT' ; E==failed -> + ModLoc = mod_loc(Loc), fw_error_notify(Mod, Func, NewConf1, - TCError, mod_loc(Loc)), - {[{tc_status,{failed,TCError}}|NewConf1], + TCError, ModLoc), + {[{tc_status,{failed,TCError}}, + {tc_fail_loc,ModLoc}|NewConf1], Return,{error,TCError}}; SaveCfg={save_config,_} -> {[{tc_status,ok},SaveCfg|NewConf1],Return,ok}; {skip_and_save,Why,SaveCfg} -> Skip = {skip,Why}, - {[{tc_status,{skipped,Why}},{save_config,SaveCfg}|NewConf1], + {[{tc_status,{skipped,Why}}, + {save_config,SaveCfg}|NewConf1], Skip,Skip}; {skip,Why} -> {[{tc_status,{skipped,Why}}|NewConf1],Return,Return}; _ -> {[{tc_status,ok}|NewConf1],Return,ok} end, - %% clear current state in controller loop - group_leader() ! {set_curr_conf,undefined}, %% call user callback function if defined EndConf1 = user_callback(TCCallback, Mod, Func, 'end', EndConf), + %% update current state in controller loop + group_leader() ! {set_curr_conf,EndConf1}, {FWReturn1,TSReturn1,EndConf2} = case end_per_testcase(Mod, Func, EndConf1) of SaveCfg1={save_config,_} -> @@ -1172,6 +1187,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> _ -> {FWReturn,TSReturn,EndConf1} end, + %% clear current state in controller loop + group_leader() ! {set_curr_conf,undefined}, put(test_server_init_or_end_conf,undefined), case do_end_tc_call(Mod, Func, {FWReturn1,[EndConf2]}, TSReturn1) of {failed,Reason} = NewReturn -> -- cgit v1.2.3 From 16eaecc29b5f314fbc8f60880688049bcf074896 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Fri, 15 Jul 2011 00:41:43 +0200 Subject: Fix problem with end_tc being called with incorrect Suite argument OTP-9398: Fix error with end_tc being called with incorrect Suite argument after timeout in lib function OTP-9397: Fix problem with true error not reported to FW --- lib/test_server/src/test_server.erl | 118 +++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 41 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 52fb4fba6b..337bc1d6d7 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -955,7 +955,7 @@ spawn_fw_call(Mod,{init_per_testcase,Func},_,Pid,{timetrap_timeout,TVal}=Why, Skip = {skip,{failed,{Mod,init_per_testcase,Why}}}, %% if init_per_testcase fails, the test case %% should be skipped - case catch do_end_tc_call(Mod,Func,{Pid,Skip,[[]]},Why) of + case catch do_end_tc_call(Mod,Func, Loc, {Pid,Skip,[[]]}, Why) of {'EXIT',FwEndTCErr} -> exit({fw_notify_done,end_tc,FwEndTCErr}); _ -> @@ -971,23 +971,26 @@ spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid, {timetrap_timeout,TVal}=Why,_Loc,SendTo,Comment) -> FwCall = fun() -> - %% if end_per_testcase fails a warning should be - %% printed as comment - case catch do_end_tc_call(Mod,Func,{Pid, - {failed,{Mod, - end_per_testcase, - Why}}, - [EndConf]}, Why) of + {RetVal,Report} = + case proplists:get_value(tc_status, EndConf) of + undefined -> + E = {failed,{Mod,end_per_testcase,Why}}, + {E,E}; + E = {failed,Reason} -> + {E,{error,Reason}}; + Result -> + {Result,Result} + end, + FailLoc = proplists:get_value(tc_fail_loc, EndConf), + case catch do_end_tc_call(Mod,Func, FailLoc, + {Pid,Report,[EndConf]}, Why) of {'EXIT',FwEndTCErr} -> exit({fw_notify_done,end_tc,FwEndTCErr}); _ -> ok end, - RetVal = case proplists:get_value(tc_status, EndConf) of - undefined -> {failed,{Mod,end_per_testcase,Why}}; - Result -> Result - end, - FailLoc = proplists:get_value(tc_fail_loc, EndConf), + %% if end_per_testcase fails a warning should be + %% printed as comment Comment1 = if Comment == "" -> ""; true -> Comment ++ "
" end, @@ -1027,7 +1030,8 @@ spawn_fw_call(Mod,Func,_,Pid,Error,Loc,SendTo,Comment) -> ok end, Conf = [{tc_status,{failed,timetrap_timeout}}], - case catch do_end_tc_call(Mod,Func,{Pid,Error,[Conf]},Error) of + case catch do_end_tc_call(Mod,Func, Loc, + {Pid,Error,[Conf]},Error) of {'EXIT',FwEndTCErr} -> exit({fw_notify_done,end_tc,FwEndTCErr}); _ -> @@ -1097,22 +1101,26 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit, {ok,Args} -> run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback); Error = {error,_Reason} -> - NewResult = do_end_tc_call(Mod,Func,{Error,Args0}, + Where = {Mod,Func}, + NewResult = do_end_tc_call(Mod,Func, Where, {Error,Args0}, {skip,{failed,Error}}), - {{0,NewResult},{Mod,Func},[]}; + {{0,NewResult},Where,[]}; {fail,Reason} -> Conf = [{tc_status,{failed,Reason}} | hd(Args0)], + Where = {Mod,Func}, fw_error_notify(Mod, Func, Conf, Reason), - NewResult = do_end_tc_call(Mod,Func, {{error,Reason},[Conf]}, + NewResult = do_end_tc_call(Mod,Func, Where, {{error,Reason},[Conf]}, {fail,Reason}), - {{0,NewResult},{Mod,Func},[]}; + {{0,NewResult},Where,[]}; Skip = {skip,_Reason} -> - NewResult = do_end_tc_call(Mod,Func,{Skip,Args0},Skip), - {{0,NewResult},{Mod,Func},[]}; + Where = {Mod,Func}, + NewResult = do_end_tc_call(Mod,Func, Where, {Skip,Args0}, Skip), + {{0,NewResult},Where,[]}; {auto_skip,Reason} -> - NewResult = do_end_tc_call(Mod, Func, {{skip,Reason},Args0}, + Where = {Mod,Func}, + NewResult = do_end_tc_call(Mod,Func, Where, {{skip,Reason},Args0}, {skip,{fw_auto_skip,Reason}}), - {{0,NewResult},{Mod,Func},[]} + {{0,NewResult},Where,[]} end, exit({Ref,Time,Value,Loc,Opts}). @@ -1126,18 +1134,19 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> Skip = {skip,Reason} -> Line = get_loc(), Conf = [{tc_status,{skipped,Reason}}], - NewRes = do_end_tc_call(Mod,Func,{Skip,[Conf]}, Skip), + NewRes = do_end_tc_call(Mod,Func, Line, {Skip,[Conf]}, Skip), {{0,NewRes},Line,[]}; {skip_and_save,Reason,SaveCfg} -> Line = get_loc(), Conf = [{tc_status,{skipped,Reason}},{save_config,SaveCfg}], - NewRes = do_end_tc_call(Mod, Func, {{skip,Reason},[Conf]}, - {skip, Reason}), + NewRes = do_end_tc_call(Mod,Func, Line, {{skip,Reason},[Conf]}, + {skip,Reason}), {{0,NewRes},Line,[]}; FailTC = {fail,Reason} -> % user fails the testcase EndConf = [{tc_status,{failed,Reason}} | hd(Args)], fw_error_notify(Mod, Func, EndConf, Reason), - NewRes = do_end_tc_call(Mod, Func, {{error,Reason},[EndConf]}, + NewRes = do_end_tc_call(Mod,Func, {Mod,Func}, + {{error,Reason},[EndConf]}, FailTC), {{0,NewRes},{Mod,Func},[]}; {ok,NewConf} -> @@ -1190,7 +1199,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> %% clear current state in controller loop group_leader() ! {set_curr_conf,undefined}, put(test_server_init_or_end_conf,undefined), - case do_end_tc_call(Mod, Func, {FWReturn1,[EndConf2]}, TSReturn1) of + case do_end_tc_call(Mod,Func, Loc, + {FWReturn1,[EndConf2]}, TSReturn1) of {failed,Reason} = NewReturn -> fw_error_notify(Mod,Func,EndConf2, Reason), {{T,NewReturn},{Mod,Func},[]}; @@ -1218,14 +1228,39 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {{T,Return2},Loc,Opts} end. -do_end_tc_call(M,F,Res,Return) -> +do_end_tc_call(M,F, Loc, Res, Return) -> + FwMod = os:getenv("TEST_SERVER_FRAMEWORK"), + {Mod,Func} = + if FwMod == M ; FwMod == "undefined"; FwMod == false -> + {M,F}; + is_list(Loc) and (length(Loc)>1) -> + %% If failure in other module (M) than suite, try locate + %% suite name in Loc list and call end_tc with Suite:TestCase + %% instead of M:F. + GetSuite = fun(S,TC) -> + case lists:reverse(atom_to_list(S)) of + [$E,$T,$I,$U,$S,$_|_] -> [{S,TC}]; + _ -> [] + end + end, + case lists:flatmap(fun({S,TC,_}) -> GetSuite(S,TC); + ({{S,TC},_}) -> GetSuite(S,TC); + ({S,TC}) -> GetSuite(S,TC); + (_) -> [] + end, Loc) of + [] -> + {M,F}; + [FoundSuite|_] -> + FoundSuite + end; + true -> + {M,F} + end, + Ref = make_ref(), - case os:getenv("TEST_SERVER_FRAMEWORK") of - FW when FW == "ct_framework"; - FW == "undefined"; - FW == false -> + if FwMod == "ct_framework" ; FwMod == "undefined"; FwMod == false -> case test_server_sup:framework_call( - end_tc, [?pl2a(M),F,Res, Return], ok) of + end_tc, [?pl2a(Mod),Func,Res, Return], ok) of {fail,FWReason} -> {failed,FWReason}; ok -> @@ -1238,9 +1273,9 @@ do_end_tc_call(M,F,Res,Return) -> NewReturn -> NewReturn end; - Other -> - case test_server_sup:framework_call(Other, end_tc, - [?pl2a(M),F,Res], Ref) of + true -> + case test_server_sup:framework_call(FwMod, end_tc, + [?pl2a(Mod),Func,Res], Ref) of {fail,FWReason} -> {failed,FWReason}; _Else -> @@ -1263,7 +1298,7 @@ process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) -> true -> % must be return value from end conf case process_return_val1(Return, M,F,A, Loc, Final, []); false -> % must be Config value from init conf case - case do_end_tc_call(M,F,{ok,A}, Return) of + case do_end_tc_call(M, F, Loc, {ok,A}, Return) of {failed, FWReason} = Failed -> fw_error_notify(M,F,A, FWReason), {Failed, []}; @@ -1280,8 +1315,9 @@ process_return_val1([Failed={E,TCError}|_], M,F,A=[Args], Loc, _, SaveOpts) when E=='EXIT'; E==failed -> fw_error_notify(M,F,A, TCError, mod_loc(Loc)), - case do_end_tc_call(M,F,{{error,TCError}, - [[{tc_status,{failed,TCError}}|Args]]}, Failed) of + case do_end_tc_call(M,F, Loc, {{error,TCError}, + [[{tc_status,{failed,TCError}}|Args]]}, + Failed) of {failed,FWReason} -> {{failed,FWReason},SaveOpts}; NewReturn -> @@ -1298,8 +1334,8 @@ process_return_val1([RetVal={Tag,_}|Opts], M,F,A, Loc, _, SaveOpts) when Tag==sk process_return_val1(Opts, M,F,A, Loc, RetVal, SaveOpts); process_return_val1([_|Opts], M,F,A, Loc, Final, SaveOpts) -> process_return_val1(Opts, M,F,A, Loc, Final, SaveOpts); -process_return_val1([], M,F,A, _Loc, Final, SaveOpts) -> - case do_end_tc_call(M,F,{Final,A}, Final) of +process_return_val1([], M,F,A, Loc, Final, SaveOpts) -> + case do_end_tc_call(M,F, Loc, {Final,A}, Final) of {failed,FWReason} -> {{failed,FWReason},SaveOpts}; NewReturn -> -- cgit v1.2.3 From 8d9b760e7fafec40787be6de5994240f1540d12a Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Fri, 15 Jul 2011 14:38:51 +0200 Subject: Fix problem with incorrect src links OTP-9396 --- lib/test_server/src/test_server_sup.erl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl index e846a4c14a..77d364d5cb 100644 --- a/lib/test_server/src/test_server_sup.erl +++ b/lib/test_server/src/test_server_sup.erl @@ -540,8 +540,9 @@ format_loc({Mod,Func}) when is_atom(Func) -> format_loc({Mod,Line}) when is_integer(Line) -> %% ?line macro is used ModStr = package_str(Mod), - case lists:reverse(ModStr) of - [$E,$T,$I,$U,$S,$_|_] -> + case {lists:member(no_src, get(test_server_logopts)), + lists:reverse(ModStr)} of + {false,[$E,$T,$I,$U,$S,$_|_]} -> io_lib:format("{~s,~w}", [ModStr,downcase(ModStr),?src_listing_ext, round_to_10(Line),Line]); @@ -557,8 +558,9 @@ format_loc1([{Mod,Func,Line}|Rest]) -> [" ",format_loc1({Mod,Func,Line}),",\n"|format_loc1(Rest)]; format_loc1({Mod,Func,Line}) -> ModStr = package_str(Mod), - case lists:reverse(ModStr) of - [$E,$T,$I,$U,$S,$_|_] -> + case {lists:member(no_src, get(test_server_logopts)), + lists:reverse(ModStr)} of + {false,[$E,$T,$I,$U,$S,$_|_]} -> io_lib:format("{~s,~w,~w}", [ModStr,Func,downcase(ModStr),?src_listing_ext, round_to_10(Line),Line]); -- cgit v1.2.3 From b21b1f63bce0ad705671e0f7622d017be464ed67 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Fri, 16 Sep 2011 23:37:29 +0200 Subject: Implement support for MFA and Fun as timetrap value OTP-9501 --- lib/test_server/src/test_server.erl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 337bc1d6d7..039ea720a8 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -1905,8 +1905,28 @@ time_ms({Other,_N}) -> exit({invalid_time_spec,Other}); time_ms(Ms) when is_integer(Ms) -> Ms; time_ms(infinity) -> infinity; +time_ms(Fun) when is_function(Fun) -> + try Fun() of + Val -> time_ms1(Val) + catch + _:Error -> + exit({timetrap_error,Error}) + end; +time_ms({M,F,A}) when is_atom(M), is_atom(F), is_list(A) -> + try apply(M, F, A) of + Val -> time_ms1(Val) + catch + _:Error -> + exit({timetrap_error,Error}) + end; time_ms(Other) -> exit({invalid_time_spec,Other}). +time_ms1(MFA = {M,F,A}) when is_atom(M), is_atom(F), is_list(A) -> + exit({invalid_time_spec,MFA}); +time_ms1(Fun) when is_function(Fun) -> + exit({invalid_time_spec,Fun}); +time_ms1(Other) -> + time_ms(Other). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% timetrap_cancel(Handle) -> ok -- cgit v1.2.3 From 4c8664f1983a57c8d71ada937381b5fc5791446d Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Tue, 20 Sep 2011 16:26:49 +0200 Subject: Fix incorrect call to end_tc when tc_status=ok and end_per_testcase times out OTP-9397 --- lib/test_server/src/test_server.erl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 039ea720a8..ea55b22603 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -612,6 +612,7 @@ do_run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) -> print(minor, "Current directory is ~p\n", [Cwd]), print_timestamp(minor,"Started at "), TCCallback = get(test_server_testcase_callback), + LogOpts = get(test_server_logopts), Ref = make_ref(), OldGLeader = group_leader(), %% Set ourself to group leader for the spawned process @@ -621,7 +622,7 @@ do_run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) -> fun() -> run_test_case_eval(Mod, Func, Args, Name, Ref, RunInit, TimetrapData, - TCCallback) + LogOpts, TCCallback) end), group_leader(OldGLeader, self()), put(test_server_detected_fail, []), @@ -979,7 +980,8 @@ spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid, E = {failed,Reason} -> {E,{error,Reason}}; Result -> - {Result,Result} + E = {failed,{Mod,end_per_testcase,Why}}, + {Result,E} end, FailLoc = proplists:get_value(tc_fail_loc, EndConf), case catch do_end_tc_call(Mod,Func, FailLoc, @@ -1092,8 +1094,9 @@ job_proxy_msgloop() -> %% or sends a message {failed, File, Line} to it's group_leader run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit, - TimetrapData, TCCallback) -> - put(test_server_multiply_timetraps,TimetrapData), + TimetrapData, LogOpts, TCCallback) -> + put(test_server_multiply_timetraps, TimetrapData), + put(test_server_logopts, LogOpts), {{Time,Value},Loc,Opts} = case test_server_sup:framework_call(init_tc,[?pl2a(Mod),Func,Args0], -- cgit v1.2.3 From d7391d973f453de4749857291680380b60330bc7 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 21 Sep 2011 23:14:34 +0200 Subject: Fix problem with error message not being printed correctly --- lib/test_server/src/test_server.erl | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index ea55b22603..ae54925c2e 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -746,6 +746,9 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) -> Other end, run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate1,NewComment2,CurrConf); + {read_comment,From} -> + From ! {self(),read_comment,Comment}, + run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); {set_curr_conf,NewCurrConf} -> run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,NewCurrConf); {'EXIT',Pid,{Ref,Time,Value,Loc,Opts}} -> @@ -1443,9 +1446,13 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) -> {'$test_server_ok',_} -> ok; {'EXIT',Reason} = Why -> - comment(io_lib:format("" + Comment0 = case read_comment() of + "" -> ""; + Cmt -> Cmt ++ "
" + end, + comment(io_lib:format("~s" "WARNING: ~w crashed!" - "\n",[EndFunc])), + "
\n",[Comment0,EndFunc])), group_leader() ! {printout,12, "WARNING: ~w crashed!\n" "Reason: ~p\n" @@ -1455,9 +1462,13 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) -> mod_loc(get_loc()))]}, {failed,{Mod,end_per_testcase,Why}}; Other -> - comment(io_lib:format("" + Comment0 = case read_comment() of + "" -> ""; + Cmt -> Cmt ++ "
" + end, + comment(io_lib:format("~s" "WARNING: ~w thrown!" - "\n",[EndFunc])), + "
\n",[Comment0,EndFunc])), group_leader() ! {printout,12, "WARNING: ~w thrown!\n" "Reason: ~p\n" @@ -2363,6 +2374,22 @@ comment(String) -> group_leader() ! {comment,String}, ok. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% read_comment() -> string() +%% +%% Read the current comment string stored in +%% state during test case execution. +read_comment() -> + MsgLooper = group_leader(), + MsgLooper ! {read_comment,self()}, + receive + {MsgLooper,read_comment,Comment} -> + Comment + after + 5000 -> + "" + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% os_type() -> OsType %% -- cgit v1.2.3 From 11107d76a34667ec87668b2624a0f3df43dea655 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 22 Sep 2011 12:46:12 +0200 Subject: Fix error with incorrect notification after end_per_testcase craches --- lib/test_server/src/test_server.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index ae54925c2e..303ee3ae95 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -1194,12 +1194,17 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> SaveCfg1={save_config,_} -> {FWReturn,TSReturn,[SaveCfg1|lists:keydelete(save_config,1, EndConf1)]}; - {fail,ReasonToFail} -> % user has failed the testcase + {fail,ReasonToFail} -> + %% user has failed the testcase fw_error_notify(Mod, Func, EndConf1, ReasonToFail), {{error,ReasonToFail},{failed,ReasonToFail},EndConf1}; - {failed,{_,end_per_testcase,_}} = Failure -> % unexpected termination + {failed,{_,end_per_testcase,_}} = Failure when FWReturn == ok -> + %% unexpected termination in end_per_testcase + %% report this as the result to the framework {Failure,TSReturn,EndConf1}; _ -> + %% test case result should be reported to framework + %% no matter the status of end_per_testcase {FWReturn,TSReturn,EndConf1} end, %% clear current state in controller loop -- cgit v1.2.3 From c7d6fa638a635a9abc7c2f10071f755032ba3617 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 22 Sep 2011 18:48:56 +0200 Subject: Fix problem with location value when init config func calls help func --- lib/test_server/src/test_server.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 303ee3ae95..e1a139af6f 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -1235,7 +1235,7 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> %% call user callback function if defined Return1 = user_callback(TCCallback, Mod, Func, 'end', Return), {Return2,Opts} = process_return_val([Return1], Mod, Func, - Args1, Loc, Return1), + Args1, {Mod,Func}, Return1), {{T,Return2},Loc,Opts} end. -- cgit v1.2.3 From 26550631bf825d738bd8c20c9fdb600e9867d81f Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Tue, 27 Sep 2011 01:24:12 +0200 Subject: Fix problem with test_server_ctrl creating invalid conf test OTP-9584 --- lib/test_server/src/test_server_ctrl.erl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 7554a31530..4fad86d16d 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -2039,6 +2039,21 @@ add_init_and_end_per_suite([{skip_case,{conf,_,{Mod,_},_}}=Case|Cases], LastMod, PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)]; add_init_and_end_per_suite([{skip_case,_}=Case|Cases], LastMod, LastRef, FwMod) -> [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)]; +add_init_and_end_per_suite([{conf,Ref,Props,{FwMod,Func}}=Case|Cases], LastMod, + LastRef, FwMod) -> + %% if Mod == FwMod, this conf test is (probably) a test case group where + %% the init- and end-functions are missing in the suite, and if so, + %% the suite name should be stored as {suite,Suite} in Props + case proplists:get_value(suite, Props) of + Suite when Suite =/= undefined, Suite =/= LastMod -> + {PreCases, NextMod, NextRef} = + do_add_init_and_end_per_suite(LastMod, LastRef, Suite), + Case1 = {conf,Ref,proplists:delete(suite,Props),{FwMod,Func}}, + PreCases ++ [Case1|add_init_and_end_per_suite(Cases, NextMod, + NextRef, FwMod)]; + _ -> + [Case|add_init_and_end_per_suite(Cases, LastMod, LastRef, FwMod)] + end; add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod, LastRef, FwMod) when Mod =/= LastMod, Mod =/= FwMod -> {PreCases, NextMod, NextRef} = -- cgit v1.2.3 From b7f1a0861daa57db115b358927293d98e1630810 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 28 Sep 2011 17:43:26 +0200 Subject: Add missing tests for timetrap handling and fix remaining errors OTP-9593 --- lib/test_server/src/test_server.erl | 61 +++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 19 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index e1a139af6f..12625e3c00 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -1921,30 +1921,53 @@ time_ms({seconds,N}) -> seconds(N); time_ms({Other,_N}) -> format("=== ERROR: Invalid time specification: ~p. " "Should be seconds, minutes, or hours.~n", [Other]), - exit({invalid_time_spec,Other}); + exit({invalid_time_format,Other}); time_ms(Ms) when is_integer(Ms) -> Ms; time_ms(infinity) -> infinity; time_ms(Fun) when is_function(Fun) -> - try Fun() of - Val -> time_ms1(Val) - catch - _:Error -> - exit({timetrap_error,Error}) - end; -time_ms({M,F,A}) when is_atom(M), is_atom(F), is_list(A) -> - try apply(M, F, A) of - Val -> time_ms1(Val) - catch - _:Error -> + time_ms_apply(Fun); +time_ms({M,F,A}=MFA) when is_atom(M), is_atom(F), is_list(A) -> + time_ms_apply(MFA); +time_ms(Other) -> exit({invalid_time_format,Other}). + +time_ms_apply(Func) -> + time_ms_apply(Func, [5000,30000,60000,infinity]). + +time_ms_apply(Func, TOs) -> + Apply = fun() -> + case Func of + {M,F,A} -> + exit({self(),apply(M, F, A)}); + Fun -> + exit({self(),Fun()}) + end + end, + Pid = spawn(Apply), + Ref = monitor(process, Pid), + time_ms_wait(Func, Pid, Ref, TOs). + +time_ms_wait(Func, Pid, Ref, [TO|TOs]) -> + receive + {'DOWN',Ref,process,Pid,{Pid,Result}} -> + time_ms_check(Result); + {'DOWN',Ref,process,Pid,Error} -> exit({timetrap_error,Error}) + after + TO -> + format("=== WARNING: No return from timetrap function ~p~n", [Func]), + time_ms_wait(Func, Pid, Ref, TOs) end; -time_ms(Other) -> exit({invalid_time_spec,Other}). - -time_ms1(MFA = {M,F,A}) when is_atom(M), is_atom(F), is_list(A) -> - exit({invalid_time_spec,MFA}); -time_ms1(Fun) when is_function(Fun) -> - exit({invalid_time_spec,Fun}); -time_ms1(Other) -> +%% this clause will never execute if 'infinity' is in TOs list, that's ok! +time_ms_wait(Func, Pid, Ref, []) -> + demonitor(Ref), + exit(Pid, kill), + exit({timetrap_error,{no_return_from_timetrap_function,Func}}). + +time_ms_check(MFA = {M,F,A}) when is_atom(M), is_atom(F), is_list(A) -> + exit({invalid_time_format,MFA}); +time_ms_check(Fun) when is_function(Fun) -> + exit({invalid_time_format,Fun}); +time_ms_check(Other) -> time_ms(Other). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From 345992c1e82eb2e876139248cc50eb4df029a5f5 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 29 Sep 2011 17:06:25 +0200 Subject: Create temporary fix for problem with parallel test cases OTP-9600 --- lib/test_server/src/test_server.erl | 40 ++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'lib/test_server/src') diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 12625e3c00..244207e140 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -749,7 +749,8 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) -> {read_comment,From} -> From ! {self(),read_comment,Comment}, run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,CurrConf); - {set_curr_conf,NewCurrConf} -> + {set_curr_conf,From,NewCurrConf} -> + From ! {self(),set_curr_conf,ok}, run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,Comment,NewCurrConf); {'EXIT',Pid,{Ref,Time,Value,Loc,Opts}} -> RetVal = {Time/1000000,Value,mod_loc(Loc),Opts,Comment}, @@ -973,10 +974,19 @@ spawn_fw_call(Mod,{init_per_testcase,Func},_,Pid,{timetrap_timeout,TVal}=Why, spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid, {timetrap_timeout,TVal}=Why,_Loc,SendTo,Comment) -> + %%! This is a temporary fix that keeps Test Server alive during + %%! execution of a parallel test case group, when sometimes + %%! this clause gets called with EndConf == undefined. See OTP-9594 + %%! for more info. + EndConf1 = if EndConf == undefined -> + [{tc_status,{failed,{Mod,end_per_testcase,Why}}}]; + true -> + EndConf + end, FwCall = fun() -> {RetVal,Report} = - case proplists:get_value(tc_status, EndConf) of + case proplists:get_value(tc_status, EndConf1) of undefined -> E = {failed,{Mod,end_per_testcase,Why}}, {E,E}; @@ -986,9 +996,9 @@ spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid, E = {failed,{Mod,end_per_testcase,Why}}, {Result,E} end, - FailLoc = proplists:get_value(tc_fail_loc, EndConf), + FailLoc = proplists:get_value(tc_fail_loc, EndConf1), case catch do_end_tc_call(Mod,Func, FailLoc, - {Pid,Report,[EndConf]}, Why) of + {Pid,Report,[EndConf1]}, Why) of {'EXIT',FwEndTCErr} -> exit({fw_notify_done,end_tc,FwEndTCErr}); _ -> @@ -1160,7 +1170,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> %% call user callback function if defined NewConf1 = user_callback(TCCallback, Mod, Func, init, NewConf), %% save current state in controller loop - group_leader() ! {set_curr_conf,{{Mod,Func},NewConf1}}, + sync_send(group_leader(),set_curr_conf,{{Mod,Func},NewConf1}, + 5000, fun() -> exit(no_answer_from_group_leader) end), put(test_server_loc, {Mod,Func}), %% execute the test case {{T,Return},Loc} = {ts_tc(Mod, Func, [NewConf1]),get_loc()}, @@ -1188,7 +1199,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 - group_leader() ! {set_curr_conf,EndConf1}, + 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,_} -> @@ -1208,7 +1220,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) -> {FWReturn,TSReturn,EndConf1} end, %% clear current state in controller loop - group_leader() ! {set_curr_conf,undefined}, + sync_send(group_leader(),set_curr_conf,undefined, + 5000, fun() -> exit(no_answer_from_group_leader) end), put(test_server_init_or_end_conf,undefined), case do_end_tc_call(Mod,Func, Loc, {FWReturn1,[EndConf2]}, TSReturn1) of @@ -2016,6 +2029,19 @@ hours(N) -> trunc(N * 1000 * 60 * 60). minutes(N) -> trunc(N * 1000 * 60). seconds(N) -> trunc(N * 1000). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% sync_send(Pid,Tag,Msg,Timeout,DoAfter) -> Result +%% +sync_send(Pid,Tag,Msg,Timeout,DoAfter) -> + Pid ! {Tag,self(),Msg}, + receive + {Pid,Tag,Result} -> + Result + after Timeout -> + DoAfter() + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% timecall(M,F,A) -> {Time,Val} %% Time = float() -- cgit v1.2.3