shutdown_SUITE.erl 5.7 KB

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