aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/common_test/doc/src/cover_chapter.xml8
-rw-r--r--lib/dialyzer/src/dialyzer.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl5
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/contract34
-rw-r--r--lib/erl_interface/doc/src/notes.xml16
-rw-r--r--lib/erl_interface/include/ei.h2
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src2
-rw-r--r--lib/inets/src/http_client/httpc_response.erl2
-rw-r--r--lib/observer/doc/src/crashdump_ug.xml4
-rw-r--r--lib/observer/src/crashdump_viewer.erl5
-rw-r--r--lib/observer/src/observer_tv_table.erl4
-rw-r--r--lib/ssh/doc/src/notes.xml28
-rw-r--r--lib/ssh/src/ssh.appup.src7
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl31
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl2
-rw-r--r--lib/stdlib/test/ets_SUITE.erl20
-rw-r--r--lib/test_server/doc/src/basics_chapter.xml12
-rw-r--r--lib/test_server/doc/src/part.xml4
-rw-r--r--lib/test_server/doc/src/part_notes.xml4
-rw-r--r--lib/test_server/doc/src/part_notes_history.xml4
-rw-r--r--lib/test_server/doc/src/ref_man.xml4
-rw-r--r--lib/test_server/doc/src/test_server.xml11
-rw-r--r--lib/test_server/doc/src/test_server_app.xml5
-rw-r--r--lib/test_server/doc/src/test_server_ctrl.xml55
-rw-r--r--lib/test_server/doc/src/test_spec_chapter.xml5
-rw-r--r--lib/test_server/doc/src/write_framework_chapter.xml13
-rw-r--r--lib/test_server/doc/src/write_test_chapter.xml3
-rw-r--r--lib/test_server/src/test_server.erl37
-rw-r--r--lib/test_server/src/test_server_ctrl.erl101
-rw-r--r--lib/test_server/src/test_server_internal.hrl10
-rw-r--r--lib/test_server/src/test_server_node.erl67
-rw-r--r--lib/test_server/src/ts_erl_config.erl22
-rw-r--r--lib/tools/doc/src/cover.xml18
-rw-r--r--lib/tools/emacs/erlang-pkg.el2
-rw-r--r--lib/tools/src/cover.erl86
36 files changed, 278 insertions, 334 deletions
diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml
index 4fa92d5583..736486350b 100644
--- a/lib/common_test/doc/src/cover_chapter.xml
+++ b/lib/common_test/doc/src/cover_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2012</year>
+ <year>2006</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -74,12 +74,6 @@
executed during the test. In overview mode, only the code
coverage overview page gets printed.</p>
- <p><em>Note:</em> Currently, for Common Test to be able to print
- code coverage HTML files for the modules included in the
- analysis, the source code files of these modules must be
- located in the same directory as the corresponding <c>.beam</c>
- files. This is a limitation that will be removed later.</p>
-
<p>You can choose to export and import code coverage data between
tests. If you specify the name of an export file in the cover
specification file, Common Test will export collected coverage
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index 63c51e219a..be4b9b6e12 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -409,9 +409,10 @@ message_to_string({extra_range, [M, F, A, ExtraRanges, SigRange]}) ->
io_lib:format("The specification for ~w:~w/~w states that the function"
" might also return ~s but the inferred return is ~s\n",
[M, F, A, ExtraRanges, SigRange]);
-message_to_string({overlapping_contract, []}) ->
- "Overloaded contract has overlapping domains;"
- " such contracts are currently unsupported and are simply ignored\n";
+message_to_string({overlapping_contract, [M, F, A]}) ->
+ io_lib:format("Overloaded contract for ~w:~w/~w has overlapping domains;"
+ " such contracts are currently unsupported and are simply ignored\n",
+ [M, F, A]);
message_to_string({spec_missing_fun, [M, F, A]}) ->
io_lib:format("Contract for function that does not exist: ~w:~w/~w\n",
[M, F, A]);
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 157c951f77..410be8586e 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -520,6 +520,8 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left],
case check_contract(Contract, Sig) of
{error, invalid_contract} ->
[invalid_contract_warning(MFA, FileLine, Sig, RecDict)|Acc];
+ {error, {overlapping_contract, []}} ->
+ [overlapping_contract_warning(MFA, FileLine)|Acc];
{error, {extra_range, ExtraRanges, STRange}} ->
Warn =
case t_from_forms_without_remote(Contract#contract.forms,
@@ -571,6 +573,9 @@ invalid_contract_warning({M, F, A}, FileLine, SuccType, RecDict) ->
SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
{?WARN_CONTRACT_TYPES, FileLine, {invalid_contract, [M, F, A, SuccTypeStr]}}.
+overlapping_contract_warning({M, F, A}, FileLine) ->
+ {?WARN_CONTRACT_TYPES, FileLine, {overlapping_contract, [M, F, A]}}.
+
extra_range_warning({M, F, A}, FileLine, ExtraRanges, STRange) ->
ERangesStr = erl_types:t_to_string(ExtraRanges),
STRangeStr = erl_types:t_to_string(STRange),
diff --git a/lib/dialyzer/test/small_SUITE_data/results/contract3 b/lib/dialyzer/test/small_SUITE_data/results/contract3
index 44b49e745a..6e111f87d9 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/contract3
+++ b/lib/dialyzer/test/small_SUITE_data/results/contract3
@@ -1,3 +1,3 @@
-contract3.erl:17: Overloaded contract has overlapping domains; such contracts are currently unsupported and are simply ignored
-contract3.erl:29: Overloaded contract has overlapping domains; such contracts are currently unsupported and are simply ignored
+contract3.erl:17: Overloaded contract for contract3:t1/1 has overlapping domains; such contracts are currently unsupported and are simply ignored
+contract3.erl:29: Overloaded contract for contract3:t3/3 has overlapping domains; such contracts are currently unsupported and are simply ignored
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index ae25f0c9ab..4c0267c264 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -30,6 +30,22 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.7.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Superfluous trailing comma in enum erlang_char_encoding
+ causing compile error for g++ with --pedantic option.</p>
+ <p>
+ Own Id: OTP-10913 Aux Id: seq12264 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.7.11</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index f51f377b9c..9b83385a46 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -193,7 +193,7 @@ extern volatile int __erl_errno;
typedef enum {
ERLANG_ASCII = 1,
ERLANG_LATIN1 = 2,
- ERLANG_UTF8 = 4,
+ ERLANG_UTF8 = 4
}erlang_char_encoding;
/* a pid */
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index 06ea973d9a..9287e105df 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1 +1 @@
-EI_VSN = 3.7.11
+EI_VSN = 3.7.12
diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
index 89fca8d270..d09f45df73 100644
--- a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
+++ b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src
@@ -66,7 +66,7 @@ CLASS_FILES = $(JAVA_FILES:.java=.class)
ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl
EBINS = $(ERL_FILES:.erl=.@EMULATOR@)
-@IFEQ@ (@jinterface_classpath@,)
+@IFEQ@ (@jinterface@,not_found)
all:
@ELSE@
all: $(CLASS_FILES) $(EBINS)
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index f177aac8f2..9107dfbf05 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -430,8 +430,6 @@ format_response({StatusLine, Headers, Body}) ->
Length = list_to_integer(Headers#http_response_h.'content-length'),
{NewBody, Data} =
case Length of
- 0 ->
- {Body, <<>>};
-1 -> % When no lenght indicator is provided
{Body, <<>>};
Length when (Length =< size(Body)) ->
diff --git a/lib/observer/doc/src/crashdump_ug.xml b/lib/observer/doc/src/crashdump_ug.xml
index dc65fe5b39..8b60f6ee98 100644
--- a/lib/observer/doc/src/crashdump_ug.xml
+++ b/lib/observer/doc/src/crashdump_ug.xml
@@ -48,8 +48,8 @@
Information which shows a short summary of the information in
the crashdump.</p>
- <p>The default browser is Internet Explorer on Windows or else
- Firefox. To use another browser, give the browser's start command
+ <p>The default browser is Internet Explorer on Windows, open on Mac OS X,
+ or else Firefox. To use another browser, give the browser's start command
as the second argument to <c>cdv</c>. If the given browser name is
not known to Crashdump Viewer, the browser argument is executed as
a command with the start URL as the only argument.</p>
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index 3b8d17c7d9..64a8457d16 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -214,6 +214,7 @@ script_start([File]) ->
DefaultBrowser =
case os:type() of
{win32,_} -> iexplore;
+ {unix,darwin} -> open;
_ -> firefox
end,
script_start([File,DefaultBrowser]);
@@ -277,8 +278,8 @@ usage() ->
io:format(
"\nusage: cdv file [ browser ]\n"
"\tThe \'file\' must be an existing erlang crash dump.\n"
- "\tDefault browser is \'iexplore\' (Internet Explorer) on Windows\n"
- "\tor else \'firefox\'.\n",
+ "\tDefault browser is \'iexplore\' (Internet Explorer) on Windows,\n"
+ "\t\'open\' on Mac OS X, or else \'firefox\'.\n",
[]).
diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl
index 5d1ab2e946..83619414ad 100644
--- a/lib/observer/src/observer_tv_table.erl
+++ b/lib/observer/src/observer_tv_table.erl
@@ -784,8 +784,10 @@ format_list(List) ->
make_list([Last]) ->
[format(Last), $]];
+make_list([Head|Tail]) when is_list(Tail) ->
+ [format(Head), $,|make_list(Tail)];
make_list([Head|Tail]) ->
- [format(Head), $,|make_list(Tail)].
+ [format(Head), $|, format(Tail), $]].
map_printable_list([$\n|Cs]) ->
[$\\, $n|map_printable_list(Cs)];
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 12175d9a29..dead764700 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -29,6 +29,34 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 2.1.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Bug in rekeying for daemon fixed.</p>
+ <p>
+ Own Id: OTP-10911</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Enhanced error message and added test for ssh clients
+ trying to start non existing subsystems.</p>
+ <p>
+ Own Id: OTP-10714</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 2.1.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index f4986410ab..b25e0c9e37 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,7 +19,8 @@
{"%VSN%",
[
- {<<"2.1.4">>, [{load_module, ssh_sftp, soft_purge, soft_purge, []}]},
+ {<<"2.1.4">>, [{load_module, ssh_sftp, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []}]},
{<<"2.1.3">>, [{restart_application, ssh}]},
{<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
@@ -28,7 +29,9 @@
{<<"1\\.*">>, [{restart_application, ssh}]}
],
[
- {<<"2.1.4">>, [{load_module, ssh_sftp, soft_purge, soft_purge, []}]},
+ {<<"2.1.4">>, [{load_module, ssh_sftp, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_handler, soft_purge, soft_purge, []}]},
+ {<<"2.1.3">>, [{restart_application, ssh}]},
{<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
{<<"2.1">>,[{restart_application, ssh}]},
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 74a6ac7d19..1c4477aeb3 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -213,6 +213,29 @@ key_exchange(#ssh_msg_kexdh_init{} = Msg,
description = Desc,
language = "en"}, State)
end;
+
+key_exchange({#ssh_msg_kexinit{} = Kex, Payload},
+ #state{ssh_params = #ssh{role = Role} = Ssh0,
+ key_exchange_init_msg = OwnKex} =
+ State) ->
+ Ssh1 = ssh_transport:key_init(opposite_role(Role), Ssh0, Payload),
+ try ssh_transport:handle_kexinit_msg(Kex, OwnKex, Ssh1) of
+ {ok, NextKexMsg, Ssh} when Role == client ->
+ send_msg(NextKexMsg, State),
+ {next_state, key_exchange,
+ next_packet(State#state{ssh_params = Ssh})};
+ {ok, Ssh} when Role == server ->
+ {next_state, key_exchange,
+ next_packet(State#state{ssh_params = Ssh})}
+ catch
+ #ssh_msg_disconnect{} = DisconnectMsg ->
+ handle_disconnect(DisconnectMsg, State);
+ _:Error ->
+ Desc = log_error(Error),
+ handle_disconnect(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = Desc,
+ language = "en"}, State)
+ end;
key_exchange(#ssh_msg_kexdh_reply{} = Msg,
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
@@ -456,7 +479,9 @@ userauth(#ssh_msg_userauth_banner{message = Msg},
{next_state, userauth, next_packet(State)}.
connected({#ssh_msg_kexinit{}, _Payload} = Event, State) ->
- kexinit(Event, State#state{renegotiate = true}).
+ kexinit(Event, State#state{renegotiate = true});
+connected({#ssh_msg_kexdh_init{}, _Payload} = Event, State) ->
+ key_exchange(Event, State#state{renegotiate = true}).
%%--------------------------------------------------------------------
%% Function:
@@ -510,7 +535,7 @@ handle_event({info, From, Options}, StateName, #state{ssh_params = Ssh} = State
spawn(?MODULE, ssh_info_handler, [Options, Ssh, From]),
{next_state, StateName, State};
handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
- Sent = inet:getstat(State#state.socket, [send_oct]),
+ {ok, [{send_oct,Sent}]} = inet:getstat(State#state.socket, [send_oct]),
MaxSent = proplists:get_value(rekey_limit, State#state.opts, 1024000000),
case Sent >= MaxSent of
true ->
@@ -518,7 +543,7 @@ handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
send_msg(SshPacket, State),
{next_state, connected,
next_packet(State#state{ssh_params = Ssh,
- key_exchange_init_msg = KeyInitMsg,
+ key_exchange_init_msg = KeyInitMsg,
renegotiate = true})};
_ ->
{next_state, connected, next_packet(State)}
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index dceec52464..93029c5038 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -272,7 +272,7 @@ rekey(Config) ->
{user_interaction, false},
{rekey_limit, 0}]),
receive
- after 15000 ->
+ after 200000 ->
%%By this time rekeying would have been done
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid)
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index b6c94a6f6d..d40609eeb0 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -3218,6 +3218,7 @@ delete_large_tab_1(Name, Flags, Data, Fix) ->
end
end,
0),
+ SchedTracerMon = monitor(process, SchedTracer),
?line Loopers = start_loopers(erlang:system_info(schedulers),
Prio,
fun (_) -> erlang:yield() end,
@@ -3237,12 +3238,14 @@ delete_large_tab_1(Name, Flags, Data, Fix) ->
N >= 5 -> ?line ok;
true -> ?line ?t:fail()
end
- end.
+ end,
+ receive {'DOWN',SchedTracerMon,process,SchedTracer,_} -> ok end,
+ ok.
delete_large_named_table(doc) ->
"Delete a large name table and try to create a new table with the same name in another process.";
delete_large_named_table(Config) when is_list(Config) ->
- ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
+ ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)],
?line EtsMem = etsmem(),
repeat_for_opts(fun(Opts) -> delete_large_named_table_do(Opts,Data) end),
?line verify_etsmem(EtsMem),
@@ -3264,16 +3267,17 @@ delete_large_named_table_1(Name, Flags, Data, Fix) ->
?line lists:foreach(fun({K,_}) -> ets:delete(Tab, K) end, Data)
end,
Parent = self(),
- Pid = my_spawn_link(fun() ->
- receive
- {trace,Parent,call,_} ->
- ets_new(Name, [named_table])
- end
- end),
+ {Pid, MRef} = my_spawn_opt(fun() ->
+ receive
+ {trace,Parent,call,_} ->
+ ets_new(Name, [named_table])
+ end
+ end, [link, monitor]),
?line erlang:trace(self(), true, [call,{tracer,Pid}]),
?line erlang:trace_pattern({ets,delete,1}, true, [global]),
?line erlang:yield(), true = ets:delete(Tab),
?line erlang:trace_pattern({ets,delete,1}, false, [global]),
+ receive {'DOWN',MRef,process,Pid,_} -> ok end,
ok.
evil_delete(doc) ->
diff --git a/lib/test_server/doc/src/basics_chapter.xml b/lib/test_server/doc/src/basics_chapter.xml
index a96cc88075..2e60d412e9 100644
--- a/lib/test_server/doc/src/basics_chapter.xml
+++ b/lib/test_server/doc/src/basics_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -105,14 +105,14 @@
<p>The Test Server consists of three parts:
</p>
<list type="bulleted">
- <item>The part that executes the test suites on target and
+ <item>The part that executes the test suites and
provides support for the test suite author is called
<c>test_server</c>. This is described in the chapter about
writing test cases in this user's guide, and in the reference
manual for the <c>test_server</c> module.</item>
<item>The controlling part, which provides the low level
- operator interface, starts and stops the target node (if remote
- target) and slave nodes and writes log files, is called
+ operator interface, starts and stops slave nodes and writes
+ log files, is called
<c>test_server_ctrl</c>. The Test Server Controller should not
be used directly when running tests. Instead a framework built
on top of it should be used. More information
@@ -176,9 +176,7 @@
shall return an empty list, a test specification or
<c>{skip,Reason}</c>. If an empty list is returned, it means
that the test case shall be executed, and so it must also have
- an execution clause. Note that the specification clause is
- always executed on the controller node, i.e. not on the target
- node.
+ an execution clause.
</item>
<tag><em>test case</em></tag>
<item>A single test included in a test suite. Typically it tests
diff --git a/lib/test_server/doc/src/part.xml b/lib/test_server/doc/src/part.xml
index fdcd3d274e..a20835e035 100644
--- a/lib/test_server/doc/src/part.xml
+++ b/lib/test_server/doc/src/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,7 +30,7 @@
<description>
<p><em>Test Server</em> is a portable test server for
automated application testing. The server can run test suites
- on local or remote targets and log progress and results to HTML
+ and log progress and results to HTML
pages. The main purpose of Test Server is to act as engine
inside customized test tools. A callback interface for
such framework applications is provided.</p>
diff --git a/lib/test_server/doc/src/part_notes.xml b/lib/test_server/doc/src/part_notes.xml
index 2347f64ca1..abf949dfda 100644
--- a/lib/test_server/doc/src/part_notes.xml
+++ b/lib/test_server/doc/src/part_notes.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,7 +30,7 @@
<description>
<p>The <em>Test Server</em> is a portable test server for
application testing. The test server can run automatic test suites
- on local or remote target and log progress and results to HTML
+ and log progress and results to HTML
pages. It also provides some support for test suite authors.</p>
<p>For information about older versions, see
<url href="part_notes_history_frame.html">Release Notes History</url>.</p>
diff --git a/lib/test_server/doc/src/part_notes_history.xml b/lib/test_server/doc/src/part_notes_history.xml
index 556d172755..4746f583b9 100644
--- a/lib/test_server/doc/src/part_notes_history.xml
+++ b/lib/test_server/doc/src/part_notes_history.xml
@@ -4,7 +4,7 @@
<part>
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,7 +30,7 @@
<description>
<p>The <em>Test Server</em> is a portable test server for
application testing. The test server can run automatic test suites
- on local or remote target and log progress and results to HTML
+ and log progress and results to HTML
pages. It also provides some support for test suite authors.</p>
</description>
<include file="notes_history"></include>
diff --git a/lib/test_server/doc/src/ref_man.xml b/lib/test_server/doc/src/ref_man.xml
index 17d6093dc0..ca0b38e0c8 100644
--- a/lib/test_server/doc/src/ref_man.xml
+++ b/lib/test_server/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,7 +31,7 @@
<description>
<p><em>Test Server</em> is a portable test server for
automated application testing. The server can run test suites
- on local or remote targets and log progress and results to HTML
+ and log progress and results to HTML
pages. The main purpose of Test Server is to act as engine
inside customized test tools. A callback interface for
such framework applications is provided.</p>
diff --git a/lib/test_server/doc/src/test_server.xml b/lib/test_server/doc/src/test_server.xml
index 841cbfbe91..5ef43dd628 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>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -73,8 +73,8 @@
<d>This is the same as returned from <c>os:type/0</c></d>
</type>
<desc>
- <p>This function can be called on controller or target node, and
- it will always return the OS type of the target node.</p>
+ <p>This function is equivalent to <c>os:type/0</c>. It is kept
+ for backwards compatibility.</p>
</desc>
</func>
<func>
@@ -465,9 +465,7 @@ Tries running clock_sanity_check() up to 8 times,and
<taglist>
<tag><c>{remote, true}</c></tag>
<item>Start the node on a remote host. If not specified, the
- node will be started on the local host (with some
- exceptions, as for the case of VxWorks, where
- all nodes are started on a remote host). Test cases that
+ node will be started on the local host. Test cases that
require a remote host will fail with a reasonable comment if
no remote hosts are available at the time they are run.
</item>
@@ -748,7 +746,6 @@ Only valid for peer nodes. Note that slave nodes always
test case or <c>{skip,Comment}</c>. The syntax of a test
specification is described in the Test Server User's Guide.
</p>
- <p><em>Note that the specification clause always is executed on the controller host.</em></p>
<p>The <em>execution clause</em> (argument <c>Config</c>) is
only called if the specification clause returns an empty list.
The execution clause is the real test case. Here you must call
diff --git a/lib/test_server/doc/src/test_server_app.xml b/lib/test_server/doc/src/test_server_app.xml
index 924cdc886b..ea4b5ffecf 100644
--- a/lib/test_server/doc/src/test_server_app.xml
+++ b/lib/test_server/doc/src/test_server_app.xml
@@ -4,7 +4,7 @@
<appref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,14 +36,13 @@
<description>
<p><em>Test Server</em> is a portable test server for
automated application testing. The server can run test suites
- on local or remote targets and log progress and results to HTML
+ and log progress and results to HTML
pages. The main purpose of Test Server is to act as engine
inside customized test tools. A callback interface for
such framework applications is provided.</p>
<p>In brief the test server supports:</p>
<list type="bulleted">
<item>Running multiple, concurrent test suites</item>
- <item>Running tests on remote and even diskless targets</item>
<item>Test suites may contain other test suites, in a tree fashion</item>
<item>Logging of the events in a test suite, on both suite and case levels</item>
<item>HTML presentation of test suite results</item>
diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml
index af96f1fe7e..9252cdce4f 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>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -57,64 +57,19 @@
<funcs>
<func>
<name>start() -> Result</name>
- <name>start(ParameterFile) -> Result</name>
<fsummary>Starts the test server.</fsummary>
<type>
<v>Result = ok | {error, {already_started, pid()}</v>
- <v>ParameterFile = atom() | string()</v>
</type>
<desc>
- <p>This function starts the test server. If the parameter file
- is given, it indicates that the target is remote. In that case
- the target node is started and a socket connection is
- established between the controller and the target node.
- </p>
- <p>The parameter file is a text file containing key-value
- tuples. Each tuple must be followed by a dot-newline
- sequence. The following key-value tuples are allowed:
- </p>
- <taglist>
- <tag><c>{type,PlatformType}</c></tag>
- <item>This is an atom indicating the target platform type,
- currently supported: <c>PlatformType = vxworks</c> <br></br>
-Mandatory
- </item>
- <tag><c>{target,TargetHost}</c></tag>
- <item>This is the name of the target host, can be atom or
- string.
- <br></br>
-Mandatory
- </item>
- <tag><c>{slavetargets,SlaveTargets}</c></tag>
- <item>This is a list of available hosts where slave nodes
- can be started. The hostnames are given as atoms or strings.
- <br></br>
-Optional, default <c>SlaveTargets = []</c></item>
- <tag><c>{longnames,Bool}</c></tag>
- <item>This indicates if longnames shall be used, i.e. if the
- <c>-name</c> option should be used for the target node
- instead of <c>-sname</c> <br></br>
-Optional, default <c>Bool = false</c></item>
- <tag><c>{master, {MasterHost, MasterCookie}}</c></tag>
- <item>If target is remote and the target node is started as
- a slave node, this option indicates which master and
- cookie to use. The given master
- will also be used as master for slave nodes started with
- <c>test_server:start_node/3</c>. It is expected that the
- <c>erl_boot_server</c> is started on the master node before
- the <c>test_server_ctrl:start/1</c> function is called.
- <br></br>
-Optional, if not given the test server controller node
- is used as master and the <c>erl_boot_server</c> is
- automatically started.</item>
- </taglist>
+ <p>This function starts the test server.</p>
</desc>
</func>
<func>
<name>stop() -> ok</name>
<fsummary>Stops the test server immediately.</fsummary>
<desc>
- <p>This stops the test server (both controller and target) and
+ <p>This stops the test server and
all its activity. The running test suite (if any) will be
halted.</p>
</desc>
@@ -685,10 +640,6 @@ test_server_ctrl:cross_cover_analyse(Level,[{s1,S1LogDir},{s2,S2LogDir}])
default name. This does not apply to <c>SPEC</c> which keeps
its names.
</item>
- <tag><c>PARAMETERS parameterfile</c></tag>
- <item>Specifies the parameter file to use when starting
- remote target
- </item>
<tag><c>COVER app cover_file analyse</c></tag>
<item>Indicates that the test should be run with cover
analysis. <c>app</c>, <c>cover_file</c> and <c>analyse</c>
diff --git a/lib/test_server/doc/src/test_spec_chapter.xml b/lib/test_server/doc/src/test_spec_chapter.xml
index 3a7730d61e..c197e03bed 100644
--- a/lib/test_server/doc/src/test_spec_chapter.xml
+++ b/lib/test_server/doc/src/test_spec_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -99,8 +99,7 @@
function fails, all tests in the test suite are skipped. The
difference between this "make case" and a normal conf case is
that for the make case, <c>Init</c> and <c>Fin</c> are given with
- arguments (<c>{Mod,Func,Args}</c>), and that they are executed
- on the controller node (i.e. not on target).
+ arguments (<c>{Mod,Func,Args}</c>).
</item>
<tag><c>Case</c></tag>
<item>This can only be used inside a module, i.e. not a test
diff --git a/lib/test_server/doc/src/write_framework_chapter.xml b/lib/test_server/doc/src/write_framework_chapter.xml
index 8a20e9afec..5c1c657d9e 100644
--- a/lib/test_server/doc/src/write_framework_chapter.xml
+++ b/lib/test_server/doc/src/write_framework_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -46,15 +46,8 @@
<title>Interfacing the test server controller from Erlang</title>
<p>Using the test server from Erlang means that you have to start
the test server and then add test jobs. Use
- <c>test_server_ctrl:start/0</c> to start a local target or
- <c>test_server_ctrl:start/1</c> to start a remote target. The test
- server is stopped by <c>test_server_ctrl:stop/0</c>.
- </p>
- <p>The argument to <c>test_server_ctrl:start/1</c> is the name of a
- parameter file. The parameter file specifies what type of target
- to start and where to start it, as well as some additional
- parameters needed for different target types. See the reference
- manual for a detailed description of all valid parameters.
+ <c>test_server_ctrl:start/0</c> to start the test server, and
+ <c>test_server_ctrl:stop/0</c> to stop it.
</p>
<section>
diff --git a/lib/test_server/doc/src/write_test_chapter.xml b/lib/test_server/doc/src/write_test_chapter.xml
index 12f0dfc361..086ed2a18d 100644
--- a/lib/test_server/doc/src/write_test_chapter.xml
+++ b/lib/test_server/doc/src/write_test_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -130,7 +130,6 @@
case. If the test specification is an empty list, this indicates
that the test case is a leaf test case, i.e. one to be executed.
</p>
- <p><em>Note that the specification clause of a test case is executed on the test server controller host. This means that if target is remote, the specification clause is probably executed on a different platform than the one tested.</em></p>
<p>The execution clause implements the actual test case. It takes
one argument, <c>Config</c>, which contain configuration
information like <c>data_dir</c> and <c>priv_dir</c>. See <seealso marker="#data_priv_dir">Data and Private Directories</seealso> for
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index 4c39c604a2..8b0be51be3 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -218,17 +218,14 @@ do_cover_compile1([]) ->
%% Analyse = {details,Dir} | details | {overview,void()} | overview
%% Modules = [atom()], the modules to analyse
%%
-%% Cover analysis. If this is a remote target, analyse_to_file can not be used.
-%% In that case the analyse level 'line' is used instead if Analyse==details.
+%% Cover analysis. If Analyse=={details,Dir} analyse_to_file is used.
%%
-%% If this is a local target, the test directory is given
-%% (Analyse=={details,Dir}) and analyse_to_file can be used directly.
+%% If Analyse=={overview,Dir} analyse_to_file is not used, only an
+%% overview containing the number of covered/not covered lines in each
+%% module.
%%
-%% If Analyse==overview | {overview,Dir} analyse_to_file is not used, only
-%% an overview containing the number of covered/not covered lines in each module.
-%%
-%% Also, if a Dir exists, cover data will be exported to a file called
-%% all.coverdata in that directory.
+%% Also, cover data will be exported to a file called all.coverdata in
+%% the given directory.
%%
%% Finally, if Stop==true, then cover will be stopped after the
%% analysis is completed. Stopping cover causes the original (non
@@ -261,24 +258,13 @@ cover_analyse(Analyse,Modules,Stop) ->
Error ->
fun(_) -> Error end
end;
- details ->
- fun(M) ->
- case cover:analyse(M,line) of
- {ok,Lines} ->
- {lines,Lines};
- Error ->
- Error
- end
- end;
{overview,Dir} ->
case cover:export(filename:join(Dir,"all.coverdata")) of
ok ->
fun(_) -> undefined end;
Error ->
fun(_) -> Error end
- end;
- overview ->
- fun(_) -> undefined end
+ end
end,
R = pmap(
fun(M) ->
@@ -512,10 +498,10 @@ run_test_case_msgloop(#st{ref=Ref,pid=Pid,end_conf_pid=EndConfPid0}=St0) ->
end,
run_test_case_msgloop(St);
{sync_apply,From,MFA} ->
- sync_local_or_remote_apply(false,From,MFA),
+ do_sync_apply(false,From,MFA),
run_test_case_msgloop(St0);
{sync_apply_proxy,Proxy,From,MFA} ->
- sync_local_or_remote_apply(Proxy,From,MFA),
+ do_sync_apply(Proxy,From,MFA),
run_test_case_msgloop(St0);
{comment,NewComment0} ->
NewComment1 = test_server_ctrl:to_string(NewComment0),
@@ -2599,10 +2585,9 @@ purify_format(Format, Args) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% Generic send functions for communication with host
+%% Apply given function and reply to caller or proxy.
%%
-sync_local_or_remote_apply(Proxy, From, {M,F,A}) ->
- %% i'm a local target
+do_sync_apply(Proxy, From, {M,F,A}) ->
Result = apply(M, F, A),
if is_pid(Proxy) -> Proxy ! {sync_result_proxy,From,Result};
true -> From ! {sync_result,Result}
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 5d4d392166..a5216571c7 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -251,8 +251,6 @@ parse_cmd_line(['MODULE',Mod|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
parse_cmd_line(['CASE',Mod,Case|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
parse_cmd_line(Cmds,[{topcase,{Mod,Case}}|SpecList],[atom_to_list(Mod)|Names],
Param, Trc, Cov, TCCB);
-parse_cmd_line(['PARAMETERS',Param|Cmds], SpecList, Names, _Param, Trc, Cov, TCCB) ->
- parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, TCCB);
parse_cmd_line(['TRACE',Trc|Cmds], SpecList, Names, Param, _Trc, Cov, TCCB) ->
parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, TCCB);
parse_cmd_line(['COVER',App,CF,Analyse|Cmds], SpecList, Names, Param, Trc, _Cov, TCCB) ->
@@ -284,19 +282,23 @@ cast_to_list(X) -> lists:flatten(io_lib:format("~w", [X])).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% START INTERFACE
-start() ->
- start(local).
+%% Kept for backwards compatibility
+start(_) ->
+ start().
+start_link(_) ->
+ start_link().
-start(Param) ->
- case gen_server:start({local,?MODULE}, ?MODULE, [Param], []) of
+
+start() ->
+ case gen_server:start({local,?MODULE}, ?MODULE, [], []) of
{ok, Pid} ->
{ok, Pid};
Other ->
Other
end.
-start_link(Param) ->
- case gen_server:start_link({local,?MODULE}, ?MODULE, [Param], []) of
+start_link() ->
+ case gen_server:start_link({local,?MODULE}, ?MODULE, [], []) of
{ok, Pid} ->
{ok, Pid};
Other ->
@@ -463,24 +465,11 @@ controller_call(Arg, Timeout) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% init([Mode])
-%% Mode = lazy | error_logger
-%% StateFile = string()
-%% ReadMode = ignore_errors | halt_on_errors
+%% init([])
%%
%% init() is the init function of the test_server's gen_server.
-%% When Mode=error_logger: The init function of the test_server's gen_event
-%% event handler used as a replacement error_logger when running test_suites.
%%
-%% The init function reads the test server state file, to see what test
-%% suites were running when the test server was last running, and which
-%% flags that were in effect. If no state file is found, or there are
-%% errors in it, defaults are used.
-%%
-%% Mode 'lazy' ignores (and resets to []) any jobs in the state file
-%%
-
-init([_]) ->
+init([]) ->
case os:getenv("TEST_SERVER_CALL_TRACE") of
false ->
ok;
@@ -505,7 +494,6 @@ init([_]) ->
end,
test_server_sup:cleanup_crash_dumps(),
State = #state{jobs=[],finish=false},
- put(test_server_free_targets,[]),
TI0 = test_server:init_target_info(),
TargetHost = test_server_sup:hoststr(),
TI = TI0#target_info{host=TargetHost,
@@ -529,7 +517,7 @@ naming() ->
%% is completed.
%%
handle_call(kill_slavenodes, _From, State) ->
- Nodes = test_server_node:kill_nodes(State#state.target_info),
+ Nodes = test_server_node:kill_nodes(),
{reply, Nodes, State};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -950,11 +938,11 @@ handle_call({wait_for_node, Node}, From, State) ->
%% - the node is really stopped by test_server when this returns.
handle_call({stop_node, Name}, _From, State) ->
- R = test_server_node:stop_node(Name, State#state.target_info),
+ R = test_server_node:stop_node(Name),
{reply, R, State};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% handle_call({stop_node,Name}, _, State) -> ok | {error,Reason}
+%% handle_call({is_release_available,Name}, _, State) -> ok | {error,Reason}
%%
%% Tests if the release is available.
@@ -993,9 +981,7 @@ handle_cast({node_started,Node}, State) ->
%%
%% Handles exit messages from linked processes. Only test suites are
%% expected to be linked. When a test suite terminates, it is removed
-%% from the job queue. If a target client terminates it means that we
-%% lost contact with target. The test_server_ctrl process is
-%% terminated, and teminate/2 will do the cleanup
+%% from the job queue.
handle_info(report_idle, State) ->
Finish = State#state.finish,
@@ -1047,35 +1033,12 @@ handle_info({'EXIT',Pid,Reason}, State) ->
end
end;
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% handle_info({tcp,Sock,Bin}, State)
-%%
-%% Message from remote main target process
-%% Only valid message is 'job_proc_killed', which indicates
-%% that a process running a test suite was killed
-
-handle_info({tcp,_MainSock,<<1,Request/binary>>}, State) ->
- case binary_to_term(Request) of
- {job_proc_killed,Name,Reason} ->
- %% The only purpose of this is to inform the user about what
- %% happened on target.
- %% The local job proc will soon be killed by the closed socket or
- %% because the job is finished. Then the above clause ('EXIT') will
- %% handle the problem.
- io:format("Suite ~ts was killed on remote target with reason"
- " ~p\n", [Name,Reason]);
- _ ->
- ignore
- end,
- {noreply,State};
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% handle_info({tcp_closed,Sock}, State)
%%
%% A Socket was closed. This indicates that a node died.
%% This can be
-%% *Target node (if remote)
%% *Slave or peer node started by a test suite
%% *Trace controll node
@@ -1084,7 +1047,7 @@ handle_info({tcp_closed,Sock}, State=#state{trc=Sock}) ->
%%! Maybe print something???
{noreply,State#state{trc=false}};
handle_info({tcp_closed,Sock}, State) ->
- test_server_node:nodedown(Sock, State#state.target_info),
+ test_server_node:nodedown(Sock),
{noreply,State};
handle_info(_, State) ->
%% dummy; accept all, do nothing.
@@ -1095,7 +1058,7 @@ handle_info(_, State) ->
%% Reason = term()
%%
%% Cleans up when the test_server is terminating. Kills the running
-%% test suites (if any) and terminates the remote target (if is exists)
+%% test suites (if any) and any possible remainting slave node
terminate(_Reason, State) ->
case State#state.trc of
@@ -1103,7 +1066,7 @@ terminate(_Reason, State) ->
Sock -> test_server_node:stop_tracer_node(Sock)
end,
kill_all_jobs(State#state.jobs),
- test_server_node:stop(State#state.target_info),
+ test_server_node:kill_nodes(),
case lists:keysearch(sasl, 1, application:which_applications()) of
{value,_} ->
test_server_h:restore();
@@ -2071,7 +2034,6 @@ do_add_end_per_suite_and_skip(LastMod, LastRef, Mod, FwMod) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% run_test_cases(TestSpec, Config, TimetrapData) -> exit(Result)
%%
-%% If remote target, a socket connection is established.
%% Runs the specified tests, then displays/logs the summary.
run_test_cases(TestSpec, Config, TimetrapData) ->
@@ -2137,8 +2099,7 @@ run_test_cases(TestSpec, Config, TimetrapData) ->
%% return a new configuration.
%%
%% {make,Ref,{Mod,Func,Args}} Mod:Func is a make function, and it is called
-%% with the given arguments. This function will *always* be called on the host
-%% - not on target.
+%% with the given arguments.
%%
%% {Mod,Case} This is a normal test case. Determine the correct
%% configuration, and insert {Mod,Case,Config} as head of the list,
@@ -3462,20 +3423,16 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% run_test_case(Ref, Num, Mod, Func, Args, RunInit,
-%% Where, TimetrapData, Mode) -> RetVal
+%% TimetrapData, Mode) -> RetVal
%%
%% Creates the minor log file and inserts some test case specific headers
-%% and footers into the log files. If a remote target is used, the test
-%% suite (binary) and the content of data_dir is sent. Then the test case
-%% is executed and the result is printed to the log files (also info
-%% about lingering processes & slave nodes in the system is presented).
+%% and footers into the log files. Then the test case is executed and the
+%% result is printed to the log files (also info about lingering processes
+%% & slave nodes in the system is presented).
%%
%% RunInit decides if the per test case init is to be run (true for all
%% but conf cases).
%%
-%% Where specifies if the test case should run on target or on the host.
-%% (Note that 'make' test cases always run on host).
-%%
%% Mode specifies if the test case should be executed by a dedicated,
%% parallel, process rather than sequentially by the main process. If
%% the former, the new process is spawned and the dictionary of the main
@@ -4110,11 +4067,6 @@ do_format_exception(Reason={Error,Stack}) ->
%% DetectedFail = [{File,Line}]
%% ProcessesBefore = ProcessesAfter = integer()
%%
-%% Where indicates if the test should run on target or always on the host.
-%%
-%% If test is to be run on target, and target is remote the request is
-%% sent over socket to target, and test_server runs the case and sends the
-%% result back over the socket. Else test_server runs the case directly on host.
run_test_case_apply(CaseNum, Mod, Func, Args, Name, RunInit,
TimetrapData) ->
@@ -4351,8 +4303,7 @@ update_config(Config, []) ->
%% Cases is treated according to this table, then
%% FinMFA is placed in the BasicCaseList. InitMFA
%% and FinMFA are make/unmake functions. If InitMFA
-%% fails, Cases are not run. InitMFA and FinMFA are
-%% always run on the host - not on target.
+%% fails, Cases are not run.
%%
%% When a function is called, above, it means that the function is invoked
%% and the return is expected to be:
@@ -4702,7 +4653,7 @@ keep_name(Props) ->
(_) -> false end, Props).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Target node handling functions %%
+%% Node handling functions %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/test_server/src/test_server_internal.hrl b/lib/test_server/src/test_server_internal.hrl
index 9a11182725..4e734a330b 100644
--- a/lib/test_server/src/test_server_internal.hrl
+++ b/lib/test_server/src/test_server_internal.hrl
@@ -21,8 +21,7 @@
-define(MAIN_PORT,3289).
-define(ACCEPT_TIMEOUT,20000).
-%% Target information generated by test_server:init_target_info/0 and
-%% test_server_ctrl:contact_main_target/2
+%% Target information generated by test_server:init_target_info/0
%% Once initiated, this information will never change!!
-record(target_info, {os_family, % atom(); win32 | unix
os_type, % result of os:type()
@@ -36,21 +35,16 @@
username, % string()
cookie, % string(); Cookie for target node
naming, % string(); "-name" | "-sname"
- master, % string(); Was used for OSE's master
+ master}). % string(); Was used for OSE's master
% node for main target and slave nodes.
% For other platforms the target node
% itself is master for slave nodes
- %% The following are only used for remote targets
- slave_targets=[]}).% list() of atom(); all available
- % targets for starting slavenodes
-
%% Temporary information generated by test_server_ctrl:read_parameters/X
%% This information is used when starting the main target, and for
%% initiating the #target_info record.
-record(par, {type,
target,
- slave_targets=[],
naming,
master,
cookie}).
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index 54a49b31ca..619fd463de 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -26,10 +26,9 @@
%% Test Controller interface
-export([is_release_available/1]).
--export([stop/1]).
-export([start_tracer_node/2,trace_nodes/2,stop_tracer_node/1]).
--export([start_node/5, stop_node/2]).
--export([kill_nodes/1, nodedown/2]).
+-export([start_node/5, stop_node/1]).
+-export([kill_nodes/0, nodedown/1]).
%% Internal export
-export([node_started/1,trc/1,handle_debug/4]).
@@ -57,23 +56,12 @@ is_release_available(Rel) ->
false
end.
-stop(TI) ->
- kill_nodes(TI).
-
-nodedown(Sock, TI) ->
+nodedown(Sock) ->
Match = #slave_info{name='$1',socket=Sock,client='$2',_='_'},
case ets:match(slave_tab,Match) of
- [[Node,Client]] -> % Slave node died
+ [[Node,_Client]] -> % Slave node died
gen_tcp:close(Sock),
ets:delete(slave_tab,Node),
- close_target_client(Client),
- HostAtom = test_server_sup:hostatom(Node),
- case lists:member(HostAtom,TI#target_info.slave_targets) of
- true ->
- put(test_server_free_targets,
- get(test_server_free_targets) ++ [HostAtom]);
- false -> ok
- end,
slave_died;
[] ->
ok
@@ -300,9 +288,11 @@ start_node(_SlaveName, _Type, _Options, _From, _TI) ->
%%
%% Peer nodes are always started on the same host as test_server_ctrl
-%% Socket communication is used in case target and controller is
-%% not the same node (target must not know the controller node
-%% via erlang distribution)
+%%
+%% (Socket communication is used since in early days the test target
+%% and the test server controller node could be on different hosts and
+%% the target could not know the controller node via erlang
+%% distribution)
%%
start_node_peer(SlaveName, OptList, From, TI) ->
SuppliedArgs = start_node_get_option_value(args, OptList, []),
@@ -403,8 +393,6 @@ do_start_node_slave(Host0, SlaveName, Args, Prog, Cleanup) ->
_ -> cast_to_list(Host0)
end,
Cmd = Prog ++ " " ++ Args,
- %% Can use slave.erl here because I'm both controller and target
- %% so I will ping the new node anyway
case slave:start(Host, SlaveName, Args, no_link, Prog) of
{ok,Nodename} ->
case Cleanup of
@@ -545,62 +533,37 @@ start_node_get_option_value(Key, List, Default) ->
%% stop_node(Name) -> ok | {error,Reason}
%%
%% Clean up - test_server will stop this node
-stop_node(Name, TI) ->
+stop_node(Name) ->
case ets:lookup(slave_tab,Name) of
- [#slave_info{client=Client}] ->
+ [#slave_info{}] ->
ets:delete(slave_tab,Name),
- HostAtom = test_server_sup:hostatom(Name),
- case lists:member(HostAtom,TI#target_info.slave_targets) of
- true ->
- put(test_server_free_targets,
- get(test_server_free_targets) ++ [HostAtom]);
- false -> ok
- end,
- close_target_client(Client),
ok;
[] ->
{error, not_a_slavenode}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% kill_nodes(TI) -> ok
+%% kill_nodes() -> ok
%%
%% Brutally kill all slavenodes that were not stopped by test_server
-kill_nodes(TI) ->
+kill_nodes() ->
case ets:match_object(slave_tab,'_') of
[] -> [];
List ->
- lists:map(fun(SI) -> kill_node(SI,TI) end, List)
+ lists:map(fun(SI) -> kill_node(SI) end, List)
end.
-kill_node(SI,TI) ->
+kill_node(SI) ->
Name = SI#slave_info.name,
ets:delete(slave_tab,Name),
- HostAtom = test_server_sup:hostatom(Name),
- case lists:member(HostAtom,TI#target_info.slave_targets) of
- true ->
- put(test_server_free_targets,
- get(test_server_free_targets) ++ [HostAtom]);
- false -> ok
- end,
case SI#slave_info.socket of
undefined ->
catch rpc:call(Name,erlang,halt,[]);
Sock ->
gen_tcp:close(Sock)
end,
- close_target_client(SI#slave_info.client),
Name.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%% Platform specific code
-
-close_target_client(undefined) ->
- ok.
-
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% cast_to_list(X) -> string()
%%% X = list() | atom() | void()
diff --git a/lib/test_server/src/ts_erl_config.erl b/lib/test_server/src/ts_erl_config.erl
index 73abe86e11..a0fab4e2d2 100644
--- a/lib/test_server/src/ts_erl_config.erl
+++ b/lib/test_server/src/ts_erl_config.erl
@@ -32,7 +32,7 @@ variables(Base0, OsType) ->
Base2 = get_app_vars(fun erl_interface/2, Base1, OsType),
Base3 = get_app_vars(fun ic/2, Base2, OsType),
Base4 = get_app_vars(fun jinterface/2, Base3, OsType),
- Base5 = dl_vars(Base4, OsType),
+ Base5 = dl_vars(Base4, Base3, OsType),
Base6 = emu_vars(Base5),
Base7 = get_app_vars(fun ssl/2, Base6, OsType),
Base8 = erts_lib(Base7, OsType),
@@ -60,7 +60,7 @@ get_app_vars(AppFun, Vars, OsType) ->
exit({unexpected_internal_error, Garbage})
end.
-dl_vars(Vars, _) ->
+dl_vars(Vars, Base3, OsType) ->
ShlibRules0 = ".SUFFIXES:\n" ++
".SUFFIXES: @dll@ @obj@ .c\n\n" ++
".c@dll@:\n" ++
@@ -68,7 +68,23 @@ dl_vars(Vars, _) ->
"\t@SHLIB_LD@ @CROSSLDFLAGS@ @SHLIB_LDFLAGS@ $(SHLIB_EXTRA_LDFLAGS) -o $@ $*@obj@ @SHLIB_LDLIBS@ $(SHLIB_EXTRA_LDLIBS)",
ShlibRules = ts_lib:subst(ShlibRules0, Vars),
- [{'SHLIB_RULES', ShlibRules}|Vars].
+ case get_app_vars2(fun jinterface/2, Base3, OsType) of
+ {App, not_found} ->
+ [{'SHLIB_RULES', ShlibRules}, {App, "not_found"}|Vars];
+ _ ->
+ [{'SHLIB_RULES', ShlibRules}|Vars]
+ end.
+get_app_vars2(AppFun, Vars, OsType) ->
+ case catch AppFun(Vars,OsType) of
+ Res when is_list(Res) ->
+ {jinterface, ok};
+ {cannot_find_app, App} ->
+ {App, not_found};
+ {'EXIT', Reason} ->
+ exit(Reason);
+ Garbage ->
+ exit({unexpected_internal_error, Garbage})
+ end.
erts_lib_name(multi_threaded, {win32, V}) ->
link_library("erts_MD" ++ case is_debug_build() of
diff --git a/lib/tools/doc/src/cover.xml b/lib/tools/doc/src/cover.xml
index a2444ec947..beefd4ee8d 100644
--- a/lib/tools/doc/src/cover.xml
+++ b/lib/tools/doc/src/cover.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2001</year>
- <year>2012</year>
+ <year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -214,7 +214,9 @@
<c>{no_abstract_code,BeamFile}</c> is returned.
If the abstract code is encrypted, and no key is available
for decrypting it, the error reason
- <c><![CDATA[{encrypted_abstract_code,BeamFile} is returned. <p>If only the module name (i.e. not the full name of the <c>.beam]]></c> file) is given to this function, the
+ <c>{encrypted_abstract_code,BeamFile}</c> is returned.</p>
+ <p>If only the module name (i.e. not the full name of the
+ <c>.beam</c> file) is given to this function, the
<c>.beam</c> file is found by calling
<c>code:which(Module)</c>. If no <c>.beam</c> file is found,
the error reason <c>non_existing</c> is returned. If the
@@ -313,9 +315,15 @@
file, i.e. using <c>compile_beam/1</c> or
<c>compile_beam_directory/0,1</c>, it is assumed that the
source code can be found in the same directory as the
- <c>.beam</c> file, or in <c>../src</c> relative to that
- directory. If no source code is found,
- <c>,{error,no_source_code_found}</c> is returned.</p>
+ <c>.beam</c> file, in <c>../src</c> relative to that
+ directory, or using the source path in
+ <c>Module:module_info(compile)</c>. When using the latter,
+ two paths are examined: first the one constructed by
+ joining <c>../src</c> and the tail of the compiled path
+ below a trailing <c>src</c> component, then the compiled
+ path itself.
+ If no source code is found,
+ <c>{error,no_source_code_found}</c> is returned.</p>
<p>HINT: It is possible to issue multiple analyse_to_file commands at
the same time. </p>
</desc>
diff --git a/lib/tools/emacs/erlang-pkg.el b/lib/tools/emacs/erlang-pkg.el
index decc696e21..4d0aa6fcd3 100644
--- a/lib/tools/emacs/erlang-pkg.el
+++ b/lib/tools/emacs/erlang-pkg.el
@@ -1,3 +1,3 @@
(define-package "erlang" "2.7.0"
"Erlang major mode"
- '((flymake-mode "0.4.6")))
+ '())
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index 2579711dc7..dfcfc3675f 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1951,47 +1951,61 @@ move_clauses([{M,F,A,C,_L}|Clauses]) ->
move_clauses(Clauses);
move_clauses([]) ->
ok.
-
%% Given a .beam file, find the .erl file. Look first in same directory as
-%% the .beam file, then in <beamdir>/../src
+%% the .beam file, then in ../src, then in compile info.
find_source(Module, File0) ->
- case filename:rootname(File0,".beam") of
- File0 ->
- File0;
- File ->
- InSameDir = File++".erl",
- case filelib:is_file(InSameDir) of
- true ->
- InSameDir;
- false ->
- Dir = filename:dirname(File),
- Mod = filename:basename(File),
- InDotDotSrc = filename:join([Dir,"..","src",Mod++".erl"]),
- case filelib:is_file(InDotDotSrc) of
- true ->
- InDotDotSrc;
- false ->
- find_source_from_module(Module, File0)
- end
- end
+ try
+ Root = filename:rootname(File0, ".beam"),
+ Root == File0 andalso throw(File0), %% not .beam
+ %% Look for .erl in pwd.
+ File = Root ++ ".erl",
+ throw_file(File),
+ %% Not in pwd: look in ../src.
+ BeamDir = filename:dirname(File),
+ Base = filename:basename(File),
+ throw_file(filename:join([BeamDir, "..", "src", Base])),
+ %% Not in ../src: look for source path in compile info, but
+ %% first look relative the beam directory.
+ Info = lists:keyfind(source, 1, Module:module_info(compile)),
+ false == Info andalso throw({beam, File0}), %% stripped
+ {source, SrcFile} = Info,
+ throw_file(splice(BeamDir, SrcFile)), %% below ../src
+ throw_file(SrcFile), %% or absolute
+ %% No success means that source is either not under ../src or
+ %% its relative path differs from that of compile info. (For
+ %% example, compiled under src/x but installed under src/y.)
+ %% An option to specify an arbitrary source path explicitly is
+ %% probably a better solution than either more heuristics or a
+ %% potentially slow filesystem search.
+ {beam, File0}
+ catch
+ Path -> Path
end.
-%% In case we can't find the file from the given .beam,
-%% we try to get the information directly from the module source
-find_source_from_module(Module, File) ->
- Compile = Module:module_info(compile),
- case lists:keyfind(source, 1, Compile) of
- {source, Path} ->
- case filelib:is_file(Path) of
- true ->
- Path;
- false ->
- {beam, File}
- end;
- false ->
- {beam, File}
- end.
+throw_file(Path) ->
+ false /= Path andalso filelib:is_file(Path) andalso throw(Path).
+
+%% Splice the tail of a source path, starting from the last "src"
+%% component, onto the parent of a beam directory, or return false if
+%% no "src" component is found.
+%%
+%% Eg. splice("/path/to/app-1.0/ebin", "/compiled/path/to/app/src/x/y.erl")
+%% --> "/path/to/app-1.0/ebin/../src/x/y.erl"
+%%
+%% This handles the case of source in subdirectories of ../src with
+%% beams that have moved since compilation.
+%%
+splice(BeamDir, SrcFile) ->
+ case lists:splitwith(fun(C) -> C /= "src" end, revsplit(SrcFile)) of
+ {T, [_|_]} -> %% found src component
+ filename:join([BeamDir, "..", "src" | lists:reverse(T)]);
+ {_, []} -> %% or not
+ false
+ end.
+
+revsplit(Path) ->
+ lists:reverse(filename:split(Path)).
do_parallel_analysis(Module, Analysis, Level, Loaded, From, State) ->
analyse_info(Module,State#main_state.imported),