aboutsummaryrefslogtreecommitdiffstats
path: root/lib/test_server
diff options
context:
space:
mode:
Diffstat (limited to 'lib/test_server')
-rw-r--r--lib/test_server/doc/src/notes.xml98
-rw-r--r--lib/test_server/doc/src/test_server.xml2
-rw-r--r--lib/test_server/doc/src/test_server_ctrl.xml2
-rw-r--r--lib/test_server/doc/src/ts.xml2
-rw-r--r--lib/test_server/include/test_server.hrl5
-rw-r--r--lib/test_server/include/test_server_line.hrl3
-rw-r--r--lib/test_server/src/Makefile3
-rw-r--r--lib/test_server/src/configure.in4
-rw-r--r--lib/test_server/src/test_server.app.src1
-rw-r--r--lib/test_server/src/test_server.erl299
-rw-r--r--lib/test_server/src/test_server_ctrl.erl65
-rw-r--r--lib/test_server/src/test_server_line.erl387
-rw-r--r--lib/test_server/src/test_server_node.erl2
-rw-r--r--lib/test_server/src/test_server_sup.erl15
-rw-r--r--lib/test_server/src/ts.erl2
-rw-r--r--lib/test_server/src/ts_install.erl9
-rw-r--r--lib/test_server/src/ts_install_cth.erl19
-rw-r--r--lib/test_server/src/ts_run.erl20
-rw-r--r--lib/test_server/test/Makefile6
-rw-r--r--lib/test_server/test/test_server_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_line_SUITE.erl2
-rw-r--r--lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl2
-rw-r--r--lib/test_server/test/test_server_test_lib.erl2
-rw-r--r--lib/test_server/vsn.mk2
30 files changed, 394 insertions, 572 deletions
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index ab329c399b..50923b1b03 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,102 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.4.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ It was previously not possible to use timetrap value
+ 'infinity' with ct:timetrap/1. This has been fixed.</p>
+ <p>
+ Own Id: OTP-9159</p>
+ </item>
+ <item>
+ <p>
+ A bug that made it impossible to cancel the previous
+ timetrap when calling ct:timetrap/1 has been corrected.</p>
+ <p>
+ Own Id: OTP-9233 Aux Id: OTP-9159 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ When running tests with auto-compilation disabled, Common
+ Test could only display the test suite source code on
+ html format in the test case log if the source file was
+ located in the same directory as the pre-compiled suite.
+ This has been modified so that Common Test now tries to
+ locate the source file by means of the test suite module
+ info (Suite:module_info/1). As a result, a suite may now
+ be compiled to a different output directory (e.g.
+ $MYTEST/bin) than the source code directory (e.g.
+ $MYTEST/src), without the source-code-to-html generation
+ being affected.</p>
+ <p>
+ Own Id: OTP-9138</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to return a tuple {fail,Reason} from
+ init_per_testcase/2. The result is that the associated
+ test case gets logged as failed without ever executing.</p>
+ <p>
+ Own Id: OTP-9160 Aux Id: seq11502 </p>
+ </item>
+ <item>
+ <p>
+ Added DragonflyBSD check in test_server configure.</p>
+ <p>
+ Own Id: OTP-9249</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Test_Server 3.4.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Updated the ts*.config files to contain information
+ relevant to testing Erlang/OTP in an open source
+ environment.</p>
+ <p>
+ Own Id: OTP-9017</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Alpha release of Common Test Hooks (CTH). CTHs allow the
+ users of common test to abtract out common behaviours
+ from test suites in a much more elegant and flexible way
+ than was possible before. Note that the addition of this
+ feature may introduce minor changes in the undocumented
+ behaviour of the interface inbetween common_test and
+ test_server.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8851</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.4.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/test_server/doc/src/test_server.xml b/lib/test_server/doc/src/test_server.xml
index 0cae75d692..78bb922cc5 100644
--- a/lib/test_server/doc/src/test_server.xml
+++ b/lib/test_server/doc/src/test_server.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2008</year>
+ <year>2011</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml
index 2368c4bacc..9028a67ecb 100644
--- a/lib/test_server/doc/src/test_server_ctrl.xml
+++ b/lib/test_server/doc/src/test_server_ctrl.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2008</year>
+ <year>2011</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/lib/test_server/doc/src/ts.xml b/lib/test_server/doc/src/ts.xml
index f60c79aadd..496ad3667a 100644
--- a/lib/test_server/doc/src/ts.xml
+++ b/lib/test_server/doc/src/ts.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2008</year>
+ <year>2011</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/lib/test_server/include/test_server.hrl b/lib/test_server/include/test_server.hrl
index 4b96d84ace..36e7e1f83d 100644
--- a/lib/test_server/include/test_server.hrl
+++ b/lib/test_server/include/test_server.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -20,11 +20,10 @@
-ifdef(line_trace).
-line_trace(true).
-define(line,
- put(test_server_loc,{?MODULE,?LINE}),
io:format(lists:concat([?MODULE,",",integer_to_list(?LINE),": ~p"]),
[erlang:now()]),).
-else.
--define(line,put(test_server_loc,{?MODULE,?LINE}),).
+-define(line,).
-endif.
-define(t,test_server).
-define(config,test_server:lookup_config).
diff --git a/lib/test_server/include/test_server_line.hrl b/lib/test_server/include/test_server_line.hrl
index 60ef860883..3c309d3ee5 100644
--- a/lib/test_server/include/test_server_line.hrl
+++ b/lib/test_server/include/test_server_line.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
@@ -16,5 +16,4 @@
%%
%% %CopyrightEnd%
%%
--compile({parse_transform,test_server_line}).
diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile
index 0858d24fce..4bc51873c2 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+# Copyright Ericsson AB 1996-2011. 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
@@ -43,7 +43,6 @@ MODULES= test_server_ctrl \
test_server_node \
test_server \
test_server_sup \
- test_server_line \
test_server_h \
erl2html2 \
vxworks_client
diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in
index 2bbbc18966..097853bcfc 100644
--- a/lib/test_server/src/configure.in
+++ b/lib/test_server/src/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script for Erlang.
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1997-2009. All Rights Reserved.
+dnl Copyright Ericsson AB 1997-2011. All Rights Reserved.
dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
@@ -136,7 +136,7 @@ case $system in
fi
SHLIB_EXTRACT_ALL=""
;;
- NetBSD-*|FreeBSD-*|OpenBSD-*)
+ NetBSD-*|FreeBSD-*|OpenBSD-*|DragonFly*)
# Not available on all versions: check for include file.
AC_CHECK_HEADER(dlfcn.h, [
SHLIB_CFLAGS="-fpic"
diff --git a/lib/test_server/src/test_server.app.src b/lib/test_server/src/test_server.app.src
index af2d4dc2cb..7e87583a7b 100644
--- a/lib/test_server/src/test_server.app.src
+++ b/lib/test_server/src/test_server.app.src
@@ -24,7 +24,6 @@
test_server_ctrl,
test_server,
test_server_h,
- test_server_line,
test_server_node,
test_server_sup
]},
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 2ab4e9c28a..04f92c5738 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -36,7 +36,7 @@
-export([capture_start/0,capture_stop/0,capture_get/0]).
-export([messages_get/0]).
-export([hours/1,minutes/1,seconds/1,sleep/1,adjusted_sleep/1,timecall/3]).
--export([timetrap_scale_factor/0,timetrap/1,timetrap_cancel/1]).
+-export([timetrap_scale_factor/0,timetrap/1,timetrap_cancel/1,timetrap_cancel/0]).
-export([m_out_of_n/3,do_times/4,do_times/2]).
-export([call_crash/3,call_crash/4,call_crash/5]).
-export([temp_name/1]).
@@ -759,7 +759,6 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,
Comment,undefined);
Loc1 ->
- {Mod,Func} = get_mf(Loc1),
%% call end_per_testcase on a separate process,
%% only so that the user has a chance to clean up
%% after init_per_testcase, even after a timetrap timeout
@@ -775,6 +774,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
TVal),
{EndConfPid,{Mod,Func},Conf};
_ ->
+ {Mod,Func} = get_mf(Loc1),
%% The framework functions mustn't execute on this
%% group leader process or io will cause deadlock,
%% so we spawn a dedicated process for the operation
@@ -810,7 +810,6 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
run_test_case_msgloop(Ref,Pid,CaptureStdout,Terminate,
Comment,undefined);
Loc1 ->
- {Mod,Func} = get_mf(Loc1),
%% call end_per_testcase on a separate process, only so
%% that the user has a chance to clean up after init_per_testcase,
%% even after abortion
@@ -828,6 +827,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
TVal),
{EndConfPid,{Mod,Func},Conf};
_ ->
+ {Mod,Func} = get_mf(Loc1),
spawn_fw_call(Mod,Func,Pid,ErrorMsg,
Loc1,self(),Comment),
undefined
@@ -1077,7 +1077,7 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
{{Time,Value},Loc,Opts} =
case test_server_sup:framework_call(init_tc,[?pl2a(Mod),Func,Args0],
- {ok, Args0}) of
+ {ok,Args0}) of
{ok,Args} ->
run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback);
Error = {error,_Reason} ->
@@ -1085,18 +1085,17 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
{skip,{failed,Error}}),
{{0,NewResult},{Mod,Func},[]};
{fail,Reason} ->
- [Conf] = Args0,
- Conf1 = [{tc_status,{failed,Reason}} | Conf],
+ Conf = [{tc_status,{failed,Reason}} | hd(Args0)],
fw_error_notify(Mod, Func, Conf, Reason),
- NewResult = do_end_tc_call(Mod,Func, {{error,Reason},[Conf1]},
- {fail, Reason}),
+ NewResult = do_end_tc_call(Mod,Func, {{error,Reason},[Conf]},
+ {fail,Reason}),
{{0,NewResult},{Mod,Func},[]};
Skip = {skip,_Reason} ->
NewResult = do_end_tc_call(Mod,Func,{Skip,Args0},Skip),
{{0,NewResult},{Mod,Func},[]};
{auto_skip,Reason} ->
NewResult = do_end_tc_call(Mod, Func, {{skip,Reason},Args0},
- {skip, {fw_auto_skip,Reason}}),
+ {skip,{fw_auto_skip,Reason}}),
{{0,NewResult},{Mod,Func},[]}
end,
exit({Ref,Time,Value,Loc,Opts}).
@@ -1116,9 +1115,15 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
{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]},
+ NewRes = do_end_tc_call(Mod, Func, {{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]},
+ FailTC),
+ {{0,NewRes},{Mod,Func},[]};
{ok,NewConf} ->
put(test_server_init_or_end_conf,undefined),
%% call user callback function if defined
@@ -1153,8 +1158,9 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
{FWReturn1,TSReturn1,EndConf2} =
case end_per_testcase(Mod, Func, EndConf1) of
SaveCfg1={save_config,_} ->
- {FWReturn,TSReturn,[SaveCfg1|lists:keydelete(save_config, 1, EndConf1)]};
- {fail,ReasonToFail} -> % user has failed the testcase
+ {FWReturn,TSReturn,[SaveCfg1|lists:keydelete(save_config,1,
+ EndConf1)]};
+ {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
@@ -1193,11 +1199,10 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
do_end_tc_call(M,F,Res,Return) ->
Ref = make_ref(),
- case test_server_sup:framework_call(
- end_tc, [?pl2a(M),F,Res], Ref) of
- {fail,FWReason} ->
- {failed,FWReason};
- Ref ->
+ case os:getenv("TEST_SERVER_FRAMEWORK") of
+ FW when FW == "ct_framework";
+ FW == "undefined";
+ FW == false ->
case test_server_sup:framework_call(
end_tc, [?pl2a(M),F,Res, Return], ok) of
{fail,FWReason} ->
@@ -1212,8 +1217,14 @@ do_end_tc_call(M,F,Res,Return) ->
NewReturn ->
NewReturn
end;
- _ ->
- Return
+ Other ->
+ case test_server_sup:framework_call(
+ end_tc, [Other,F,Res], Ref) of
+ {fail,FWReason} ->
+ {failed,FWReason};
+ _Else ->
+ Return
+ end
end.
%% the return value is a list and we have to check if it contains
@@ -1296,55 +1307,62 @@ init_per_testcase(Mod, Func, Args) ->
false -> code:load_file(Mod);
_ -> ok
end,
-%% init_per_testcase defined, returns new configuration
- case erlang:function_exported(Mod,init_per_testcase,2) of
+ case erlang:function_exported(Mod, init_per_testcase, 2) of
true ->
- case catch my_apply(Mod, init_per_testcase, [Func|Args]) of
- {'$test_server_ok',{Skip,Reason}} when Skip==skip;
- Skip==skipped ->
- {skip,Reason};
- {'$test_server_ok',Res={skip_and_save,_,_}} ->
- Res;
- {'$test_server_ok',NewConf} when is_list(NewConf) ->
- case lists:filter(fun(T) when is_tuple(T) -> false;
- (_) -> true end, NewConf) of
- [] ->
- {ok,NewConf};
- Bad ->
- group_leader() ! {printout,12,
- "ERROR! init_per_testcase has returned "
- "bad elements in Config: ~p\n",[Bad]},
- {skip,{failed,{Mod,init_per_testcase,bad_return}}}
- end;
- {'$test_server_ok',_Other} ->
- group_leader() ! {printout,12,
- "ERROR! init_per_testcase did not return "
- "a Config list.\n",[]},
- {skip,{failed,{Mod,init_per_testcase,bad_return}}};
- {'EXIT',Reason} ->
- Line = get_loc(),
- FormattedLoc = test_server_sup:format_loc(mod_loc(Line)),
- group_leader() ! {printout,12,
- "ERROR! init_per_testcase crashed!\n"
- "\tLocation: ~s\n\tReason: ~p\n",
- [FormattedLoc,Reason]},
- {skip,{failed,{Mod,init_per_testcase,Reason}}};
- Other ->
- Line = get_loc(),
- FormattedLoc = test_server_sup:format_loc(mod_loc(Line)),
- group_leader() ! {printout,12,
- "ERROR! init_per_testcase thrown!\n"
- "\tLocation: ~s\n\tReason: ~p\n",
- [FormattedLoc, Other]},
- {skip,{failed,{Mod,init_per_testcase,Other}}}
- end;
+ do_init_per_testcase(Mod, [Func|Args]);
false ->
-%% Optional init_per_testcase not defined
-%% keep quiet.
+ %% Optional init_per_testcase is not defined -- keep quiet.
[Config] = Args,
{ok, Config}
end.
+do_init_per_testcase(Mod, Args) ->
+ try apply(Mod, init_per_testcase, Args) of
+ {Skip,Reason} when Skip =:= skip; Skip =:= skipped ->
+ {skip,Reason};
+ {skip_and_save,_,_}=Res ->
+ Res;
+ NewConf when is_list(NewConf) ->
+ case lists:filter(fun(T) when is_tuple(T) -> false;
+ (_) -> true end, NewConf) of
+ [] ->
+ {ok,NewConf};
+ Bad ->
+ group_leader() ! {printout,12,
+ "ERROR! init_per_testcase has returned "
+ "bad elements in Config: ~p\n",[Bad]},
+ {skip,{failed,{Mod,init_per_testcase,bad_return}}}
+ end;
+ {fail,_Reason}=Res ->
+ Res;
+ _Other ->
+ group_leader() ! {printout,12,
+ "ERROR! init_per_testcase did not return "
+ "a Config list.\n",[]},
+ {skip,{failed,{Mod,init_per_testcase,bad_return}}}
+ catch
+ throw:Other ->
+ set_loc(erlang:get_stacktrace()),
+ Line = get_loc(),
+ FormattedLoc = test_server_sup:format_loc(mod_loc(Line)),
+ group_leader() ! {printout,12,
+ "ERROR! init_per_testcase thrown!\n"
+ "\tLocation: ~s\n\tReason: ~p\n",
+ [FormattedLoc, Other]},
+ {skip,{failed,{Mod,init_per_testcase,Other}}};
+ _:Reason0 ->
+ Stk = erlang:get_stacktrace(),
+ Reason = {Reason0,Stk},
+ set_loc(Stk),
+ Line = get_loc(),
+ FormattedLoc = test_server_sup:format_loc(mod_loc(Line)),
+ group_leader() ! {printout,12,
+ "ERROR! init_per_testcase crashed!\n"
+ "\tLocation: ~s\n\tReason: ~p\n",
+ [FormattedLoc,Reason]},
+ {skip,{failed,{Mod,init_per_testcase,Reason}}}
+ end.
+
end_per_testcase(Mod, Func, Conf) ->
case erlang:function_exported(Mod,end_per_testcase,2) of
true ->
@@ -1362,57 +1380,79 @@ end_per_testcase(Mod, Func, Conf) ->
do_end_per_testcase(Mod,EndFunc,Func,Conf) ->
put(test_server_init_or_end_conf,{EndFunc,Func}),
put(test_server_loc, {Mod,{EndFunc,Func}}),
- case catch my_apply(Mod, EndFunc, [Func,Conf]) of
- {'$test_server_ok',SaveCfg={save_config,_}} ->
+ try Mod:EndFunc(Func, Conf) of
+ {save_config,_}=SaveCfg ->
SaveCfg;
- {'$test_server_ok',{fail,_}=Fail} ->
+ {fail,_}=Fail ->
Fail;
- {'$test_server_ok',_} ->
- ok;
- {'EXIT',Reason} = Why ->
+ _ ->
+ ok
+ catch
+ throw:Other ->
+ set_loc(erlang:get_stacktrace()),
comment(io_lib:format("<font color=\"red\">"
- "WARNING: ~w crashed!"
+ "WARNING: ~w thrown!"
"</font>\n",[EndFunc])),
group_leader() ! {printout,12,
- "WARNING: ~w crashed!\n"
+ "WARNING: ~w thrown!\n"
"Reason: ~p\n"
"Line: ~s\n",
- [EndFunc, Reason,
+ [EndFunc, Other,
test_server_sup:format_loc(
mod_loc(get_loc()))]},
- {failed,{Mod,end_per_testcase,Why}};
- Other ->
+ {failed,{Mod,end_per_testcase,Other}};
+ Class:Reason ->
+ Stk = erlang:get_stacktrace(),
+ set_loc(Stk),
+ Why = case Class of
+ exit -> {'EXIT',Reason};
+ error -> {'EXIT',{Reason,Stk}}
+ end,
comment(io_lib:format("<font color=\"red\">"
- "WARNING: ~w thrown!"
+ "WARNING: ~w crashed!"
"</font>\n",[EndFunc])),
group_leader() ! {printout,12,
- "WARNING: ~w thrown!\n"
+ "WARNING: ~w crashed!\n"
"Reason: ~p\n"
"Line: ~s\n",
- [EndFunc, Other,
+ [EndFunc, Reason,
test_server_sup:format_loc(
mod_loc(get_loc()))]},
- {failed,{Mod,end_per_testcase,Other}}
+ {failed,{Mod,end_per_testcase,Why}}
end.
get_loc() ->
- case catch test_server_line:get_lines() of
- [] ->
- get(test_server_loc);
- {'EXIT',_} ->
- get(test_server_loc);
- Loc ->
- Loc
- end.
+ get(test_server_loc).
get_loc(Pid) ->
- {dictionary,Dict} = process_info(Pid, dictionary),
- lists:foreach(fun({Key,Val}) -> put(Key,Val) end,Dict),
+ [{current_stacktrace,Stk0},{dictionary,Dict}] =
+ process_info(Pid, [current_stacktrace,dictionary]),
+ lists:foreach(fun({Key,Val}) -> put(Key, Val) end, Dict),
+ Stk = [rewrite_loc_item(Loc) || Loc <- Stk0],
+ put(test_server_loc, Stk),
get_loc().
-get_mf([{M,F,_}|_]) -> {M,F};
-get_mf([{M,F}|_]) -> {M,F};
-get_mf(_) -> {undefined,undefined}.
+%% find the latest known Suite:Testcase
+get_mf(MFs) ->
+ get_mf(MFs, {undefined,undefined}).
+
+get_mf([MF|MFs], Found) when is_tuple(MF) ->
+ ModFunc = {Mod,_} = case MF of
+ {M,F,_} -> {M,F};
+ MF -> MF
+ end,
+ case is_suite(Mod) of
+ true -> ModFunc;
+ false -> get_mf(MFs, ModFunc)
+ end;
+get_mf(_, Found) ->
+ Found.
+
+is_suite(Mod) ->
+ case lists:reverse(atom_to_list(Mod)) of
+ "ETIUS" ++ _ -> true;
+ _ -> false
+ end.
mod_loc(Loc) ->
%% handle diff line num versions
@@ -1485,16 +1525,22 @@ lookup_config(Key,Config) ->
%% timer:tc/3
ts_tc(M, F, A) ->
Before = erlang:now(),
- Val = (catch my_apply(M, F, A)),
+ Result = try
+ apply(M, F, A)
+ catch
+ Type:Reason ->
+ Stk = erlang:get_stacktrace(),
+ set_loc(Stk),
+ case Type of
+ throw ->
+ {failed,{thrown,Reason}};
+ error ->
+ {'EXIT',{Reason,Stk}};
+ exit ->
+ {'EXIT',Reason}
+ end
+ end,
After = erlang:now(),
- Result = case Val of
- {'$test_server_ok', R} ->
- R; % test case ok
- {'EXIT',_Reason} = R ->
- R; % test case crashed
- Other ->
- {failed, {thrown,Other}} % test case was thrown
- end,
Elapsed =
(element(1,After)*1000000000000
+element(2,After)*1000000+element(3,After)) -
@@ -1502,8 +1548,12 @@ ts_tc(M, F, A) ->
+element(2,Before)*1000000+element(3,Before)),
{Elapsed, Result}.
-my_apply(M, F, A) ->
- {'$test_server_ok',apply(M, F, A)}.
+set_loc(Stk) ->
+ Loc = [rewrite_loc_item(I) || {_,_,_,_}=I <- Stk],
+ put(test_server_loc, Loc).
+
+rewrite_loc_item({M,F,_,Loc}) ->
+ {M,F,proplists:get_value(line, Loc, 0)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1690,7 +1740,7 @@ fail() ->
break(Comment) ->
case erase(test_server_timetraps) of
undefined -> ok;
- List -> lists:foreach(fun(Ref) -> timetrap_cancel(Ref) end,List)
+ List -> lists:foreach(fun({Ref,_}) -> timetrap_cancel(Ref) end, List)
end,
io:format(user,
"\n\n\n--- SEMIAUTOMATIC TESTING ---"
@@ -1771,14 +1821,16 @@ timetrap(Timeout0) ->
{undefined,false} -> timetrap1(Timeout, false);
{undefined,_} -> timetrap1(Timeout, true);
{infinity,_} -> infinity;
+ {_Int,_Scale} when Timeout == infinity -> infinity;
{Int,Scale} -> timetrap1(Timeout*Int, Scale)
end.
timetrap1(Timeout, Scale) ->
- Ref = spawn_link(test_server_sup,timetrap,[Timeout,Scale,self()]),
+ TCPid = self(),
+ Ref = spawn_link(test_server_sup,timetrap,[Timeout,Scale,TCPid]),
case get(test_server_timetraps) of
- undefined -> put(test_server_timetraps,[Ref]);
- List -> put(test_server_timetraps,[Ref|List])
+ undefined -> put(test_server_timetraps,[{Ref,TCPid}]);
+ List -> put(test_server_timetraps,[{Ref,TCPid}|List])
end,
Ref.
@@ -1791,14 +1843,16 @@ ensure_timetrap(Config) ->
undefined -> ok;
Garbage ->
erase(test_server_default_timetrap),
- format("=== WARNING: garbage in test_server_default_timetrap: ~p~n",
+ format("=== WARNING: garbage in "
+ "test_server_default_timetrap: ~p~n",
[Garbage])
end,
DTmo = case lists:keysearch(default_timeout,1,Config) of
{value,{default_timeout,Tmo}} -> Tmo;
_ -> ?DEFAULT_TIMETRAP_SECS
end,
- format("=== test_server setting default timetrap of ~p seconds~n",
+ format("=== test_server setting default "
+ "timetrap of ~p seconds~n",
[DTmo]),
put(test_server_default_timetrap, timetrap(seconds(DTmo)))
end.
@@ -1810,11 +1864,13 @@ cancel_default_timetrap() ->
TimeTrap when is_pid(TimeTrap) ->
timetrap_cancel(TimeTrap),
erase(test_server_default_timetrap),
- format("=== test_server canceled default timetrap since another timetrap was set~n"),
+ format("=== test_server canceled default timetrap "
+ "since another timetrap was set~n"),
ok;
Garbage ->
erase(test_server_default_timetrap),
- format("=== WARNING: garbage in test_server_default_timetrap: ~p~n",
+ format("=== WARNING: garbage in "
+ "test_server_default_timetrap: ~p~n",
[Garbage]),
error
end.
@@ -1828,6 +1884,7 @@ time_ms({Other,_N}) ->
"Should be seconds, minutes, or hours.~n", [Other]),
exit({invalid_time_spec,Other});
time_ms(Ms) when is_integer(Ms) -> Ms;
+time_ms(infinity) -> infinity;
time_ms(Other) -> exit({invalid_time_spec,Other}).
@@ -1841,11 +1898,29 @@ timetrap_cancel(infinity) ->
timetrap_cancel(Handle) ->
case get(test_server_timetraps) of
undefined -> ok;
- [Handle] -> erase(test_server_timetraps);
- List -> put(test_server_timetraps,lists:delete(Handle,List))
+ [{Handle,_}] -> erase(test_server_timetraps);
+ Timers -> put(test_server_timetraps,
+ lists:keydelete(Handle, 1, Timers))
end,
test_server_sup:timetrap_cancel(Handle).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% timetrap_cancel() -> ok
+%%
+%% Cancels timetrap for current test case.
+timetrap_cancel() ->
+ case get(test_server_timetraps) of
+ undefined ->
+ ok;
+ Timers ->
+ case lists:keysearch(self(), 2, Timers) of
+ {value,{Handle,_}} ->
+ timetrap_cancel(Handle);
+ _ ->
+ ok
+ end
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% hours(N) -> Milliseconds
%% minutes(N) -> Milliseconds
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 7cd58642d0..de9b962dfc 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. 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
@@ -1812,6 +1812,9 @@ start_log_file() ->
ok = file:make_dir(PrivDir),
put(test_server_priv_dir,PrivDir++"/"),
print_timestamp(13,"Suite started at "),
+
+ LogInfo = [{topdir,Dir},{rundir,lists:flatten(TestDir)}],
+ test_server_sup:framework_call(report, [loginfo,LogInfo]),
ok.
make_html_link(LinkName, Target, Explanation) ->
@@ -1925,7 +1928,6 @@ html_convert_modules(TestSpec, _Config) ->
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);
@@ -1939,37 +1941,56 @@ html_isolate_modules([{Mod,_Case,_Args}|Cases], Set) ->
html_isolate_modules(Cases, sets:add_element(Mod, Set)).
%% Given a list of modules, convert each module's source code to HTML.
-
html_convert_modules([Mod|Mods]) ->
case code:which(Mod) of
Path when is_list(Path) ->
SrcFile = filename:rootname(Path) ++ ".erl",
- DestDir = get(test_server_dir),
- Name = atom_to_list(Mod),
- DestFile = filename:join(DestDir, downcase(Name) ++ ?src_listing_ext),
- html_possibly_convert(SrcFile, DestFile),
- html_convert_modules(Mods);
- _Other -> ok
+ FoundSrcFile =
+ case file:read_file_info(SrcFile) of
+ {ok,SInfo} ->
+ {SrcFile,SInfo};
+ {error,_} ->
+ ModInfo = Mod:module_info(compile),
+ case proplists:get_value(source, ModInfo) of
+ undefined ->
+ undefined;
+ OtherSrcFile ->
+ case file:read_file_info(OtherSrcFile) of
+ {ok,SInfo} ->
+ {OtherSrcFile,SInfo};
+ {error,_} ->
+ undefined
+ end
+ end
+ end,
+ case FoundSrcFile of
+ undefined ->
+ html_convert_modules(Mods);
+ {SrcFile1,SrcFileInfo} ->
+ DestDir = get(test_server_dir),
+ Name = atom_to_list(Mod),
+ DestFile = filename:join(DestDir,
+ downcase(Name)++?src_listing_ext),
+ html_possibly_convert(SrcFile1, SrcFileInfo, DestFile),
+ html_convert_modules(Mods)
+ end;
+ _Other ->
+ html_convert_modules(Mods)
end;
html_convert_modules([]) -> ok.
%% Convert source code to HTML if possible and needed.
-
-html_possibly_convert(Src, Dest) ->
- case file:read_file_info(Src) of
- {ok,SInfo} ->
- case file:read_file_info(Dest) of
- {error,_Reason} -> % no dest file
- erl2html2:convert(Src, Dest);
- {ok,DInfo} when DInfo#file_info.mtime < SInfo#file_info.mtime ->
- erl2html2:convert(Src, Dest);
- {ok,_DInfo} -> ok % dest file up to date
- end;
- {error,_Reason} -> ok % no source code found
+html_possibly_convert(Src, SrcInfo, Dest) ->
+ case file:read_file_info(Dest) of
+ {error,_Reason} -> % no dest file
+ erl2html2:convert(Src, Dest);
+ {ok,DestInfo} when DestInfo#file_info.mtime < SrcInfo#file_info.mtime ->
+ erl2html2:convert(Src, Dest);
+ {ok,_DestInfo} ->
+ ok % dest file up to date
end.
%% Copy all HTML files in InDir to OutDir.
-
copy_html_files(InDir, OutDir) ->
Files = filelib:wildcard(filename:join(InDir, "*" ++ ?src_listing_ext)),
lists:foreach(fun (Src) -> copy_html_file(Src, OutDir) end, Files).
diff --git a/lib/test_server/src/test_server_line.erl b/lib/test_server/src/test_server_line.erl
deleted file mode 100644
index 848a9c23dd..0000000000
--- a/lib/test_server/src/test_server_line.erl
+++ /dev/null
@@ -1,387 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2010. 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
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(test_server_line).
-
-%% User interface
--export([get_lines/0]).
--export([clear/0]).
-
-%% Parse transform functions
--export([parse_transform/2]).
--export(['$test_server_line'/3]).
--export(['$test_server_lineQ'/3]).
--export([trace_line/3]).
-
--define(TEST_SERVER_LINE_SIZE, 10).
-%-define(STORAGE_FUNCTION, '$test_server_line').
--define(STORAGE_FUNCTION, '$test_server_lineQ').
-
--include("test_server.hrl").
-
--record(vars, {module, % atom() Module name
- function, % atom() Function name
- arity, % int() Function arity
- lines, % [int()] seen lines
- is_guard=false, % boolean()
- no_lines=[], % [{atom(),integer()}]
- % Functions to exclude
- line_trace=false
- }).
-
-
-
-
-%% Process dictionary littering variant
-%%
-
-'$test_server_line'(Mod, Func, Line) ->
- {Prev,Next} =
- case get('$test_server_line') of
- I when is_integer(I) ->
- if 1 =< I, I < ?TEST_SERVER_LINE_SIZE -> {I,I+1};
- true -> {?TEST_SERVER_LINE_SIZE,1}
- end;
- _ -> {?TEST_SERVER_LINE_SIZE,1}
- end,
- PrevTag = {'$test_server_line',Prev},
- case get(PrevTag) of
- {Mod,Func,_} -> put(PrevTag, {Mod,Func,Line});
- _ ->
- put({'$test_server_line',Next}, {Mod,Func,Line}),
- put('$test_server_line', Next)
- end, ok.
-
-test_server_line_get() ->
- case get('$test_server_line') of
- I when is_integer(I), 1 =< I, I =< ?TEST_SERVER_LINE_SIZE ->
- test_server_line_get_1(?TEST_SERVER_LINE_SIZE, I, []);
- _ -> []
- end.
-
-test_server_line_get_1(0, _I, R) ->
- R;
-test_server_line_get_1(Cnt, I, R) ->
- J = if I < ?TEST_SERVER_LINE_SIZE -> I+1;
- true -> 1 end,
- case get({'$test_server_line',J}) of
- undefined ->
- %% Less than ?TEST_SERVER_LINE_SIZE number of lines stored
- %% Start from line 1 and stop at actutual number of lines
- case get({'$test_server_line',1}) of
- undefined -> R; % no lines at all stored
- E -> test_server_line_get_1(I-1,1,[E|R])
- end;
- E ->
- test_server_line_get_1(Cnt-1, J, [E|R])
- end.
-
-test_server_line_clear() ->
- Is = lists:seq(1,?TEST_SERVER_LINE_SIZE),
- lists:foreach(fun (I) -> erase({'$test_server_line',I}) end, Is),
- erase('$test_server_line'),
- ok.
-
-
-%% Queue variant, uses just one process dictionary entry
-%%
-
-'$test_server_lineQ'(Mod, Func, Line) ->
- case get('$test_server_lineQ') of
- {I,Q} when is_integer(I), 1 =< I, I =< ?TEST_SERVER_LINE_SIZE ->
- case queue:head(Q) of
- {Mod,Func,_} ->
- %% Replace queue head
- put('$test_server_lineQ',
- {I,queue:cons({Mod,Func,Line}, queue:tail(Q))});
- _ when I < ?TEST_SERVER_LINE_SIZE ->
- put('$test_server_lineQ',
- {I+1,queue:cons({Mod,Func,Line}, Q)});
- _ ->
- %% Waste last in queue
- put('$test_server_lineQ',
- {I,queue:cons({Mod,Func,Line}, queue:lait(Q))})
- end;
- _ ->
- Q = queue:new(),
- put('$test_server_lineQ', {1,queue:cons({Mod,Func,Line}, Q)})
- end, ok.
-
-%test_server_lineQ_get() ->
-% case get('$test_server_lineQ') of
-% {I,Q} when integer(I), 1 =< I, I =< ?TEST_SERVER_LINE_SIZE ->
-% queue:to_list(Q);
-% _ -> []
-% end.
-
-test_server_lineQ_clear() ->
- erase('$test_server_lineQ'),
- ok.
-
-
-%% Get line - check if queue or dictionary is used, then get the lines
-%%
-
-get_lines() ->
- case get('$test_server_lineQ') of
- {I,Q} when is_integer(I), 1 =< I, I =< ?TEST_SERVER_LINE_SIZE ->
- queue:to_list(Q);
- _ ->
- test_server_line_get()
- end.
-
-%% Clear all dictionary entries
-%%
-clear() ->
- test_server_line_clear(),
- test_server_lineQ_clear().
-
-
-trace_line(Mod,Func,Line) ->
- io:format(lists:concat([Mod,":",Func,",",integer_to_list(Line),": ~p"]),
- [erlang:now()]).
-
-
-%%%=================================================================
-%%%========= **** PARSE TRANSFORM **** ========================
-%%%=================================================================
-parse_transform(Forms, _Options) ->
- transform(Forms, _Options).
-
-%% forms(Fs) -> lists:map(fun (F) -> form(F) end, Fs).
-
-transform(Forms, _Options)->
- Vars0 = #vars{},
- {ok, MungedForms, _Vars} = transform(Forms, [], Vars0),
- MungedForms.
-
-
-transform([Form|Forms], MungedForms, Vars) ->
- case munge(Form, Vars) of
- ignore ->
- transform(Forms, MungedForms, Vars);
- {MungedForm, Vars2} ->
- transform(Forms, [MungedForm|MungedForms], Vars2)
- end;
-transform([], MungedForms, Vars) ->
- {ok, lists:reverse(MungedForms), Vars}.
-
-%% This code traverses the abstract code, stored as the abstract_code
-%% chunk in the BEAM file, as described in absform(3) for Erlang/OTP R8B
-%% (Vsn=abstract_v2).
-%% The abstract format after preprocessing differs slightly from the abstract
-%% format given eg using epp:parse_form, this has been noted in comments.
-munge(Form={attribute,_,module,Module}, Vars) ->
- Vars2 = Vars#vars{module=Module},
- {Form, Vars2};
-
-munge(Form={attribute,_,no_lines,Funcs}, Vars) ->
- Vars2 = Vars#vars{no_lines=Funcs},
- {Form, Vars2};
-
-munge(Form={attribute,_,line_trace,_}, Vars) ->
- Vars2 = Vars#vars{line_trace=true},
- {Form, Vars2};
-
-munge({function,0,module_info,_Arity,_Clauses}, _Vars) ->
- ignore; % module_info will be added again when the forms are recompiled
-munge(Form = {function,Line,Function,Arity,Clauses}, Vars) ->
- case lists:member({Function,Arity},Vars#vars.no_lines) of
- true ->
- %% Line numbers in this function shall not be stored
- {Form,Vars};
- false ->
- Vars2 = Vars#vars{function=Function,
- arity=Arity,
- lines=[]},
- {MungedClauses, Vars3} = munge_clauses(Clauses, Vars2, []),
- {{function,Line,Function,Arity,MungedClauses}, Vars3}
- end;
-munge(Form, Vars) -> % attributes
- {Form, Vars}.
-
-munge_clauses([{clause,Line,Pattern,Guards,Body}|Clauses], Vars, MClauses) ->
- {MungedGuards, _Vars} = munge_exprs(Guards, Vars#vars{is_guard=true},[]),
- {MungedBody, Vars2} = munge_body(Body, Vars, []),
- munge_clauses(Clauses, Vars2,
- [{clause,Line,Pattern,MungedGuards,MungedBody}|
- MClauses]);
-munge_clauses([], Vars, MungedClauses) ->
- {lists:reverse(MungedClauses), Vars}.
-
-munge_body([Expr|Body], Vars, MungedBody) ->
- %% Here is the place to add a call to storage function!
- Line = element(2, Expr),
- Lines = Vars#vars.lines,
- case lists:member(Line,Lines) of
- true -> % already a bump at this line!
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- munge_body(Body, Vars2, [MungedExpr|MungedBody]);
- false ->
- Bump = {call, 0, {remote,0,
- {atom,0,?MODULE},
- {atom,0,?STORAGE_FUNCTION}},
- [{atom,0,Vars#vars.module},
- {atom, 0, Vars#vars.function},
- {integer, 0, Line}]},
- Lines2 = [Line|Lines],
-
- {MungedExpr, Vars2} = munge_expr(Expr, Vars#vars{lines=Lines2}),
- MungedBody2 =
- if Vars#vars.line_trace ->
- LineTrace = {call, 0, {remote,0,
- {atom,0,?MODULE},
- {atom,0,trace_line}},
- [{atom,0,Vars#vars.module},
- {atom, 0, Vars#vars.function},
- {integer, 0, Line}]},
- [MungedExpr,LineTrace,Bump|MungedBody];
- true ->
- [MungedExpr,Bump|MungedBody]
- end,
- munge_body(Body, Vars2, MungedBody2)
- end;
-munge_body([], Vars, MungedBody) ->
- {lists:reverse(MungedBody), Vars}.
-
-munge_expr({match,Line,ExprL,ExprR}, Vars) ->
- {MungedExprL, Vars2} = munge_expr(ExprL, Vars),
- {MungedExprR, Vars3} = munge_expr(ExprR, Vars2),
- {{match,Line,MungedExprL,MungedExprR}, Vars3};
-munge_expr({tuple,Line,Exprs}, Vars) ->
- {MungedExprs, Vars2} = munge_exprs(Exprs, Vars, []),
- {{tuple,Line,MungedExprs}, Vars2};
-munge_expr({record,Line,Expr,Exprs}, Vars) ->
- %% Only for Vsn=raw_abstract_v1
- {MungedExprName, Vars2} = munge_expr(Expr, Vars),
- {MungedExprFields, Vars3} = munge_exprs(Exprs, Vars2, []),
- {{record,Line,MungedExprName,MungedExprFields}, Vars3};
-munge_expr({record_field,Line,ExprL,ExprR}, Vars) ->
- %% Only for Vsn=raw_abstract_v1
- {MungedExprL, Vars2} = munge_expr(ExprL, Vars),
- {MungedExprR, Vars3} = munge_expr(ExprR, Vars2),
- {{record_field,Line,MungedExprL,MungedExprR}, Vars3};
-munge_expr({cons,Line,ExprH,ExprT}, Vars) ->
- {MungedExprH, Vars2} = munge_expr(ExprH, Vars),
- {MungedExprT, Vars3} = munge_expr(ExprT, Vars2),
- {{cons,Line,MungedExprH,MungedExprT}, Vars3};
-munge_expr({op,Line,Op,ExprL,ExprR}, Vars) ->
- {MungedExprL, Vars2} = munge_expr(ExprL, Vars),
- {MungedExprR, Vars3} = munge_expr(ExprR, Vars2),
- {{op,Line,Op,MungedExprL,MungedExprR}, Vars3};
-munge_expr({op,Line,Op,Expr}, Vars) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- {{op,Line,Op,MungedExpr}, Vars2};
-munge_expr({'catch',Line,Expr}, Vars) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- {{'catch',Line,MungedExpr}, Vars2};
-munge_expr({call,Line1,{remote,Line2,ExprM,ExprF},Exprs},
- Vars) when Vars#vars.is_guard==false->
- {MungedExprM, Vars2} = munge_expr(ExprM, Vars),
- {MungedExprF, Vars3} = munge_expr(ExprF, Vars2),
- {MungedExprs, Vars4} = munge_exprs(Exprs, Vars3, []),
- {{call,Line1,{remote,Line2,MungedExprM,MungedExprF},MungedExprs}, Vars4};
-munge_expr({call,Line1,{remote,_Line2,_ExprM,ExprF},Exprs},
- Vars) when Vars#vars.is_guard==true ->
- %% Difference in abstract format after preprocessing: BIF calls in guards
- %% are translated to {remote,...} (which is not allowed as source form)
- %% NOT NECESSARY FOR Vsn=raw_abstract_v1
- munge_expr({call,Line1,ExprF,Exprs}, Vars);
-munge_expr({call,Line,Expr,Exprs}, Vars) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- {MungedExprs, Vars3} = munge_exprs(Exprs, Vars2, []),
- {{call,Line,MungedExpr,MungedExprs}, Vars3};
-munge_expr({lc,Line,Expr,LC}, Vars) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- {MungedLC, Vars3} = munge_lc(LC, Vars2, []),
- {{lc,Line,MungedExpr,MungedLC}, Vars3};
-munge_expr({block,Line,Body}, Vars) ->
- {MungedBody, Vars2} = munge_body(Body, Vars, []),
- {{block,Line,MungedBody}, Vars2};
-munge_expr({'if',Line,Clauses}, Vars) ->
- {MungedClauses,Vars2} = munge_clauses(Clauses, Vars, []),
- {{'if',Line,MungedClauses}, Vars2};
-munge_expr({'case',Line,Expr,Clauses}, Vars) ->
- {MungedExpr,Vars2} = munge_expr(Expr,Vars),
- {MungedClauses,Vars3} = munge_clauses(Clauses, Vars2, []),
- {{'case',Line,MungedExpr,MungedClauses}, Vars3};
-munge_expr({'receive',Line,Clauses}, Vars) ->
- {MungedClauses,Vars2} = munge_clauses(Clauses, Vars, []),
- {{'receive',Line,MungedClauses}, Vars2};
-munge_expr({'receive',Line,Clauses,Expr,Body}, Vars) ->
- {MungedClauses,Vars2} = munge_clauses(Clauses, Vars, []),
- {MungedExpr, Vars3} = munge_expr(Expr, Vars2),
- {MungedBody, Vars4} = munge_body(Body, Vars3, []),
- {{'receive',Line,MungedClauses,MungedExpr,MungedBody}, Vars4};
-munge_expr({'try',Line,Exprs,Clauses,CatchClauses,After}, Vars) ->
- {MungedExprs, Vars1} = munge_exprs(Exprs, Vars, []),
- {MungedClauses, Vars2} = munge_clauses(Clauses, Vars1, []),
- {MungedCatchClauses, Vars3} = munge_clauses(CatchClauses, Vars2, []),
- {MungedAfter, Vars4} = munge_body(After, Vars3, []),
- {{'try',Line,MungedExprs,MungedClauses,MungedCatchClauses,MungedAfter},
- Vars4};
-%% Difference in abstract format after preprocessing: Funs get an extra
-%% element Extra.
-%% NOT NECESSARY FOR Vsn=raw_abstract_v1
-munge_expr({'fun',Line,{function,Name,Arity},_Extra}, Vars) ->
- {{'fun',Line,{function,Name,Arity}}, Vars};
-munge_expr({'fun',Line,{clauses,Clauses},_Extra}, Vars) ->
- {MungedClauses,Vars2}=munge_clauses(Clauses, Vars, []),
- {{'fun',Line,{clauses,MungedClauses}}, Vars2};
-munge_expr({'fun',Line,{clauses,Clauses}}, Vars) ->
- %% Only for Vsn=raw_abstract_v1
- {MungedClauses,Vars2}=munge_clauses(Clauses, Vars, []),
- {{'fun',Line,{clauses,MungedClauses}}, Vars2};
-munge_expr({bc,Line,Expr,LC}, Vars) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- {MungedLC, Vars3} = munge_lc(LC, Vars2, []),
- {{bc,Line,MungedExpr,MungedLC}, Vars3};
-munge_expr(Form, Vars) -> % var|char|integer|float|string|atom|nil|bin|eof
- {Form, Vars}.
-
-munge_exprs([Expr|Exprs], Vars, MungedExprs) when Vars#vars.is_guard==true,
- is_list(Expr) ->
- {MungedExpr, _Vars} = munge_exprs(Expr, Vars, []),
- munge_exprs(Exprs, Vars, [MungedExpr|MungedExprs]);
-munge_exprs([Expr|Exprs], Vars, MungedExprs) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- munge_exprs(Exprs, Vars2, [MungedExpr|MungedExprs]);
-munge_exprs([], Vars, MungedExprs) ->
- {lists:reverse(MungedExprs), Vars}.
-
-munge_lc([{generate,Line,Pattern,Expr}|LC], Vars, MungedLC) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- munge_lc(LC, Vars2, [{generate,Line,Pattern,MungedExpr}|MungedLC]);
-munge_lc([{b_generate,Line,Pattern,Expr}|LC], Vars, MungedLC) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- munge_lc(LC, Vars2, [{b_generate,Line,Pattern,MungedExpr}|MungedLC]);
-munge_lc([Expr|LC], Vars, MungedLC) ->
- {MungedExpr, Vars2} = munge_expr(Expr, Vars),
- munge_lc(LC, Vars2, [MungedExpr|MungedLC]);
-munge_lc([], Vars, MungedLC) ->
- {lists:reverse(MungedLC), Vars}.
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index 056d18da96..1fd40d1dd9 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. 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
diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl
index 4a7804a482..ec9be52bd3 100644
--- a/lib/test_server/src/test_server_sup.erl
+++ b/lib/test_server/src/test_server_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. 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
@@ -51,18 +51,19 @@ timetrap(Timeout0, Scale, Pid) ->
Timeout = if not Scale -> Timeout0;
true -> test_server:timetrap_scale_factor() * Timeout0
end,
+ TruncTO = trunc(Timeout),
receive
- after trunc(Timeout) ->
- Line = test_server:get_loc(Pid),
+ after TruncTO ->
+ MFLs = test_server:get_loc(Pid),
Mon = erlang:monitor(process, Pid),
Trap =
case get(test_server_init_or_end_conf) of
undefined ->
- {timetrap_timeout,trunc(Timeout),Line};
+ {timetrap_timeout,TruncTO,MFLs};
InitOrEnd ->
- {timetrap_timeout,trunc(Timeout),Line,InitOrEnd}
+ {timetrap_timeout,TruncTO,MFLs,InitOrEnd}
end,
- exit(Pid,Trap),
+ exit(Pid, Trap),
receive
{'DOWN', Mon, process, Pid, _} ->
ok
@@ -83,13 +84,13 @@ timetrap(Timeout0, Scale, Pid) ->
%% Handle = term()
%%
%% Cancels a time trap.
-
timetrap_cancel(Handle) ->
unlink(Handle),
MonRef = erlang:monitor(process, Handle),
exit(Handle, kill),
receive {'DOWN',MonRef,_,_,_} -> ok after 2000 -> ok end.
+
capture_get(Msgs) ->
receive
{captured,Msg} ->
diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl
index 3d55f41b8c..729a2b11fc 100644
--- a/lib/test_server/src/ts.erl
+++ b/lib/test_server/src/ts.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl
index 2ddffccf5b..9703478f20 100644
--- a/lib/test_server/src/ts_install.erl
+++ b/lib/test_server/src/ts_install.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -22,6 +22,7 @@
-export([install/2, platform_id/1]).
-include("ts.hrl").
+-include_lib("kernel/include/file.hrl").
install(install_local, Options) ->
install(os:type(), Options);
@@ -150,11 +151,17 @@ add_vars(Vars0, Opts0) ->
end,
{PlatformId, PlatformLabel, PlatformFilename, Version} =
platform([{longnames, LongNames}|Vars0]),
+ NetDir = lists:concat(["/net", hostname()]),
+ Mounted = case file:read_file_info(NetDir) of
+ {ok, #file_info{type = directory}} -> NetDir;
+ _ -> ""
+ end,
{Opts, [{longnames, LongNames},
{platform_id, PlatformId},
{platform_filename, PlatformFilename},
{rsh_name, get_rsh_name()},
{platform_label, PlatformLabel},
+ {ts_net_dir, Mounted},
{erl_flags, []},
{erl_release, Version},
{ts_testcase_callback, get_testcase_callback()} | Vars0]}.
diff --git a/lib/test_server/src/ts_install_cth.erl b/lib/test_server/src/ts_install_cth.erl
index d1a24525ab..a41916fd0a 100644
--- a/lib/test_server/src/ts_install_cth.erl
+++ b/lib/test_server/src/ts_install_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2011. 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
@@ -49,8 +49,7 @@
-include_lib("kernel/include/file.hrl").
--type proplist() :: list({atom(),term()}).
--type config() :: proplist().
+-type config() :: proplists:proplist().
-type reason() :: term().
-type skip_or_fail() :: {skip, reason()} |
{auto_skip, reason()} |
@@ -65,19 +64,19 @@ id(_Opts) ->
?MODULE.
%% @doc Always called before any other callback function.
--spec init(Id :: term(), Opts :: proplist()) ->
- State :: #state{}.
+-spec init(Id :: term(), Opts :: proplists:proplist()) ->
+ {ok, State :: #state{}}.
init(_Id, Opts) ->
Nodenames = proplists:get_value(nodenames, Opts, 0),
Nodes = proplists:get_value(nodes, Opts, 0),
TSConfDir = proplists:get_value(ts_conf_dir, Opts),
TargetSystem = proplists:get_value(target_system, Opts, install_local),
InstallOpts = proplists:get_value(install_opts, Opts, []),
- #state{ nodenames = Nodenames,
- nodes = Nodes,
- ts_conf_dir = TSConfDir,
- target_system = TargetSystem,
- install_opts = InstallOpts }.
+ {ok, #state{ nodenames = Nodenames,
+ nodes = Nodes,
+ ts_conf_dir = TSConfDir,
+ target_system = TargetSystem,
+ install_opts = InstallOpts } }.
%% @doc Called before init_per_suite is called.
-spec pre_init_per_suite(Suite :: atom(),
diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl
index d572b1454c..885a3c9b96 100644
--- a/lib/test_server/src/ts_run.erl
+++ b/lib/test_server/src/ts_run.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -212,6 +212,12 @@ make_command(Vars, Spec, State) ->
false ->
ok
end,
+
+ %% If Common Test specific variables are needed, add them here
+ %% on form: "{key1,value1}" "{key2,value2}" ...
+ NetDir = ts_lib:var(ts_net_dir, Vars),
+ TestVars = [ "\"{net_dir,\\\"",NetDir,"\\\"}\"" ],
+
%% NOTE: Do not use ' in these commands as it wont work on windows
Cmd = [Erl, Naming, "test_server"
" -rsh ", ts_lib:var(rsh_name, Vars),
@@ -224,6 +230,7 @@ make_command(Vars, Spec, State) ->
%% " -test_server_format_exception false",
" -boot start_sasl -sasl errlog_type error",
" -pz ",Cwd,
+ " -ct_test_vars ",TestVars,
" -eval \"file:set_cwd(\\\"",TestDir,"\\\")\" "
" -eval \"ct:run_test(",
backslashify(lists:flatten(State#state.test_server_args)),")\""
@@ -358,6 +365,14 @@ make_common_test_args(Args0, Options, _Vars) ->
[{logdir,"../test_server"}]
end,
+ TimeTrap = case test_server:timetrap_scale_factor() of
+ 1 ->
+ [];
+ Scale ->
+ [{multiply_timetraps, Scale},
+ {scale_timetraps, true}]
+ end,
+
ConfigPath = case {os:getenv("TEST_CONFIG_PATH"),
lists:keysearch(config, 1, Options)} of
{false,{value, {config, Path}}} ->
@@ -369,9 +384,8 @@ make_common_test_args(Args0, Options, _Vars) ->
end,
ConfigFiles = [{config,[filename:join(ConfigPath,File)
|| File <- get_config_files()]}],
-
io_lib:format("~100000p",[Args0++Trace++Cover++Logdir++
- ConfigFiles++Options]).
+ ConfigFiles++Options++TimeTrap]).
to_list(X) when is_atom(X) ->
atom_to_list(X);
diff --git a/lib/test_server/test/Makefile b/lib/test_server/test/Makefile
index 0648c1f96a..198440bb17 100644
--- a/lib/test_server/test/Makefile
+++ b/lib/test_server/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. 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
@@ -85,8 +85,8 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR)
- $(INSTALL_DATA) test_server.spec test_server.cover $(RELSYSDIR)
- chmod -f -R u+w $(RELSYSDIR)
+ $(INSTALL_DATA) test_server_test_lib.hrl test_server.spec test_server.cover $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
release_docs_spec:
diff --git a/lib/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl
index f4c19eeaf9..4c344717f0 100644
--- a/lib/test_server/test/test_server_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2011. 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
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
index 0563e1104f..dfcdff0c3e 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
index a6d7dfe851..06e0ea80c4 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
index deba4660c6..ccc0f12bf5 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
index 0e7f329f89..f38f768f3b 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
index 7ad269501d..0faf50a345 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
index 4037e1cc0e..9607d0d689 100644
--- a/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
diff --git a/lib/test_server/test/test_server_line_SUITE.erl b/lib/test_server/test/test_server_line_SUITE.erl
index aa14862e5a..0aba54f6b5 100644
--- a/lib/test_server/test/test_server_line_SUITE.erl
+++ b/lib/test_server/test/test_server_line_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
diff --git a/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl b/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl
index c3ee1b68cd..8f3477d3ac 100644
--- a/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl
+++ b/lib/test_server/test/test_server_line_SUITE_data/parse_transform_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
diff --git a/lib/test_server/test/test_server_test_lib.erl b/lib/test_server/test/test_server_test_lib.erl
index 66ff06e0ce..5ca24f3df7 100644
--- a/lib/test_server/test/test_server_test_lib.erl
+++ b/lib/test_server/test/test_server_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 4e293b76a7..1dd4a84ce9 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1,2 +1,2 @@
-TEST_SERVER_VSN = 3.4.2
+TEST_SERVER_VSN = 3.4.4