diff options
author | Micael Karlberg <bmk@erlang.org> | 2021-09-02 11:39:52 +0200 |
---|---|---|
committer | Micael Karlberg <bmk@erlang.org> | 2021-09-02 11:39:52 +0200 |
commit | 94d230be77ac1f8a26db869b16987e55795fc000 (patch) | |
tree | 03bb8dbe5b215d6c82b1d93e121322d2b44e5e61 | |
parent | 8591132d91fce51eb7409b64c3d905aa8324f268 (diff) | |
parent | ecf6b31a8e28f523e3e88bd0a8c2f5ea52e4237a (diff) | |
download | erlang-94d230be77ac1f8a26db869b16987e55795fc000.tar.gz |
Merge branch 'bmk/megaco/20210830/use_inet_backend/OTP-17533' into maint
OTP-17533
(OTP-17156)
-rw-r--r-- | lib/kernel/src/gen_tcp_socket.erl | 66 | ||||
-rw-r--r-- | lib/megaco/doc/src/megaco_tcp.xml | 38 | ||||
-rw-r--r-- | lib/megaco/doc/src/megaco_udp.xml | 34 | ||||
-rw-r--r-- | lib/megaco/src/tcp/megaco_tcp.erl | 93 | ||||
-rw-r--r-- | lib/megaco/src/tcp/megaco_tcp.hrl | 9 | ||||
-rw-r--r-- | lib/megaco/src/tcp/megaco_tcp_accept.erl | 22 | ||||
-rw-r--r-- | lib/megaco/src/udp/megaco_udp.erl | 44 | ||||
-rw-r--r-- | lib/megaco/src/udp/megaco_udp.hrl | 5 | ||||
-rw-r--r-- | lib/megaco/src/udp/megaco_udp_server.erl | 31 | ||||
-rw-r--r-- | lib/megaco/test/megaco_load_SUITE.erl | 125 | ||||
-rw-r--r-- | lib/megaco/test/megaco_mreq_SUITE.erl | 123 | ||||
-rw-r--r-- | lib/megaco/test/megaco_tcp_SUITE.erl | 197 | ||||
-rw-r--r-- | lib/megaco/test/megaco_test_lib.erl | 92 | ||||
-rw-r--r-- | lib/megaco/test/megaco_test_lib.hrl | 12 | ||||
-rw-r--r-- | lib/megaco/test/megaco_test_mg.erl | 121 | ||||
-rw-r--r-- | lib/megaco/test/megaco_test_mgc.erl | 107 | ||||
-rw-r--r-- | lib/megaco/test/megaco_udp_SUITE.erl | 150 |
17 files changed, 934 insertions, 335 deletions
diff --git a/lib/kernel/src/gen_tcp_socket.erl b/lib/kernel/src/gen_tcp_socket.erl index 1841623241..12e6e15f4c 100644 --- a/lib/kernel/src/gen_tcp_socket.erl +++ b/lib/kernel/src/gen_tcp_socket.erl @@ -50,7 +50,7 @@ -include("inet_int.hrl"). --define(DBG(T), erlang:display({{self(), ?MODULE, ?LINE, ?FUNCTION_NAME}, T})). +%% -define(DBG(T), erlang:display({{self(), ?MODULE, ?LINE, ?FUNCTION_NAME}, T})). %% ------------------------------------------------------------------------- @@ -1127,6 +1127,7 @@ server_opts() -> -compile({inline, [meta/1]}). meta(D) -> maps:with(maps:keys(server_write_opts()), D). + %%% ======================================================================== %%% State Machine %%% @@ -1249,7 +1250,7 @@ init({prepare, D, Owner}) -> owner_mon = OwnerMon}, {ok, accept, {P, D#{type => undefined, buffer => <<>>}}}; init(Arg) -> - error_logger:error_report([{badarg, {?MODULE, init, [Arg]}}]), + error_report([{badarg, {?MODULE, init, [Arg]}}]), error(badarg, [Arg]). @@ -1694,17 +1695,15 @@ handle_event( %% Handle select done - try recv again handle_event( info, ?socket_select(Socket, SelectRef), - #recv{info = ?select_info(SelectRef)}, + #recv{info = ?select_info(SelectRef)} = _State, {#params{socket = Socket} = P, D}) -> - %% %% ?DBG([info, {socket, Socket}, {ref, SelectRef}]), handle_recv(P, D, []); %% handle_event( info, ?socket_abort(Socket, SelectRef, Reason), - #recv{info = ?select_info(SelectRef)}, + #recv{info = ?select_info(SelectRef)} = _State, {#params{socket = Socket} = P, D}) -> - %% %% ?DBG({abort, Reason}), handle_connected(P, cleanup_recv_reply(P, D, [], Reason)); %% @@ -1764,9 +1763,9 @@ handle_shutdown2(Socket, NextState, How) -> handle_unexpected(Type, Content, State, {P, _D}) -> - error_logger:warning_report( - [{module, ?MODULE}, {socket, P#params.socket}, - {unknown_event, {Type, Content}}, {state, State}]), + warning_report([{socket, P#params.socket}, + {unknown_event, {Type, Content}}, + {state, State}]), case Type of {call, From} -> {keep_state_and_data, @@ -1781,9 +1780,9 @@ handle_closed(Type, Content, State, {P, _D}) -> {keep_state_and_data, [{reply, From, {error, closed}}]}; _ -> - error_logger:warning_report( - [{module, ?MODULE}, {socket, P#params.socket}, - {unknown_event, {Type, Content}}, {state, State}]), + warning_report([{socket, P#params.socket}, + {unknown_event, {Type, Content}}, + {state, State}]), keep_state_and_data end. @@ -1999,14 +1998,14 @@ handle_buffered(P, #{packet_size := PacketSize} = D, %% What do we do here? %% Keep the buffer and hope that it will go better with more data? %% Or discard it and continue as if nothing happened? - error_logger:warning_msg("Failed decoding message" - "~n Socket: ~p" - "~n Socket server: ~p" - "~n Packet type: ~p" - "~n byte_size(Data): ~p" - "~n Reason: ~p", - [P#params.socket, self(), - Type, byte_size(Data), Reason]), + warning_msg("Failed decoding message" + "~n Socket: ~p" + "~n Socket server: ~p" + "~n Packet type: ~p" + "~n byte_size(Data): ~p" + "~n Reason: ~p", + [P#params.socket, self(), + Type, byte_size(Data), Reason]), D end. @@ -2557,6 +2556,7 @@ state_setopts_server(P, D, State, Opts, {Tag, Value}) -> end. state_setopts_active(P, D, State, Opts, Active) -> + %% ?DBG([{active, Active}]), if Active =:= once; Active =:= true -> @@ -2780,8 +2780,34 @@ timeout(EndTime) -> -endif. + %% ------------------------------------------------------------------------- error_msg(F, A) -> error_logger:error_msg(F ++ "~n", A). +warning_msg(F, A) -> + error_logger:error_msg(F ++ "~n", A). + +error_report(Report) -> + error_logger:error_report(Report). + +warning_report(Report) -> + error_logger:warning_report([{module, ?MODULE}|Report]). + + + +%% ------------------------------------------------------------------------- + +%% formated_timestamp() -> +%% format_timestamp(os:timestamp()). + +%% format_timestamp(TS) -> +%% megaco:format_timestamp(TS). + +%% d(F) -> +%% d(F, []). + +%% d(F, A) -> +%% io:format("*** [~s] ~p ~w " ++ F ++ "~n", +%% [formated_timestamp(), self(), ?MODULE | A]). diff --git a/lib/megaco/doc/src/megaco_tcp.xml b/lib/megaco/doc/src/megaco_tcp.xml index 74a16eefab..eee44ef7f2 100644 --- a/lib/megaco/doc/src/megaco_tcp.xml +++ b/lib/megaco/doc/src/megaco_tcp.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2000</year><year>2020</year> + <year>2000</year><year>2021</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -56,7 +56,7 @@ <type> <v>TransportRef = pid() | regname()</v> <v>OptionListPerPort = [Option]</v> - <v>Option = {port, integer()} |{options, list()} |{receive_handle, term()}</v> + <v>Option = {port, integer()} | {options, list()} | {receive_handle, term()} | {inet_backend, default | inet | socket}</v> </type> <desc> <p>This function is used for starting new TPKT listening socket @@ -64,25 +64,43 @@ definitions.</p> </desc> </func> + <func> <name since="">connect(TransportRef, OptionList) -> {ok, Handle, ControlPid} | {error, Reason}</name> <fsummary></fsummary> <type> <v>TransportRef = pid() | regname()</v> <v>OptionList = [Option]</v> - <v>Option = {host, Ipaddr} | {port, integer()} |{options, list()} |{receive_handle, term()} |{module, atom()}</v> + <v>Option = {host, IpAddr} | + {port, integer()} | + {options, list()} | + {receive_handle, term()} | + {module, atom()} | + {inet_backend, default | inet | socket}</v> <v>Handle = socket_handle()</v> <v>ControlPid = pid()</v> <v>Reason = term()</v> </type> <desc> - <p>This function is used to open a TPKT connection.</p> - <p>The <c><![CDATA[module]]></c> option makes it possible for the user to provide - their own callback module. The <c><![CDATA[receive_message/4]]></c> or - <c><![CDATA[process_received_message/4]]></c> functions of this module is called - when a new message is received (which one depends on the size of the - message; small - receive_message, large - process_received_message). - Default value is <em>megaco</em>.</p> + <p>This function is used to open a TPKT connection.</p> + <taglist> + <tag><c><![CDATA[module]]></c></tag> + <item> + <p>This option makes it possible for the user to provide + their own callback module. + The <c><![CDATA[receive_message/4]]></c> + or <c><![CDATA[process_received_message/4]]></c> functions of + this module is called when a new message is received. + Which one is called depends on the size of the message; </p> + <taglist> + <tag><c><![CDATA[small]]></c></tag> + <item><p>receive_message</p></item> + <tag><c><![CDATA[large]]></c></tag> + <item><p>process_received_message</p></item> + </taglist> + <p>Default value is <em>megaco</em>. </p> + </item> + </taglist> </desc> </func> <func> diff --git a/lib/megaco/doc/src/megaco_udp.xml b/lib/megaco/doc/src/megaco_udp.xml index 2809bc8ce9..f9dc551f6c 100644 --- a/lib/megaco/doc/src/megaco_udp.xml +++ b/lib/megaco/doc/src/megaco_udp.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2000</year><year>2020</year> + <year>2000</year><year>2021</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -56,20 +56,36 @@ <type> <v>TransportRef = pid() | regname()</v> <v>OptionList = [option()]</v> - <v>option() = {port, integer()} |{options, list()} |{receive_handle, receive_handle()} |{module, atom()}</v> + <v>option() = {port, integer()} | + {options, list()} | + {receive_handle, receive_handle()} | + {module, atom()} | + {inet_backend, default | inet | socket}</v> <v>Handle = socket_handle()</v> <v>receive_handle() = term()</v> <v>ControlPid = pid()</v> <v>Reason = term()</v> </type> <desc> - <p>This function is used to open an UDP/IP socket.</p> - <p>The <c><![CDATA[module]]></c> option makes it possible for the user to provide - their own callback module. The functions <c><![CDATA[receive_message/4]]></c> or - <c><![CDATA[process_received_message/4]]></c> of this module is called when a new - message is received (which one depends on the size of the message; - small - receive_message, large - process_received_message). - Default value is <em>megaco</em>.</p> + <p>This function is used to open an UDP/IP socket.</p> + <taglist> + <tag><c><![CDATA[module]]></c></tag> + <item> + <p>The option makes it possible for the user to provide + their own callback module. + The functions <c><![CDATA[receive_message/4]]></c> or + <c><![CDATA[process_received_message/4]]></c> + of this module is called when a new message is received. + Which one depends on the size of the message: </p> + <taglist> + <tag><c><![CDATA[small]]></c></tag> + <item><p>receive_message</p></item> + <tag><c><![CDATA[large]]></c></tag> + <item><p>process_received_message</p></item> + </taglist> + <p>Default value is <em>megaco</em>.</p> + </item> + </taglist> </desc> </func> <func> diff --git a/lib/megaco/src/tcp/megaco_tcp.erl b/lib/megaco/src/tcp/megaco_tcp.erl index 1735439501..460e679efc 100644 --- a/lib/megaco/src/tcp/megaco_tcp.erl +++ b/lib/megaco/src/tcp/megaco_tcp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -66,6 +66,8 @@ reset_stats/0, reset_stats/1 ]). +%% -export([tcp_sockets/0]). + %%----------------------------------------------------------------- %% Internal exports @@ -177,11 +179,18 @@ connect(SupPid, Parameters) -> ?d1("connect -> options parsed: " "~n Rec: ~p", [Rec]), - #megaco_tcp{host = Host, - port = Port, - options = Options} = Rec, + #megaco_tcp{host = Host, + port = Port, + options = Options, + inet_backend = IB} = Rec, - IpOpt = [binary, {packet, tpkt}, {active, once} | Options], + IpOpt = + case IB of + default -> + []; + _ -> + [{inet_backend, IB}] + end ++ [binary, {packet, tpkt}, {active, once} | Options], %%------------------------------------------------------ %% Connect the other side @@ -376,7 +385,7 @@ create_snmp_counters(Socket, [Counter|Counters]) -> %%----------------------------------------------------------------- init({SupPid, _}) -> process_flag(trap_exit, true), - {ok, #state{supervisor_pid = SupPid}}. + {ok, #state{supervisor_pid = SupPid, linkdb = []}}. %%----------------------------------------------------------------- %% Func: terminate/1 @@ -409,7 +418,11 @@ start_tcp_listener(P, State) -> {error, Reason} -> ?d1("start_tcp_listener -> setup failed" "~n Reason: ~p", [Reason]), - {reply, {error, {could_not_start_listener, Reason}}, State} + DB = State#state.linkdb, + DBStatus = [{LPid, {LRec, LSock}, inet:info(LSock)} || + {LPid, {LRec, LSock}} <- DB], + Reply = {error, {could_not_start_listener, Reason, DBStatus}}, + {reply, Reply, State} end. @@ -480,10 +493,18 @@ setup(SupPid, Options) -> %%------------------------------------------------------ %% Setup the listen socket - IpOpts = [binary, {packet, tpkt}, {active, once}, - {reuseaddr, true} | TcpRec#megaco_tcp.options], - case catch gen_tcp:listen(TcpRec#megaco_tcp.port, IpOpts) of - {ok, Listen} -> + IpOpts = + case TcpRec#megaco_tcp.inet_backend of + default -> + []; + IB -> + [{inet_backend, IB}] + end ++ + [binary, {packet, tpkt}, {active, once}, + {reuseaddr, true} | TcpRec#megaco_tcp.options], + Port = TcpRec#megaco_tcp.port, + case catch gen_tcp:listen(Port, IpOpts) of + {ok, LSock} -> ?d1("setup -> listen ok" "~n Listen: ~p", [Listen]), @@ -491,14 +512,13 @@ setup(SupPid, Options) -> %%----------------------------------------------- %% Startup the accept process that will wait for %% connect attempts - case start_accept(SupPid, TcpRec, Listen) of + case start_accept(SupPid, TcpRec, LSock) of {ok, Pid} -> - ?d1("setup -> accept process started" "~n Pid: ~p", [Pid]), - ?tcp_debug(TcpRec, "tcp listen setup", []), - {ok, Pid, {TcpRec, Listen}}; + {ok, Pid, {TcpRec, LSock}}; + {error, _Reason} = Error -> ?d1("setup -> failed starting accept process" "~n Error: ~p", [Error]), @@ -506,16 +526,17 @@ setup(SupPid, Options) -> [Error]), Error end; + {error, Reason} -> ?d1("setup -> listen failed" "~n Reason: ~p", [Reason]), - Error = {error, {gen_tcp_listen, Reason}}, + Error = {error, {gen_tcp_listen, Reason, [Port, IpOpts]}}, ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]), Error; {'EXIT', _Reason} = Exit -> ?d1("setup -> listen exited" "~n Exit: ~p", [Exit]), - Error = {error, {gen_tcp_listen, Exit}}, + Error = {error, {gen_tcp_listen, Exit, [Port, IpOpts]}}, ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]), Error end; @@ -642,6 +663,10 @@ parse_options([{Tag, Val} | T], TcpRec, Mand) -> parse_options(T, TcpRec#megaco_tcp{module = Val}, Mand2); serialize when (Val =:= true) orelse (Val =:= false) -> parse_options(T, TcpRec#megaco_tcp{serialize = Val}, Mand2); + inet_backend when (Val =:= default) orelse + (Val =:= inet) orelse + (Val =:= socket) -> + parse_options(T, TcpRec#megaco_tcp{inet_backend = Val}, Mand2); Bad -> ?d1("parse_options -> bad option: " "~n Tag: ~p", [Tag]), @@ -691,3 +716,37 @@ warning_msg(F, A) -> call(Pid, Req) -> gen_server:call(Pid, Req, infinity). + + +%%----------------------------------------------------------------- + +%% formated_timestamp() -> +%% format_timestamp(os:timestamp()). + +%% format_timestamp(TS) -> +%% megaco:format_timestamp(TS). + +%% d(F) -> +%% d(F, []). + +%% d(F, A) -> +%% io:format("*** [~s] ~p ~w " ++ F ++ "~n", +%% [formated_timestamp(), self(), ?MODULE | A]). + + +%%----------------------------------------------------------------- + +%% tcp_sockets() -> +%% port_list("tcp_inet") ++ gen_tcp_socket:which_sockets(). + + +%% %% Return all ports having the name 'Name' +%% port_list(Name) -> +%% lists:filter( +%% fun(Port) -> +%% case erlang:port_info(Port, name) of +%% {name, Name} -> true; +%% _ -> false +%% end +%% end, erlang:ports()). + diff --git a/lib/megaco/src/tcp/megaco_tcp.hrl b/lib/megaco/src/tcp/megaco_tcp.hrl index 0c01f36b55..6d138eb2eb 100644 --- a/lib/megaco/src/tcp/megaco_tcp.hrl +++ b/lib/megaco/src/tcp/megaco_tcp.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -34,12 +34,13 @@ proxy_pid, receive_handle, module = megaco, - serialize = false % false: Spawn a new process for each message + serialize = false, % false: Spawn a new process for each message + inet_backend = default }). --define(GC_MSG_LIMIT,1000). --define(HEAP_SIZE(S),5000 + 2*(S)). +-define(GC_MSG_LIMIT, 1000). +-define(HEAP_SIZE(S), 5000 + 2*(S)). %%---------------------------------------------------------------------- diff --git a/lib/megaco/src/tcp/megaco_tcp_accept.erl b/lib/megaco/src/tcp/megaco_tcp_accept.erl index 5fcff200aa..da163dcc10 100644 --- a/lib/megaco/src/tcp/megaco_tcp_accept.erl +++ b/lib/megaco/src/tcp/megaco_tcp_accept.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -81,8 +81,7 @@ do_accept(Tcp, Sup, Fd) -> {ok, S} -> ?d1("do_accept -> accepted: " "~n S: ~p", [S]), - case megaco_tcp:start_connection(Sup, - Tcp#megaco_tcp{socket = S}) of + case megaco_tcp:start_connection(Sup, Tcp#megaco_tcp{socket = S}) of {ok, Pid} -> ?d1("do_accept -> connection started" "~n Pid: ~p", [Pid]), @@ -122,3 +121,20 @@ tcp_clear(Socket) -> after 0 -> ok end. + + + +%%----------------------------------------------------------------- + +%% formated_timestamp() -> +%% format_timestamp(os:timestamp()). + +%% format_timestamp(TS) -> +%% megaco:format_timestamp(TS). + +%% d(F) -> +%% d(F, []). + +%% d(F, A) -> +%% io:format("*** [~s] ~p ~w " ++ F ++ "~n", +%% [formated_timestamp(), self(), ?MODULE | A]). diff --git a/lib/megaco/src/udp/megaco_udp.erl b/lib/megaco/src/udp/megaco_udp.erl index 01aaa90f6c..099f4b7455 100644 --- a/lib/megaco/src/udp/megaco_udp.erl +++ b/lib/megaco/src/udp/megaco_udp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -114,9 +114,15 @@ open(SupPid, Options) -> %%------------------------------------------------------ %% Setup the socket - IpOpts = [binary, {reuseaddr, true}, {active, once} | - UdpRec#megaco_udp.options], - + IpOpts = + case UdpRec#megaco_udp.inet_backend of + default -> + []; + IB -> + [{inet_backend, IB}] + end ++ + [binary, {reuseaddr, true}, {active, once} | + UdpRec#megaco_udp.options], case (catch gen_udp:open(UdpRec#megaco_udp.port, IpOpts)) of {ok, Socket} -> ?udp_debug(UdpRec, "udp open", []), @@ -258,9 +264,9 @@ close(#send_handle{socket = Socket}) -> close(Socket); close(Socket) -> ?udp_debug({socket, Socket}, "udp close", []), - case erlang:port_info(Socket, connected) of - {connected, ControlPid} -> - megaco_udp_server:stop(ControlPid); + case inet:info(Socket) of + #{owner := ControlPid} = _Info when is_pid(ControlPid) -> + (catch megaco_udp_server:stop(ControlPid)); undefined -> {error, already_closed} end. @@ -294,8 +300,12 @@ parse_options([{Tag, Val} | T], UdpRec, Mand) -> parse_options(T, UdpRec#megaco_udp{receive_handle = Val}, Mand2); module when is_atom(Val) -> parse_options(T, UdpRec#megaco_udp{module = Val}, Mand2); - serialize when (Val =:= true) orelse (Val =:= false) -> + serialize when is_boolean(Val) -> parse_options(T, UdpRec#megaco_udp{serialize = Val}, Mand2); + inet_backend when (Val =:= default) orelse + (Val =:= inet) orelse + (Val =:= socket) -> + parse_options(T, UdpRec#megaco_udp{inet_backend = Val}, Mand2); Bad -> {error, {bad_option, Bad}} end; @@ -321,5 +331,19 @@ incNumOutOctets(SH, NumOctets) -> incCounter(Key, Inc) -> ets:update_counter(megaco_udp_stats, Key, Inc). -% incNumErrors(SH) -> -% incCounter({SH, medGwyGatewayNumErrors}, 1). +%% incNumErrors(SH) -> +%% incCounter({SH, medGwyGatewayNumErrors}, 1). + +%%----------------------------------------------------------------- + +%% formated_timestamp() -> +%% format_timestamp(os:timestamp()). + +%% format_timestamp(TS) -> +%% megaco:format_timestamp(TS). + +%% d(F) -> +%% d(F, []). + +%% d(F, A) -> +%% io:format("*** [~s] ~p " ++ F ++ "~n", [formated_timestamp(), self() | A]). diff --git a/lib/megaco/src/udp/megaco_udp.hrl b/lib/megaco/src/udp/megaco_udp.hrl index b5422d28c9..2560b4ad96 100644 --- a/lib/megaco/src/udp/megaco_udp.hrl +++ b/lib/megaco/src/udp/megaco_udp.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2016. All Rights Reserved. +%% Copyright Ericsson AB 2000-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -32,7 +32,8 @@ socket, receive_handle, module = megaco, - serialize = false % false: Spawn a new process for each message + serialize = false, % false: Spawn a new process for each message + inet_backend = default }). diff --git a/lib/megaco/src/udp/megaco_udp_server.erl b/lib/megaco/src/udp/megaco_udp_server.erl index 1df9a76671..5abb4165ae 100644 --- a/lib/megaco/src/udp/megaco_udp_server.erl +++ b/lib/megaco/src/udp/megaco_udp_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -29,9 +29,11 @@ -behaviour(gen_server). + %%----------------------------------------------------------------- %% Include files %%----------------------------------------------------------------- + -include_lib("megaco/src/udp/megaco_udp.hrl"). -include_lib("megaco/src/app/megaco_internal.hrl"). @@ -39,6 +41,7 @@ %%----------------------------------------------------------------- %% External exports %%----------------------------------------------------------------- + -export([ start_link/1, stop/1, @@ -46,9 +49,11 @@ upgrade_receive_handle/2 ]). + %%----------------------------------------------------------------- %% Internal exports %%----------------------------------------------------------------- + -export([ init/1, handle_call/3, @@ -60,6 +65,7 @@ handle_received_message/5 ]). + %%----------------------------------------------------------------- %% External interface functions %%----------------------------------------------------------------- @@ -71,6 +77,7 @@ start_link(Arg) -> gen_server:start_link(?MODULE, Arg, []). + %%----------------------------------------------------------------- %% Func: stop/1 %% Description: Stops the process that keeps track of an UDP @@ -83,6 +90,7 @@ stop(Pid) -> upgrade_receive_handle(Pid, NewHandle) -> call(Pid, {upgrade_receive_handle, NewHandle}). + %%----------------------------------------------------------------- %% Internal interface functions %%----------------------------------------------------------------- @@ -98,6 +106,7 @@ init(Arg) -> ?udp_debug(Arg, "udp server starting", [self()]), {ok, Arg}. + %%----------------------------------------------------------------- %% Func: terminate/2 %% Description: Termination function for the generic server @@ -106,6 +115,7 @@ terminate(Reason, State) -> ?udp_debug(State, "udp server terminating", [self(), Reason]), ok. + %%----------------------------------------------------------------- %% Func: handle_call/3 %% Description: Handling call messages (really just stop and garbage) @@ -120,6 +130,7 @@ handle_call(Req, From, UdpRec) -> "~n~p", [From, Req]), {reply, {error, {invalid_request, Req}}, UdpRec}. + %%----------------------------------------------------------------- %% Func: handle_cast/2 %% Description: Handling cast messages (really just stop and garbage) @@ -132,12 +143,13 @@ handle_cast(Msg, UdpRec) -> "~n~w", [Msg]), {noreply, UdpRec}. + %%----------------------------------------------------------------- %% Func: handle_info/2 %% Description: Handling non call/cast messages. Incomming messages %% from the socket and exit codes. %%----------------------------------------------------------------- -handle_info({udp, _UdpId, Ip, Port, Msg}, +handle_info({udp, _Socket, Ip, Port, Msg}, #megaco_udp{serialize = false} = UdpRec) -> #megaco_udp{socket = Socket, module = Mod, receive_handle = RH} = UdpRec, SH = megaco_udp:create_send_handle(Socket, Ip, Port), @@ -150,9 +162,9 @@ handle_info({udp, _UdpId, Ip, Port, Msg}, Sz -> receive_message(Mod, RH, SH, Sz, Msg) end, - inet:setopts(Socket, [{active, once}]), + activate(Socket), {noreply, UdpRec}; -handle_info({udp, _UdpId, Ip, Port, Msg}, +handle_info({udp, _Socket, Ip, Port, Msg}, #megaco_udp{serialize = true} = UdpRec) -> #megaco_udp{socket = Socket, module = Mod, receive_handle = RH} = UdpRec, SH = megaco_udp:create_send_handle(Socket, Ip, Port), @@ -160,7 +172,7 @@ handle_info({udp, _UdpId, Ip, Port, Msg}, incNumInMessages(SH), incNumInOctets(SH, MsgSize), process_received_message(Mod, RH, SH, Msg), - inet:setopts(Socket, [{active, once}]), + activate(Socket), {noreply, UdpRec}; handle_info(Info, UdpRec) -> warning_msg("received unexpected info: " @@ -203,6 +215,11 @@ do_stop(#megaco_udp{socket = Socket}) -> gen_udp:close(Socket). +-compile({inline, [activate/1]}). +activate(Socket) -> + inet:setopts(Socket, [{active, once}]). + + %%----------------------------------------------------------------- %% Func: incNumInMessages/1, incNumInOctets/2, incNumErrors/1 %% Description: SNMP counter increment functions @@ -217,8 +234,8 @@ incNumInOctets(SH, NumOctets) -> incCounter(Key, Inc) -> ets:update_counter(megaco_udp_stats, Key, Inc). -% incNumErrors(SH) -> -% incCounter({SH, medGwyGatewayNumErrors}, 1). +%% incNumErrors(SH) -> +%% incCounter({SH, medGwyGatewayNumErrors}, 1). %% info_msg(F, A) -> diff --git a/lib/megaco/test/megaco_load_SUITE.erl b/lib/megaco/test/megaco_load_SUITE.erl index d033e137ec..42e1a122a4 100644 --- a/lib/megaco/test/megaco_load_SUITE.erl +++ b/lib/megaco/test/megaco_load_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2020. All Rights Reserved. +%% Copyright Ericsson AB 2003-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -62,7 +62,7 @@ -define(MGC_START(Node, Mid, ET, Conf, Verb), megaco_test_mgc:start(Node, Mid, ET, - [{megaco_trace, false}] ++ Conf, Verb)). + Conf ++ [{megaco_trace, false}], Verb)). -define(MGC_STOP(Pid), megaco_test_mgc:stop(Pid)). -define(MGC_USER_INFO(Pid,Tag), megaco_test_mgc:user_info(Pid,Tag)). -define(MGC_CONN_INFO(Pid,Tag), megaco_test_mgc:conn_info(Pid,Tag)). @@ -70,8 +70,8 @@ -define(MG_START(Pid, Mid, Enc, Transp, Conf, Verb), megaco_test_mg:start(Pid, Mid, Enc, Transp, - [{megaco_trace, false}, - {transport_opts, [{serialize, true}]}] ++ Conf, + Conf ++ [{megaco_trace, false}, + {transport_opts, [{serialize, true}]}], Verb)). -define(MG_STOP(Pid), megaco_test_mg:stop(Pid)). -define(MG_USER_INFO(Pid,Tag), megaco_test_mg:user_info(Pid,Tag)). @@ -92,15 +92,47 @@ suite() -> [{ct_hooks, [ts_install_cth]}]. all() -> + %% This is a temporary messure to ensure that we can + %% test the socket backend without effecting *all* + %% applications on *all* machines. + %% This flag is set only for *one* host. + case ?TEST_INET_BACKENDS() of + true -> + [ + {group, inet_backend_default}, + {group, inet_backend_inet}, + {group, inet_backend_socket} + ]; + _ -> + [ + {group, inet_backend_default} + ] + end. + +groups() -> [ - {group, single}, - {group, multi} + {inet_backend_default, [], inet_backend_default_cases()}, + {inet_backend_inet, [], inet_backend_inet_cases()}, + {inet_backend_socket, [], inet_backend_socket_cases()}, + + {all, [], all_cases()}, + {single, [], single_cases()}, + {multi, [], multi_cases()} ]. -groups() -> +inet_backend_default_cases() -> + [{all, [], all_cases()}]. + +inet_backend_inet_cases() -> + [{all, [], all_cases()}]. + +inet_backend_socket_cases() -> + [{all, [], all_cases()}]. + +all_cases() -> [ - {single, [], single_cases()}, - {multi, [], multi_cases()} + {group, single}, + {group, multi} ]. single_cases() -> @@ -174,10 +206,39 @@ end_per_suite(Config0) when is_list(Config0) -> %% ----- %% -init_per_group(_GroupName, Config) -> +init_per_group(inet_backend_default = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + [{socket_create_opts, []} | Config]; +init_per_group(inet_backend_inet = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{socket_create_opts, [{inet_backend, inet}]} | Config] + end; +init_per_group(inet_backend_socket = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{socket_create_opts, [{inet_backend, socket}]} | Config] + end; +init_per_group(Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), Config. -end_per_group(_GroupName, Config) -> +end_per_group(Group, Config) when (inet_backend_default =:= Group) orelse + (inet_backend_init =:= Group) orelse + (inet_backend_socket =:= Group) -> + ?SLEEP(?SECS(5)), + Config; +end_per_group(_Group, Config) -> Config. @@ -397,25 +458,28 @@ try_single_user_load(Name, Config, NumLoaders0) -> single_user_load(State, Config, NumLoaders) -> i("starting with ~w loader(s)", [NumLoaders]), + SCO = ?config(socket_create_opts, Config), Res = load_controller(Config, fun(Env) -> populate(Env), - exit( single_user_load(State, NumLoaders) ) + exit( do_single_user_load(SCO, + State, NumLoaders) ) end), i("done"), Res. -single_user_load([MgcNode, MgNode], NumLoaders) -> +do_single_user_load(SCO, + [MgcNode, MgNode], NumLoaders) -> %% Start the MGC and MGs i("[MGC] start"), MgcMid = {deviceName, "ctrl"}, ET = [{text, tcp, [{serialize, true}]}], DSI = maybe_display_system_info(NumLoaders), - {ok, Mgc} = ?MGC_START(MgcNode, MgcMid, ET, DSI, ?MGC_VERBOSITY), + {ok, Mgc} = ?MGC_START(MgcNode, MgcMid, ET, SCO ++ DSI, ?MGC_VERBOSITY), i("[MG] start"), MgMid = {deviceName, "mg"}, - {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, DSI, ?MG_VERBOSITY), + {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, SCO ++ DSI, ?MG_VERBOSITY), d("MG user info: ~p", [?MG_USER_INFO(Mg, all)]), @@ -501,17 +565,18 @@ try_multi_user_load(Name, Config, NumUsers, NumLoaders0) -> multi_user_load(State, Config, NumUsers, NumLoaders) -> i("starting with ~w loader(s)", [NumLoaders]), + SCO = ?config(socket_create_opts, Config), Res = load_controller( Config, fun(Env) -> populate(Env), - exit( multi_user_load(State, NumUsers, NumLoaders) ) + exit( do_multi_user_load(SCO, State, NumUsers, NumLoaders) ) end), i("done"), Res. -multi_user_load([MgcNode | MgNodes], NumUsers, NumLoaders) +do_multi_user_load(SCO, [MgcNode | MgNodes], NumUsers, NumLoaders) when (is_integer(NumUsers) andalso (NumUsers > 1) andalso is_integer(NumLoaders) andalso (NumLoaders >= 1)) -> %% Start the MGC and MGs @@ -519,7 +584,7 @@ multi_user_load([MgcNode | MgNodes], NumUsers, NumLoaders) MgcMid = {deviceName, "ctrl"}, ET = [{text, tcp, [{serialize, false}]}], DSI = maybe_display_system_info(2 * NumUsers * NumLoaders), - {ok, Mgc} = ?MGC_START(MgcNode, MgcMid, ET, DSI, ?MGC_VERBOSITY), + {ok, Mgc} = ?MGC_START(MgcNode, MgcMid, ET, SCO ++ DSI, ?MGC_VERBOSITY), megaco_test_mgc:update_user_info(Mgc,reply_timer,1000), d("MGC user info: ~p", [?MGC_USER_INFO(Mgc, all)]), @@ -527,7 +592,7 @@ multi_user_load([MgcNode | MgNodes], NumUsers, NumLoaders) MgUsers = make_mids(MgNodes), d("start MGs, apply the load and stop MGs"), - ok = multi_load(MgUsers, DSI, NumLoaders, ?MULTI_USER_LOAD_NUM_REQUESTS), + ok = multi_load(MgUsers, SCO ++ DSI, NumLoaders, ?MULTI_USER_LOAD_NUM_REQUESTS), i("flush the message queue: ~p", [megaco_test_lib:flush()]), @@ -542,14 +607,14 @@ multi_user_load([MgcNode | MgNodes], NumUsers, NumLoaders) ok. -multi_load(MGs, DSI, NumLoaders, NumReqs) -> +multi_load(MGs, Conf, NumLoaders, NumReqs) -> d("multi_load -> entry with" "~n MGs: ~p" - "~n DSI: ~p" + "~n Conf: ~p" "~n NumLoaders: ~p" - "~n NumReqs: ~p", [MGs, DSI, NumLoaders, NumReqs]), + "~n NumReqs: ~p", [MGs, Conf, NumLoaders, NumReqs]), - Pids = multi_load_collector_start(MGs, DSI, NumLoaders, NumReqs, []), + Pids = multi_load_collector_start(MGs, Conf, NumLoaders, NumReqs, []), case timer:tc(?MODULE, do_multi_load, [Pids, NumLoaders, NumReqs]) of {Time, {ok, OKs, []}} -> Sec = Time / 1000000, @@ -569,13 +634,13 @@ do_multi_load(Pids, _NumLoaders, _NumReqs) -> lists:foreach(Fun, Pids), await_multi_load_collectors(Pids, [], []). -multi_load_collector_start([], _DSI, _NumLoaders, _NumReqs, Pids) -> +multi_load_collector_start([], _Conf, _NumLoaders, _NumReqs, Pids) -> Pids; -multi_load_collector_start([{Mid, Node}|MGs], DSI, NumLoaders, NumReqs, Pids) -> +multi_load_collector_start([{Mid, Node}|MGs], Conf, NumLoaders, NumReqs, Pids) -> Env = get(), Pid = spawn_link(?MODULE, multi_load_collector, - [self(), Node, Mid, DSI, NumLoaders, NumReqs, Env]), - multi_load_collector_start(MGs, DSI, NumLoaders, NumReqs, [{Pid,Mid}|Pids]). + [self(), Node, Mid, Conf, NumLoaders, NumReqs, Env]), + multi_load_collector_start(MGs, Conf, NumLoaders, NumReqs, [{Pid,Mid}|Pids]). get_env(Key, Env) -> case lists:keysearch(Key, 1, Env) of @@ -585,13 +650,13 @@ get_env(Key, Env) -> undefined end. -multi_load_collector(Parent, Node, Mid, DSI, NumLoaders, NumReqs, Env) -> +multi_load_collector(Parent, Node, Mid, Conf, NumLoaders, NumReqs, Env) -> put(verbosity, get_env(verbosity, Env)), put(tc, get_env(tc, Env)), put(sname, get_env(sname, Env) ++ "-loader"), - case ?MG_START(Node, Mid, text, tcp, DSI, ?MG_VERBOSITY) of + case ?MG_START(Node, Mid, text, tcp, Conf, ?MG_VERBOSITY) of {ok, Pid} -> - d("MG ~p user info: ~n~p", [Mid, ?MG_USER_INFO(Pid,all)]), + d("MG ~p user info: ~n~p", [Mid, ?MG_USER_INFO(Pid, all)]), ServChRes = ?MG_SERV_CHANGE(Pid), d("service change result: ~p", [ServChRes]), megaco_test_mg:update_conn_info(Pid,reply_timer,1000), diff --git a/lib/megaco/test/megaco_mreq_SUITE.erl b/lib/megaco/test/megaco_mreq_SUITE.erl index b53e99a995..12eb67f749 100644 --- a/lib/megaco/test/megaco_mreq_SUITE.erl +++ b/lib/megaco/test/megaco_mreq_SUITE.erl @@ -36,6 +36,7 @@ ]). +-include_lib("common_test/include/ct.hrl"). -include_lib("megaco/include/megaco.hrl"). -include_lib("megaco/include/megaco_message_v1.hrl"). -include("megaco_test_lib.hrl"). @@ -50,8 +51,8 @@ -define(A5555, ["11111111", "11111111", "00000000"]). -define(A5556, ["11111111", "11111111", "11111111"]). --define(MGC_START(Pid, Mid, ET, Verb), - megaco_test_mgc:start(Pid, Mid, ET, Verb)). +-define(MGC_START(Pid, Mid, ET, Conf, Verb), + megaco_test_mgc:start(Pid, Mid, ET, Conf, Verb)). -define(MGC_STOP(Pid), megaco_test_mgc:stop(Pid)). -define(MGC_GET_STATS(Pid, No), megaco_test_mgc:get_stats(Pid, No)). -define(MGC_RESET_STATS(Pid), megaco_test_mgc:reset_stats(Pid)). @@ -59,8 +60,8 @@ -define(MGC_REQ_PEND(Pid,To), megaco_test_mgc:request_pending(Pid,To)). -define(MGC_REQ_HAND(Pid), megaco_test_mgc:request_handle(Pid)). --define(MG_START(Pid, Mid, Enc, Transp, Verb), - megaco_test_mg:start(Pid, Mid, Enc, Transp, Verb)). +-define(MG_START(Pid, Mid, Enc, Transp, Conf, Verb), + megaco_test_mg:start(Pid, Mid, Enc, Transp, Conf, Verb)). -define(MG_STOP(Pid), megaco_test_mg:stop(Pid)). -define(MG_GET_STATS(Pid), megaco_test_mg:get_stats(Pid)). -define(MG_RESET_STATS(Pid), megaco_test_mg:reset_stats(Pid)). @@ -80,15 +81,48 @@ suite() -> [{ct_hooks, [ts_install_cth]}]. all() -> + %% This is a temporary messure to ensure that we can + %% test the socket backend without effecting *all* + %% applications on *all* machines. + %% This flag is set only for *one* host. + case ?TEST_INET_BACKENDS() of + true -> + [ + {group, inet_backend_default}, + {group, inet_backend_inet}, + {group, inet_backend_socket} + ]; + _ -> + [ + {group, inet_backend_default} + ] + end. + +groups() -> + [ + {inet_backend_default, [], inet_backend_default_cases()}, + {inet_backend_inet, [], inet_backend_inet_cases()}, + {inet_backend_socket, [], inet_backend_socket_cases()}, + + {all, [], all_cases()} + ]. + +inet_backend_default_cases() -> + [{all, [], all_cases()}]. + +inet_backend_inet_cases() -> + [{all, [], all_cases()}]. + +inet_backend_socket_cases() -> + [{all, [], all_cases()}]. + +all_cases() -> [ req_and_rep, req_and_pending, req_and_cancel ]. -groups() -> - []. - %% @@ -144,10 +178,34 @@ end_per_suite(Config0) when is_list(Config0) -> %% ----- %% -init_per_group(_GroupName, Config) -> +init_per_group(inet_backend_default = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + [{socket_create_opts, []} | Config]; +init_per_group(inet_backend_inet = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{socket_create_opts, [{inet_backend, inet}]} | Config] + end; +init_per_group(inet_backend_socket = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{socket_create_opts, [{inet_backend, socket}]} | Config] + end; +init_per_group(Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), Config. -end_per_group(_GroupName, Config) -> +end_per_group(_Group, Config) -> Config. @@ -200,7 +258,10 @@ req_and_rep(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun do_req_and_rep/1, + Case = fun(X) -> + SCO = ?config(socket_create_opts, Config), + do_req_and_rep(SCO, X) + end, Post = fun(Nodes) -> d("stop nodes (in the reverse order):" "~n ~p", [Nodes]), @@ -208,19 +269,19 @@ req_and_rep(Config) when is_list(Config) -> end, try_tc(req_and_rep, Pre, Case, Post). -do_req_and_rep([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) -> +do_req_and_rep(SCO, [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) -> %% Start the MGC and MGs i("start the MGC"), ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}], {ok, Mgc} = - ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY), + ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, SCO, ?MGC_VERBOSITY), i("start and connect the MGs"), MgConf0 = [{Mg1Node, "mg1", text, tcp, ?MG_VERBOSITY}, {Mg2Node, "mg2", text, udp, ?MG_VERBOSITY}, {Mg3Node, "mg3", binary, tcp, ?MG_VERBOSITY}, {Mg4Node, "mg4", binary, udp, ?MG_VERBOSITY}], - MgConf = rar_connect_mg(MgConf0, []), + MgConf = rar_connect_mg(SCO, MgConf0, []), %% Collect the (initial) MGs statistics Stats1 = rar_get_mg_stats(MgConf, []), @@ -309,19 +370,19 @@ do_req_and_rep([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) -> ok. -rar_connect_mg([], Acc) -> +rar_connect_mg(_, [], Acc) -> lists:reverse(Acc); -rar_connect_mg([{Node, Name, Coding, Trans, Verb}|Mg], Acc) -> - Pid = rar_connect_mg(Node, Name, Coding, Trans, Verb), - rar_connect_mg(Mg, [{Name, Pid}|Acc]). +rar_connect_mg(SCO, [{Node, Name, Coding, Trans, Verb}|Mg], Acc) -> + Pid = rar_connect_mg(SCO, Node, Name, Coding, Trans, Verb), + rar_connect_mg(SCO, Mg, [{Name, Pid}|Acc]). -rar_connect_mg(Node, Name, Coding, Trans, Verb) -> +rar_connect_mg(SCO, Node, Name, Coding, Trans, Verb) -> Mid = {deviceName, Name}, - {ok, Pid} = ?MG_START(Node, Mid, Coding, Trans, Verb), + {ok, Pid} = ?MG_START(Node, Mid, Coding, Trans, SCO, Verb), %% Ask the MGs to do a service change Res = ?MG_SERV_CHANGE(Pid), - d("rar_connect_mg -> (~s) service change result: ~p", [Name,Res]), + d("rar_connect_mg -> (~s) service change result: ~p", [Name, Res]), Pid. @@ -396,7 +457,10 @@ req_and_pending(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun do_req_and_pending/1, + Case = fun(X) -> + SCO = ?config(socket_create_opts, Config), + do_req_and_pending(SCO, X) + end, Post = fun(Nodes) -> d("stop nodes (in the reverse order):" "~n ~p", [Nodes]), @@ -404,17 +468,17 @@ req_and_pending(Config) when is_list(Config) -> end, try_tc(req_and_pending, Pre, Case, Post). -do_req_and_pending([MgcNode, MgNode]) -> +do_req_and_pending(SCO, [MgcNode, MgNode]) -> %% Start the MGC and MGs i("try start the MGC"), ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}], {ok, Mgc} = - ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY), + ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, SCO, ?MGC_VERBOSITY), i("try start the MG"), {ok, Mg} = - ?MG_START(MgNode, {deviceName, "mg"}, text, tcp, ?MG_VERBOSITY), + ?MG_START(MgNode, {deviceName, "mg"}, text, tcp, SCO, ?MG_VERBOSITY), i("connect MG (to MFC)"), Res1 = ?MG_SERV_CHANGE(Mg), @@ -462,7 +526,10 @@ req_and_cancel(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun do_req_and_cancel/1, + Case = fun(X) -> + SCO = ?config(socket_create_opts, Config), + do_req_and_cancel(SCO, X) + end, Post = fun(Nodes) -> d("stop nodes (in the reverse order):" "~n ~p", [Nodes]), @@ -470,16 +537,16 @@ req_and_cancel(Config) when is_list(Config) -> end, try_tc(req_and_cancel, Pre, Case, Post). -do_req_and_cancel([MgcNode, MgNode]) -> +do_req_and_cancel(SCO, [MgcNode, MgNode]) -> %% Start the MGC and MGs i("start the MGC"), ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}], {ok, Mgc} = - ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY), + ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, SCO, ?MGC_VERBOSITY), i("start the MG"), {ok, Mg} = - ?MG_START(MgNode, {deviceName, "mg"}, text, tcp, ?MG_VERBOSITY), + ?MG_START(MgNode, {deviceName, "mg"}, text, tcp, SCO, ?MG_VERBOSITY), i("connect the MG"), Res1 = ?MG_SERV_CHANGE(Mg), diff --git a/lib/megaco/test/megaco_tcp_SUITE.erl b/lib/megaco/test/megaco_tcp_SUITE.erl index 5792c6b380..88c7934894 100644 --- a/lib/megaco/test/megaco_tcp_SUITE.erl +++ b/lib/megaco/test/megaco_tcp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2020. All Rights Reserved. +%% Copyright Ericsson AB 2000-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -70,6 +70,11 @@ -define(CH, megaco_test_command_handler). -define(TEST_VERBOSITY, debug). +%% We have some strange reuseaddr issue (*some* times we eaddrinuse), +%% so this is intended to "ensure" we get no conflict. +-define(SERVER_PORT(C, I), + 2944 + proplists:get_value(adjust_server_port, C) + (I-1)). + %%---------------------------------------------------------------------- %% Records @@ -84,18 +89,51 @@ suite() -> [{ct_hooks, [ts_install_cth]}]. all() -> + %% This is a temporary messure to ensure that we can + %% test the socket backend without effecting *all* + %% applications on *all* machines. + %% This flag is set only for *one* host. + case ?TEST_INET_BACKENDS() of + true -> + [ + {group, inet_backend_default}, + {group, inet_backend_inet}, + {group, inet_backend_socket} + ]; + _ -> + [ + {group, inet_backend_default} + ] + end. + +groups() -> + [ + {inet_backend_default, [], inet_backend_default_cases()}, + {inet_backend_inet, [], inet_backend_inet_cases()}, + {inet_backend_socket, [], inet_backend_socket_cases()}, + + {all, [], all_cases()}, + {start, [], start_cases()}, + {sending, [], sending_cases()}, + {error, [], error_cases()} + ]. + +inet_backend_default_cases() -> + [{all, [], all_cases()}]. + +inet_backend_inet_cases() -> + [{all, [], all_cases()}]. + +inet_backend_socket_cases() -> + [{all, [], all_cases()}]. + +all_cases() -> [ {group, start}, {group, sending}, {group, error} ]. -groups() -> - [ - {start, [], start_cases()}, - {sending, [], sending_cases()}, - {error, [], error_cases()} - ]. start_cases() -> [ @@ -173,10 +211,41 @@ end_per_suite(Config0) when is_list(Config0) -> %% ----- %% +init_per_group(inet_backend_default = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + [{adjust_server_port, 0}, + {socket_create_opts, []} | Config]; +init_per_group(inet_backend_inet = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{adjust_server_port, 100}, + {socket_create_opts, [{inet_backend, inet}]} | Config] + end; +init_per_group(inet_backend_socket = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{adjust_server_port, 200}, + {socket_create_opts, [{inet_backend, socket}]} | Config] + end; init_per_group(Group, Config) -> ?ANNOUNCE_GROUP_INIT(Group), Config. +end_per_group(GroupName, Config) when (inet_backend_default =:= GroupName) orelse + (inet_backend_init =:= GroupName) orelse + (inet_backend_socket =:= GroupName) -> + ?SLEEP(?SECS(5)), + Config; end_per_group(_GroupName, Config) -> Config. @@ -198,8 +267,9 @@ init_per_testcase(Case, Config) -> end_per_testcase(Case, Config) -> p("end_per_testcase -> entry with" - "~n Config: ~p" - "~n Nodes: ~p", [Config, erlang:nodes()]), + "~n Config: ~p" + "~n Nodes: ~p", + [Config, erlang:nodes()]), p("system events during test: " "~n ~p", [megaco_test_global_sys_monitor:events()]), @@ -219,7 +289,7 @@ start_normal(Config) when is_list(Config) -> put(sname, "start_normal"), p("BEGIN TEST-CASE"), Options = [{port, 20000}, {receive_handle, apa}], - {ok, Pid} = start_case(Options, ok), + {ok, Pid} = start_case(Config, Options, ok), megaco_tcp:stop_transport(Pid), p("done"), ok. @@ -233,7 +303,7 @@ start_invalid_opt(Config) when is_list(Config) -> put(sname, "start_invalid_opt"), p("BEGIN TEST-CASE"), Options = [{port, 20000}, {receivehandle, apa}], - ok = start_case(Options, error), + ok = start_case(Config, Options, error), p("done"), ok. @@ -254,20 +324,28 @@ start_and_stop(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun do_start_and_stop/1, + Case = fun(X) -> do_start_and_stop(Config, X) end, + %% Case = fun(X) -> do_start_and_stop(Config, X, 10) end, Post = fun(Nodes) -> p("stop nodes"), ?STOP_NODES(lists:reverse(Nodes)) end, try_tc(start_and_stop, Pre, Case, Post). -do_start_and_stop([ServerNode, ClientNode]) -> + +%% do_start_and_stop(_Config, _Nodes, 0) -> +%% ok; +%% do_start_and_stop(Config, Nodes, N) -> +%% do_start_and_stop(Config, Nodes), +%% do_start_and_stop(Config, Nodes, N-1). + +do_start_and_stop(Config, [ServerNode, ClientNode]) -> %% Create command sequences p("create command sequences"), - ServerPort = 2944, - ServerCmds = start_and_stop_server_commands(ServerPort), + ServerPort = ?SERVER_PORT(Config, 1), % 2944, + ServerCmds = start_and_stop_server_commands(Config, ServerPort), {ok, ServerHost} = inet:gethostname(), - ClientCmds = start_and_stop_client_commands(ServerPort, ServerHost), + ClientCmds = start_and_stop_client_commands(Config, ServerPort, ServerHost), %% Start the test procs used in the test-case, one for each node p("start command handlers"), @@ -283,7 +361,7 @@ do_start_and_stop([ServerNode, ClientNode]) -> ok. -start_and_stop_server_commands(Port) -> +start_and_stop_server_commands(Config, Port) -> Opts = [{port, Port}], Self = self(), [ @@ -302,7 +380,7 @@ start_and_stop_server_commands(Port) -> #{id => 3, desc => "Listen", cmd => fun(State) -> - server_listen(State, Opts) + server_listen(Config, State, Opts) end}, #{id => 4, @@ -326,7 +404,7 @@ start_and_stop_server_commands(Port) -> ]. -start_and_stop_client_commands(ServerPort, ServerHost) -> +start_and_stop_client_commands(Config, ServerPort, ServerHost) -> Opts = [{port, ServerPort}, {host, ServerHost}], Self = self(), [ @@ -351,7 +429,7 @@ start_and_stop_client_commands(ServerPort, ServerHost) -> #{id => 4, desc => "Connect", cmd => fun(State) -> - client_connect(State, Opts) + client_connect(Config, State, Opts) end}, #{id => 5, @@ -389,20 +467,20 @@ sendreceive(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun do_sendreceive/1, + Case = fun(X) -> do_sendreceive(Config, X) end, Post = fun(Nodes) -> p("stop nodes"), ?STOP_NODES(lists:reverse(Nodes)) end, try_tc(sendreceive, Pre, Case, Post). -do_sendreceive([ServerNode, ClientNode]) -> +do_sendreceive(Config, [ServerNode, ClientNode]) -> %% Create command sequences p("create command sequences"), - ServerPort = 2944, - ServerCmds = sendreceive_server_commands(ServerPort), + ServerPort = ?SERVER_PORT(Config, 2), % 2944, + ServerCmds = sendreceive_server_commands(Config, ServerPort), {ok, ServerHost} = inet:gethostname(), - ClientCmds = sendreceive_client_commands(ServerPort, ServerHost), + ClientCmds = sendreceive_client_commands(Config, ServerPort, ServerHost), %% Start the test procs used in the test-case, one for each node p("start command handlers"), @@ -418,7 +496,7 @@ do_sendreceive([ServerNode, ClientNode]) -> ok. -sendreceive_server_commands(Port) -> +sendreceive_server_commands(Config, Port) -> Opts = [{port, Port}], Self = self(), [ @@ -437,7 +515,7 @@ sendreceive_server_commands(Port) -> #{id => 3, desc => "Listen", cmd => fun(State) -> - server_listen(State, Opts) + server_listen(Config, State, Opts) end}, #{id => 4, @@ -502,7 +580,7 @@ sendreceive_server_commands(Port) -> ]. -sendreceive_client_commands(ServerPort, ServerHost) -> +sendreceive_client_commands(Config, ServerPort, ServerHost) -> Opts = [{port, ServerPort}, {host, ServerHost}], Self = self(), [ @@ -527,7 +605,7 @@ sendreceive_client_commands(ServerPort, ServerHost) -> #{id => 4, desc => "Connect", cmd => fun(State) -> - client_connect(State, Opts) + client_connect(Config, State, Opts) end}, #{id => 5, @@ -594,20 +672,20 @@ block_unblock(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun do_block_unblock/1, + Case = fun(X) -> do_block_unblock(Config, X) end, Post = fun(Nodes) -> p("stop nodes"), ?STOP_NODES(lists:reverse(Nodes)) end, try_tc(block_unblock, Pre, Case, Post). -do_block_unblock([ServerNode, ClientNode]) -> +do_block_unblock(Config, [ServerNode, ClientNode]) -> %% Create command sequences p("create command sequences"), - ServerPort = 2944, - ServerCmds = block_unblock_server_commands(ServerPort), + ServerPort = ?SERVER_PORT(Config, 3), % 2944, + ServerCmds = block_unblock_server_commands(Config, ServerPort), {ok, ServerHost} = inet:gethostname(), - ClientCmds = block_unblock_client_commands(ServerPort, ServerHost), + ClientCmds = block_unblock_client_commands(Config, ServerPort, ServerHost), %% Start the test procs used in the test-case, one for each node p("start command handlers"), @@ -625,8 +703,8 @@ do_block_unblock([ServerNode, ClientNode]) -> ok. -block_unblock_server_commands(Port) -> - Opts = [{port, Port}], +block_unblock_server_commands(Config, Port) -> + Opts = [{port, Port}], Self = self(), [ #{id => 1, @@ -644,7 +722,7 @@ block_unblock_server_commands(Port) -> #{id => 3, desc => "Listen", cmd => fun(State) -> - server_listen(State, Opts) + server_listen(Config, State, Opts) end}, #{id => 4, @@ -671,11 +749,11 @@ block_unblock_server_commands(Port) -> server_await_continue_signal(State, 5000) end}, - #{id => 9, - desc => "Await nothing before sending a message (hejsan)", - cmd => fun(State) -> - server_await_nothing(State, 1000) - end}, + %% #{id => 9, + %% desc => "Await nothing before sending a message (hejsan)", + %% cmd => fun(State) -> + %% server_await_nothing(State, 1000) + %% end}, #{id => 10, desc => "Send message (hejsan)", @@ -715,7 +793,7 @@ block_unblock_server_commands(Port) -> ]. -block_unblock_client_commands(ServerPort, ServerHost) -> +block_unblock_client_commands(Config, ServerPort, ServerHost) -> Opts = [{port, ServerPort}, {host, ServerHost}], Self = self(), [ @@ -740,7 +818,7 @@ block_unblock_client_commands(ServerPort, ServerHost) -> #{id => 4, desc => "Connect", cmd => fun(State) -> - client_connect(State, Opts) + client_connect(Config, State, Opts) end}, #{id => 5, @@ -788,7 +866,7 @@ block_unblock_client_commands(ServerPort, ServerHost) -> #{id => 12, desc => "Await message (hejsan)", cmd => fun(State) -> - client_await_message(State, "hejsan", 100) + client_await_message(State, "hejsan", 500) end}, #{id => 13, @@ -895,33 +973,37 @@ tcp_server(Config) when is_list(Config) -> %% Test functions %%====================================================================== -start_case(Options, Expect) -> +start_case(Config, Options, Expect) -> p("start transport"), case (catch megaco_tcp:start_transport()) of {ok, Pid} -> p("create listen socket"), - case (catch megaco_tcp:listen(Pid, Options)) of + case (catch ?LISTEN(Config, Pid, Options)) of ok when Expect =:= ok -> p("extected listen result [ok]"), {ok, Pid}; ok -> - p("unextected listen result [ok] - stop transport"), + p("unexpected listen result [ok] - stop transport"), megaco_tcp:stop_transport(Pid), ?ERROR(unexpected_start_sucesss); - {error, _Reason} when Expect =:= error -> - p("extected listen result [error] - stop transport"), + {error, Reason} when Expect =:= error -> + p("expected listen result [error] - stop transport: " + "~n Reason: ~p", [Reason]), megaco_tcp:stop_transport(Pid), ok; {error, Reason} -> - p("unextected listen result [error] - stop transport"), + p("unexpected listen result [error] - stop transport: " + "~n Reason: ~p", [Reason]), megaco_tcp:stop_transport(Pid), ?ERROR({unexpected_start_failure, Reason}); Error -> - p("unextected listen result"), + p("unexpected listen result: " + "~n Error: ~p", [Error]), + megaco_tcp:stop_transport(Pid), ?ERROR({unexpected_result, Error}) end; {error, Reason} -> - p("unextected start_transport result"), + p("unexpected start_transport result"), ?ERROR({failed_starting_transport, Reason}) end. @@ -1019,10 +1101,11 @@ server_start_transport(State) when is_map(State) -> Error end. -server_listen(#{transport_ref := Ref} = State, Options) +server_listen(Config, #{transport_ref := Ref} = State, Options) when is_list(Options) -> + ?SLEEP(1000), Opts = [{receive_handle, self()}, {module, ?MODULE} | Options], - case (catch megaco_tcp:listen(Ref, Opts)) of + case (catch ?LISTEN(Config, Ref, Opts)) of ok -> {ok, State}; Error -> @@ -1110,10 +1193,10 @@ client_start_transport(State) when is_map(State) -> Error end. -client_connect(#{transport_ref := Ref} = State, Options) +client_connect(Config, #{transport_ref := Ref} = State, Options) when is_list(Options) -> Opts = [{receive_handle, self()}, {module, ?MODULE} | Options], - case (catch megaco_tcp:connect(Ref, Opts)) of + case (catch ?CONNECT(Config, Ref, Opts)) of {ok, Handle, ControlPid} -> {ok, State#{control_pid => ControlPid, handle => Handle}}; diff --git a/lib/megaco/test/megaco_test_lib.erl b/lib/megaco/test/megaco_test_lib.erl index 10e7ed90c8..e39e1e3e8a 100644 --- a/lib/megaco/test/megaco_test_lib.erl +++ b/lib/megaco/test/megaco_test_lib.erl @@ -60,7 +60,13 @@ start_node/3, start_node/4, stop_nodes/3, - stop_node/3 + stop_node/3, + + is_socket_backend/1, + inet_backend_opts/1, + explicit_inet_backend/0, test_inet_backends/0, + open/3, + listen/3, connect/3 ]). -export([init_per_suite/1, end_per_suite/1, @@ -475,6 +481,17 @@ pprint(F, A) -> init_per_suite(Config) -> + p("megaco environment: " + "~n (megaco) app: ~p" + "~n (all) init: ~p" + "~n (megaco) init: ~p", + [application:get_all_env(megaco), + init:get_arguments(), + case init:get_argument(megaco) of + {ok, Args} -> Args; + error -> undefined + end]), + ct:timetrap(minutes(3)), try analyze_and_print_host_info() of @@ -2209,3 +2226,76 @@ p(F, A) -> print(Pre, F, A) -> io:format("*** [~s] [~s] ~p " ++ F ++ "~n", [?FTS(), Pre, self() | A]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +explicit_inet_backend() -> + %% This is intentional! + %% This is a kernel flag, which if set disables + %% our own special handling of the inet_backend + %% in our test suites. + case application:get_all_env(kernel) of + Env when is_list(Env) -> + case lists:keysearch(inet_backend, 1, Env) of + {value, {inet_backend, _}} -> + true; + _ -> + false + end; + _ -> + false + end. + +test_inet_backends() -> + case init:get_argument(megaco) of + {ok, SnmpArgs} when is_list(SnmpArgs) -> + test_inet_backends(SnmpArgs, atom_to_list(?FUNCTION_NAME)); + error -> + false + end. + +test_inet_backends([], _) -> + false; +test_inet_backends([[Key, Val] | _], Key) -> + case list_to_atom(string:to_lower(Val)) of + Bool when is_boolean(Bool) -> + Bool; + _ -> + false + end; +test_inet_backends([_|Args], Key) -> + test_inet_backends(Args, Key). + + +inet_backend_opts(Config) when is_list(Config) -> + case lists:keysearch(socket_create_opts, 1, Config) of + {value, {socket_create_opts, InetBackendOpts}} -> + InetBackendOpts; + false -> + [] + end. + +is_socket_backend(Config) when is_list(Config) -> + case lists:keysearch(socket_create_opts, 1, Config) of + {value, {socket_create_opts, [{inet_backend, socket}]}} -> + true; + _ -> + false + end. + + +open(Config, Pid, Opts) + when is_list(Config) andalso is_pid(Pid) andalso is_list(Opts) -> + InetBackendOpts = inet_backend_opts(Config), + megaco_udp:open(Pid, InetBackendOpts ++ Opts). + +listen(Config, Pid, Opts) + when is_list(Config) andalso is_pid(Pid) andalso is_list(Opts) -> + InetBackendOpts = inet_backend_opts(Config), + megaco_tcp:listen(Pid, InetBackendOpts ++ Opts). + +connect(Config, Ref, Opts) + when is_list(Config) andalso is_list(Opts) -> + InetBackendOpts = inet_backend_opts(Config), + megaco_tcp:connect(Ref, InetBackendOpts ++ Opts). + diff --git a/lib/megaco/test/megaco_test_lib.hrl b/lib/megaco/test/megaco_test_lib.hrl index 0777adbcd0..653af70da4 100644 --- a/lib/megaco/test/megaco_test_lib.hrl +++ b/lib/megaco/test/megaco_test_lib.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2020. All Rights Reserved. +%% Copyright Ericsson AB 1999-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -106,6 +106,16 @@ -define(FTS(TS), megaco:format_timestamp(TS)). -define(F(F,A), lists:flatten(io_lib:format(F, A))). +-define(INET_BACKEND_OPTS(C), ?LIB:inet_backend_opts(C)). +-define(EXPLICIT_INET_BACKEND(), ?LIB:explicit_inet_backend()). +-define(TEST_INET_BACKENDS(), ?LIB:test_inet_backends()). +-define(IS_SOCKET_BACKEND(C), ?LIB:is_socket_backend(C)). + +-define(OPEN(C, P, O), ?LIB:open(C, P, O)). +-define(LISTEN(C, P, O), ?LIB:listen(C, P, O)). +-define(CONNECT(C, R, O), ?LIB:connect(C, R, O)). + + -define(ANNOUNCE_SUITE_INIT(), io:format(user, "~n*** ~s *** suite ~w init~n~n", [?FTS(), ?MODULE])). -define(ANNOUNCE_GROUP_INIT(GR), diff --git a/lib/megaco/test/megaco_test_mg.erl b/lib/megaco/test/megaco_test_mg.erl index e84adc7de6..7fae24326a 100644 --- a/lib/megaco/test/megaco_test_mg.erl +++ b/lib/megaco/test/megaco_test_mg.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2020. All Rights Reserved. +%% Copyright Ericsson AB 2003-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -67,7 +67,9 @@ -define(A5555, tid(255*256*256 + 255*256) ). -define(A5556, tid(255*256*256 + 255*256 + 255) ). --record(mg, {mid = undefined, +-record(mg, {parent = undefined, + inet_backend = default, + mid = undefined, state = initiated, req_handler = undefined, call_mode = async, @@ -78,7 +80,6 @@ load_counter = 0, reply_counter = 0, mload_info = undefined, - parent = undefined, dsi_timer, evs = []}). @@ -354,11 +355,16 @@ mg(Parent, Verbosity, Config) -> case (catch init(Config)) of {error, _} = Error -> exit(Error); + {'EXIT', Reason} -> exit({init_failed, Reason}); - {ok, Mid, DSITimer} -> + + {ok, IB, Mid, DSITimer} -> notify_started(Parent), - MG = #mg{parent = Parent, mid = Mid, dsi_timer = DSITimer}, + MG = #mg{parent = Parent, + inet_backend = IB, + mid = Mid, + dsi_timer = DSITimer}, i("mg -> started"), put(verbosity, Verbosity), case (catch loop(evs(MG, started))) of @@ -380,12 +386,16 @@ init(Config) -> "~n Config: ~p", [Config]), random_init(), d("init -> random initiated"), - Mid = get_conf(local_mid, Config), - d("init -> Mid: ~p", [Mid]), + + IB = get_conf(inet_backend, Config, default), + Mid = get_conf(local_mid, Config), RI = get_conf(receive_info, Config), - d("init -> RI: ~p", [RI]), - d("init -> maybe start the display system info timer"), + d("init -> " + "~n Inet Backend: ~p" + "~n Mid: ~p" + "~n RI: ~p", [IB, Mid, RI]), + DSITimer = case get_conf(display_system_info, Config, undefined) of Time when is_integer(Time) -> @@ -395,6 +405,7 @@ init(Config) -> undefined end, Conf0 = lists:keydelete(display_system_info, 1, Config), + Conf1 = lists:keydelete(inet_backend, 1, Conf0), d("init -> start megaco"), application:start(megaco), @@ -411,12 +422,12 @@ init(Config) -> _ -> ok end, - Conf1 = lists:keydelete(megaco_trace, 1, Conf0), + Conf2 = lists:keydelete(megaco_trace, 1, Conf1), d("init -> start megaco user"), - Conf2 = lists:keydelete(local_mid, 1, Conf1), - Conf3 = lists:keydelete(receive_info, 1, Conf2), - ok = megaco:start_user(Mid, Conf3), + Conf3 = lists:keydelete(local_mid, 1, Conf2), + Conf4 = lists:keydelete(receive_info, 1, Conf3), + ok = megaco:start_user(Mid, Conf4), d("init -> update user info (user_mod)"), ok = megaco:update_user_info(Mid, user_mod, ?MODULE), d("init -> update user info (user_args)"), @@ -427,8 +438,8 @@ init(Config) -> d("init -> parse receive info"), {MgcPort, MgcHost, RH1, TO} = parse_receive_info(RI, RH), d("init -> start transport (with ~p)", [TO]), - {ok, _CH} = start_transport(MgcPort, MgcHost, RH1, TO), - {ok, Mid, DSITimer}. + {ok, _CH} = start_transport(IB, MgcPort, MgcHost, RH1, TO), + {ok, IB, Mid, DSITimer}. loop(#mg{parent = Parent, mid = Mid} = S) -> @@ -936,39 +947,43 @@ parse_receive_info(RI, RH) -> {TP, TH, RH1, TO}. -start_transport(MgcPort, MgcHost, - #megaco_receive_handle{send_mod = megaco_tcp} = RH, TO) -> - start_tcp(MgcPort, MgcHost, RH, TO); -start_transport(MgcPort, MgcHost, - #megaco_receive_handle{send_mod = megaco_udp} = RH, TO) -> - start_udp(MgcPort, MgcHost, RH, TO); -start_transport(_, _, #megaco_receive_handle{send_mod = Mod}, _TO) -> +start_transport(IB, + MgcPort, MgcHost, + #megaco_receive_handle{send_mod = megaco_tcp} = RH, TO) -> + start_tcp(IB, RH, TO, MgcPort, MgcHost); +start_transport(IB, + MgcPort, MgcHost, + #megaco_receive_handle{send_mod = megaco_udp} = RH, TO) -> + start_udp(IB, RH, TO, MgcPort, MgcHost); +start_transport(_, _, _, #megaco_receive_handle{send_mod = Mod}, _TO) -> throw({error, {bad_send_mod, Mod}}). -start_tcp(MgcPort, MgcHost, RH, TO) -> +start_tcp(IB, RH, TO, MgcPort, MgcHost) -> d("start tcp transport: " + "~n Inet Backend: ~p" "~n MGC Port: ~p" "~n MGC Host: ~p" "~n Receive handle: ~p" - "~n Transport options: ~p", [MgcPort, MgcHost, RH, TO]), + "~n Transport options: ~p", [IB, MgcPort, MgcHost, RH, TO]), case megaco_tcp:start_transport() of {ok, Sup} -> d("tcp transport started: ~p", [Sup]), - start_tcp_connect(TO, RH, MgcPort, MgcHost, Sup); + start_tcp_connect(IB, TO, RH, MgcPort, MgcHost, Sup); {error, Reason} -> throw({error, {megaco_tcp_start_transport, Reason}}) end. -start_tcp_connect(TO, RH, Port, Host, Sup) -> +start_tcp_connect(IB, TO, RH, Port, Host, Sup) -> d("try tcp connecting to: ~p:~p", [Host, Port]), - Opts = [{host, Host}, + Opts = [{inet_backend, IB}, + {host, Host}, {port, Port}, {receive_handle, RH}, {tcp_options, [{nodelay, true}]}] ++ TO, - try_start_tcp_connect(RH, Sup, Opts, 250, noError). + try_start_tcp_connect(RH, Opts, Sup, 250, noError). -try_start_tcp_connect(RH, Sup, Opts, Timeout, Error0) when (Timeout < 5000) -> +try_start_tcp_connect(RH, Opts, Sup, Timeout, Error0) when (Timeout < 5000) -> Sleep = random(Timeout) + 100, d("try tcp connect (~p,~p)", [Timeout, Sleep]), case megaco_tcp:connect(Sup, Opts) of @@ -978,13 +993,13 @@ try_start_tcp_connect(RH, Sup, Opts, Timeout, Error0) when (Timeout < 5000) -> Error1 when Error0 =:= noError -> % Keep the first error d("failed connecting [1]: ~p", [Error1]), sleep(Sleep), - try_start_tcp_connect(RH, Sup, Opts, Timeout*2, Error1); + try_start_tcp_connect(RH, Opts, Sup, Timeout*2, Error1); Error2 -> d("failed connecting [2]: ~p", [Error2]), sleep(Sleep), - try_start_tcp_connect(RH, Sup, Opts, Timeout*2, Error0) + try_start_tcp_connect(RH, Opts, Sup, Timeout*2, Error0) end; -try_start_tcp_connect(_RH, Sup, _Opts, _Timeout, Error) -> +try_start_tcp_connect(_RH, _Opts, Sup, _Timeout, Error) -> megaco_tcp:stop_transport(Sup), throw({error, {megaco_tcp_connect, Error}}). @@ -995,25 +1010,45 @@ megaco_tcp_connect(RH, SendHandle, ControlPid) -> d("megaco connected: ~p", [CH]), {ok, CH}. -start_udp(MgcPort, MgcHost, RH, TO) -> +start_udp(IB, RH, TO, MgcPort, MgcHost) -> d("start udp transport (~p)", [MgcPort]), case megaco_udp:start_transport() of {ok, Sup} -> d("udp transport started: ~p", [Sup]), - Opts = [{port, 0}, {receive_handle, RH}] ++ TO, - d("udp open", []), - case megaco_udp:open(Sup, Opts) of - {ok, Handle, ControlPid} -> - d("udp opened: ~p, ~p", [Handle, ControlPid]), - megaco_udp_connect(MgcPort, MgcHost, - RH, Handle, ControlPid); - {error, Reason} -> - throw({error, {megaco_udp_open, Reason}}) - end; + start_udp_open(IB, RH, TO, MgcPort, MgcHost, Sup); + %% Opts = [{inet_backend, IB}, {port, 0}, {receive_handle, RH}] ++ TO, + %% d("udp open", []), + %% case megaco_udp:open(Sup, Opts) of + %% {ok, Handle, ControlPid} -> + %% d("udp opened: ~p, ~p", [Handle, ControlPid]), + %% megaco_udp_connect(IB, + %% MgcPort, MgcHost, + %% RH, Handle, ControlPid); + %% {error, Reason} -> + %% throw({error, {megaco_udp_open, Reason}}) + %% end; {error, Reason} -> throw({error, {megaco_udp_start_transport, Reason}}) end. +start_udp_open(IB, RH, TO, MgcPort, MgcHost, Sup) -> + Opts = [{inet_backend, IB}, {port, 0}, {receive_handle, RH}] ++ TO, + try_start_udp_open(RH, Opts, MgcPort, MgcHost, Sup). + +try_start_udp_open(RH, Opts, MgcPort, MgcHost, Sup) -> + d("udp open", []), + case megaco_udp:open(Sup, Opts) of + {ok, Handle, ControlPid} -> + d("udp opened: ~p, ~p", [Handle, ControlPid]), + megaco_udp_connect(MgcPort, MgcHost, + RH, Handle, ControlPid); + {error, Reason} -> + megaco_udp:stop_transport(Sup), + throw({error, {megaco_udp_open, Reason}}) + end. + + + megaco_udp_connect(MgcPort, MgcHost, RH, Handle, ControlPid) -> MgcMid = preliminary_mid, SendHandle = megaco_udp:create_send_handle(Handle, MgcHost, MgcPort), diff --git a/lib/megaco/test/megaco_test_mgc.erl b/lib/megaco/test/megaco_test_mgc.erl index a7d0731b0f..74fd9fc7fc 100644 --- a/lib/megaco/test/megaco_test_mgc.erl +++ b/lib/megaco/test/megaco_test_mgc.erl @@ -57,6 +57,8 @@ -include_lib("megaco/include/megaco.hrl"). -include_lib("megaco/include/megaco_message_v1.hrl"). +-define(NO_ERROR, 'no error'). + -define(A4444, ["11111111", "00000000", "00000000"]). -define(A4445, ["11111111", "00000000", "11111111"]). -define(A5555, ["11111111", "11111111", "00000000"]). @@ -65,18 +67,19 @@ -define(valid_actions, [ignore, pending, pending_ignore, discard_ack, handle_ack, handle_pending_ack, handle_sloppy_ack]). --record(mgc, {parent = undefined, - tcp_sup = undefined, - udp_sup = undefined, - req_action = discard_ack, - req_timeout = 0, - mid = undefined, - ack_info = undefined, - abort_info = undefined, - req_info = undefined, - mg = [], +-record(mgc, {parent = undefined, + inet_backend = default, + tcp_sup = undefined, + udp_sup = undefined, + req_action = discard_ack, + req_timeout = 0, + mid = undefined, + ack_info = undefined, + abort_info = undefined, + req_info = undefined, + mg = [], dsi_timer, - evs = []}). + evs = []}). -define(EVS_MAX, 10). @@ -330,13 +333,14 @@ mgc(Parent, Verbosity, Config) -> case (catch init(Config)) of {error, Reason} -> exit(Reason); - {Mid, TcpSup, UdpSup, DSITimer} -> + {IB, Mid, TcpSup, UdpSup, DSITimer} -> notify_started(Parent), - S = #mgc{parent = Parent, - tcp_sup = TcpSup, - udp_sup = UdpSup, - mid = Mid, - dsi_timer = DSITimer}, + S = #mgc{parent = Parent, + tcp_sup = TcpSup, + udp_sup = UdpSup, + mid = Mid, + dsi_timer = DSITimer, + inet_backend = IB}, i("mgc -> started"), display_system_info("at start "), loop(evs(S, started)) @@ -345,10 +349,15 @@ mgc(Parent, Verbosity, Config) -> init(Config) -> d("init -> entry"), random_init(), - Mid = get_conf(local_mid, Config), + + IB = get_conf(inet_backend, Config, default), + Mid = get_conf(local_mid, Config), RI = get_conf(receive_info, Config), - d("init -> maybe start the display system info timer"), + d("init -> " + "~n Inet Backend: ~p" + "~n Mid: ~p" + "~n RI: ~p", [IB, Mid, RI]), DSITimer = case get_conf(display_system_info, Config, undefined) of Time when is_integer(Time) -> @@ -358,6 +367,7 @@ init(Config) -> undefined end, Conf0 = lists:keydelete(display_system_info, 1, Config), + Conf1 = lists:keydelete(inet_backend, 1, Conf0), d("init -> start megaco"), application:start(megaco), @@ -373,12 +383,12 @@ init(Config) -> _ -> ok end, - Conf1 = lists:keydelete(megaco_trace, 1, Conf0), + Conf2 = lists:keydelete(megaco_trace, 1, Conf1), d("init -> start megaco user"), - Conf2 = lists:keydelete(local_mid, 1, Conf1), - Conf3 = lists:keydelete(receive_info, 1, Conf2), - ok = megaco:start_user(Mid, Conf3), + Conf3 = lists:keydelete(local_mid, 1, Conf2), + Conf4 = lists:keydelete(receive_info, 1, Conf3), + ok = megaco:start_user(Mid, Conf4), d("init -> update user info (user_mod)"), ok = megaco:update_user_info(Mid, user_mod, ?MODULE), @@ -392,8 +402,8 @@ init(Config) -> Transports = parse_receive_info(RI, RH), d("init -> start transports"), - {Tcp, Udp} = start_transports(Transports), - {Mid, Tcp, Udp, DSITimer}. + {Tcp, Udp} = start_transports(IB, Transports), + {IB, Mid, Tcp, Udp, DSITimer}. loop(S) -> d("loop -> await request"), @@ -722,11 +732,11 @@ parse_receive_info1(RI, RH) -> %% send/receive port (udp). %% The second step *may* need to be repeated! %% -------------------------------------------------------- -start_transports([]) -> +start_transports(_, []) -> throw({error, no_transport}); -start_transports(Transports) when is_list(Transports) -> +start_transports(IB, Transports) when is_list(Transports) -> {Tcp, Udp} = start_transports1(Transports, undefined, undefined), - ok = start_transports2(Transports, Tcp, Udp), + ok = start_transports2(IB, Transports, Tcp, Udp), {Tcp, Udp}. start_transports1([], Tcp, Udp) -> @@ -760,28 +770,29 @@ start_transports1([{_TO, _Port, RH}|Transports], Tcp, Udp) start_transports1([_|Transports], Tcp, Udp) -> start_transports1(Transports, Tcp, Udp). -start_transports2([], _, _) -> +start_transports2(_, [], _, _) -> ok; -start_transports2([{TO, Port, RH}|Transports], Tcp, Udp) +start_transports2(IB, [{TO, Port, RH}|Transports], Tcp, Udp) when RH#megaco_receive_handle.send_mod =:= megaco_tcp -> - start_tcp(TO, RH, Port, Tcp), - start_transports2(Transports, Tcp, Udp); -start_transports2([{TO, Port, RH}|Transports], Tcp, Udp) + start_tcp(IB, TO, RH, Port, Tcp), + start_transports2(IB, Transports, Tcp, Udp); +start_transports2(IB, [{TO, Port, RH}|Transports], Tcp, Udp) when RH#megaco_receive_handle.send_mod =:= megaco_udp -> - start_udp(TO, RH, Port, Udp), - start_transports2(Transports, Tcp, Udp). + start_udp(IB, TO, RH, Port, Udp), + start_transports2(IB, Transports, Tcp, Udp). -start_tcp(TO, RH, Port, Sup) -> +start_tcp(IB, TO, RH, Port, Sup) -> d("start tcp transport"), - start_tcp(TO, RH, Port, Sup, 250). + start_tcp(IB, TO, RH, Port, Sup, 250). -start_tcp(TO, RH, Port, Sup, Timeout) +start_tcp(IB, TO, RH, Port, Sup, Timeout) when is_pid(Sup) andalso is_integer(Timeout) andalso (Timeout > 0) -> d("tcp listen on ~p", [Port]), - Opts = [{port, Port}, + Opts = [{inet_backend, IB}, + {port, Port}, {receive_handle, RH}, {tcp_options, [{nodelay, true}]}] ++ TO, - try_start_tcp(Sup, Opts, Timeout, noError). + try_start_tcp(Sup, Opts, Timeout, ?NO_ERROR). try_start_tcp(Sup, Opts, Timeout, Error0) when (Timeout < 5000) -> Sleep = random(Timeout) + 100, @@ -790,7 +801,7 @@ try_start_tcp(Sup, Opts, Timeout, Error0) when (Timeout < 5000) -> ok -> d("listen socket created", []), Sup; - Error1 when Error0 =:= noError -> % Keep the first error + Error1 when Error0 =:= ?NO_ERROR -> % Keep the first error d("failed creating listen socket [1]: ~p", [Error1]), sleep(Sleep), try_start_tcp(Sup, Opts, Timeout*2, Error1); @@ -809,14 +820,16 @@ try_start_tcp(Sup, _Opts, _Timeout, Error) -> end. -start_udp(TO, RH, Port, Sup) -> +start_udp(IB, TO, RH, Port, Sup) -> d("start udp transport"), - start_udp(TO, RH, Port, Sup, 250). + start_udp(IB, TO, RH, Port, Sup, 250). -start_udp(TO, RH, Port, Sup, Timeout) -> +start_udp(IB, TO, RH, Port, Sup, Timeout) -> d("udp open ~p", [Port]), - Opts = [{port, Port}, {receive_handle, RH}] ++ TO, - try_start_udp(Sup, Opts, Timeout, noError). + Opts = [{inet_backend, IB}, + {port, Port}, + {receive_handle, RH}] ++ TO, + try_start_udp(Sup, Opts, Timeout, ?NO_ERROR). try_start_udp(Sup, Opts, Timeout, Error0) when (Timeout < 5000) -> d("try open udp socket (~p)", [Timeout]), @@ -824,7 +837,7 @@ try_start_udp(Sup, Opts, Timeout, Error0) when (Timeout < 5000) -> {ok, _SendHandle, _ControlPid} -> d("port opened", []), Sup; - Error1 when Error0 =:= noError -> % Keep the first error + Error1 when Error0 =:= ?NO_ERROR -> % Keep the first error d("failed open port [1]: ~p", [Error1]), sleep(Timeout), try_start_udp(Sup, Opts, Timeout*2, Error1); diff --git a/lib/megaco/test/megaco_udp_SUITE.erl b/lib/megaco/test/megaco_udp_SUITE.erl index e8fea517f6..461b56fad4 100644 --- a/lib/megaco/test/megaco_udp_SUITE.erl +++ b/lib/megaco/test/megaco_udp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2020 All Rights Reserved. +%% Copyright Ericsson AB 2000-2021 All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -81,17 +81,49 @@ suite() -> [{ct_hooks, [ts_install_cth]}]. all() -> + %% This is a temporary messure to ensure that we can + %% test the socket backend without effecting *all* + %% applications on *all* machines. + %% This flag is set only for *one* host. + case ?TEST_INET_BACKENDS() of + true -> + [ + {group, inet_backend_default}, + {group, inet_backend_inet}, + {group, inet_backend_socket} + ]; + _ -> + [ + {group, inet_backend_default} + ] + end. + +groups() -> [ - {group, start}, - {group, sending}, - {group, error} + {inet_backend_default, [], inet_backend_default_cases()}, + {inet_backend_inet, [], inet_backend_inet_cases()}, + {inet_backend_socket, [], inet_backend_socket_cases()}, + + {all, [], all_cases()}, + {start, [], start_cases()}, + {sending, [], sending_cases()}, + {error, [], error_cases()} ]. -groups() -> +inet_backend_default_cases() -> + [{all, [], all_cases()}]. + +inet_backend_inet_cases() -> + [{all, [], all_cases()}]. + +inet_backend_socket_cases() -> + [{all, [], all_cases()}]. + +all_cases() -> [ - {start, [], start_cases()}, - {sending, [], sending_cases()}, - {error, [], error_cases()} + {group, start}, + {group, sending}, + {group, error} ]. start_cases() -> @@ -167,6 +199,29 @@ end_per_suite(Config0) when is_list(Config0) -> %% ----- %% +init_per_group(inet_backend_default = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + [{socket_create_opts, []} | Config]; +init_per_group(inet_backend_inet = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{socket_create_opts, [{inet_backend, inet}]} | Config] + end; +init_per_group(inet_backend_socket = Group, Config) -> + ?ANNOUNCE_GROUP_INIT(Group), + case ?EXPLICIT_INET_BACKEND() of + true -> + %% The environment trumps us, + %% so only the default group should be run! + {skip, "explicit inet backend"}; + false -> + [{socket_create_opts, [{inet_backend, socket}]} | Config] + end; init_per_group(Group, Config) -> ?ANNOUNCE_GROUP_INIT(Group), Config. @@ -203,7 +258,6 @@ end_per_testcase(Case, Config) -> - %% ================================================= %% %% ------------------ start ------------------------ @@ -217,7 +271,7 @@ start_normal(suite) -> start_normal(Config) when is_list(Config) -> ?ACQUIRE_NODES(1, Config), Opts = [{port, 0}, {receive_handle, apa}], - {ok, Pid} = start_case(Opts, ok), + {ok, Pid} = start_case(Config, Opts, ok), megaco_udp:stop_transport(Pid), ok. @@ -229,7 +283,7 @@ start_invalid_opt(suite) -> start_invalid_opt(Config) when is_list(Config) -> ?ACQUIRE_NODES(1, Config), Opts = [{port, 0}, {receivehandle, apa}], - start_case(Opts, error). + start_case(Config, Opts, error). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -250,22 +304,22 @@ start_and_stop(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun(X) -> do_start_and_stop(Factor, X) end, + Case = fun(X) -> do_start_and_stop(Config, Factor, X) end, Post = fun(Nodes) -> p("stop nodes"), ?STOP_NODES(lists:reverse(Nodes)) end, try_tc(start_and_stop, Pre, Case, Post). -do_start_and_stop(Factor, [ServerNode, ClientNode]) -> +do_start_and_stop(Config, Factor, [ServerNode, ClientNode]) -> %% Create command sequences TOCalc = fun(BaseTO) -> to_calc(Factor, BaseTO) end, TO = TOCalc(?SECS(5)), p("create command sequences"), ServerPort = 2944, - ServerCmds = start_and_stop_server_commands(ServerPort), + ServerCmds = start_and_stop_server_commands(Config, ServerPort), {ok, ServerHost} = inet:gethostname(), - ClientCmds = start_and_stop_client_commands(TO, ServerPort, ServerHost), + ClientCmds = start_and_stop_client_commands(Config, TO, ServerPort, ServerHost), %% Start the test procs used in the test-case, one for each node p("start command handlers"), @@ -294,7 +348,7 @@ do_start_and_stop(Factor, [ServerNode, ClientNode]) -> ok. -start_and_stop_server_commands(Port) -> +start_and_stop_server_commands(Config, Port) -> Opts = [{port, Port}], Self = self(), [ @@ -313,7 +367,7 @@ start_and_stop_server_commands(Port) -> #{id => 3, desc => "Open", cmd => fun(State) -> - server_open(State, Opts) + server_open(Config, State, Opts) end}, #{id => 4, @@ -342,7 +396,7 @@ start_and_stop_server_commands(Port) -> ]. -start_and_stop_client_commands(TO, ServerPort, _ServerHost) -> +start_and_stop_client_commands(Config, TO, ServerPort, _ServerHost) -> Opts = [{port, ServerPort}], Self = self(), [ @@ -361,7 +415,7 @@ start_and_stop_client_commands(TO, ServerPort, _ServerHost) -> #{id => 3, desc => "Open", cmd => fun(State) -> - client_open(State, Opts) + client_open(Config, State, Opts) end}, #{id => 4, @@ -414,22 +468,22 @@ sendreceive(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun(X) -> do_sendreceive(Factor, X) end, + Case = fun(X) -> do_sendreceive(Config, Factor, X) end, Post = fun(Nodes) -> p("stop nodes"), ?STOP_NODES(lists:reverse(Nodes)) end, try_tc(sendreceive, Pre, Case, Post). -do_sendreceive(Factor, [ServerNode, ClientNode]) -> +do_sendreceive(Config, Factor, [ServerNode, ClientNode]) -> %% Create command sequences p("create command sequences"), TOCalc = fun(BaseTO) -> to_calc(Factor, BaseTO) end, TO = TOCalc(?SECS(5)), ServerPort = 2944, - ServerCmds = sendreceive_server_commands(TO, ServerPort), + ServerCmds = sendreceive_server_commands(Config, TO, ServerPort), {ok, ServerHost} = inet:gethostname(), - ClientCmds = sendreceive_client_commands(TO, ServerPort, ServerHost), + ClientCmds = sendreceive_client_commands(Config, TO, ServerPort, ServerHost), %% Start the test procs used in the test-case, one for each node p("start command handlers"), @@ -458,7 +512,7 @@ do_sendreceive(Factor, [ServerNode, ClientNode]) -> ok. -sendreceive_server_commands(TO, Port) -> +sendreceive_server_commands(Config, TO, Port) -> Opts = [{port, Port}], Self = self(), [ @@ -477,7 +531,7 @@ sendreceive_server_commands(TO, Port) -> #{id => 3, desc => "Open", cmd => fun(State) -> - server_open(State, Opts) + server_open(Config, State, Opts) end}, #{id => 4, @@ -541,7 +595,7 @@ sendreceive_server_commands(TO, Port) -> end} ]. -sendreceive_client_commands(TO, ServerPort, ServerHost) -> +sendreceive_client_commands(Config, TO, ServerPort, ServerHost) -> OwnPort = ServerPort+1, Opts = [{port, OwnPort}], Self = self(), @@ -561,7 +615,7 @@ sendreceive_client_commands(TO, ServerPort, ServerHost) -> #{id => 3, desc => "Open", cmd => fun(State) -> - client_open(State, Opts) + client_open(Config, State, Opts) end}, #{id => 4, @@ -643,23 +697,23 @@ block_unblock(Config) when is_list(Config) -> ok = ?START_NODES(Nodes), Nodes end, - Case = fun(X) -> do_block_unblock(Factor, X) end, + Case = fun(X) -> do_block_unblock(Config, Factor, X) end, Post = fun(Nodes) -> p("stop nodes"), ?STOP_NODES(lists:reverse(Nodes)) end, try_tc(block_unblock, Pre, Case, Post). -do_block_unblock(Factor, [ServerNode, ClientNode]) -> +do_block_unblock(Config, Factor, [ServerNode, ClientNode]) -> %% Create command sequences p("create command sequences"), TOCalc = fun(BaseTO) -> to_calc(Factor, BaseTO) end, TO = TOCalc(?SECS(5)), ServerPort = 2944, p("generated command sequences with timeout: ~w msec", [TO]), - ServerCmds = block_unblock_server_commands(TO, ServerPort), + ServerCmds = block_unblock_server_commands(Config, TO, ServerPort), {ok, ServerHost} = inet:gethostname(), - ClientCmds = block_unblock_client_commands(TO, ServerPort, ServerHost), + ClientCmds = block_unblock_client_commands(Config, TO, ServerPort, ServerHost), %% Start the test procs used in the test-case, one for each node p("start command handlers"), @@ -707,7 +761,7 @@ do_block_unblock(Factor, [ServerNode, ClientNode]) -> ok. -block_unblock_server_commands(TO, Port) -> +block_unblock_server_commands(Config, TO, Port) -> Opts = [{port, Port}], Self = self(), [ @@ -726,7 +780,7 @@ block_unblock_server_commands(TO, Port) -> #{id => 3, desc => "Open", cmd => fun(State) -> - server_open(State, Opts) + server_open(Config, State, Opts) end}, #{id => 4, @@ -791,7 +845,7 @@ block_unblock_server_commands(TO, Port) -> ]. -block_unblock_client_commands(TO, ServerPort, ServerHost) -> +block_unblock_client_commands(Config, TO, ServerPort, ServerHost) -> OwnPort = ServerPort+1, Opts = [{port, OwnPort}], Self = self(), @@ -811,7 +865,7 @@ block_unblock_client_commands(TO, ServerPort, ServerHost) -> #{id => 3, desc => "Open", cmd => fun(State) -> - client_open(State, Opts) + client_open(Config, State, Opts) end}, #{id => 4, @@ -842,7 +896,7 @@ block_unblock_client_commands(TO, ServerPort, ServerHost) -> desc => "Pre-Block info", cmd => fun(#{socket := Socket} = State) -> p("Socket Info: " - "~n Port Info: ~p", [erlang:port_info(Socket)]), + "~n Port Info: ~p", [inet:info(Socket)]), {ok, State} end}, @@ -865,7 +919,7 @@ block_unblock_client_commands(TO, ServerPort, ServerHost) -> p("Socket Info: " "~n Active: ~p" "~n Port Info: ~p", - [Active, erlang:port_info(Socket)]), + [Active, inet:info(Socket)]), {ok, State} end}, @@ -890,7 +944,7 @@ block_unblock_client_commands(TO, ServerPort, ServerHost) -> p("Socket Info: " "~n Active: ~p" "~n Port Info: ~p", - [Active, erlang:port_info(Socket)]), + [Active, inet:info(Socket)]), ok end, client_await_nothing(State, Fail, TO div 2) @@ -909,7 +963,7 @@ block_unblock_client_commands(TO, ServerPort, ServerHost) -> p("Socket Info: " "~n Active: ~p" "~n Port Info: ~p", - [Active, erlang:port_info(Socket)]), + [Active, inet:info(Socket)]), {ok, State} end}, @@ -932,7 +986,7 @@ block_unblock_client_commands(TO, ServerPort, ServerHost) -> p("Socket Info: " "~n Active: ~p" "~n Port Info: ~p", - [Active, erlang:port_info(Socket)]), + [Active, inet:info(Socket)]), {ok, State} end}, @@ -991,10 +1045,10 @@ socket_failure(Config) when is_list(Config) -> %% Test functions %%====================================================================== -start_case(Opts, Expect) -> +start_case(Config, Opts, Expect) -> case (catch megaco_udp:start_transport()) of {ok, Pid} -> - case (catch megaco_udp:open(Pid, Opts)) of + case (catch ?OPEN(Config, Pid, Opts)) of {ok, _Handle, _CtrlPid} when Expect =:= ok -> {ok, Pid}; {ok, Handle, CtrlPid} -> @@ -1048,16 +1102,20 @@ server_start_command_handler(Node, Commands) -> server_start_transport(State) when is_map(State) -> case (catch megaco_udp:start_transport()) of {ok, Ref} -> + p("Transport started: ~p", [Ref]), {ok, State#{transport_ref => Ref}}; Error -> Error end. -server_open(#{transport_ref := Ref} = State, Options) +server_open(Config, #{transport_ref := Ref} = State, Options) when is_list(Options) -> Opts = [{receive_handle, self()}, {module, ?MODULE} | Options], - try megaco_udp:open(Ref, Opts) of + try ?OPEN(Config, Ref, Opts) of {ok, Socket, ControlPid} -> + p("opened: " + "~n Socket: ~p" + "~n ControlPid: ~p", [Socket, ControlPid]), {ok, State#{handle => {socket, Socket}, % Temporary control_pid => ControlPid}}; {error, {could_not_open_udp_port, eaddrinuse}} -> @@ -1167,10 +1225,10 @@ client_start_transport(State) when is_map(State) -> Error end. -client_open(#{transport_ref := Ref} = State, Options) +client_open(Config, #{transport_ref := Ref} = State, Options) when is_list(Options) -> Opts = [{receive_handle, self()}, {module, ?MODULE} | Options], - try megaco_udp:open(Ref, Opts) of + try ?OPEN(Config, Ref, Opts) of {ok, Socket, ControlPid} -> {ok, State#{handle => {socket, Socket}, socket => Socket, |