From 52f3b4e508cf1f43c88bd20b0e1e6cc75ec4f020 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sun, 9 Oct 2011 20:36:31 +0200 Subject: Use tcp/sctp port resolution from testsuites --- lib/diameter/test/diameter_util.erl | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'lib/diameter/test/diameter_util.erl') diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl index f9942c3408..3313e6ab75 100644 --- a/lib/diameter/test/diameter_util.erl +++ b/lib/diameter/test/diameter_util.erl @@ -23,12 +23,19 @@ %% Utility functions. %% +%% generic -export([consult/2, run/1, fold/3, foldl/3, - scramble/1, - write_priv/3, + scramble/1]). + +%% diameter-specific +-export([lport/2, + lport/3]). + +%% common_test-specific +-export([write_priv/3, read_priv/2]). -define(L, atom_to_list). @@ -172,6 +179,26 @@ eval(F) when is_function(F,0) -> F(). +%% lport/2-3 + +lport(M, Ref) -> + lport(M, Ref, 1). + +lport(M, Ref, Tries) -> + lp(tmod(M), Ref, Tries). + +tmod(sctp) -> diameter_sctp; +tmod(tcp) -> diameter_tcp. + +lp(M, Ref, T) -> + L = [N || {listen, N, _} <- M:ports(Ref)], + if [] /= L orelse T =< 1 -> + L; + true -> + receive after 50 -> ok end, + lp(M, Ref, T-1) + end. + %% write_priv/3 write_priv(Config, Name, Term) -> -- cgit v1.2.3 From 421281c888cc99239833c5cd359e12a9c7594b42 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sun, 9 Oct 2011 15:18:01 +0200 Subject: Add util functions for managing connections --- lib/diameter/test/diameter_util.erl | 140 +++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 16 deletions(-) (limited to 'lib/diameter/test/diameter_util.erl') diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl index 3313e6ab75..3574094417 100644 --- a/lib/diameter/test/diameter_util.erl +++ b/lib/diameter/test/diameter_util.erl @@ -32,14 +32,19 @@ %% diameter-specific -export([lport/2, - lport/3]). + lport/3, + service/1, + listen/2, + connect/3]). %% common_test-specific -export([write_priv/3, - read_priv/2]). + read_priv/2, + map_priv/3]). -define(L, atom_to_list). +%% --------------------------------------------------------------------------- %% consult/2 %% %% Extract info from the app/appup file (presumably) of the named @@ -64,6 +69,7 @@ consult(Path) -> %% Name/Path in the return value distinguish the errors and allow for %% a useful badmatch. +%% --------------------------------------------------------------------------- %% run/1 %% %% Evaluate functions in parallel and return a list of those that @@ -79,6 +85,7 @@ cons(true, _, _, Acc) -> cons(false, F, RC, Acc) -> [{F, RC} | Acc]. +%% --------------------------------------------------------------------------- %% fold/3 %% %% Parallel fold. Results are folded in the order received. @@ -124,6 +131,7 @@ down(MRef) -> down() -> receive {'DOWN', MRef, process, _, Reason} -> {MRef, Reason} end. +%% --------------------------------------------------------------------------- %% foldl/3 %% %% Parallel fold. Results are folded in order of the function list. @@ -139,6 +147,7 @@ recvl([{MRef, F} | L], Ref, Fun, Acc) -> R = down(MRef), recvl(L, Ref, Fun, acc(R, Ref, F, Fun, Acc)). +%% --------------------------------------------------------------------------- %% scramble/1 %% %% Sort a list into random order. @@ -158,7 +167,10 @@ s(Acc, L) -> {H, [T|Rest]} = lists:split(random:uniform(length(L)) - 1, L), s([T|Acc], H ++ Rest). +%% --------------------------------------------------------------------------- %% eval/1 +%% +%% Evaluate a function in one of a number of forms. eval({M,[F|A]}) when is_atom(F) -> @@ -179,7 +191,52 @@ eval(F) when is_function(F,0) -> F(). +%% --------------------------------------------------------------------------- +%% write_priv/3 +%% +%% Write an arbitrary term to a named file. + +write_priv(Config, Name, Term) -> + write(path(Config, Name), Term). + +write(Path, Term) -> + ok = file:write_file(Path, term_to_binary(Term)). + +%% read_priv/2 +%% +%% Read a term from a file. + +read_priv(Config, Name) -> + read(path(Config, Name)). + +read(Path) -> + {ok, Bin} = file:read_file(Path), + binary_to_term(Bin). + +%% map_priv/3 +%% +%% Modify a term in a file and return both old and new values. + +map_priv(Config, Name, Fun1) -> + map(path(Config, Name), Fun1). + +map(Path, Fun1) -> + T0 = read(Path), + T1 = Fun1(T0), + write(Path, T1), + {T0, T1}. + +path(Config, Name) + when is_atom(Name) -> + path(Config, ?L(Name)); +path(Config, Name) -> + Dir = proplists:get_value(priv_dir, Config), + filename:join([Dir, Name]). + +%% --------------------------------------------------------------------------- %% lport/2-3 +%% +%% Lookup the port number of a tcp/sctp listening transport. lport(M, Ref) -> lport(M, Ref, 1). @@ -187,9 +244,6 @@ lport(M, Ref) -> lport(M, Ref, Tries) -> lp(tmod(M), Ref, Tries). -tmod(sctp) -> diameter_sctp; -tmod(tcp) -> diameter_tcp. - lp(M, Ref, T) -> L = [N || {listen, N, _} <- M:ports(Ref)], if [] /= L orelse T =< 1 -> @@ -199,17 +253,71 @@ lp(M, Ref, T) -> lp(M, Ref, T-1) end. -%% write_priv/3 +%% --------------------------------------------------------------------------- +%% service/1 +%% +%% Start a new diameter service and return its generated name. -write_priv(Config, Name, Term) -> - Dir = proplists:get_value(priv_dir, Config), - Path = filename:join([Dir, Name]), - ok = file:write_file(Path, term_to_binary(Term)). +service(Opts) -> + Name = make_ref(), -%% read_priv/2 + case diameter:start_service(Name, Opts) of + ok -> + {ok, Name}; + {error, _} = No -> + No + end. -read_priv(Config, Name) -> - Dir = proplists:get_value(priv_dir, Config), - Path = filename:join([Dir, Name]), - {ok, Bin} = file:read_file(Path), - binary_to_term(Bin). +%% --------------------------------------------------------------------------- +%% listen/2 +%% +%% Add a listening transport on the loopback address and a free port. + +listen(SvcName, Prot) -> + add_transport(SvcName, {listen, transport(Prot, listen)}). + +%% --------------------------------------------------------------------------- +%% connect/3 +%% +%% Add a connecting transport on and connect to a listening transport +%% with the specified reference. + +connect(SvcName, Prot, LRef) -> + [PortNr] = lport(Prot, LRef), + Ref = add_transport(SvcName, {connect, transport(Prot, PortNr)}), + true = diameter:subscribe(SvcName), + receive + {diameter_event, SvcName, {up, Ref, _, _, _}} -> Ref + after 2000 -> + error({up, SvcName, Prot, PortNr}) + end. + +%% --------------------------------------------------------------------------- + +-define(ADDR, {127,0,0,1}). + +add_transport(SvcName, T) -> + {ok, Ref} = diameter:add_transport(SvcName, T), + Ref. + +tmod(tcp) -> + diameter_tcp; +tmod(sctp) -> + diameter_sctp. + +transport(Prot, T) -> + {tag(T), opts(Prot, T)}. + +tag(listen = T) -> + T; +tag(_PortNr) -> + connect. + +opts(Prot, T) -> + [{transport_module, tmod(Prot)}, + {transport_config, [{ip, ?ADDR}, {port, 0} | opts(T)]}]. + +opts(listen) -> + []; +opts(PortNr) -> + [{raddr, ?ADDR}, {rport, PortNr}]. -- cgit v1.2.3 From bc099fc49937477d96f930237fc58d388a0d43ef Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sun, 9 Oct 2011 23:37:21 +0200 Subject: Use util to simplify connection establishment in suites --- lib/diameter/test/diameter_util.erl | 63 +++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 35 deletions(-) (limited to 'lib/diameter/test/diameter_util.erl') diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl index 3574094417..3fe8ea5363 100644 --- a/lib/diameter/test/diameter_util.erl +++ b/lib/diameter/test/diameter_util.erl @@ -33,9 +33,9 @@ %% diameter-specific -export([lport/2, lport/3, - service/1, listen/2, - connect/3]). + connect/3, + disconnect/4]). %% common_test-specific -export([write_priv/3, @@ -253,28 +253,13 @@ lp(M, Ref, T) -> lp(M, Ref, T-1) end. -%% --------------------------------------------------------------------------- -%% service/1 -%% -%% Start a new diameter service and return its generated name. - -service(Opts) -> - Name = make_ref(), - - case diameter:start_service(Name, Opts) of - ok -> - {ok, Name}; - {error, _} = No -> - No - end. - %% --------------------------------------------------------------------------- %% listen/2 %% %% Add a listening transport on the loopback address and a free port. listen(SvcName, Prot) -> - add_transport(SvcName, {listen, transport(Prot, listen)}). + add_transport(SvcName, {listen, opts(Prot, listen)}). %% --------------------------------------------------------------------------- %% connect/3 @@ -282,15 +267,31 @@ listen(SvcName, Prot) -> %% Add a connecting transport on and connect to a listening transport %% with the specified reference. -connect(SvcName, Prot, LRef) -> - [PortNr] = lport(Prot, LRef), - Ref = add_transport(SvcName, {connect, transport(Prot, PortNr)}), - true = diameter:subscribe(SvcName), - receive - {diameter_event, SvcName, {up, Ref, _, _, _}} -> Ref - after 2000 -> - error({up, SvcName, Prot, PortNr}) - end. +connect(Client, Prot, LRef) -> + [PortNr] = lport(Prot, LRef, 20), + Ref = add_transport(Client, {connect, opts(Prot, PortNr)}), + true = diameter:subscribe(Client), + ok = receive + {diameter_event, Client, {up, Ref, _, _, _}} -> ok + after 2000 -> + {Client, Prot, PortNr, process_info(self(), messages)} + end, + Ref. + +%% --------------------------------------------------------------------------- +%% disconnect/4 +%% +%% Remove the client transport and expect the server transport to go +%% down. + +disconnect(Client, Ref, Server, LRef) -> + true = diameter:subscribe(Server), + ok = diameter:remove_transport(Client, Ref), + ok = receive + {diameter_event, Server, {down, LRef, _, _}} -> ok + after 2000 -> + {Client, Ref, Server, LRef, process_info(self(), messages)} + end. %% --------------------------------------------------------------------------- @@ -305,14 +306,6 @@ tmod(tcp) -> tmod(sctp) -> diameter_sctp. -transport(Prot, T) -> - {tag(T), opts(Prot, T)}. - -tag(listen = T) -> - T; -tag(_PortNr) -> - connect. - opts(Prot, T) -> [{transport_module, tmod(Prot)}, {transport_config, [{ip, ?ADDR}, {port, 0} | opts(T)]}]. -- cgit v1.2.3