aboutsummaryrefslogtreecommitdiffstats
path: root/lib/test_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/test_server/src')
-rw-r--r--lib/test_server/src/configure.in57
-rw-r--r--lib/test_server/src/erl2html2.erl1
-rw-r--r--lib/test_server/src/test_server.erl47
-rw-r--r--lib/test_server/src/test_server_ctrl.erl428
-rw-r--r--lib/test_server/src/test_server_node.erl31
-rw-r--r--lib/test_server/src/ts.erl94
-rw-r--r--lib/test_server/src/ts.unix.config2
-rw-r--r--lib/test_server/src/ts_erl_config.erl58
-rw-r--r--lib/test_server/src/ts_install.erl14
-rw-r--r--lib/test_server/src/ts_lib.erl5
-rw-r--r--lib/test_server/src/ts_make.erl6
-rw-r--r--lib/test_server/src/ts_run.erl6
12 files changed, 554 insertions, 195 deletions
diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in
index 3815027721..067663feb4 100644
--- a/lib/test_server/src/configure.in
+++ b/lib/test_server/src/configure.in
@@ -38,6 +38,35 @@ AC_ARG_ENABLE(debug-mode,
*) CFLAGS=$DEBUG_FLAGS ;;
esac ], )
+AC_ARG_ENABLE(m64-build,
+AS_HELP_STRING([--enable-m64-build],
+ [build 64-bit binaries using the -m64 flag to (g)cc]),
+[ case "$enableval" in
+ no) enable_m64_build=no ;;
+ *) enable_m64_build=yes ;;
+ esac
+],enable_m64_build=no)
+
+AC_ARG_ENABLE(m32-build,
+AS_HELP_STRING([--enable-m32-build],
+ [build 32-bit binaries using the -m32 flag to (g)cc]),
+[ case "$enableval" in
+ no) enable_m32_build=no ;;
+ *) enable_m32_build=yes ;;
+ esac
+],enable_m32_build=no)
+
+no_mXX_LDFLAGS="$LDFLAGS"
+
+if test X${enable_m64_build} = Xyes; then
+ CFLAGS="-m64 $CFLAGS"
+ LDFLAGS="-m64 $LDFLAGS"
+fi
+if test X${enable_m32_build} = Xyes; then
+ CFLAGS="-m32 $CFLAGS"
+ LDFLAGS="-m32 $LDFLAGS"
+fi
+
AC_CHECK_LIB(m, sin)
#--------------------------------------------------------------------
@@ -132,6 +161,12 @@ case $system in
AC_CHECK_HEADER(dld.h, [
SHLIB_LD="ld"
SHLIB_LDFLAGS="-shared"])
+ if test X${enable_m64_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 64-bit dynamic drivers)
+ fi
+ if test X${enable_m32_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers)
+ fi
fi
SHLIB_EXTRACT_ALL=""
;;
@@ -142,11 +177,17 @@ case $system in
SHLIB_LD="ld"
SHLIB_LDFLAGS="$LDFLAGS -Bshareable -x"
SHLIB_SUFFIX=".so"
+ if test X${enable_m64_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 64-bit dynamic drivers)
+ fi
+ if test X${enable_m32_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers)
+ fi
], [
# No dynamic loading.
SHLIB_CFLAGS=""
SHLIB_LD="ld"
- SHLIB_LDFLAGS="$LDFLAGS"
+ SHLIB_LDFLAGS=""
SHLIB_SUFFIX=""
AC_MSG_ERROR(don't know how to compile and link dynamic drivers)
])
@@ -155,7 +196,13 @@ case $system in
*-solaris2*|*-sysv4*)
SHLIB_CFLAGS="-KPIC"
SHLIB_LD="/usr/ccs/bin/ld"
- SHLIB_LDFLAGS="$LDFLAGS -G -z text"
+ SHLIB_LDFLAGS="$no_mXX_LDFLAGS -G -z text"
+ if test X${enable_m64_build} = Xyes; then
+ SHLIB_LDFLAGS="-64 $SHLIB_LDFLAGS"
+ fi
+ if test X${enable_m32_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers)
+ fi
SHLIB_SUFFIX=".so"
SHLIB_EXTRACT_ALL="-z allextract"
;;
@@ -170,6 +217,12 @@ case $system in
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="ld"
SHLIB_LDFLAGS="$LDFLAGS -shared"
+ if test X${enable_m64_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 64-bit dynamic drivers)
+ fi
+ if test X${enable_m32_build} = Xyes; then
+ AC_MSG_ERROR(don't know how to link 32-bit dynamic drivers)
+ fi
SHLIB_SUFFIX=".so"
SHLIB_EXTRACT_ALL=""
;;
diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl
index d0f40c47a7..952036502a 100644
--- a/lib/test_server/src/erl2html2.erl
+++ b/lib/test_server/src/erl2html2.erl
@@ -1,4 +1,3 @@
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 6ddb2b615f..bc83739ba6 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -405,6 +405,7 @@ run_test_case_apply({CaseNum,Mod,Func,Args,Name,
ref :: reference(),
pid :: pid(),
mf :: {atom(),atom()},
+ last_known_loc :: term(),
status :: tc_status() | 'undefined',
ret_val :: term(),
comment :: list(char()),
@@ -436,8 +437,9 @@ run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) ->
LogOpts, TCCallback)
end),
put(test_server_detected_fail, []),
- St = #st{ref=Ref,pid=Pid,mf={Mod,Func},status=starting,ret_val=[],
- comment="",timeout=infinity,config=hd(Args)},
+ St = #st{ref=Ref,pid=Pid,mf={Mod,Func},last_known_loc=unknown,
+ status=starting,ret_val=[],comment="",timeout=infinity,
+ config=hd(Args)},
run_test_case_msgloop(St).
%% Ugly bug (pre R5A):
@@ -537,7 +539,22 @@ run_test_case_msgloop(#st{ref=Ref,pid=Pid,end_conf_pid=EndConfPid0}=St0) ->
St = setup_termination(RetVal, St0#st{config=undefined}),
run_test_case_msgloop(St);
{'EXIT',Pid,Reason} ->
- St = handle_tc_exit(Reason, St0),
+ %% This exit typically happens when an unknown external process
+ %% has caused a test case process to terminate (e.g. if a linked
+ %% process has crashed).
+ St =
+ case Reason of
+ {What,[Loc0={_M,_F,A,[{file,_}|_]}|_]} when
+ is_integer(A) ->
+ Loc = rewrite_loc_item(Loc0),
+ handle_tc_exit(What, St0#st{last_known_loc=[Loc]});
+ {What,[Details,Loc0={_M,_F,A,[{file,_}|_]}|_]} when
+ is_integer(A) ->
+ Loc = rewrite_loc_item(Loc0),
+ handle_tc_exit({What,Details}, St0#st{last_known_loc=[Loc]});
+ _ ->
+ handle_tc_exit(Reason, St0)
+ end,
run_test_case_msgloop(St);
{EndConfPid0,{call_end_conf,Data,_Result}} ->
#st{mf={Mod,Func},config=CurrConf} = St0,
@@ -695,7 +712,7 @@ handle_tc_exit(Reason, #st{config=Config,mf={Mod,Func0},pid=Pid,
{testcase_aborted=E,AbortReason,Loc0} ->
{{E,AbortReason},Loc0};
Other ->
- {Other,unknown}
+ {Other,St#st.last_known_loc}
end,
Func = case Status of
init_per_testcase=F -> {F,Func0};
@@ -837,9 +854,13 @@ spawn_fw_call(FwMod,FwFunc,_,_Pid,{framework_error,FwError},_,SendTo) ->
spawn_link(FwCall);
spawn_fw_call(Mod,Func,CurrConf,Pid,Error,Loc,SendTo) ->
+ Func1 = case Func of
+ {_InitOrEndPerTC,F} -> F;
+ F -> F
+ end,
FwCall =
fun() ->
- case catch fw_error_notify(Mod,Func,[],
+ case catch fw_error_notify(Mod,Func1,[],
Error,Loc) of
{'EXIT',FwErrorNotifyErr} ->
exit({fw_notify_done,error_notification,
@@ -847,8 +868,8 @@ spawn_fw_call(Mod,Func,CurrConf,Pid,Error,Loc,SendTo) ->
_ ->
ok
end,
- Conf = [{tc_status,{failed,timetrap_timeout}}|CurrConf],
- case catch do_end_tc_call(Mod,Func,
+ Conf = [{tc_status,{failed,Error}}|CurrConf],
+ case catch do_end_tc_call(Mod,Func1,
{Pid,Error,[Conf]},Error) of
{'EXIT',FwEndTCErr} ->
exit({fw_notify_done,end_tc,FwEndTCErr});
@@ -915,6 +936,7 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
put(test_server_logopts, LogOpts),
Where = [{Mod,Func}],
put(test_server_loc, Where),
+
FWInitResult = test_server_sup:framework_call(init_tc,[Mod,Func,Args0],
{ok,Args0}),
set_tc_state(running),
@@ -924,7 +946,7 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback);
Error = {error,_Reason} ->
NewResult = do_end_tc_call(Mod,Func, {Error,Args0},
- {skip,{failed,Error}}),
+ {auto_skip,{failed,Error}}),
{{0,NewResult},Where,[]};
{fail,Reason} ->
Conf = [{tc_status,{failed,Reason}} | hd(Args0)],
@@ -935,9 +957,9 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
Skip = {skip,_Reason} ->
NewResult = do_end_tc_call(Mod,Func, {Skip,Args0}, Skip),
{{0,NewResult},Where,[]};
- {auto_skip,Reason} ->
- NewResult = do_end_tc_call(Mod,Func, {{skip,Reason},Args0},
- {skip,Reason}),
+ AutoSkip = {auto_skip,_Reason} ->
+ %% special case where a conf case "pretends" to be skipped
+ NewResult = do_end_tc_call(Mod,Func, {AutoSkip,Args0}, AutoSkip),
{{0,NewResult},Where,[]}
end,
exit({Ref,Time,Value,Loc,Opts}).
@@ -955,7 +977,8 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
{{0,NewRes},Line,[]};
{skip_and_save,Reason,SaveCfg} ->
Line = get_loc(),
- Conf = [{tc_status,{skipped,Reason}},{save_config,SaveCfg}|hd(Args)],
+ Conf = [{tc_status,{skipped,Reason}},
+ {save_config,SaveCfg}|hd(Args)],
NewRes = do_end_tc_call(Mod,Func, {{skip,Reason},[Conf]},
{skip,Reason}),
{{0,NewRes},Line,[]};
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index d0f31af198..e24d6ceacb 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -1161,8 +1161,11 @@ init_tester(Mod, Func, Args, Dir, Name, {_,_,MinLev}=Levels,
end,
{SkippedN,SkipStr} =
case get(test_server_skipped) of
- {0,_} -> {0,""};
- {Skipped,_} -> {Skipped,io_lib:format(", ~w Skipped", [Skipped])}
+ {0,0} ->
+ {0,""};
+ {USkipped,ASkipped} ->
+ Skipped = USkipped+ASkipped,
+ {Skipped,io_lib:format(", ~w Skipped", [Skipped])}
end,
OkN = get(test_server_ok),
FailedN = get(test_server_failed),
@@ -1402,10 +1405,23 @@ remove_conf([{conf, _Ref, Props, _MF}|Cases], NoConf, Repeats) ->
end;
remove_conf([{make,_Ref,_MF}|Cases], NoConf, Repeats) ->
remove_conf(Cases, NoConf, Repeats);
+remove_conf([{skip_case,{{_M,all},_Cmt}}|Cases], NoConf, Repeats) ->
+ remove_conf(Cases, NoConf, Repeats);
remove_conf([{skip_case,{Type,_Ref,_MF,_Cmt}}|Cases],
NoConf, Repeats) when Type==conf;
Type==make ->
remove_conf(Cases, NoConf, Repeats);
+remove_conf([{skip_case,{Type,_Ref,_MF,_Cmt},_Mode}|Cases],
+ NoConf, Repeats) when Type==conf;
+ Type==make ->
+ remove_conf(Cases, NoConf, Repeats);
+remove_conf([C={Mod,error_in_suite,_}|Cases], NoConf, Repeats) ->
+ FwMod = get_fw_mod(?MODULE),
+ if Mod == FwMod ->
+ remove_conf(Cases, NoConf, Repeats);
+ true ->
+ remove_conf(Cases, [C|NoConf], Repeats)
+ end;
remove_conf([C|Cases], NoConf, Repeats) ->
remove_conf(Cases, [C|NoConf], Repeats);
remove_conf([], NoConf, true) ->
@@ -1413,6 +1429,11 @@ remove_conf([], NoConf, true) ->
remove_conf([], NoConf, false) ->
lists:reverse(NoConf).
+get_suites([{skip_case,{{Mod,_Func},_Cmt}}|Tests], Mods) when is_atom(Mod) ->
+ case add_mod(Mod, Mods) of
+ true -> get_suites(Tests, [Mod|Mods]);
+ false -> get_suites(Tests, Mods)
+ end;
get_suites([{Mod,_Case}|Tests], Mods) when is_atom(Mod) ->
case add_mod(Mod, Mods) of
true -> get_suites(Tests, [Mod|Mods]);
@@ -1478,8 +1499,10 @@ do_test_cases(TopCases, SkipCases,
end,
put(test_server_cases, N),
put(test_server_case_num, 0),
+
TestSpec =
add_init_and_end_per_suite(TestSpec0, undefined, undefined, FwMod),
+
TI = get_target_info(),
print(1, "Starting test~ts",
[print_if_known(N, {", ~w test cases",[N]},
@@ -1795,23 +1818,40 @@ downcase([], Result) ->
%%
%% Errors are silently ignored.
-html_convert_modules(TestSpec, _Config) ->
- Mods = html_isolate_modules(TestSpec),
+html_convert_modules(TestSpec, _Config, FwMod) ->
+ Mods = html_isolate_modules(TestSpec, FwMod),
html_convert_modules(Mods),
copy_html_files(get(test_server_dir), get(test_server_log_dir_base)).
%% Retrieve a list of modules out of the test spec.
-html_isolate_modules(List) -> html_isolate_modules(List, sets:new()).
-
-html_isolate_modules([], Set) -> sets:to_list(Set);
-html_isolate_modules([{skip_case,_}|Cases], Set) ->
- html_isolate_modules(Cases, Set);
-html_isolate_modules([{conf,_Ref,_Props,{Mod,_Func}}|Cases], Set) ->
- html_isolate_modules(Cases, sets:add_element(Mod, Set));
-html_isolate_modules([{Mod,_Case}|Cases], Set) ->
- html_isolate_modules(Cases, sets:add_element(Mod, Set));
-html_isolate_modules([{Mod,_Case,_Args}|Cases], Set) ->
- html_isolate_modules(Cases, sets:add_element(Mod, Set)).
+html_isolate_modules(List, FwMod) ->
+ html_isolate_modules(List, sets:new(), FwMod).
+
+html_isolate_modules([], Set, _) -> sets:to_list(Set);
+html_isolate_modules([{skip_case,_}|Cases], Set, FwMod) ->
+ html_isolate_modules(Cases, Set, FwMod);
+html_isolate_modules([{conf,_Ref,Props,{FwMod,_Func}}|Cases], Set, FwMod) ->
+ Set1 = case proplists:get_value(suite, Props) of
+ undefined -> Set;
+ Mod -> sets:add_element(Mod, Set)
+ end,
+ html_isolate_modules(Cases, Set1, FwMod);
+html_isolate_modules([{conf,_Ref,_Props,{Mod,_Func}}|Cases], Set, FwMod) ->
+ html_isolate_modules(Cases, sets:add_element(Mod, Set), FwMod);
+html_isolate_modules([{skip_case,{conf,_Ref,{FwMod,_Func},_Cmt},Mode}|Cases],
+ Set, FwMod) ->
+ Set1 = case proplists:get_value(suite, get_props(Mode)) of
+ undefined -> Set;
+ Mod -> sets:add_element(Mod, Set)
+ end,
+ html_isolate_modules(Cases, Set1, FwMod);
+html_isolate_modules([{skip_case,{conf,_Ref,{Mod,_Func},_Cmt},_Props}|Cases],
+ Set, FwMod) ->
+ html_isolate_modules(Cases, sets:add_element(Mod, Set), FwMod);
+html_isolate_modules([{Mod,_Case}|Cases], Set, FwMod) ->
+ html_isolate_modules(Cases, sets:add_element(Mod, Set), FwMod);
+html_isolate_modules([{Mod,_Case,_Args}|Cases], Set, FwMod) ->
+ html_isolate_modules(Cases, sets:add_element(Mod, Set), FwMod).
%% Given a list of modules, convert each module's source code to HTML.
html_convert_modules([Mod|Mods]) ->
@@ -1902,13 +1942,16 @@ add_init_and_end_per_suite([{skip_case,{{Mod,_},_}}=Case|Cases], LastMod,
{PreCases, NextMod, NextRef} =
do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod),
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, FwMod),
+ 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, FwMod),
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
@@ -1918,7 +1961,8 @@ add_init_and_end_per_suite([{conf,Ref,Props,{FwMod,Func}}=Case|Cases], LastMod,
Suite when Suite =/= undefined, Suite =/= LastMod ->
{PreCases, NextMod, NextRef} =
do_add_init_and_end_per_suite(LastMod, LastRef, Suite, FwMod),
- Case1 = {conf,Ref,proplists:delete(suite,Props),{FwMod,Func}},
+ Case1 = {conf,Ref,[{suite,NextMod}|proplists:delete(suite,Props)],
+ {FwMod,Func}},
PreCases ++ [Case1|add_init_and_end_per_suite(Cases, NextMod,
NextRef, FwMod)];
_ ->
@@ -1929,6 +1973,9 @@ add_init_and_end_per_suite([{conf,_,_,{Mod,_}}=Case|Cases], LastMod,
{PreCases, NextMod, NextRef} =
do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod),
PreCases ++ [Case|add_init_and_end_per_suite(Cases, NextMod, NextRef, FwMod)];
+add_init_and_end_per_suite([SkipCase|Cases], LastMod, LastRef, FwMod)
+ when element(1,SkipCase) == skip_case ->
+ [SkipCase|add_init_and_end_per_suite(Cases, LastMod, LastRef, 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)
@@ -2043,7 +2090,8 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
true ->
ok;
false ->
- html_convert_modules(TestSpec, Config)
+ FwMod = get_fw_mod(?MODULE),
+ html_convert_modules(TestSpec, Config, FwMod)
end,
run_test_cases_loop(TestSpec, [Config], TimetrapData, [], []),
@@ -2209,34 +2257,50 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
%% group1_end | --->
%%
-run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
- Config, TimetrapData, Mode, Status) when Type==conf;
- Type==make ->
+run_test_cases_loop([{SkipTag,CaseData={Type,_Ref,_Case,_Comment}}|Cases],
+ Config, TimetrapData, Mode, Status) when
+ ((SkipTag==auto_skip_case) or (SkipTag==skip_case)) and
+ ((Type==conf) or (Type==make)) ->
+ run_test_cases_loop([{SkipTag,CaseData,Mode}|Cases],
+ Config, TimetrapData, Mode, Status);
+
+run_test_cases_loop([{SkipTag,{Type,Ref,Case,Comment},SkipMode}|Cases],
+ Config, TimetrapData, Mode, Status) when
+ ((SkipTag==auto_skip_case) or (SkipTag==skip_case)) and
+ ((Type==conf) or (Type==make)) ->
file:set_cwd(filename:dirname(get(test_server_dir))),
CurrIOHandler = get(test_server_common_io_handler),
ParentMode = tl(Mode),
+ {AutoOrUser,ReportTag} =
+ if SkipTag == auto_skip_case -> {auto,tc_auto_skip};
+ SkipTag == skip_case -> {user,tc_user_skip}
+ end,
+
%% check and update the mode for test case execution and io msg handling
case {curr_ref(Mode),check_props(parallel, Mode)} of
{Ref,Ref} ->
case check_props(parallel, ParentMode) of
false ->
- %% this is a skipped end conf for a top level parallel group,
- %% buffered io can be flushed
+ %% this is a skipped end conf for a top level parallel
+ %% group, buffered io can be flushed
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,
- {Mod,Func,Comment}]),
+ {Mod,Func} = skip_case(AutoOrUser, Ref, 0, Case, Comment,
+ false, SkipMode),
+ ConfData = {Mod,{Func,get_name(SkipMode)},Comment},
+ test_server_sup:framework_call(report,
+ [ReportTag,ConfData]),
run_test_cases_loop(Cases, Config, TimetrapData, ParentMode,
delete_status(Ref, Status));
_ ->
- %% this is a skipped end conf for a parallel group nested under a
- %% parallel group (io buffering is active)
+ %% this is a skipped end conf for a parallel group nested
+ %% under a 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,
- {Mod,Func,Comment}]),
+ {Mod,Func} = skip_case(AutoOrUser, Ref, 0, Case, Comment,
+ true, SkipMode),
+ ConfData = {Mod,{Func,get_name(SkipMode)},Comment},
+ test_server_sup:framework_call(report, [ReportTag,ConfData]),
case CurrIOHandler of
{Ref,_} ->
%% current_io_handler was set by start conf of this
@@ -2246,18 +2310,21 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
_ ->
ok
end,
- run_test_cases_loop(Cases, Config, TimetrapData, ParentMode,
+ run_test_cases_loop(Cases, Config,
+ TimetrapData, ParentMode,
delete_status(Ref, Status))
end;
{Ref,false} ->
%% this is a skipped end conf for a non-parallel group that's not
%% nested under a parallel group
- {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, false, SkipMode),
- test_server_sup:framework_call(report, [tc_auto_skip,{Mod,Func,Comment}]),
-
- %% Check if this group is auto skipped because of error in the init conf.
- %% If so, check if the parent group is a sequence, and if it is, skip
- %% all proceeding tests in that group.
+ {Mod,Func} = skip_case(AutoOrUser, Ref, 0, Case, Comment,
+ false, SkipMode),
+ ConfData = {Mod,{Func,get_name(SkipMode)},Comment},
+ test_server_sup:framework_call(report, [ReportTag,ConfData]),
+
+ %% Check if this group is auto skipped because of error in the
+ %% init conf. If so, check if the parent group is a sequence,
+ %% and if it is, skip all proceeding tests in that group.
GrName = get_name(Mode),
Cases1 =
case get_tc_results(Status) of
@@ -2270,7 +2337,8 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
ParentRef ->
Reason = {group_result,GrName,failed},
skip_cases_upto(ParentRef, Cases,
- Reason, tc, Mode)
+ Reason, tc, Mode,
+ SkipTag)
end;
false ->
Cases
@@ -2283,8 +2351,10 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
{Ref,_} ->
%% this is a skipped end conf for a non-parallel group nested under
%% a parallel group (io buffering is active)
- {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, true, SkipMode),
- test_server_sup:framework_call(report, [tc_auto_skip,{Mod,Func,Comment}]),
+ {Mod,Func} = skip_case(AutoOrUser, Ref, 0, Case, Comment,
+ true, SkipMode),
+ ConfData = {Mod,{Func,get_name(SkipMode)},Comment},
+ test_server_sup:framework_call(report, [ReportTag,ConfData]),
case CurrIOHandler of
{Ref,_} ->
%% current_io_handler was set by start conf of this
@@ -2299,20 +2369,27 @@ run_test_cases_loop([{auto_skip_case,{Type,Ref,Case,Comment},SkipMode}|Cases],
{_,false} ->
%% this is a skipped start conf for a group which is not nested
%% under a parallel group
- {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, false, SkipMode),
- test_server_sup:framework_call(report, [tc_auto_skip,{Mod,Func,Comment}]),
- run_test_cases_loop(Cases, Config, TimetrapData, [conf(Ref,[])|Mode], Status);
+ {Mod,Func} = skip_case(AutoOrUser, Ref, 0, Case, Comment,
+ false, SkipMode),
+ ConfData = {Mod,{Func,get_name(SkipMode)},Comment},
+ test_server_sup:framework_call(report, [ReportTag,ConfData]),
+ run_test_cases_loop(Cases, Config, TimetrapData,
+ [conf(Ref,[])|Mode], Status);
{_,Ref0} when is_reference(Ref0) ->
- %% this is a skipped start conf for a group nested under a parallel group
- %% and if this is the first nested group, io buffering must be activated
+ %% this is a skipped start conf for a group nested under a parallel
+ %% group and if this is the first nested group, io buffering must
+ %% be activated
if CurrIOHandler == undefined ->
set_io_buffering({Ref,self()});
true ->
ok
end,
- {Mod,Func} = skip_case(auto, Ref, 0, Case, Comment, true, SkipMode),
- test_server_sup:framework_call(report, [tc_auto_skip,{Mod,Func,Comment}]),
- run_test_cases_loop(Cases, Config, TimetrapData, [conf(Ref,[])|Mode], Status)
+ {Mod,Func} = skip_case(AutoOrUser, Ref, 0, Case, Comment,
+ true, SkipMode),
+ ConfData = {Mod,{Func,get_name(SkipMode)},Comment},
+ test_server_sup:framework_call(report, [ReportTag,ConfData]),
+ run_test_cases_loop(Cases, Config, TimetrapData,
+ [conf(Ref,[])|Mode], Status)
end;
run_test_cases_loop([{auto_skip_case,{Case,Comment},SkipMode}|Cases],
@@ -2323,21 +2400,12 @@ run_test_cases_loop([{auto_skip_case,{Case,Comment},SkipMode}|Cases],
run_test_cases_loop(Cases, Config, TimetrapData, Mode,
update_status(skipped, Mod, Func, Status));
-run_test_cases_loop([{skip_case,{conf,Ref,Case,Comment}}|Cases0],
+run_test_cases_loop([{skip_case,{{Mod,all}=Case,Comment}}|Cases],
Config, TimetrapData, Mode, Status) ->
- {Mod,Func} = skip_case(user, Ref, 0, Case, Comment, is_io_buffered()),
- {Cases,Config1} =
- case curr_ref(Mode) of
- Ref ->
- %% skipped end conf
- {Cases0,tl(Config)};
- _ ->
- %% skipped start conf
- {skip_cases_upto(Ref, Cases0, Comment, conf, Mode),Config}
- end,
- test_server_sup:framework_call(report, [tc_user_skip,{Mod,Func,Comment}]),
- run_test_cases_loop(Cases, Config1, TimetrapData, Mode,
- update_status(skipped, Mod, Func, Status));
+ skip_case(user, undefined, 0, Case, Comment, false, Mode),
+ test_server_sup:framework_call(report, [tc_user_skip,
+ {Mod,all,Comment}]),
+ run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status);
run_test_cases_loop([{skip_case,{Case,Comment}}|Cases],
Config, TimetrapData, Mode, Status) ->
@@ -2597,7 +2665,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
"~n*** ~w returned bad elements in Config: ~p.~n",
[Func,Bad]),
Reason = {failed,{Mod,init_per_suite,bad_return}},
- Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
+ Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode,
+ auto_skip_case),
set_io_buffering(IOHandler),
stop_minor_log_file(),
run_test_cases_loop(Cases2, Config, TimetrapData, Mode,
@@ -2623,7 +2692,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
print(minor, "~n*** ~w failed.~n"
" Skipping all cases.", [Func]),
Reason = {failed,{Mod,Func,Fail}},
- {skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
+ {skip_cases_upto(Ref, Cases, Reason, conf, CurrMode,
+ auto_skip_case),
Config,
update_status(failed, group_result, get_name(Mode),
delete_status(Ref, Status2))};
@@ -2635,14 +2705,37 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
set_io_buffering(IOHandler),
stop_minor_log_file(),
run_test_cases_loop(Cases2, Config1, TimetrapData, Mode, Status3);
+
+ {_,{auto_skip,SkipReason},_} ->
+ %% this case can only happen if the framework (not the user)
+ %% decides to skip execution of a conf function
+ {Cases2,Config1,Status3} =
+ if StartConf ->
+ ReportAbortRepeat(auto_skipped),
+ print(minor, "~n*** ~w auto skipped.~n"
+ " Skipping all cases.", [Func]),
+ {skip_cases_upto(Ref, Cases, SkipReason, conf, CurrMode,
+ auto_skip_case),
+ Config,
+ delete_status(Ref, Status2)};
+ not StartConf ->
+ ReportRepeatStop(),
+ print_conf_time(ConfTime),
+ {Cases,tl(Config),delete_status(Ref, Status2)}
+ end,
+ set_io_buffering(IOHandler),
+ stop_minor_log_file(),
+ run_test_cases_loop(Cases2, Config1, TimetrapData, Mode, Status3);
+
{_,{Skip,Reason},_} when StartConf and ((Skip==skip) or (Skip==skipped)) ->
ReportAbortRepeat(skipped),
print(minor, "~n*** ~w skipped.~n"
" Skipping all cases.", [Func]),
set_io_buffering(IOHandler),
stop_minor_log_file(),
- run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
- Config, TimetrapData, Mode,
+ run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf,
+ CurrMode, skip_case),
+ [hd(Config)|Config], TimetrapData, Mode,
delete_status(Ref, Status2));
{_,{skip_and_save,Reason,_SavedConfig},_} when StartConf ->
ReportAbortRepeat(skipped),
@@ -2650,13 +2743,15 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
" Skipping all cases.", [Func]),
set_io_buffering(IOHandler),
stop_minor_log_file(),
- run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
- Config, TimetrapData, Mode,
+ run_test_cases_loop(skip_cases_upto(Ref, Cases, Reason, conf,
+ CurrMode, skip_case),
+ [hd(Config)|Config], TimetrapData, Mode,
delete_status(Ref, Status2));
{_,_Other,_} when Func == init_per_suite ->
print(minor, "~n*** init_per_suite failed to return a Config list.~n", []),
Reason = {failed,{Mod,init_per_suite,bad_return}},
- Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode),
+ Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode,
+ auto_skip_case),
set_io_buffering(IOHandler),
stop_minor_log_file(),
run_test_cases_loop(Cases2, Config, TimetrapData, Mode,
@@ -2668,7 +2763,6 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
stop_minor_log_file(),
run_test_cases_loop(Cases, [hd(Config)|Config], TimetrapData,
Mode, Status2);
-
{_,_EndConfRetVal,Opts} ->
%% Check if return_group_result is set (ok, skipped or failed) and
%% if so:
@@ -2683,7 +2777,8 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
case {curr_ref(Mode),check_prop(sequence, Mode)} of
{ParentRef,ParentRef} ->
Reason = {group_result,GrName,failed},
- {skip_cases_upto(ParentRef, Cases, Reason, tc, Mode),
+ {skip_cases_upto(ParentRef, Cases, Reason, tc,
+ Mode, auto_skip_case),
update_status(failed, group_result, GrName,
delete_status(Ref, Status2))};
_ ->
@@ -2701,16 +2796,19 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
ReportRepeatStop(),
set_io_buffering(IOHandler),
stop_minor_log_file(),
- run_test_cases_loop(Cases2, tl(Config), TimetrapData, Mode, Status3)
+ run_test_cases_loop(Cases2, tl(Config), TimetrapData,
+ Mode, Status3)
end;
-run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, TimetrapData, Mode, Status) ->
+run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, TimetrapData,
+ Mode, Status) ->
case run_test_case(Ref, 0, Mod, Func, Args, skip_init, TimetrapData) of
{_,Why={'EXIT',_},_} ->
print(minor, "~n*** ~w failed.~n"
" Skipping all cases.", [Func]),
Reason = {failed,{Mod,Func,Why}},
- Cases = skip_cases_upto(Ref, Cases0, Reason, conf, Mode),
+ Cases = skip_cases_upto(Ref, Cases0, Reason, conf, Mode,
+ auto_skip_case),
stop_minor_log_file(),
run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status);
{_,_Whatever,_} ->
@@ -2735,7 +2833,14 @@ run_test_cases_loop([{Mod,Case}|Cases], Config, TimetrapData, Mode, Status) ->
TimetrapData, Mode, Status);
run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status) ->
- Num = put(test_server_case_num, get(test_server_case_num)+1),
+ {Num,RunInit} =
+ case FwMod = get_fw_mod(?MODULE) of
+ Mod when Func == error_in_suite ->
+ {-1,skip_init};
+ _ ->
+ {put(test_server_case_num, get(test_server_case_num)+1),
+ run_init}
+ end,
%% check the current execution mode and save info about the case if
%% detected that printouts to common log files is handled later
@@ -2750,7 +2855,7 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
end,
case run_test_case(undefined, Num+1, Mod, Func, Args,
- run_init, TimetrapData, Mode) of
+ RunInit, TimetrapData, Mode) of
%% callback to framework module failed, exit immediately
{_,{framework_error,{FwMod,FwFunc},Reason},_} ->
print(minor, "~n*** ~w failed in ~w. Reason: ~p~n",
@@ -2791,7 +2896,8 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
" Skipping all other cases in sequence.",
[Func]),
Reason = {failed,{Mod,Func}},
- Cases2 = skip_cases_upto(Ref, Cases, Reason, tc, Mode),
+ Cases2 = skip_cases_upto(Ref, Cases, Reason, tc,
+ Mode, auto_skip_case),
stop_minor_log_file(),
run_test_cases_loop(Cases2, Config, TimetrapData, Mode, Status1)
end
@@ -3012,13 +3118,13 @@ cases_to_shuffle(Ref, Cases) ->
cases_to_shuffle(Ref, [{conf,Ref,_,_} | _]=Cs, N, Ix) -> % end
{N-1,Ix,Cs};
-cases_to_shuffle(Ref, [{skip_case,{_,Ref,_,_}} | _]=Cs, N, Ix) -> % end
+cases_to_shuffle(Ref, [{skip_case,{_,Ref,_,_},_} | _]=Cs, N, Ix) -> % end
{N-1,Ix,Cs};
cases_to_shuffle(Ref, [{conf,Ref1,_,_}=C | Cs], N, Ix) -> % nested group
{Cs1,Rest} = get_subcases(Ref1, Cs, []),
cases_to_shuffle(Ref, Rest, N+1, [{N,[C|Cs1]} | Ix]);
-cases_to_shuffle(Ref, [{skip_case,{_,Ref1,_,_}}=C | Cs], N, Ix) -> % nested group
+cases_to_shuffle(Ref, [{skip_case,{_,Ref1,_,_},_}=C | Cs], N, Ix) -> % nested group
{Cs1,Rest} = get_subcases(Ref1, Cs, []),
cases_to_shuffle(Ref, Rest, N+1, [{N,[C|Cs1]} | Ix]);
@@ -3027,7 +3133,7 @@ cases_to_shuffle(Ref, [C | Cs], N, Ix) ->
get_subcases(SubRef, [{conf,SubRef,_,_}=C | Cs], SubCs) ->
{lists:reverse([C|SubCs]),Cs};
-get_subcases(SubRef, [{skip_case,{_,SubRef,_,_}}=C | Cs], SubCs) ->
+get_subcases(SubRef, [{skip_case,{_,SubRef,_,_},_}=C | Cs], SubCs) ->
{lists:reverse([C|SubCs]),Cs};
get_subcases(SubRef, [C|Cs], SubCs) ->
get_subcases(SubRef, Cs, [C|SubCs]).
@@ -3075,13 +3181,27 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
ResultCol = if Type == auto -> ?auto_skip_color;
Type == user -> ?user_skip_color
end,
-
- Comment1 = reason_to_string(Comment),
-
print(major, "~n=case ~w:~w", [Mod,Func]),
- print(major, "=started ~s", [lists:flatten(timestamp_get(""))]),
- print(major, "=result skipped: ~ts", [Comment1]),
- print(2,"*** Skipping test case #~w ~w ***", [CaseNum,{Mod,Func}]),
+ GroupName = case get_name(Mode) of
+ undefined ->
+ "";
+ GrName ->
+ GrName1 = cast_to_list(GrName),
+ print(major, "=group_props ~p", [[{name,GrName1}]]),
+ GrName1
+ end,
+ print(major, "=started ~s", [lists:flatten(timestamp_get(""))]),
+ Comment1 = reason_to_string(Comment),
+ if Type == auto ->
+ print(major, "=result auto_skipped: ~ts", [Comment1]);
+ Type == user ->
+ print(major, "=result skipped: ~ts", [Comment1])
+ end,
+ if CaseNum == 0 ->
+ print(2,"*** Skipping ~w ***", [{Mod,Func}]);
+ true ->
+ print(2,"*** Skipping test case #~w ~w ***", [CaseNum,{Mod,Func}])
+ end,
TR = xhtml("<tr valign=\"top\">", ["<tr class=\"",odd_or_even(),"\">"]),
GroupName = case get_name(Mode) of
undefined -> "";
@@ -3097,6 +3217,7 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
"<td><font color=\"~ts\">SKIPPED</font></td>"
"<td>~ts</td></tr>\n",
[num2str(CaseNum),fw_name(Mod),GroupName,Func,ResultCol,Comment1]),
+
if CaseNum > 0 ->
{US,AS} = get(test_server_skipped),
case Type of
@@ -3110,12 +3231,14 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% skip_cases_upto(Ref, Cases, Reason, Origin, Mode) -> Cases1
+%% skip_cases_upto(Ref, Cases, Reason, Origin, Mode, SkipType) -> Cases1
%%
+%% SkipType = skip_case | auto_skip_case
%% Mark all cases tagged with Ref as skipped.
-skip_cases_upto(Ref, Cases, Reason, Origin, Mode) ->
- {_,Modified,Rest} = modify_cases_upto(Ref, {skip,Reason,Origin,Mode}, Cases),
+skip_cases_upto(Ref, Cases, Reason, Origin, Mode, SkipType) ->
+ {_,Modified,Rest} =
+ modify_cases_upto(Ref, {skip,Reason,Origin,Mode,SkipType}, Cases),
Modified++Rest.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -3151,6 +3274,7 @@ modify_cases_upto(Ref, ModOp, Cases, Orig, Alt) ->
%% same ref in the list, if not, this *is* an end conf case
case lists:any(fun({_,R,_,_}) when R == Ref -> true;
({_,R,_}) when R == Ref -> true;
+ ({skip_case,{_,R,_,_},_}) when R == Ref -> true;
({skip_case,{_,R,_,_}}) when R == Ref -> true;
(_) -> false
end, Cases) of
@@ -3161,25 +3285,39 @@ modify_cases_upto(Ref, ModOp, Cases, Orig, Alt) ->
end.
%% next case is a conf with same ref, must be end conf = we're done
-modify_cases_upto1(Ref, {skip,Reason,conf,Mode}, [{conf,Ref,_Props,MF}|T], Orig, Alt) ->
+modify_cases_upto1(Ref, {skip,Reason,conf,Mode,skip_case},
+ [{conf,Ref,_Props,MF}|T], Orig, Alt) ->
+ {Orig,[{skip_case,{conf,Ref,MF,Reason},Mode}|Alt],T};
+modify_cases_upto1(Ref, {skip,Reason,conf,Mode,auto_skip_case},
+ [{conf,Ref,_Props,MF}|T], Orig, Alt) ->
{Orig,[{auto_skip_case,{conf,Ref,MF,Reason},Mode}|Alt],T};
modify_cases_upto1(Ref, {copy,NewRef}, [{conf,Ref,Props,MF}=C|T], Orig, Alt) ->
{[C|Orig],[{conf,NewRef,update_repeat(Props),MF}|Alt],T};
%% we've skipped all remaining cases in a sequence
-modify_cases_upto1(Ref, {skip,_,tc,_}, [{conf,Ref,_Props,_MF}|_]=Cs, Orig, Alt) ->
+modify_cases_upto1(Ref, {skip,_,tc,_,_},
+ [{conf,Ref,_Props,_MF}|_]=Cs, Orig, Alt) ->
{Orig,Alt,Cs};
%% next is a make case
-modify_cases_upto1(Ref, {skip,Reason,_,Mode}, [{make,Ref,MF}|T], Orig, Alt) ->
- {Orig,[{auto_skip_case,{make,Ref,MF,Reason},Mode}|Alt],T};
+modify_cases_upto1(Ref, {skip,Reason,_,Mode,SkipType},
+ [{make,Ref,MF}|T], Orig, Alt) ->
+ {Orig,[{SkipType,{make,Ref,MF,Reason},Mode}|Alt],T};
modify_cases_upto1(Ref, {copy,NewRef}, [{make,Ref,MF}=M|T], Orig, Alt) ->
{[M|Orig],[{make,NewRef,MF}|Alt],T};
%% next case is a user skipped end conf with the same ref = we're done
-modify_cases_upto1(Ref, {skip,Reason,_,Mode}, [{skip_case,{Type,Ref,MF,_Cmt}}|T], Orig, Alt) ->
- {Orig,[{auto_skip_case,{Type,Ref,MF,Reason},Mode}|Alt],T};
-modify_cases_upto1(Ref, {copy,NewRef}, [{skip_case,{Type,Ref,MF,Cmt}}=C|T], Orig, Alt) ->
+modify_cases_upto1(Ref, {skip,Reason,_,Mode,SkipType},
+ [{skip_case,{Type,Ref,MF,_Cmt},_}|T], Orig, Alt) ->
+ {Orig,[{SkipType,{Type,Ref,MF,Reason},Mode}|Alt],T};
+modify_cases_upto1(Ref, {skip,Reason,_,Mode,SkipType},
+ [{skip_case,{Type,Ref,MF,_Cmt}}|T], Orig, Alt) ->
+ {Orig,[{SkipType,{Type,Ref,MF,Reason},Mode}|Alt],T};
+modify_cases_upto1(Ref, {copy,NewRef},
+ [{skip_case,{Type,Ref,MF,Cmt},Mode}=C|T], Orig, Alt) ->
+ {[C|Orig],[{skip_case,{Type,NewRef,MF,Cmt},Mode}|Alt],T};
+modify_cases_upto1(Ref, {copy,NewRef},
+ [{skip_case,{Type,Ref,MF,Cmt}}=C|T], Orig, Alt) ->
{[C|Orig],[{skip_case,{Type,NewRef,MF,Cmt}}|Alt],T};
%% next is a skip_case, could be one test case or 'all' in suite, we must proceed
@@ -3187,13 +3325,17 @@ modify_cases_upto1(Ref, ModOp, [{skip_case,{_F,_Cmt}}=MF|T], Orig, Alt) ->
modify_cases_upto1(Ref, ModOp, T, [MF|Orig], [MF|Alt]);
%% next is a normal case (possibly in a sequence), mark as skipped, or copy, and proceed
-modify_cases_upto1(Ref, {skip,Reason,_,Mode}=Op, [{_M,_F}=MF|T], Orig, Alt) ->
+modify_cases_upto1(Ref, {skip,Reason,_,_,skip_case}=Op,
+ [{_M,_F}=MF|T], Orig, Alt) ->
+ modify_cases_upto1(Ref, Op, T, Orig, [{skip_case,{MF,Reason}}|Alt]);
+modify_cases_upto1(Ref, {skip,Reason,_,Mode,auto_skip_case}=Op,
+ [{_M,_F}=MF|T], Orig, Alt) ->
modify_cases_upto1(Ref, Op, T, Orig, [{auto_skip_case,{MF,Reason},Mode}|Alt]);
modify_cases_upto1(Ref, CopyOp, [{_M,_F}=MF|T], Orig, Alt) ->
modify_cases_upto1(Ref, CopyOp, T, [MF|Orig], [MF|Alt]);
%% next is some other case, ignore or copy
-modify_cases_upto1(Ref, {skip,_,_,_}=Op, [_|T], Orig, Alt) ->
+modify_cases_upto1(Ref, {skip,_,_,_,_}=Op, [_|T], Orig, Alt) ->
modify_cases_upto1(Ref, Op, T, Orig, Alt);
modify_cases_upto1(Ref, CopyOp, [C|T], Orig, Alt) ->
modify_cases_upto1(Ref, CopyOp, T, [C|Orig], [C|Alt]).
@@ -3567,7 +3709,8 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
{died,Reason} ->
progress(failed, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
- {_,{'EXIT',{Skip,Reason}}} when Skip==skip; Skip==skipped ->
+ {_,{'EXIT',{Skip,Reason}}} when Skip==skip; Skip==skipped;
+ Skip==auto_skip ->
progress(skip, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
{_,{'EXIT',_Pid,{Skip,Reason}}} when Skip==skip; Skip==skipped ->
@@ -3579,10 +3722,13 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
{_,{'EXIT',Reason}} ->
progress(failed, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
- {_, {Fail, Reason}} when Fail =:= fail; Fail =:= failed ->
+ {_,{Fail,Reason}} when Fail =:= fail; Fail =:= failed ->
progress(failed, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
- {_, {Skip, Reason}} when Skip==skip; Skip==skipped ->
+ {_,Reason={auto_skip,_Why}} ->
+ progress(skip, Num, Mod, Func, Loc, Reason,
+ Time, Comment, Style);
+ {_,{Skip,Reason}} when Skip==skip; Skip==skipped ->
progress(skip, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
{Time,RetVal} ->
@@ -3699,15 +3845,15 @@ num2str(N) -> integer_to_list(N).
progress(skip, CaseNum, Mod, Func, Loc, Reason, Time,
Comment, {St0,St1}) ->
- {Reason1,{Color,Ret}} =
+ {Reason1,{Color,Ret,ReportTag}} =
if_auto_skip(Reason,
- fun() -> {?auto_skip_color,auto_skip} end,
- fun() -> {?user_skip_color,skip} end),
- print(major, "=result skipped", []),
- print(1, "*** SKIPPED *** ~ts",
- [get_info_str(Func, CaseNum, get(test_server_cases))]),
+ fun() -> {?auto_skip_color,auto_skip,auto_skipped} end,
+ fun() -> {?user_skip_color,skip,skipped} end),
+ print(major, "=result ~w: ~p", [ReportTag,Reason1]),
+ print(1, "*** SKIPPED ~ts ***",
+ [get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,Func,
- {skipped,Reason1}}]),
+ {ReportTag,Reason1}}]),
ReasonStr = reason_to_string(Reason1),
ReasonStr1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(ReasonStr,[$\n])]),
@@ -3734,8 +3880,8 @@ progress(skip, CaseNum, Mod, Func, Loc, Reason, Time,
progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T,
Comment0, {St0,St1}) ->
print(major, "=result failed: timeout, ~p", [Loc]),
- print(1, "*** FAILED *** ~ts",
- [get_info_str(Func, CaseNum, get(test_server_cases))]),
+ print(1, "*** FAILED ~ts ***",
+ [get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report,
[tc_done,{Mod,Func,
{failed,timetrap_timeout}}]),
@@ -3760,8 +3906,8 @@ progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T,
progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T,
Comment0, {St0,St1}) ->
print(major, "=result failed: testcase_aborted, ~p", [Loc]),
- print(1, "*** FAILED *** ~ts",
- [get_info_str(Func, CaseNum, get(test_server_cases))]),
+ print(1, "*** FAILED ~ts ***",
+ [get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report,
[tc_done,{Mod,Func,
{failed,testcase_aborted}}]),
@@ -3786,8 +3932,8 @@ progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T,
progress(failed, CaseNum, Mod, Func, unknown, Reason, Time,
Comment0, {St0,St1}) ->
print(major, "=result failed: ~p, ~w", [Reason,unknown]),
- print(1, "*** FAILED *** ~ts",
- [get_info_str(Func, CaseNum, get(test_server_cases))]),
+ print(1, "*** FAILED ~ts ***",
+ [get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,Func,
{failed,Reason}}]),
TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
@@ -3822,8 +3968,8 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time,
progress(failed, CaseNum, Mod, Func, Loc, Reason, Time,
Comment0, {St0,St1}) ->
print(major, "=result failed: ~p, ~p", [Reason,Loc]),
- print(1, "*** FAILED *** ~ts",
- [get_info_str(Func, CaseNum, get(test_server_cases))]),
+ print(1, "*** FAILED ~ts ***",
+ [get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,Func,
{failed,Reason}}]),
TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
@@ -3920,24 +4066,25 @@ fw_name(Mod) ->
if_auto_skip(Reason={failed,{_,init_per_testcase,_}}, True, _False) ->
{Reason,True()};
-if_auto_skip({_T,{skip,Reason={failed,{_,init_per_testcase,_}}},_Opts}, True, _False) ->
+if_auto_skip({skip,Reason={failed,{_,init_per_testcase,_}}}, True, _False) ->
{Reason,True()};
-if_auto_skip({fw_auto_skip,Reason}, True, _False) ->
- {Reason,True()};
-if_auto_skip({_T,{skip,{fw_auto_skip,Reason}},_Opts}, True, _False) ->
+if_auto_skip({auto_skip,Reason}, True, _False) ->
{Reason,True()};
if_auto_skip(Reason, _True, False) ->
{Reason,False()}.
-update_skip_counters(RetVal, {US,AS}) ->
- {_,Result} = if_auto_skip(RetVal, fun() -> {US,AS+1} end, fun() -> {US+1,AS} end),
+update_skip_counters({_T,Pat,_Opts}, {US,AS}) ->
+ {_,Result} = if_auto_skip(Pat, fun() -> {US,AS+1} end, fun() -> {US+1,AS} end),
+ Result;
+update_skip_counters(Pat, {US,AS}) ->
+ {_,Result} = if_auto_skip(Pat, fun() -> {US,AS+1} end, fun() -> {US+1,AS} end),
Result.
-get_info_str(Func, 0, _Cases) ->
- atom_to_list(Func);
-get_info_str(_Func, CaseNum, unknown) ->
+get_info_str(Mod,Func, 0, _Cases) ->
+ io_lib:format("~w", [{Mod,Func}]);
+get_info_str(_Mod,_Func, CaseNum, unknown) ->
"test case " ++ integer_to_list(CaseNum);
-get_info_str(_Func, CaseNum, Cases) ->
+get_info_str(_Mod,_Func, CaseNum, Cases) ->
"test case " ++ integer_to_list(CaseNum) ++
" of " ++ integer_to_list(Cases).
@@ -4396,12 +4543,27 @@ collect_cases({conf,Props,InitMF,CaseList,FinMF} = Conf, St) ->
Props1 ->
Ref = make_ref(),
Skips = St#cc.skip,
+ Props2 = [{suite,St#cc.mod} | lists:delete(suite,Props1)],
+ Mode = [{Ref,Props2,undefined}],
case in_skip_list({St#cc.mod,Conf}, Skips) of
{true,Comment} -> % conf init skipped
- {ok,[{skip_case,{conf,Ref,InitMF,Comment}} |
+ {ok,[{skip_case,{conf,Ref,InitMF,Comment},Mode} |
[] ++ [{conf,Ref,[],FinMF}]],St};
{true,Name,Comment} when is_atom(Name) -> % all cases skipped
- {ok,[{skip_case,{{St#cc.mod,{group,Name}},Comment}}],St};
+ case collect_cases(CaseList, St) of
+ {ok,[],_St} = Empty ->
+ Empty;
+ {ok,FlatCases,St1} ->
+ Cases2Skip = FlatCases ++ [{conf,Ref,
+ keep_name(Props1),
+ FinMF}],
+ Skipped = skip_cases_upto(Ref, Cases2Skip, Comment,
+ conf, Mode, skip_case),
+ {ok,[{skip_case,{conf,Ref,InitMF,Comment},Mode} |
+ Skipped],St1};
+ {error,_Reason} = Error ->
+ Error
+ end;
{true,ToSkip,_} when is_list(ToSkip) -> % some cases skipped
case collect_cases(CaseList,
St#cc{skip=ToSkip++Skips}) of
@@ -4678,7 +4840,7 @@ start_node(Name, Type, Options) ->
case controller_call({start_node,Name,Type,Options}, T) of
{{ok,Nodename}, Host, Cmd, Info, Warning} ->
format(minor,
- "Successfully started node ~w on ~tp with command: ~tp",
+ "Successfully started node ~w on ~tp with command: ~ts",
[Nodename, Host, Cmd]),
format(major, "=node_start ~w", [Nodename]),
case Info of
@@ -4694,7 +4856,7 @@ start_node(Name, Type, Options) ->
{ok, Nodename};
{fail,{Ret, Host, Cmd}} ->
format(minor,
- "Failed to start node ~tp on ~tp with command: ~tp~n"
+ "Failed to start node ~tp on ~tp with command: ~ts~n"
"Reason: ~p",
[Name, Host, Cmd, Ret]),
{fail,Ret};
@@ -4703,7 +4865,7 @@ start_node(Name, Type, Options) ->
Ret;
{Ret, Host, Cmd} ->
format(minor,
- "Failed to start node ~tp on ~tp with command: ~tp~n"
+ "Failed to start node ~tp on ~tp with command: ~ts~n"
"Reason: ~p",
[Name, Host, Cmd, Ret]),
Ret
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index 619fd463de..582abb2153 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -82,7 +82,7 @@ start_tracer_node(TraceFile,TI) ->
Cookie = TI#target_info.cookie,
{ok,LSock} = gen_tcp:listen(0,[binary,{reuseaddr,true},{packet,2}]),
{ok,TracePort} = inet:port(LSock),
- Prog = pick_erl_program(default),
+ Prog = quote_progname(pick_erl_program(default)),
Cmd = lists:concat([Prog, " -sname tracer -hidden -setcookie ", Cookie,
" -s ", ?MODULE, " trc ", TraceFile, " ",
TracePort, " ", TI#target_info.os_family]),
@@ -312,7 +312,7 @@ start_node_peer(SlaveName, OptList, From, TI) ->
FailOnError = start_node_get_option_value(fail_on_error, OptList, true),
Pa = TI#target_info.test_server_dir,
Prog0 = start_node_get_option_value(erl, OptList, default),
- Prog = pick_erl_program(Prog0),
+ Prog = quote_progname(pick_erl_program(Prog0)),
Args =
case string:str(SuppliedArgs,"-setcookie") of
0 -> "-setcookie " ++ TI#target_info.cookie ++ " " ++ SuppliedArgs;
@@ -589,7 +589,32 @@ pick_erl_program(L) ->
{release, S} ->
find_release(S);
this ->
- lib:progname()
+ cast_to_list(lib:progname())
+ end.
+
+%% This is an attempt to distinguish between spaces in the program
+%% path and spaces that separate arguments. The program is quoted to
+%% allow spaces in the path.
+%%
+%% Arguments could exist either if the executable is excplicitly given
+%% ({prog,String}) or if the -program switch to beam is used and
+%% includes arguments (typically done by cerl in OTP test environment
+%% in order to ensure that slave/peer nodes are started with the same
+%% emulator and flags as the test node. The return from lib:progname()
+%% could then typically be '/<full_path_to>/cerl -gcov').
+quote_progname(Progname) ->
+ do_quote_progname(string:tokens(Progname," ")).
+
+do_quote_progname([Prog]) ->
+ "\""++Prog++"\"";
+do_quote_progname([Prog,Arg|Args]) ->
+ case os:find_executable(Prog) of
+ false ->
+ do_quote_progname([Prog++" "++Arg | Args]);
+ _ ->
+ %% this one has an executable - we assume the rest are arguments
+ "\""++Prog++"\""++
+ lists:flatten(lists:map(fun(X) -> [" ",X] end, [Arg|Args]))
end.
random_element(L) ->
diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl
index 8e71c69d35..11d6f7af4d 100644
--- a/lib/test_server/src/ts.erl
+++ b/lib/test_server/src/ts.erl
@@ -212,6 +212,12 @@ run_all(_Vars) ->
run_some([], _Opts) ->
ok;
+run_some([{Spec,Mod}|Specs], Opts) ->
+ case run(Spec, Mod, Opts) of
+ ok -> ok;
+ Error -> io:format("~p: ~p~n",[{Spec,Mod},Error])
+ end,
+ run_some(Specs, Opts);
run_some([Spec|Specs], Opts) ->
case run(Spec, Opts) of
ok -> ok;
@@ -263,8 +269,17 @@ run(List, Opts) when is_list(List), is_list(Opts) ->
run_some(List, Opts);
%% run/2
-%% Runs one test spec with Options
-run(Testspec, Config) when is_atom(Testspec), is_list(Config) ->
+%% Runs one test spec with list of suites or with options
+run(Testspec, ModsOrConfig) when is_atom(Testspec),
+ is_list(ModsOrConfig) ->
+ case is_list_of_suites(ModsOrConfig) of
+ false ->
+ run(Testspec, {config_list,ModsOrConfig});
+ true ->
+ run_some([{Testspec,M} || M <- ModsOrConfig],
+ [batch])
+ end;
+run(Testspec, {config_list,Config}) ->
Options=check_test_get_opts(Testspec, Config),
IsSmoke=proplists:get_value(smoke,Config),
File=atom_to_list(Testspec),
@@ -310,34 +325,85 @@ run(Testspec, Config) when is_atom(Testspec), is_list(Config) ->
run_test(File, [{spec,[Spec]}], Options);
%% Runs one module in a spec (interactive)
run(Testspec, Mod) when is_atom(Testspec), is_atom(Mod) ->
- run_test({atom_to_list(Testspec), Mod},
+ run_test({atom_to_list(Testspec),Mod},
[{suite,Mod}],
[interactive]).
%% run/3
%% Run one module in a spec with Config
-run(Testspec,Mod,Config) when is_atom(Testspec), is_atom(Mod), is_list(Config) ->
+run(Testspec, Mod, Config) when is_atom(Testspec),
+ is_atom(Mod),
+ is_list(Config) ->
Options=check_test_get_opts(Testspec, Config),
- run_test({atom_to_list(Testspec), Mod},
- [{suite,Mod}],
- Options);
-
-%% Runs one testcase in a module.
-run(Testspec, Mod, Case) when is_atom(Testspec), is_atom(Mod), is_atom(Case) ->
+ run_test({atom_to_list(Testspec),Mod},
+ [{suite,Mod}], Options);
+%% Run multiple modules with Config
+run(Testspec, Mods, Config) when is_atom(Testspec),
+ is_list(Mods),
+ is_list(Config) ->
+ run_some([{Testspec,M} || M <- Mods], Config);
+%% Runs one test case in a module.
+run(Testspec, Mod, Case) when is_atom(Testspec),
+ is_atom(Mod),
+ is_atom(Case) ->
Options=check_test_get_opts(Testspec, []),
- Args = [{suite,atom_to_list(Mod)},{testcase,atom_to_list(Case)}],
+ Args = [{suite,Mod},{testcase,Case}],
+ run_test(atom_to_list(Testspec), Args, Options);
+%% Runs one or more groups in a module.
+run(Testspec, Mod, Grs={group,_Groups}) when is_atom(Testspec),
+ is_atom(Mod) ->
+ Options=check_test_get_opts(Testspec, []),
+ Args = [{suite,Mod},Grs],
+ run_test(atom_to_list(Testspec), Args, Options);
+%% Runs one or more test cases in a module.
+run(Testspec, Mod, TCs={testcase,_Cases}) when is_atom(Testspec),
+ is_atom(Mod) ->
+ Options=check_test_get_opts(Testspec, []),
+ Args = [{suite,Mod},TCs],
run_test(atom_to_list(Testspec), Args, Options).
%% run/4
-%% Run one testcase in a module with Options.
+%% Run one test case in a module with Options.
run(Testspec, Mod, Case, Config) when is_atom(Testspec),
is_atom(Mod),
is_atom(Case),
is_list(Config) ->
Options=check_test_get_opts(Testspec, Config),
- Args = [{suite,atom_to_list(Mod)}, {testcase,atom_to_list(Case)}],
+ Args = [{suite,Mod},{testcase,Case}],
+ run_test(atom_to_list(Testspec), Args, Options);
+%% Run one or more test cases in a module with Options.
+run(Testspec, Mod, {testcase,Cases}, Config) when is_atom(Testspec),
+ is_atom(Mod) ->
+ run(Testspec, Mod, Cases, Config);
+run(Testspec, Mod, Cases, Config) when is_atom(Testspec),
+ is_atom(Mod),
+ is_list(Cases),
+ is_list(Config) ->
+ Options=check_test_get_opts(Testspec, Config),
+ Args = [{suite,Mod},Cases],
+ run_test(atom_to_list(Testspec), Args, Options);
+%% Run one or more groups in a module with Options.
+run(Testspec, Mod, Grs={group,_Groups}, Config) when is_atom(Testspec),
+ is_atom(Mod) ->
+ Options=check_test_get_opts(Testspec, Config),
+ Args = [{suite,Mod},Grs],
run_test(atom_to_list(Testspec), Args, Options).
+
+is_list_of_suites(List) ->
+ lists:all(fun(Suite) ->
+ S = if is_atom(Suite) -> atom_to_list(Suite);
+ true -> Suite
+ end,
+ try lists:last(string:tokens(S,"_")) of
+ "SUITE" -> true;
+ "suite" -> true;
+ _ -> false
+ catch
+ _:_ -> false
+ end
+ end, List).
+
%% Create a spec to skip all SUITES, this is used when the application
%% to be tested is not part of the OTP release to be tested.
create_skip_spec(Testspec, SuitesToSkip) ->
@@ -622,7 +688,7 @@ run_test(File, Args, Options) ->
run_test(File, Args, Options, Vars) ->
ts_run:run(File, Args, Options, Vars).
-
+
%% This module provides some convenient shortcuts to running
%% the test server from within a started Erlang shell.
%% (This are here for backwards compatibility.)
diff --git a/lib/test_server/src/ts.unix.config b/lib/test_server/src/ts.unix.config
index 5a2580f464..a34857b9e5 100644
--- a/lib/test_server/src/ts.unix.config
+++ b/lib/test_server/src/ts.unix.config
@@ -2,3 +2,5 @@
%% Always run a (VNC) X server on host
%% {xserver, "xserver.example.com:66"}.
+
+{unix,[{telnet,"belegost"},{username,"bofh"},{password,"root"},{keep_alive,true}]}.
diff --git a/lib/test_server/src/ts_erl_config.erl b/lib/test_server/src/ts_erl_config.erl
index 8cd6a333d8..2d45d39700 100644
--- a/lib/test_server/src/ts_erl_config.erl
+++ b/lib/test_server/src/ts_erl_config.erl
@@ -109,7 +109,10 @@ erts_lib(Vars,OsType) ->
ErtsLibIncludeInternal,
ErtsLibIncludeInternalGenerated,
ErtsLibPath,
- ErtsLibInternalPath}
+ ErtsLibInternalPath,
+ ErtsLibEthreadMake,
+ ErtsLibInternalMake
+ }
= case erl_root(Vars) of
{installed, _Root} ->
Erts = lib_dir(Vars, erts),
@@ -117,12 +120,17 @@ erts_lib(Vars,OsType) ->
ErtsIncludeInternal = filename:join([ErtsInclude, "internal"]),
ErtsLib = filename:join([Erts, "lib"]),
ErtsLibInternal = filename:join([ErtsLib, "internal"]),
+ ErtsEthreadMake = filename:join([ErtsIncludeInternal, "ethread.mk"]),
+ ErtsInternalMake = filename:join([ErtsIncludeInternal, "erts_internal.mk"]),
+
{ErtsInclude,
ErtsInclude,
ErtsIncludeInternal,
ErtsIncludeInternal,
ErtsLib,
- ErtsLibInternal};
+ ErtsLibInternal,
+ ErtsEthreadMake,
+ ErtsInternalMake};
{srctree, Root, Target} ->
Erts = filename:join([Root, "erts"]),
ErtsInclude = filename:join([Erts, "include"]),
@@ -136,12 +144,17 @@ erts_lib(Vars,OsType) ->
"lib",
"internal",
Target]),
+ ErtsEthreadMake = filename:join([ErtsIncludeInternalTarget, "ethread.mk"]),
+ ErtsInternalMake = filename:join([ErtsIncludeInternalTarget, "erts_internal.mk"]),
+
{ErtsInclude,
ErtsIncludeTarget,
ErtsIncludeInternal,
ErtsIncludeInternalTarget,
ErtsLib,
- ErtsLibInternal}
+ ErtsLibInternal,
+ ErtsEthreadMake,
+ ErtsInternalMake}
end,
[{erts_lib_include,
quote(filename:nativename(ErtsLibInclude))},
@@ -154,7 +167,9 @@ erts_lib(Vars,OsType) ->
{erts_lib_path, quote(filename:nativename(ErtsLibPath))},
{erts_lib_internal_path, quote(filename:nativename(ErtsLibInternalPath))},
{erts_lib_multi_threaded, erts_lib_name(multi_threaded, OsType)},
- {erts_lib_single_threaded, erts_lib_name(single_threaded, OsType)}
+ {erts_lib_single_threaded, erts_lib_name(single_threaded, OsType)},
+ {erts_lib_make_ethread, quote(ErtsLibEthreadMake)},
+ {erts_lib_make_internal, quote(ErtsLibInternalMake)}
| Vars].
erl_include(Vars) ->
@@ -190,10 +205,10 @@ erl_interface(Vars,OsType) ->
case erl_root(Vars) of
{installed, _Root} ->
{filename:join(Dir, "lib"),
- filename:join(Dir, "src")};
+ filename:join([Dir, "src", "eidefs.mk"])};
{srctree, _Root, Target} ->
{filename:join([Dir, "obj", Target]),
- filename:join([Dir, "src", Target])}
+ filename:join([Dir, "src", Target, "eidefs.mk"])}
end}
end,
Lib = link_library("erl_interface",OsType),
@@ -234,10 +249,10 @@ erl_interface(Vars,OsType) ->
end,
[{erl_interface_libpath, quote(filename:nativename(LibPath))},
{erl_interface_sock_libs, sock_libraries(OsType)},
- {erl_interface_lib, Lib},
- {erl_interface_eilib, Lib1},
- {erl_interface_lib_drv, LibDrv},
- {erl_interface_eilib_drv, Lib1Drv},
+ {erl_interface_lib, quote(filename:join(LibPath, Lib))},
+ {erl_interface_eilib, quote(filename:join(LibPath, Lib1))},
+ {erl_interface_lib_drv, quote(filename:join(LibPath, LibDrv))},
+ {erl_interface_eilib_drv, quote(filename:join(LibPath, Lib1Drv))},
{erl_interface_threadlib, ThreadLib},
{erl_interface_include, quote(filename:nativename(Incl))},
{erl_interface_mk_include, quote(filename:nativename(MkIncl))}
@@ -260,7 +275,7 @@ ic(Vars, OsType) ->
end,
[{ic_classpath, quote(filename:nativename(ClassPath))},
{ic_libpath, quote(filename:nativename(LibPath))},
- {ic_lib, link_library("ic", OsType)},
+ {ic_lib, quote(filename:join(filename:nativename(LibPath),link_library("ic", OsType)))},
{ic_include_path, quote(filename:nativename(Incl))}|Vars].
jinterface(Vars, _OsType) ->
@@ -370,9 +385,18 @@ separators(Vars, {win32,_}) ->
separators(Vars, _) ->
[{'DS',"/"},{'PS',":"}|Vars].
-quote([$ |R]) ->
- "\\ "++quote(R);
-quote([C|R]) ->
- [C|quote(R)];
-quote([]) ->
- [].
+quote(List) ->
+ case lists:member($ , List) of
+ false -> List;
+ true -> make_quote(List)
+ end.
+
+make_quote(List) ->
+ case os:type() of
+ {win32, _} -> %% nmake"
+ [$"] ++ List ++ [$"];
+ _ -> %% make
+ BackQuote = fun($ , Acc) -> [$\\ , $ |Acc];
+ (Char, Acc) -> [Char|Acc] end,
+ lists:foldr(BackQuote, [], List)
+ end.
diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl
index e9e559df5d..bc62015ac3 100644
--- a/lib/test_server/src/ts_install.erl
+++ b/lib/test_server/src/ts_install.erl
@@ -112,6 +112,12 @@ get_vars([], name, [], Result) ->
get_vars(_, _, _, _) ->
{error, fatal_bad_conf_vars}.
+config_flags() ->
+ case os:getenv("CONFIG_FLAGS") of
+ false -> [];
+ CF -> string:tokens(CF, " \t\n")
+ end.
+
unix_autoconf(XConf) ->
Configure = filename:absname("configure"),
Flags = proplists:get_value(crossflags,XConf,[]),
@@ -122,11 +128,14 @@ unix_autoconf(XConf) ->
erlang:system_info(threads) /= false],
Debug = [" --enable-debug-mode" ||
string:str(erlang:system_info(system_version),"debug") > 0],
- Args = Host ++ Build ++ Threads ++ Debug,
+ MXX_Build = [Y || Y <- config_flags(),
+ Y == "--enable-m64-build"
+ orelse Y == "--enable-m32-build"],
+ Args = Host ++ Build ++ Threads ++ Debug ++ " " ++ MXX_Build,
case filelib:is_file(Configure) of
true ->
OSXEnv = macosx_cflags(),
- io:format("Running ~sEnv: ~p~n",
+ io:format("Running ~s~nEnv: ~p~n",
[lists:flatten(Configure ++ Args),Env++OSXEnv]),
Port = open_port({spawn, lists:flatten(["\"",Configure,"\"",Args])},
[stream, eof, {env,Env++OSXEnv}]),
@@ -135,7 +144,6 @@ unix_autoconf(XConf) ->
{error, no_configure_script}
end.
-
get_xcomp_flag(Flag, Flags) ->
get_xcomp_flag(Flag, Flag, Flags).
get_xcomp_flag(Flag, Tag, Flags) ->
diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl
index 52bb346043..5368960446 100644
--- a/lib/test_server/src/ts_lib.erl
+++ b/lib/test_server/src/ts_lib.erl
@@ -145,16 +145,13 @@ suite_order(sasl) -> 16;
suite_order(tools) -> 18;
suite_order(runtime_tools) -> 19;
suite_order(parsetools) -> 20;
-suite_order(pman) -> 21;
suite_order(debugger) -> 22;
-suite_order(toolbar) -> 23;
suite_order(ic) -> 24;
suite_order(orber) -> 26;
suite_order(inets) -> 28;
suite_order(asn1) -> 30;
suite_order(os_mon) -> 32;
suite_order(snmp) -> 38;
-suite_order(mnesia_session) -> 42;
suite_order(mnesia) -> 44;
suite_order(system) -> 999; %% IMPORTANT: system SHOULD always be last!
suite_order(_) -> 200.
@@ -167,7 +164,7 @@ subst_file(In, Out, Vars) ->
case file:read_file(In) of
{ok, Bin} ->
Subst = subst(b2s(Bin), Vars, []),
- case file:write_file(Out, Subst) of
+ case file:write_file(Out, unicode:characters_to_binary(Subst)) of
ok ->
ok;
{error, Reason} ->
diff --git a/lib/test_server/src/ts_make.erl b/lib/test_server/src/ts_make.erl
index f3266f5836..8727f7ebfe 100644
--- a/lib/test_server/src/ts_make.erl
+++ b/lib/test_server/src/ts_make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -67,7 +67,7 @@ get_port_data(Port, Last0, Complete0) ->
end.
update_last([C|Rest], Line, true) ->
- io:put_chars(Line),
+ io:put_chars(list_to_binary(Line)), %% Utf-8 list to utf-8 binary
io:nl(),
update_last([C|Rest], [], false);
update_last([$\r|Rest], Result, Complete) ->
@@ -79,7 +79,7 @@ update_last([C|Rest], Result, Complete) ->
update_last([], Result, Complete) ->
{Result, Complete};
update_last(eof, Result, _) ->
- Result.
+ unicode:characters_to_list(list_to_binary(Result)).
run_make_script({win32, _}, Make, Dir, Makefile) ->
{"run_make.bat",
diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl
index 60c9a7a4b7..d96abfc55a 100644
--- a/lib/test_server/src/ts_run.erl
+++ b/lib/test_server/src/ts_run.erl
@@ -224,7 +224,7 @@ make_command(Vars, Spec, State) ->
CrashFile = filename:join(Cwd,State#state.file ++ "_erl_crash.dump"),
case filelib:is_file(CrashFile) of
true ->
- io:format("ts_run: Deleting dump: ~s\n",[CrashFile]),
+ io:format("ts_run: Deleting dump: ~ts\n",[CrashFile]),
file:delete(CrashFile);
false ->
ok
@@ -258,8 +258,8 @@ make_command(Vars, Spec, State) ->
run_batch(Vars, _Spec, State) ->
process_flag(trap_exit, true),
Command = State#state.command ++ " -noinput -s erlang halt",
- ts_lib:progress(Vars, 1, "Command: ~s~n", [Command]),
- io:format(user, "Command: ~s~n",[Command]),
+ ts_lib:progress(Vars, 1, "Command: ~ts~n", [Command]),
+ io:format(user, "Command: ~ts~n",[Command]),
Port = open_port({spawn, Command}, [stream, in, eof]),
Timeout = 30000 * case os:getenv("TS_RUN_VALGRIND") of
false -> 1;