diff options
Diffstat (limited to 'lib/diameter/test/diameter_transport_SUITE.erl')
-rw-r--r-- | lib/diameter/test/diameter_transport_SUITE.erl | 134 |
1 files changed, 51 insertions, 83 deletions
diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl index 97f4cec11f..c94f46b7a5 100644 --- a/lib/diameter/test/diameter_transport_SUITE.erl +++ b/lib/diameter/test/diameter_transport_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. 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% %% @@ -53,7 +54,7 @@ %% Receive a message. -define(RECV(Pat, Ret), receive Pat -> Ret end). --define(RECV(Pat), ?RECV(Pat, now())). +-define(RECV(Pat), ?RECV(Pat, diameter_lib:now())). %% Sockets are opened on the loopback address. -define(ADDR, {127,0,0,1}). @@ -64,7 +65,7 @@ = #diameter_caps{host_ip_address = Addrs}}). -%% The term we register after open a listening port with gen_tcp. +%% The term we register after open a listening port with gen_{tcp,sctp}. -define(TEST_LISTENER(Ref, PortNr), {?MODULE, listen, Ref, PortNr}). @@ -85,7 +86,7 @@ %% =========================================================================== suite() -> - [{timetrap, {minutes, 2}}]. + [{timetrap, {seconds, 15}}]. all() -> [start, @@ -104,7 +105,7 @@ tc() -> reconnect]. init_per_suite(Config) -> - [{sctp, have_sctp()} | Config]. + [{sctp, ?util:have_sctp()} | Config]. end_per_suite(_Config) -> ok. @@ -127,7 +128,10 @@ tcp_accept(_) -> accept(tcp). sctp_accept(Config) -> - if_sctp(fun accept/1, Config). + case lists:member({sctp, true}, Config) of + true -> accept(sctp); + false -> {skip, no_sctp} + end. %% Start multiple accepting transport processes that are connected to %% with an equal number of connecting processes using gen_tcp/sctp @@ -136,7 +140,9 @@ sctp_accept(Config) -> -define(PEER_COUNT, 8). accept(Prot) -> - T = {Prot, make_ref()}, + Ref = make_ref(), + true = diameter_reg:add_new({diameter_config, transport, Ref}), %% fake it + T = {Prot, Ref}, [] = ?util:run(?util:scramble(acc(2*?PEER_COUNT, T, []))). acc(0, _, Acc) -> @@ -157,7 +163,10 @@ tcp_connect(_) -> connect(tcp). sctp_connect(Config) -> - if_sctp(fun connect/1, Config). + case lists:member({sctp, true}, Config) of + true -> connect(sctp); + false -> {skip, no_sctp} + end. connect(Prot) -> T = {Prot, make_ref()}, @@ -180,12 +189,13 @@ reconnect({listen, Ref}) -> [_] = diameter_reg:wait({diameter_tcp, listener, {LRef, '_'}}), true = diameter_reg:add_new({?MODULE, Ref, LRef}), - %% Wait for partner to request transport death: kill to force the - %% peer to reconnect. + %% Wait for partner to request transport death. TPid = abort(SvcName, LRef, Ref), + %% Kill transport to force the peer to reconnect. exit(TPid, kill), + %% Wait for the partner again. abort(SvcName, LRef, Ref); reconnect({connect, Ref}) -> @@ -193,14 +203,14 @@ reconnect({connect, Ref}) -> true = diameter:subscribe(SvcName), ok = start_service(SvcName), [{{_, _, LRef}, Pid}] = diameter_reg:wait({?MODULE, Ref, '_'}), - CRef = ?util:connect(SvcName, tcp, LRef, [{reconnect_timer, 2000}, + CRef = ?util:connect(SvcName, tcp, LRef, [{connect_timer, 2000}, {watchdog_timer, 6000}]), %% Tell partner to kill transport after seeing that there are no %% reconnection attempts. abort(SvcName, Pid, Ref), - %% Transport does down and is reestablished. + %% Transport goes down and is reestablished. ?RECV(#diameter_event{service = SvcName, info = {down, CRef, _, _}}), ?RECV(#diameter_event{service = SvcName, info = {reconnect, CRef, _}}), ?RECV(#diameter_event{service = SvcName, info = {up, CRef, _, _, _}}), @@ -218,7 +228,7 @@ reconnect(_) -> || T <- [listen, connect]]). start_service(SvcName) -> - OH = io_lib:format("~p-~p-~p", tuple_to_list(now())), + OH = diameter_util:unique_string(), Opts = [{application, [{dictionary, diameter_gen_base_rfc6733}, {module, diameter_callback}]}, {'Origin-Host', OH}, @@ -250,28 +260,6 @@ abort(SvcName, LRef, Ref) %% =========================================================================== %% =========================================================================== -%% have_sctp/0 - -have_sctp() -> - case gen_sctp:open() of - {ok, Sock} -> - gen_sctp:close(Sock), - true; - {error, E} when E == eprotonosupport; - E == esocktnosupport -> %% fail on any other reason - false - end. - -%% if_sctp/2 - -if_sctp(F, Config) -> - case proplists:get_value(sctp, Config) of - true -> - F(sctp); - false -> - {skip, no_sctp} - end. - %% init/2 init(accept, {Prot, Ref}) -> @@ -350,13 +338,12 @@ make_msg() -> %% crypto:rand_bytes/1 isn't available on all platforms (since openssl %% isn't) so roll our own. rand_bytes(N) -> - random:seed(now()), rand_bytes(N, <<>>). rand_bytes(0, Bin) -> Bin; rand_bytes(N, Bin) -> - Oct = random:uniform(256) - 1, + Oct = rand:uniform(256) - 1, rand_bytes(N-1, <<Oct, Bin/binary>>). %% =========================================================================== @@ -380,37 +367,14 @@ start_connect(tcp, T, Svc, Opts) -> diameter_tcp:start(T, Svc, Opts). %% start_accept/2 -%% -%% Start transports sequentially by having each wait for a message -%% from a job in a queue before commencing. Only one transport with a -%% pending accept is started at a time since diameter_{tcp,sctp} -%% currently assume (and diameter currently implements) this. start_accept(Prot, Ref) -> - Pid = sync(accept, Ref), {Mod, Opts} = tmod(Prot), - - try - {ok, TPid, [?ADDR]} = Mod:start({accept, Ref}, - ?SVC([?ADDR]), - [{port, 0} | Opts]), - ?RECV(?TMSG({TPid, connected})), - TPid - after - Pid ! Ref - end. - -sync(What, Ref) -> - ok = diameter_sync:cast({?MODULE, What, Ref}, - [fun lock/2, Ref, self()], - infinity, - infinity), - receive {start, Ref, Pid} -> Pid end. - -lock(Ref, Pid) -> - Pid ! {start, Ref, self()}, - erlang:monitor(process, Pid), - Ref = receive T -> T end. + {ok, TPid, [?ADDR]} = Mod:start({accept, Ref}, + ?SVC([?ADDR]), + [{port, 0} | Opts]), + ?RECV(?TMSG({TPid, connected})), + TPid. tmod(sctp) -> {diameter_sctp, [{sctp_initmsg, ?SCTP_INIT}]}; @@ -439,12 +403,13 @@ gen_listen(tcp) -> %% gen_accept/2 gen_accept(sctp, Sock) -> - Assoc = ?RECV(?SCTP(Sock, {_, #sctp_assoc_change{state = comm_up, - outbound_streams = O, - inbound_streams = I, - assoc_id = A}}), - {O, I, A}), - putr(assoc, Assoc), + #sctp_assoc_change{state = comm_up, + outbound_streams = OS, + inbound_streams = IS, + assoc_id = Id} + = ?RECV(?SCTP(Sock, {_, #sctp_assoc_change{} = S}), S), + + putr(assoc, {OS, IS, Id}), {ok, Sock}; gen_accept(tcp, LSock) -> gen_tcp:accept(LSock). @@ -453,8 +418,7 @@ gen_accept(tcp, LSock) -> gen_send(sctp, Sock, Bin) -> {OS, _IS, Id} = getr(assoc), - {_, _, Us} = now(), - gen_sctp:send(Sock, Id, Us rem OS, Bin); + gen_sctp:send(Sock, Id, erlang:unique_integer([positive]) rem OS, Bin); gen_send(tcp, Sock, Bin) -> gen_tcp:send(Sock, Bin). @@ -462,7 +426,11 @@ gen_send(tcp, Sock, Bin) -> gen_recv(sctp, Sock) -> {_OS, _IS, Id} = getr(assoc), - ?RECV(?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], Bin}), Bin); + receive + ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], Bin}) + when is_binary(Bin) -> + Bin + end; gen_recv(tcp, Sock) -> tcp_recv(Sock, <<>>). |