diff options
author | Loïc Hoguin <[email protected]> | 2012-12-21 17:04:42 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2012-12-21 17:04:42 +0100 |
commit | 058ad09e8b2c885a0888bda47459acd32ece917e (patch) | |
tree | dcbf07093880e6b4315c86336b92236ee310fa72 /test/acceptor_SUITE.erl | |
parent | 7f4261d1d83dde90be93d3615693b44969f6b446 (diff) | |
parent | 66618454e0925ebd46b6905a1957206b2f2663e9 (diff) | |
download | ranch-058ad09e8b2c885a0888bda47459acd32ece917e.tar.gz ranch-058ad09e8b2c885a0888bda47459acd32ece917e.tar.bz2 ranch-058ad09e8b2c885a0888bda47459acd32ece917e.zip |
Merge branch 'fix/listener_sup_failures' of git://github.com/keynslug/syncranch
Diffstat (limited to 'test/acceptor_SUITE.erl')
-rw-r--r-- | test/acceptor_SUITE.erl | 124 |
1 files changed, 123 insertions, 1 deletions
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl index 59513ab..582e564 100644 --- a/test/acceptor_SUITE.erl +++ b/test/acceptor_SUITE.erl @@ -41,10 +41,15 @@ -export([tcp_max_connections_and_beyond/1]). -export([tcp_upgrade/1]). +%% supervisor. +-export([supervisor_clean_restart/1]). +-export([supervisor_clean_child_restart/1]). +-export([supervisor_conns_alive/1]). + %% ct. all() -> - [{group, tcp}, {group, ssl}, {group, misc}]. + [{group, tcp}, {group, ssl}, {group, misc}, {group, supervisor}]. groups() -> [{tcp, [ @@ -61,6 +66,10 @@ groups() -> ssl_echo ]}, {misc, [ misc_bad_transport + ]}, {supervisor, [ + supervisor_clean_restart, + supervisor_clean_child_restart, + supervisor_conns_alive ]}]. init_per_suite(Config) -> @@ -261,6 +270,119 @@ tcp_upgrade(_) -> ok = connect_loop(Port, 1, 0), receive upgraded -> ok after 1000 -> error(timeout) end. +%% Supervisor tests + +supervisor_clean_restart(_) -> + %% There we verify that mature listener death will not let + %% whole supervisor down and also the supervisor itself will + %% restart everything properly. + Ref = supervisor_clean_restart, + NbAcc = 4, + {ok, Pid} = ranch:start_listener(Ref, + NbAcc, ranch_tcp, [{port, 0}], echo_protocol, []), + %% Trace supervisor spawns. + 1 = erlang:trace(Pid, true, [procs, set_on_spawn]), + ListenerPid0 = ranch_server:lookup_listener(Ref), + erlang:exit(ListenerPid0, kill), + receive after 1000 -> ok end, + %% Verify that supervisor is alive + true = is_process_alive(Pid), + %% ...but children are dead. + false = is_process_alive(ListenerPid0), + %% Receive traces from newly started children + ListenerPid = receive {trace, Pid, spawn, Pid1, _} -> Pid1 end, + _ConnSupPid = receive {trace, Pid, spawn, Pid2, _} -> Pid2 end, + AccSupPid = receive {trace, Pid, spawn, Pid3, _} -> Pid3 end, + %% ...and its acceptors. + [receive {trace, AccSupPid, spawn, _Pid, _} -> ok end || + _ <- lists:seq(1, NbAcc)], + %% No more traces then. + receive + {trace, EPid, spawn, _, _} when EPid == Pid; EPid == AccSupPid -> + error(invalid_restart) + after 1000 -> ok end, + %% Verify that new children registered themselves properly. + ListenerPid = ranch_server:lookup_listener(Ref), + _ = erlang:trace(all, false, [all]), + ok = clean_traces(). + +supervisor_clean_child_restart(_) -> + %% Then we verify that only parts of the supervision tree + %% restarted in the case of failure. + Ref = supervisor_clean_child_restart, + %% Trace socket allocations. + _ = erlang:trace(new, true, [call]), + 1 = erlang:trace_pattern({ranch_tcp, listen, 1}, [{'_', [], [{return_trace}]}], [global]), + {ok, Pid} = ranch:start_listener(Ref, + 1, ranch_tcp, [{port, 0}], echo_protocol, []), + %% Trace supervisor spawns. + 1 = erlang:trace(Pid, true, [procs, set_on_spawn]), + ListenerPid0 = ranch_server:lookup_listener(Ref), + %% Manually shut the listening socket down. + LSocket = receive + {trace, _, return_from, {ranch_tcp, listen, 1}, {ok, Socket}} -> + Socket + after 0 -> + error(lsocket_unknown) + end, + ok = gen_tcp:close(LSocket), + receive after 1000 -> ok end, + %% Verify that supervisor and its first two children are alive. + true = is_process_alive(Pid), + true = is_process_alive(ListenerPid0), + %% Check that acceptors_sup is restarted properly. + AccSupPid = receive {trace, Pid, spawn, Pid1, _} -> Pid1 end, + AccPid = receive {trace, AccSupPid, spawn, Pid2, _} -> Pid2 end, + receive {trace, AccPid, spawn, _, _} -> ok end, + %% No more traces then. + receive + {trace, _, spawn, _, _} -> error(invalid_restart) + after 1000 -> ok end, + %% Verify that children still registered right. + ListenerPid0 = ranch_server:lookup_listener(Ref), + _ = erlang:trace_pattern({ranch_tcp, listen, 1}, false, []), + _ = erlang:trace(all, false, [all]), + ok = clean_traces(), + ok. + +supervisor_conns_alive(_) -> + %% And finally we make sure that in the case of partial failure + %% live connections are not being killed. + Ref = supervisor_conns_alive, + _ = erlang:trace(new, true, [call]), + 1 = erlang:trace_pattern({ranch_tcp, listen, 1}, [{'_', [], [{return_trace}]}], [global]), + {ok, _} = ranch:start_listener(Ref, + 1, ranch_tcp, [{port, 0}], remove_conn_and_wait_protocol, [{remove, false}]), + ok, + %% Get the listener socket + LSocket = receive + {trace, _, return_from, {ranch_tcp, listen, 1}, {ok, S}} -> + S + after 0 -> + error(lsocket_unknown) + end, + TcpPort = ranch:get_port(Ref), + {ok, Socket} = gen_tcp:connect("localhost", TcpPort, + [binary, {active, true}, {packet, raw}]), + %% Shut the socket down + ok = gen_tcp:close(LSocket), + %% Assert that client is still viable. + receive {tcp_closed, _} -> error(closed) after 1500 -> ok end, + ok = gen_tcp:send(Socket, <<"poke">>), + receive {tcp_closed, _} -> ok end, + _ = erlang:trace(all, false, [all]), + ok = clean_traces(). + +clean_traces() -> + receive + {trace, _, _, _} -> + clean_traces(); + {trace, _, _, _, _} -> + clean_traces() + after 0 -> + ok + end. + %% Utility functions. connect_loop(_, 0, _) -> |