aboutsummaryrefslogblamecommitdiffstats
path: root/lib/kernel/test/gen_sctp_SUITE.erl
blob: b19ce4d40b71b5c326e87d55784e68ed280c099a (plain) (tree)

























                                                                         

                                                                  

             
                                                                            








































































































































































































































































































                                                                            
                                                      









                                                                












































                                                                              
%% 
%% %CopyrightBegin%
%% 
%% Copyright Ericsson AB 2007-2009. 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/.
%% 
%% 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.
%% 
%% %CopyrightEnd%
%% 
-module(gen_sctp_SUITE).

-include("test_server.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

%%-compile(export_all).

-export([all/1,init_per_testcase/2,fin_per_testcase/2,
	 basic/1,api_open_close/1,api_listen/1,api_connect_init/1,
	 xfer_min/1,xfer_active/1]).

all(suite) ->
    [basic,api_open_close,api_listen,api_connect_init,xfer_min,xfer_active].

init_per_testcase(_Func, Config) ->
    Dog = test_server:timetrap(test_server:seconds(15)),
    [{watchdog, Dog}|Config].
fin_per_testcase(_Func, Config) ->
    Dog = ?config(watchdog, Config),
    test_server:timetrap_cancel(Dog).



basic(doc) ->
    "Hello world";
basic(suite) ->
    [];
basic(Config) when is_list(Config) ->
    ?line {ok,S} = gen_sctp:open(),
    ?line ok = gen_sctp:close(S),
    ok.

xfer_min(doc) ->
    "Minimal data transfer";
xfer_min(suite) ->
    [];
xfer_min(Config) when is_list(Config) ->
    ?line Stream = 0,
    ?line Data = <<"The quick brown fox jumps over a lazy dog 0123456789">>,
    ?line Loopback = {127,0,0,1},
    ?line {ok,Sb} = gen_sctp:open(),
    ?line {ok,Pb} = inet:port(Sb),
    ?line ok = gen_sctp:listen(Sb, true),
    
    ?line {ok,Sa} = gen_sctp:open(),
    ?line {ok,Pa} = inet:port(Sa),
    ?line {ok,#sctp_assoc_change{state=comm_up,
				 error=0,
				 outbound_streams=SaOutboundStreams,
				 inbound_streams=SaInboundStreams,
				 assoc_id=SaAssocId}=SaAssocChange} =
	gen_sctp:connect(Sa, Loopback, Pb, []),
    ?line {ok,{Loopback,
	       Pa,[],
	       #sctp_assoc_change{state=comm_up,
				  error=0,
				  outbound_streams=SbOutboundStreams,
				  inbound_streams=SbInboundStreams,
				  assoc_id=SbAssocId}}} =
	gen_sctp:recv(Sb, infinity),
    ?line SaOutboundStreams = SbInboundStreams,
    ?line SbOutboundStreams = SaInboundStreams,
    ?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data),
    ?line case gen_sctp:recv(Sb, infinity) of
	      {ok,{Loopback,
		   Pa,
		   [#sctp_sndrcvinfo{stream=Stream,
				     assoc_id=SbAssocId}],
		   Data}} -> ok;
	      {ok,{Loopback,
		   Pa,[],
		   #sctp_paddr_change{addr = {Loopback,_},
				      state = addr_available,
				      error = 0,
				      assoc_id = SbAssocId}}} ->
		  {ok,{Loopback,
		       Pa,
		       [#sctp_sndrcvinfo{stream=Stream,
					 assoc_id=SbAssocId}],
		       Data}} =	gen_sctp:recv(Sb, infinity)
	  end,
    ?line ok = gen_sctp:send(Sb, SbAssocId, 0, Data),
    ?line {ok,{Loopback,
	       Pb,
	       [#sctp_sndrcvinfo{stream=Stream,
				 assoc_id=SaAssocId}],
	       Data}} =
	gen_sctp:recv(Sa, infinity),
    %%
    ?line ok = gen_sctp:eof(Sa, SaAssocChange),
    ?line {ok,{Loopback,
 	       Pa,[],
 	       #sctp_shutdown_event{assoc_id=SbAssocId}}} =
 	gen_sctp:recv(Sb, infinity),
    ?line {ok,{Loopback,
 	       Pb,[],
 	       #sctp_assoc_change{state=shutdown_comp,
 				  error=0,
 				  assoc_id=SaAssocId}}} =
 	gen_sctp:recv(Sa, infinity),
    ?line {ok,{Loopback,
 	       Pa,[],
 	       #sctp_assoc_change{state=shutdown_comp,
 				  error=0,
 				  assoc_id=SbAssocId}}} =
 	gen_sctp:recv(Sb, infinity),
    ?line ok = gen_sctp:close(Sa),
    ?line ok = gen_sctp:close(Sb),
    
    ?line receive
	      Msg -> test_server:fail({received,Msg})
	  after 17 -> ok
	  end,
    ok.

