use a tcp socket server in common tests

Pablo Platt <>
Sun Jan 30 22:06:49 CET 2011


I'm trying to write a test for a tcp client.
I've created a fake tcp server that send predefined packets.
I can't run the server in the init_per_suite of the test.
When I start the server from the shell and run the test
or when I run a module that run the server and execute the same actions like in 
the test it works.

I'm getting two types of errors:
1. timeout when calling the server.
2. {error,eaddrinuse} in the second time running the test because the 
end_per_suite didn't have chance to stop the server.

Is there a different way I should start the tcp server in the common test?
Is there a way to execute end_per_suite even if the test fails?

A simplified version of the code I'm using:

common test
----------------
init_per_suite(Config) ->    
    myserver:start_link(?PORT),
    gen_fsm:send_event(myserver, accept).
    {ok, Conn} = myclient:start_link(?HOST, ?FAKEPORT),
    unlink(Conn),
    [{conn, Conn} | Config].

test(Config) ->
    Conn = ?config(conn, Config),
    Packet = <<1,0,0,0>>,
    <<2,0,0,0>> = gen_server:call(Conn, {packet, Packet}).

server
--------------
start_link(Port) ->
    gen_fsm:start_link({local, ?MODULE}, ?MODULE, Port, []).

init(Port) ->
    {ok, LSocket} = gen_tcp:listen(Port, [binary, {active, true}]),
    {ok, waiting, LSocket}.

waiting(accept, LSocket) ->
    {ok, _Socket} = gen_tcp:accept(LSocket),
    {next_state, waiting, LSocket}.

handle_info({tcp, Socket, Data}, StateName, State) ->
    Resp = <<2,0,0,0>>,
    gen_tcp:send(Socket, Resp),
    {next_state, StateName, State}.

client
---------------
start_link(Host, Port) ->
    gen_server:start_link(?MODULE, [Host, Port], []).

init([Host, Port]) ->
    {ok, Socket} = gen_tcp:connect(Host, Port, [binary, {active, true}])
    {ok, {Socket, from}}.

handle_call({packet, Packet}, From,{Socket, from}) ->    
    gen_tcp:send(Socket, Packet),
    {noreply, {Socket, From}}.

handle_info({tcp, _Socket, Data}, {Socket, From}) ->
    gen_server:reply(From, Data),
    {noreply, NewState}.


      


More information about the erlang-questions mailing list