aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/src/ct_gen_conn.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common_test/src/ct_gen_conn.erl')
-rw-r--r--lib/common_test/src/ct_gen_conn.erl174
1 files changed, 82 insertions, 92 deletions
diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl
index 56082086f6..1ab9946d96 100644
--- a/lib/common_test/src/ct_gen_conn.erl
+++ b/lib/common_test/src/ct_gen_conn.erl
@@ -1,40 +1,33 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2018. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
-%%% @doc Generic connection owner process.
+%%% Generic connection owner process.
%%%
-%%% @type handle() = pid(). A handle for using a connection implemented
+%%% -type handle() = pid(). A handle for using a connection implemented
%%% with ct_gen_conn.erl.
-module(ct_gen_conn).
--compile(export_all).
-
--export([start/4, stop/1, get_conn_pid/1]).
+-export([start/4, stop/1, get_conn_pid/1, check_opts/1]).
-export([call/2, call/3, return/2, do_within_time/2]).
-
-%%----------------------------------------------------------------------
-%% Exported types
-%%----------------------------------------------------------------------
--export_type([server_id/0,
- target_name/0,
- key_or_name/0]).
+-export([log/3, start_log/1, cont_log/2, cont_log_no_timestamp/2, end_log/0]).
-ifdef(debug).
-define(dbg,true).
@@ -54,20 +47,8 @@
cb_state,
ct_util_server}).
-%%------------------------------------------------------------------
-%% Type declarations
-%%------------------------------------------------------------------
--type server_id() :: atom().
-%% A `ServerId' which exists in a configuration file.
--type target_name() :: atom().
-%% A name which is associated to a `server_id()' via a
-%% `require' statement or a call to {@link ct:require/2} in the
-%% test suite.
--type key_or_name() :: server_id() | target_name().
-
-
%%%-----------------------------------------------------------------
-%%% @spec start(Address,InitData,CallbackMod,Opts) ->
+%%% -spec start(Address,InitData,CallbackMod,Opts) ->
%%% {ok,Handle} | {error,Reason}
%%% Name = term()
%%% CallbackMod = atom()
@@ -77,57 +58,52 @@
%%% Opt = {name,Name} | {use_existing_connection,boolean()} |
%%% {reconnect,boolean()} | {forward_messages,boolean()}
%%%
-%%% @doc Open a connection and start the generic connection owner process.
+%%% Open a connection and start the generic connection owner process.
%%%
-%%% <p>The <code>CallbackMod</code> is a specific callback module for
+%%% The CallbackMod is a specific callback module for
%%% each type of connection (e.g. telnet, ftp,...). It must export the
-%%% function <code>init/3</code> which takes the arguments
-%%% <code>Name</code>, <code>Addresse</code>) and
-%%% <code>InitData</code> and returna
-%%% <code>{ok,ConnectionPid,State}</code> or
-%%% <code>{error,Reason}</code>.</p>
+%%% function init/3 which takes the arguments
+%%% Name, Addresse) and
+%%% InitData and returna
+%%% {ok,ConnectionPid,State} or
+%%% {error,Reason}.
%%%
-%%% If no name is given, the <code>Name</code> argument in init/3 will
-%%% have the value <code>undefined</code>.
+%%% If no name is given, the Name argument in init/3 will
+%%% have the value undefined.
%%%
%%% The callback modules must also export
-%%% ```
+%%%
%%% handle_msg(Msg,From,State) -> {reply,Reply,State} |
%%% {noreply,State} |
%%% {stop,Reply,State}
%%% terminate(ConnectionPid,State) -> term()
%%% close(Handle) -> term()
-%%% '''
%%%
-%%% The <code>close/1</code> callback function is actually a callback
+%%% The close/1 callback function is actually a callback
%%% for ct_util, for closing registered connections when
-%%% ct_util_server is terminated. <code>Handle</code> is the Pid of
+%%% ct_util_server is terminated. Handle is the Pid of
%%% the ct_gen_conn process.
%%%
-%%% If option <code>reconnect</code> is <code>true</code>, then the
+%%% If option reconnect is true, then the
%%% callback must also export
-%%% ```
+%%%
%%% reconnect(Address,State) -> {ok,ConnectionPid,State}
-%%% '''
%%%
-%%% If option <code>forward_messages</code> is <ocde>true</code>, then
+%%% If option forward_messages is <ocde>true, then
%%% the callback must also export
-%%% ```
+%%%
%%% handle_msg(Msg,State) -> {noreply,State} | {stop,State}
-%%% '''
%%%
%%% An old interface still exists. This is used by ct_telnet, ct_ftp
%%% and ct_ssh. The start function then has an explicit
-%%% <code>Name</code> argument, and no <code>Opts</code> argument. The
+%%% Name argument, and no Opts argument. The
%%% callback must export:
%%%
-%%% ```
%%% init(Name,Address,InitData) -> {ok,ConnectionPid,State}
%%% handle_msg(Msg,State) -> {Reply,State}
%%% reconnect(Address,State) -> {ok,ConnectionPid,State}
%%% terminate(ConnectionPid,State) -> term()
%%% close(Handle) -> term()
-%%% '''
%%%
start(Address,InitData,CallbackMod,Opts) when is_list(Opts) ->
do_start(Address,InitData,CallbackMod,Opts);
@@ -135,71 +111,81 @@ start(Name,Address,InitData,CallbackMod) ->
do_start(Address,InitData,CallbackMod,[{name,Name},{old,true}]).
%%%-----------------------------------------------------------------
-%%% @spec stop(Handle) -> ok
+%%% -spec stop(Handle) -> ok
%%% Handle = handle()
%%%
-%%% @doc Close the connection and stop the process managing it.
+%%% Close the connection and stop the process managing it.
stop(Handle) ->
call(Handle,stop,5000).
%%%-----------------------------------------------------------------
-%%% @spec get_conn_pid(Handle) -> ok
+%%% -spec get_conn_pid(Handle) -> ok
%%% Handle = handle()
%%%
-%%% @doc Return the connection pid associated with Handle
+%%% Return the connection pid associated with Handle
get_conn_pid(Handle) ->
call(Handle,get_conn_pid).
%%%-----------------------------------------------------------------
-%%% @spec log(Heading,Format,Args) -> ok
+%%% -spec log(Heading,Format,Args) -> ok
%%%
-%%% @doc Log activities on the current connection (tool-internal use only).
-%%% @see ct_logs:log/3
+%%% Log activities on the current connection (tool-internal use only).
+%%% See ct_logs:log/3
log(Heading,Format,Args) ->
log(log,[Heading,Format,Args]).
%%%-----------------------------------------------------------------
-%%% @spec start_log(Heading) -> ok
+%%% -spec start_log(Heading) -> ok
%%%
-%%% @doc Log activities on the current connection (tool-internal use only).
-%%% @see ct_logs:start_log/1
+%%% Log activities on the current connection (tool-internal use only).
+%%% See ct_logs:start_log/1
start_log(Heading) ->
log(start_log,[Heading]).
%%%-----------------------------------------------------------------
-%%% @spec cont_log(Format,Args) -> ok
+%%% -spec cont_log(Format,Args) -> ok
%%%
-%%% @doc Log activities on the current connection (tool-internal use only).
-%%% @see ct_logs:cont_log/2
+%%% Log activities on the current connection (tool-internal use only).
+%%% See ct_logs:cont_log/2
cont_log(Format,Args) ->
log(cont_log,[Format,Args]).
%%%-----------------------------------------------------------------
-%%% @spec end_log() -> ok
+%%% -spec cont_log_no_timestamp(Format,Args) -> ok
+%%%
+%%% Log activities on the current connection (tool-internal use only).
+%%% See ct_logs:cont_log/2
+cont_log_no_timestamp(Format,Args) ->
+ log(cont_log_no_timestamp,[Format,Args]).
+
+%%%-----------------------------------------------------------------
+%%% -spec end_log() -> ok
%%%
-%%% @doc Log activities on the current connection (tool-internal use only).
-%%% @see ct_logs:end_log/0
+%%% Log activities on the current connection (tool-internal use only).
+%%% See ct_logs:end_log/0
end_log() ->
log(end_log,[]).
%%%-----------------------------------------------------------------
-%%% @spec do_within_time(Fun,Timeout) -> FunResult | {error,Reason}
+%%% -spec do_within_time(Fun,Timeout) -> FunResult | {error,Reason}
%%% Fun = function()
%%% Timeout = integer()
%%%
-%%% @doc Execute a function within a limited time (tool-internal use only).
+%%% Execute a function within a limited time (tool-internal use only).
%%%
-%%% <p>Execute the given <code>Fun</code>, but interrupt if it takes
-%%% more than <code>Timeout</code> milliseconds.</p>
+%%% Execute the given Fun, but interrupt if it takes
+%%% more than Timeout milliseconds.
%%%
-%%% <p>The execution is also interrupted if the connection is
-%%% closed.</p>
+%%% The execution is also interrupted if the connection is
+%%% closed.
do_within_time(Fun,Timeout) ->
Self = self(),
Silent = get(silent),
- TmpPid = spawn_link(fun() -> put(silent,Silent),
- R = Fun(),
- Self ! {self(),R}
+ TmpPid = spawn_link(fun() ->
+ ct_util:mark_process(),
+ put(silent,Silent),
+ R = Fun(),
+ Self ! {self(),R}
end),
ConnPid = get(conn_pid),
receive
@@ -258,7 +244,7 @@ do_start(Opts) ->
Error;
{'DOWN',MRef,process,_,Reason} ->
log("ct_gen_conn:start",
- "Connection process died: ~p\n",
+ "Connection process died: ~tp\n",
[Reason]),
{error,{connection_process_died,Reason}}
end.
@@ -312,6 +298,7 @@ return({To,Ref},Result) ->
init_gen(Parent,Opts) ->
process_flag(trap_exit,true),
+ ct_util:mark_process(),
put(silent,false),
try (Opts#gen_opts.callback):init(Opts#gen_opts.name,
Opts#gen_opts.address,
@@ -338,7 +325,7 @@ loop(Opts) ->
case Opts#gen_opts.reconnect of
true ->
log("Connection down!\nOpening new!",
- "Reason: ~p\nAddress: ~p\n",
+ "Reason: ~tp\nAddress: ~tp\n",
[Reason,Opts#gen_opts.address]),
case reconnect(Opts) of
{ok, NewPid, NewState} ->
@@ -349,12 +336,12 @@ loop(Opts) ->
Error ->
ct_util:unregister_connection(self()),
log("Reconnect failed. Giving up!",
- "Reason: ~p\n",
+ "Reason: ~tp\n",
[Error])
end;
false ->
ct_util:unregister_connection(self()),
- log("Connection closed!","Reason: ~p\n",[Reason])
+ log("Connection closed!","Reason: ~tp\n",[Reason])
end;
{'EXIT',Pid,Reason} ->
case Opts#gen_opts.ct_util_server of
@@ -365,8 +352,9 @@ loop(Opts) ->
end;
{stop, From} ->
ct_util:unregister_connection(self()),
- (Opts#gen_opts.callback):terminate(Opts#gen_opts.conn_pid,
- Opts#gen_opts.cb_state),
+ ConnPid = Opts#gen_opts.conn_pid,
+ unlink(ConnPid),
+ (Opts#gen_opts.callback):terminate(ConnPid,Opts#gen_opts.cb_state),
return(From,ok),
ok;
{{retry,{Error,_Name,CPid,_Msg}}, From} when
@@ -403,8 +391,9 @@ loop(Opts) ->
loop(Opts#gen_opts{cb_state=NewState});
{stop,Reply,NewState} ->
ct_util:unregister_connection(self()),
- (Opts#gen_opts.callback):terminate(Opts#gen_opts.conn_pid,
- NewState),
+ ConnPid = Opts#gen_opts.conn_pid,
+ unlink(ConnPid),
+ (Opts#gen_opts.callback):terminate(ConnPid,NewState),
return(From,Reply)
end;
Msg when Opts#gen_opts.forward==true ->
@@ -414,8 +403,9 @@ loop(Opts) ->
loop(Opts#gen_opts{cb_state=NewState});
{stop,NewState} ->
ct_util:unregister_connection(self()),
- (Opts#gen_opts.callback):terminate(Opts#gen_opts.conn_pid,
- NewState)
+ ConnPid = Opts#gen_opts.conn_pid,
+ unlink(ConnPid),
+ (Opts#gen_opts.callback):terminate(ConnPid,NewState)
end
end.