shutdown_SUITE.erl 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. %% Copyright (c) 2013, Loïc Hoguin <essen@ninenines.eu>
  2. %%
  3. %% Permission to use, copy, modify, and/or distribute this software for any
  4. %% purpose with or without fee is hereby granted, provided that the above
  5. %% copyright notice and this permission notice appear in all copies.
  6. %%
  7. %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. -module(shutdown_SUITE).
  15. -include_lib("common_test/include/ct.hrl").
  16. %% ct.
  17. -export([all/0]).
  18. -export([init_per_suite/1]).
  19. -export([end_per_suite/1]).
  20. %% Tests.
  21. -export([brutal_kill/1]).
  22. -export([infinity/1]).
  23. -export([infinity_trap_exit/1]).
  24. -export([timeout/1]).
  25. -export([timeout_trap_exit/1]).
  26. %% ct.
  27. all() ->
  28. [brutal_kill, infinity, infinity_trap_exit, timeout, timeout_trap_exit].
  29. init_per_suite(Config) ->
  30. ok = application:start(ranch),
  31. Config.
  32. end_per_suite(_) ->
  33. application:stop(ranch),
  34. ok.
  35. %% Tests.
  36. brutal_kill(_) ->
  37. Name = brutal_kill,
  38. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  39. ranch_tcp, [{port, 0}, {shutdown, brutal_kill}],
  40. echo_protocol, []),
  41. Port = ranch:get_port(Name),
  42. {ok, _} = gen_tcp:connect("localhost", Port, []),
  43. receive after 100 -> ok end,
  44. ListenerSupChildren = supervisor:which_children(ListenerSup),
  45. {_, ConnsSup, _, _}
  46. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  47. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  48. true = is_process_alive(Pid),
  49. ranch:stop_listener(Name),
  50. receive after 100 -> ok end,
  51. false = is_process_alive(Pid),
  52. false = is_process_alive(ListenerSup),
  53. {error, _} = gen_tcp:connect("localhost", Port, []),
  54. ok.
  55. infinity(_) ->
  56. Name = infinity,
  57. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  58. ranch_tcp, [{port, 0}, {shutdown, infinity}],
  59. echo_protocol, []),
  60. Port = ranch:get_port(Name),
  61. {ok, _} = gen_tcp:connect("localhost", Port, []),
  62. receive after 100 -> ok end,
  63. ListenerSupChildren = supervisor:which_children(ListenerSup),
  64. {_, ConnsSup, _, _}
  65. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  66. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  67. true = is_process_alive(Pid),
  68. ranch:stop_listener(Name),
  69. receive after 100 -> ok end,
  70. false = is_process_alive(Pid),
  71. false = is_process_alive(ListenerSup),
  72. {error, _} = gen_tcp:connect("localhost", Port, []),
  73. ok.
  74. infinity_trap_exit(_) ->
  75. Name = infinity_trap_exit,
  76. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  77. ranch_tcp, [{port, 0}, {shutdown, infinity}],
  78. trap_exit_protocol, []),
  79. Port = ranch:get_port(Name),
  80. {ok, _} = gen_tcp:connect("localhost", Port, []),
  81. receive after 100 -> ok end,
  82. ListenerSupChildren = supervisor:which_children(ListenerSup),
  83. {_, ConnsSup, _, _}
  84. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  85. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  86. true = is_process_alive(Pid),
  87. %% This call will block infinitely.
  88. SpawnPid = spawn(fun() -> ranch:stop_listener(Name) end),
  89. receive after 100 -> ok end,
  90. %% The protocol traps exit signals, and ignore them, so it won't die.
  91. true = is_process_alive(Pid),
  92. %% The listener will stay up forever too.
  93. true = is_process_alive(ListenerSup),
  94. %% We can't connect, though.
  95. {error, _} = gen_tcp:connect("localhost", Port, []),
  96. %% Killing the process unblocks everything.
  97. exit(Pid, kill),
  98. receive after 100 -> ok end,
  99. false = is_process_alive(ListenerSup),
  100. false = is_process_alive(SpawnPid),
  101. ok.
  102. %% Same as infinity because the protocol doesn't trap exits.
  103. timeout(_) ->
  104. Name = timeout,
  105. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  106. ranch_tcp, [{port, 0}, {shutdown, 500}],
  107. echo_protocol, []),
  108. Port = ranch:get_port(Name),
  109. {ok, _} = gen_tcp:connect("localhost", Port, []),
  110. receive after 100 -> ok end,
  111. ListenerSupChildren = supervisor:which_children(ListenerSup),
  112. {_, ConnsSup, _, _}
  113. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  114. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  115. true = is_process_alive(Pid),
  116. ranch:stop_listener(Name),
  117. receive after 100 -> ok end,
  118. false = is_process_alive(Pid),
  119. false = is_process_alive(ListenerSup),
  120. {error, _} = gen_tcp:connect("localhost", Port, []),
  121. ok.
  122. timeout_trap_exit(_) ->
  123. Name = timeout_trap_exit,
  124. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  125. ranch_tcp, [{port, 0}, {shutdown, 500}],
  126. trap_exit_protocol, []),
  127. Port = ranch:get_port(Name),
  128. {ok, _} = gen_tcp:connect("localhost", Port, []),
  129. receive after 100 -> ok end,
  130. ListenerSupChildren = supervisor:which_children(ListenerSup),
  131. {_, ConnsSup, _, _}
  132. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  133. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  134. true = is_process_alive(Pid),
  135. %% This call will block for the duration of the shutdown.
  136. SpawnPid = spawn(fun() -> ranch:stop_listener(Name) end),
  137. receive after 100 -> ok end,
  138. %% The protocol traps exit signals, and ignore them, so it won't die.
  139. true = is_process_alive(Pid),
  140. %% The listener will stay up for now too.
  141. true = is_process_alive(ListenerSup),
  142. %% We can't connect, though.
  143. {error, _} = gen_tcp:connect("localhost", Port, []),
  144. %% Wait for the timeout to finish and see that everything is killed.
  145. receive after 500 -> ok end,
  146. false = is_process_alive(Pid),
  147. false = is_process_alive(ListenerSup),
  148. false = is_process_alive(SpawnPid),
  149. ok.