xfer_active(doc) ->
    "Minimal data transfer in active mode";
xfer_active(suite) ->
    [];
xfer_active(Config) when is_list(Config) ->
    ?line Timeout = 2000,
    ?line Stream = 0,
    ?line Data = <<"The quick brown fox jumps over a lazy dog 0123456789">>,
    ?line Loopback = {127,0,0,1},
    ?line {ok,Sb} = gen_sctp:open([{active,true}]),
    ?line {ok,Pb} = inet:port(Sb),
    ?line ok = gen_sctp:listen(Sb, true),
    
    ?line {ok,Sa} = gen_sctp:open([{active,true}]),
    ?line {ok,Pa} = inet:port(Sa),
    ?line {ok,#sctp_assoc_change{state=comm_up,
				 error=0,
				 outbound_streams=SaOutboundStreams,
				 inbound_streams=SaInboundStreams,
				 assoc_id=SaAssocId}=SaAssocChange} =
	gen_sctp:connect(Sa, Loopback, Pb, []),
    ?line io:format("Sa=~p, Pa=~p, Sb=~p, Pb=~p, SaAssocId=~p, "
		    "SaOutboundStreams=~p, SaInboundStreams=~p~n",
		    [Sa,Pa,Sb,Pb,SaAssocId,
		     SaOutboundStreams,SaInboundStreams]),
    ?line SbAssocId = 
	receive
	    {sctp,Sb,Loopback,Pa,
	     {[],
	      #sctp_assoc_change{state=comm_up,
				 error=0,
				   outbound_streams=SbOutboundStreams,
				 inbound_streams=SbInboundStreams,
				 assoc_id=SBAI}}} ->
		?line SaOutboundStreams = SbInboundStreams,
		?line  SaInboundStreams = SbOutboundStreams,
		SBAI
	after Timeout ->
		?line test_server:fail({unexpected,flush()})
	end,
    ?line io:format("SbAssocId=~p~n", [SbAssocId]),
    ?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data),
    ?line receive
	      {sctp,Sb,Loopback,Pa,
	       {[#sctp_sndrcvinfo{stream=Stream,
				  assoc_id=SbAssocId}],
		Data}} -> ok;
	      {sctp,Sb,Loopback,Pa,
	       {[],
		#sctp_paddr_change{addr = {Loopback,_},
				   state = addr_available,
				   error = 0,
				   assoc_id = SbAssocId}}} ->
		  ?line receive
			    {sctp,Sb,Loopback,Pa,
			     {[#sctp_sndrcvinfo{stream=Stream,
						assoc_id=SbAssocId}],
			      Data}} -> ok
			end
	  after Timeout ->
		  ?line test_server:fail({unexpected,flush()})
	  end,
    ?line ok = gen_sctp:send(Sb, SbAssocId, 0, Data),
    ?line receive
	      {sctp,Sa,Loopback,Pb,
	       {[#sctp_sndrcvinfo{stream=Stream,
				  assoc_id=SaAssocId}],
		Data}} -> ok
	  after Timeout ->
		  ?line test_server:fail({unexpected,flush()})
	  end,
    %%
    ?line ok = gen_sctp:abort(Sa, SaAssocChange),
    ?line receive
	      {sctp,Sb,Loopback,Pa,
	       {[],
		#sctp_assoc_change{state=comm_lost,
				   assoc_id=SbAssocId}}} -> ok
	  after Timeout ->
		  ?line test_server:fail({unexpected,flush()})
	  end,
    ?line ok = gen_sctp:close(Sb),
    ?line receive
	      {sctp,Sa,Loopback,Pb,
	       {[],
		#sctp_assoc_change{state=comm_lost,
				   assoc_id=SaAssocId}}} -> ok
	  after 17 -> ok %% On Solaris this does not arrive
	  end,
    ?line ok = gen_sctp:close(Sa),
    %%
    ?line receive
	      Msg -> test_server:fail({unexpected,[Msg]++flush()})
	  after 17 -> ok
	  end,
    ok.

flush() ->
    receive
	Msg ->
	    [Msg|flush()]
    after 17 ->
	    []
    end.

api_open_close(doc) ->
    "Test the API function open/1,2 and close/1";
api_open_close(suite) ->
    [];
