acceptor_SUITE.erl 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. %% Copyright (c) 2011-2012, 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(acceptor_SUITE).
  15. -include_lib("common_test/include/ct.hrl").
  16. %% ct.
  17. -export([all/0]).
  18. -export([groups/0]).
  19. -export([init_per_suite/1]).
  20. -export([end_per_suite/1]).
  21. -export([init_per_group/2]).
  22. -export([end_per_group/2]).
  23. %% misc.
  24. -export([misc_bad_transport/1]).
  25. %% ssl.
  26. -export([ssl_accept_error/1]).
  27. -export([ssl_active_echo/1]).
  28. -export([ssl_echo/1]).
  29. %% tcp.
  30. -export([tcp_active_echo/1]).
  31. -export([tcp_echo/1]).
  32. -export([tcp_max_connections/1]).
  33. -export([tcp_max_connections_and_beyond/1]).
  34. -export([tcp_upgrade/1]).
  35. %% ct.
  36. all() ->
  37. [{group, tcp}, {group, ssl}, {group, misc}].
  38. groups() ->
  39. [{tcp, [
  40. tcp_active_echo,
  41. tcp_echo,
  42. tcp_max_connections,
  43. tcp_max_connections_and_beyond,
  44. tcp_upgrade
  45. ]}, {ssl, [
  46. ssl_accept_error,
  47. ssl_active_echo,
  48. ssl_echo
  49. ]}, {misc, [
  50. misc_bad_transport
  51. ]}].
  52. init_per_suite(Config) ->
  53. ok = application:start(ranch),
  54. Config.
  55. end_per_suite(_) ->
  56. application:stop(ranch),
  57. ok.
  58. init_per_group(ssl, Config) ->
  59. application:start(crypto),
  60. application:start(public_key),
  61. application:start(ssl),
  62. Config;
  63. init_per_group(_, Config) ->
  64. Config.
  65. end_per_group(ssl, _) ->
  66. application:stop(ssl),
  67. application:stop(public_key),
  68. application:stop(crypto),
  69. ok;
  70. end_per_group(_, _) ->
  71. ok.
  72. %% misc.
  73. misc_bad_transport(_) ->
  74. {error, badarg} = ranch:start_listener(misc_bad_transport, 1,
  75. bad_transport, [{port, 0}],
  76. echo_protocol, []),
  77. ok.
  78. %% ssl.
  79. ssl_accept_error(Config) ->
  80. {ok, _} = ranch:start_listener(ssl_accept_error, 1,
  81. ranch_ssl, [{port, 0},
  82. {certfile, ?config(data_dir, Config) ++ "cert.pem"}],
  83. echo_protocol, []),
  84. Port = ranch:get_port(ssl_accept_error),
  85. [AcceptorPid] = ets:lookup_element(ranch_server,
  86. {acceptors, ssl_accept_error}, 2),
  87. true = is_process_alive(AcceptorPid),
  88. {ok, Socket} = gen_tcp:connect("localhost", Port,
  89. [binary, {active, false}, {packet, raw}]),
  90. ok = gen_tcp:close(Socket),
  91. receive after 500 -> ok end,
  92. true = is_process_alive(AcceptorPid).
  93. ssl_active_echo(Config) ->
  94. {ok, _} = ranch:start_listener(ssl_active_echo, 1,
  95. ranch_ssl, [{port, 0},
  96. {certfile, ?config(data_dir, Config) ++ "cert.pem"}],
  97. active_echo_protocol, []),
  98. Port = ranch:get_port(ssl_active_echo),
  99. {ok, Socket} = ssl:connect("localhost", Port,
  100. [binary, {active, false}, {packet, raw},
  101. {certfile, ?config(data_dir, Config) ++ "cert.pem"}]),
  102. ok = ssl:send(Socket, <<"SSL Ranch is working!">>),
  103. {ok, <<"SSL Ranch is working!">>} = ssl:recv(Socket, 21, 1000),
  104. ok = ranch:stop_listener(ssl_active_echo),
  105. {error, closed} = ssl:recv(Socket, 0, 1000),
  106. %% Make sure the listener stopped.
  107. {'EXIT', _} = begin catch ranch:get_port(ssl_active_echo) end,
  108. ok.
  109. ssl_echo(Config) ->
  110. {ok, _} = ranch:start_listener(ssl_echo, 1,
  111. ranch_ssl, [{port, 0},
  112. {certfile, ?config(data_dir, Config) ++ "cert.pem"}],
  113. echo_protocol, []),
  114. Port = ranch:get_port(ssl_echo),
  115. {ok, Socket} = ssl:connect("localhost", Port,
  116. [binary, {active, false}, {packet, raw},
  117. {certfile, ?config(data_dir, Config) ++ "cert.pem"}]),
  118. ok = ssl:send(Socket, <<"SSL Ranch is working!">>),
  119. {ok, <<"SSL Ranch is working!">>} = ssl:recv(Socket, 21, 1000),
  120. ok = ranch:stop_listener(ssl_echo),
  121. {error, closed} = ssl:recv(Socket, 0, 1000),
  122. %% Make sure the listener stopped.
  123. {'EXIT', _} = begin catch ranch:get_port(ssl_echo) end,
  124. ok.
  125. %% tcp.
  126. tcp_active_echo(_) ->
  127. {ok, _} = ranch:start_listener(tcp_active_echo, 1,
  128. ranch_tcp, [{port, 0}], active_echo_protocol, []),
  129. Port = ranch:get_port(tcp_active_echo),
  130. {ok, Socket} = gen_tcp:connect("localhost", Port,
  131. [binary, {active, false}, {packet, raw}]),
  132. ok = gen_tcp:send(Socket, <<"TCP Ranch is working!">>),
  133. {ok, <<"TCP Ranch is working!">>} = gen_tcp:recv(Socket, 21, 1000),
  134. ok = ranch:stop_listener(tcp_active_echo),
  135. {error, closed} = gen_tcp:recv(Socket, 0, 1000),
  136. %% Make sure the listener stopped.
  137. {'EXIT', _} = begin catch ranch:get_port(tcp_active_echo) end,
  138. ok.
  139. tcp_echo(_) ->
  140. {ok, _} = ranch:start_listener(tcp_echo, 1,
  141. ranch_tcp, [{port, 0}], echo_protocol, []),
  142. Port = ranch:get_port(tcp_echo),
  143. {ok, Socket} = gen_tcp:connect("localhost", Port,
  144. [binary, {active, false}, {packet, raw}]),
  145. ok = gen_tcp:send(Socket, <<"TCP Ranch is working!">>),
  146. {ok, <<"TCP Ranch is working!">>} = gen_tcp:recv(Socket, 21, 1000),
  147. ok = ranch:stop_listener(tcp_echo),
  148. {error, closed} = gen_tcp:recv(Socket, 0, 1000),
  149. %% Make sure the listener stopped.
  150. {'EXIT', _} = begin catch ranch:get_port(tcp_echo) end,
  151. ok.
  152. tcp_max_connections(_) ->
  153. {ok, _} = ranch:start_listener(tcp_max_connections, 1,
  154. ranch_tcp, [{port, 0}, {max_connections, 10}],
  155. notify_and_wait_protocol, [{msg, connected}, {pid, self()}]),
  156. Port = ranch:get_port(tcp_max_connections),
  157. %% @todo We'll probably want a more direct interface to count_connections.
  158. ListenerPid = ranch_server:lookup_listener(tcp_max_connections),
  159. ok = connect_loop(Port, 11, 150),
  160. 10 = ranch_server:count_connections(ListenerPid),
  161. 10 = receive_loop(connected, 400),
  162. 1 = receive_loop(connected, 1000).
  163. tcp_max_connections_and_beyond(_) ->
  164. {ok, _} = ranch:start_listener(tcp_max_connections_and_beyond, 1,
  165. ranch_tcp, [{port, 0}, {max_connections, 10}],
  166. remove_conn_and_wait_protocol, [{remove, true}]),
  167. Port = ranch:get_port(tcp_max_connections_and_beyond),
  168. %% @todo We'll probably want a more direct interface to count_connections.
  169. ListenerPid = ranch_server:lookup_listener(tcp_max_connections_and_beyond),
  170. ok = connect_loop(Port, 10, 0),
  171. 0 = ranch_server:count_connections(ListenerPid),
  172. ranch:set_protocol_options(tcp_max_connections_and_beyond,
  173. [{remove, false}]),
  174. receive after 500 -> ok end,
  175. ok = connect_loop(Port, 10, 0),
  176. receive after 500 -> ok end,
  177. 10 = ranch_server:count_connections(ListenerPid).
  178. tcp_upgrade(_) ->
  179. receive after 20000 -> ok end,
  180. {ok, _} = ranch:start_listener(tcp_upgrade, 1,
  181. ranch_tcp, [{port, 0}],
  182. notify_and_wait_protocol, [{msg, connected}, {pid, self()}]),
  183. Port = ranch:get_port(tcp_upgrade),
  184. ok = connect_loop(Port, 1, 0),
  185. receive connected -> ok after 1000 -> error(timeout) end,
  186. ranch:set_protocol_options(tcp_upgrade, [{msg, upgraded}, {pid, self()}]),
  187. ok = connect_loop(Port, 1, 0),
  188. receive upgraded -> ok after 1000 -> error(timeout) end.
  189. %% Utility functions.
  190. connect_loop(_, 0, _) ->
  191. ok;
  192. connect_loop(Port, N, Sleep) ->
  193. {ok, _} = gen_tcp:connect("localhost", Port,
  194. [binary, {active, false}, {packet, raw}]),
  195. receive after Sleep -> ok end,
  196. connect_loop(Port, N - 1, Sleep).
  197. receive_loop(Message, Timeout) ->
  198. receive_loop(Message, Timeout, 0).
  199. receive_loop(Message, Timeout, N) ->
  200. receive Message ->
  201. receive_loop(Message, Timeout, N + 1)
  202. after Timeout ->
  203. N
  204. end.