shutdown_SUITE.erl 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. -compile(export_all).
  16. -import(ct_helper, [doc/1]).
  17. %% ct.
  18. all() ->
  19. ct_helper:all(?MODULE).
  20. %% Tests.
  21. brutal_kill(_) ->
  22. Name = brutal_kill,
  23. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  24. ranch_tcp, [{port, 0}, {shutdown, brutal_kill}],
  25. echo_protocol, []),
  26. Port = ranch:get_port(Name),
  27. {ok, _} = gen_tcp:connect("localhost", Port, []),
  28. receive after 100 -> ok end,
  29. ListenerSupChildren = supervisor:which_children(ListenerSup),
  30. {_, ConnsSup, _, _}
  31. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  32. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  33. true = is_process_alive(Pid),
  34. ok = ranch:stop_listener(Name),
  35. receive after 100 -> ok end,
  36. false = is_process_alive(Pid),
  37. false = is_process_alive(ListenerSup),
  38. {error, _} = gen_tcp:connect("localhost", Port, []),
  39. ok.
  40. infinity(_) ->
  41. Name = infinity,
  42. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  43. ranch_tcp, [{port, 0}, {shutdown, infinity}],
  44. echo_protocol, []),
  45. Port = ranch:get_port(Name),
  46. {ok, _} = gen_tcp:connect("localhost", Port, []),
  47. receive after 100 -> ok end,
  48. ListenerSupChildren = supervisor:which_children(ListenerSup),
  49. {_, ConnsSup, _, _}
  50. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  51. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  52. true = is_process_alive(Pid),
  53. ok = ranch:stop_listener(Name),
  54. receive after 100 -> ok end,
  55. false = is_process_alive(Pid),
  56. false = is_process_alive(ListenerSup),
  57. {error, _} = gen_tcp:connect("localhost", Port, []),
  58. ok.
  59. infinity_trap_exit(_) ->
  60. Name = infinity_trap_exit,
  61. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  62. ranch_tcp, [{port, 0}, {shutdown, infinity}],
  63. trap_exit_protocol, []),
  64. Port = ranch:get_port(Name),
  65. {ok, _} = gen_tcp:connect("localhost", Port, []),
  66. receive after 100 -> ok end,
  67. ListenerSupChildren = supervisor:which_children(ListenerSup),
  68. {_, ConnsSup, _, _}
  69. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  70. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  71. true = is_process_alive(Pid),
  72. %% This call will block infinitely.
  73. SpawnPid = spawn(fun() -> ok = ranch:stop_listener(Name) end),
  74. receive after 100 -> ok end,
  75. %% The protocol traps exit signals, and ignore them, so it won't die.
  76. true = is_process_alive(Pid),
  77. %% The listener will stay up forever too.
  78. true = is_process_alive(ListenerSup),
  79. %% We can't connect, though.
  80. {error, _} = gen_tcp:connect("localhost", Port, []),
  81. %% Killing the process unblocks everything.
  82. exit(Pid, kill),
  83. receive after 100 -> ok end,
  84. false = is_process_alive(ListenerSup),
  85. false = is_process_alive(SpawnPid),
  86. ok.
  87. %% Same as infinity because the protocol doesn't trap exits.
  88. timeout(_) ->
  89. Name = timeout,
  90. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  91. ranch_tcp, [{port, 0}, {shutdown, 500}],
  92. echo_protocol, []),
  93. Port = ranch:get_port(Name),
  94. {ok, _} = gen_tcp:connect("localhost", Port, []),
  95. receive after 100 -> ok end,
  96. ListenerSupChildren = supervisor:which_children(ListenerSup),
  97. {_, ConnsSup, _, _}
  98. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  99. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  100. true = is_process_alive(Pid),
  101. ok = ranch:stop_listener(Name),
  102. receive after 100 -> ok end,
  103. false = is_process_alive(Pid),
  104. false = is_process_alive(ListenerSup),
  105. {error, _} = gen_tcp:connect("localhost", Port, []),
  106. ok.
  107. timeout_trap_exit(_) ->
  108. Name = timeout_trap_exit,
  109. {ok, ListenerSup} = ranch:start_listener(Name, 1,
  110. ranch_tcp, [{port, 0}, {shutdown, 500}],
  111. trap_exit_protocol, []),
  112. Port = ranch:get_port(Name),
  113. {ok, _} = gen_tcp:connect("localhost", Port, []),
  114. receive after 100 -> ok end,
  115. ListenerSupChildren = supervisor:which_children(ListenerSup),
  116. {_, ConnsSup, _, _}
  117. = lists:keyfind(ranch_conns_sup, 1, ListenerSupChildren),
  118. [{_, Pid, _, _}] = supervisor:which_children(ConnsSup),
  119. true = is_process_alive(Pid),
  120. %% This call will block for the duration of the shutdown.
  121. SpawnPid = spawn(fun() -> ok = ranch:stop_listener(Name) end),
  122. receive after 100 -> ok end,
  123. %% The protocol traps exit signals, and ignore them, so it won't die.
  124. true = is_process_alive(Pid),
  125. %% The listener will stay up for now too.
  126. true = is_process_alive(ListenerSup),
  127. %% We can't connect, though.
  128. {error, _} = gen_tcp:connect("localhost", Port, []),
  129. %% Wait for the timeout to finish and see that everything is killed.
  130. receive after 500 -> ok end,
  131. false = is_process_alive(Pid),
  132. false = is_process_alive(ListenerSup),
  133. false = is_process_alive(SpawnPid),
  134. ok.