api_open_close(Config) when is_list(Config) ->
    ?line {ok,S1} = gen_sctp:open(0),
    ?line {ok,P}  = inet:port(S1),
    ?line ok      = gen_sctp:close(S1),
    
    ?line {ok,S2} = gen_sctp:open(P),
    ?line {ok,P}  = inet:port(S2),
    ?line ok      = gen_sctp:close(S2),
    
    ?line {ok,S3} = gen_sctp:open([{port,P}]),
    ?line {ok,P}  = inet:port(S3),
    ?line ok      = gen_sctp:close(S3),
    
    ?line {ok,S4} = gen_sctp:open(P, []),
    ?line {ok,P}  = inet:port(S4),
    ?line ok      = gen_sctp:close(S4),
    
    ?line {ok,S5} = gen_sctp:open(P, [{ifaddr,any}]),
    ?line {ok,P}  = inet:port(S5),
    ?line ok      = gen_sctp:close(S5),

    ?line ok      = gen_sctp:close(S5),
    
    ?line try gen_sctp:close(0)
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open({})
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open(-1)
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open(65536)
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open(make_ref(), [])
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open(0, {})
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open(0, [make_ref()])
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open([{invalid_option,0}])
	  catch error:badarg -> ok
	  end,
    
    ?line try gen_sctp:open(0, [{mode,invalid_mode}])
	  catch error:badarg -> ok
	  end,
    ok.

api_listen(doc) ->
    "Test the API function listen/2";
api_listen(suite) ->
    [];
api_listen(Config) when is_list(Config) ->
    ?line Localhost = {127,0,0,1},
    
    ?line try gen_sctp:listen(0, true)
	  catch error:badarg -> ok
	  end,
    
    ?line {ok,S} = gen_sctp:open(),
    ?line {ok,Pb} = inet:port(S),
    ?line try gen_sctp:listen(S, not_allowed_for_listen)
	  catch error:badarg -> ok
	  end,
    ?line ok = gen_sctp:close(S),
    ?line {error,closed} = gen_sctp:listen(S, true),
    
    ?line {ok,Sb} = gen_sctp:open(Pb),
    ?line {ok,Sa} = gen_sctp:open(),
    ?line case gen_sctp:connect(Sa, localhost, Pb, []) of
	      {error,econnrefused} ->
		  ?line {ok,{Localhost,
			     Pb,[],
			     #sctp_assoc_change{
				  state=comm_lost}}} =
		      gen_sctp:recv(Sa, infinity);
	      {error,#sctp_assoc_change{state=cant_assoc}} -> ok
	  end,
    ?line ok = gen_sctp:listen(Sb, true),
    ?line {ok,#sctp_assoc_change{state=comm_up,
				 error=0}} =
	gen_sctp:connect(Sa, localhost, Pb, []),
    ?line ok = gen_sctp:close(Sa),
    ?line ok = gen_sctp:close(Sb),
    ok.

api_connect_init(doc) ->
    "Test the API function connect_init/4";
api_connect_init(suite) ->
    [];
api_connect_init(Config) when is_list(Config) ->
    ?line Localhost = {127,0,0,1},

    ?line {ok,S} = gen_sctp:open(),
    ?line {ok,Pb} = inet:port(S),
    ?line try gen_sctp:connect_init(S, Localhost, not_allowed_for_port, [])
	  catch error:badarg -> ok
	  end,
    ?line try gen_sctp:connect_init(S, Localhost, 12345, not_allowed_for_opts)
	  catch error:badarg -> ok
	  end,
    ?line ok = gen_sctp:close(S),
    ?line {error,closed} = gen_sctp:connect_init(S, Localhost, 12345, []),

    ?line {ok,Sb} = gen_sctp:open(Pb),
    ?line {ok,Sa} = gen_sctp:open(),
    ?line case gen_sctp:connect_init(Sa, localhost, Pb, []) of
	      {error,econnrefused} ->
		  ?line {ok,{Localhost,
			     Pb,[],
			     #sctp_assoc_change{state=comm_lost}}} =
		      gen_sctp:recv(Sa, infinity);
	      ok ->
		  ?line {ok,{Localhost,
			     Pb,[],
			     #sctp_assoc_change{state=cant_assoc}}} =
		      gen_sctp:recv(Sa, infinity)
	  end,
    ?line ok = gen_sctp:listen(Sb, true),
    ?line case gen_sctp:connect_init(Sa, localhost, Pb, []) of
	      ok ->
		  ?line {ok,{Localhost,
			     Pb,[],
			     #sctp_assoc_change{
				  state = comm_up}}} =
		      gen_sctp:recv(Sa, infinity)
	  end,
    ?line ok = gen_sctp:close(Sa),
    ?line ok = gen_sctp:close(Sb),
    ok.