stampede_SUITE.erl 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. %% Copyright (c) 2019, 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(stampede_SUITE).
  15. -compile(export_all).
  16. -compile(nowarn_export_all).
  17. -import(ct_helper, [doc/1]).
  18. -import(ct_helper, [name/0]).
  19. %% ct.
  20. all() ->
  21. ct_helper:all(?MODULE).
  22. init_per_suite(Config) ->
  23. {ok, _} = application:ensure_all_started(ranch),
  24. ok = application:start(stampede),
  25. %% Enable logging of progress reports.
  26. %% They will only be available in the HTML reports by default.
  27. ok = logger:set_primary_config(level, none),
  28. ok = logger:set_module_level(?MODULE, info),
  29. ok = logger:set_application_level(stampede, error),
  30. Config.
  31. end_per_suite(_) ->
  32. ok = application:stop(stampede),
  33. ok = application:stop(ranch).
  34. %% Tests.
  35. stampede_tcp(_) ->
  36. doc("Start a TCP listener, establish a hundred connections, "
  37. "run stampede, confirm we can still connect."),
  38. %% Start a TCP listener.
  39. Name = name(),
  40. {ok, _} = ranch:start_listener(Name,
  41. ranch_tcp, #{},
  42. echo_protocol, []),
  43. %% Establish a hundred connections.
  44. ok = do_connect(100, ranch_tcp, ranch:get_port(Name), 1000),
  45. %% Set restart frequency of ranch_sup.
  46. do_set_sup_frequencies([ranch_sup], 999999, 1),
  47. %% Run stampede.
  48. {ok, _} = stampede:start_herd(ranch_stampede, {application, ranch},
  49. #{interval => {100, 100}, before_kill => fun do_log/1}),
  50. ok = stampede:activate(ranch_stampede),
  51. timer:sleep(10000),
  52. ok = stampede:stop_herd(ranch_stampede),
  53. timer:sleep(1000),
  54. %% Confirm we can still connect.
  55. ok = do_connect(1, ranch_tcp, ranch:get_port(Name), 1000),
  56. ok = ranch:stop_listener(Name).
  57. stampede_ssl(_) ->
  58. doc("Start a SSL listener, establish a hundred connections, "
  59. "run stampede, confirm we can still connect."),
  60. %% Start a TCP listener.
  61. Name = name(),
  62. {ok, _} = ranch:start_listener(Name,
  63. ranch_ssl, ct_helper:get_certs_from_ets(),
  64. echo_protocol, []),
  65. %% Establish a hundred connections.
  66. ok = do_connect(100, ranch_ssl, ranch:get_port(Name), 1000),
  67. %% Set restart frequencies of ranch_sup and ssl_sup.
  68. do_set_sup_frequencies([ranch_sup, ssl_sup], 999999, 1),
  69. %% Run stampede.
  70. {ok, _} = stampede:start_herd(ranch_stampede, {application, ranch},
  71. #{interval => {100, 100}, before_kill => fun do_log/1}),
  72. {ok, _} = stampede:start_herd(ssl_stampede, {application, ssl},
  73. #{interval => {100, 100}, before_kill => fun do_log/1}),
  74. ok = stampede:activate(ranch_stampede),
  75. ok = stampede:activate(ssl_stampede),
  76. timer:sleep(10000),
  77. ok = stampede:stop_herd(ssl_stampede),
  78. ok = stampede:stop_herd(ranch_stampede),
  79. timer:sleep(1000),
  80. %% Confirm we can still connect.
  81. ok = do_connect(1, ranch_ssl, ranch:get_port(Name), 1000),
  82. ok = ranch:stop_listener(Name).
  83. stampede_embedded(_) ->
  84. doc("Start an embedded TCP listener, establish a hundred connections, "
  85. "run stampede, confirm we can still connect."),
  86. %% Start embedded listener.
  87. Name = name(),
  88. {ok, SupPid} = embedded_sup:start_link(),
  89. {ok, _} = embedded_sup:start_listener(SupPid, Name,
  90. ranch_tcp, #{}, echo_protocol, []),
  91. %% Establish a hundred connections.
  92. ok = do_connect(100, ranch_tcp, ranch:get_port(Name), 1000),
  93. %% Set restart frequency of ranch_sup and embedded_sup.
  94. do_set_sup_frequencies([ranch_sup, SupPid], 999999, 1),
  95. %% Run stampede.
  96. {ok, _} = stampede:start_herd(ranch_stampede, {application, ranch},
  97. #{interval => {100, 100}, before_kill => fun do_log/1}),
  98. {ok, _} = stampede:start_herd(embedded_stampede, {supervisor, SupPid},
  99. #{interval => {100, 100}, before_kill => fun do_log/1}),
  100. ok = stampede:activate(ranch_stampede),
  101. ok = stampede:activate(embedded_stampede),
  102. timer:sleep(10000),
  103. ok = stampede:stop_herd(ranch_stampede),
  104. ok = stampede:stop_herd(embedded_stampede),
  105. timer:sleep(1000),
  106. %% Confirm we can still connect.
  107. ok = do_connect(1, ranch_tcp, ranch:get_port(Name), 1000),
  108. ok = embedded_sup:stop_listener(SupPid, Name),
  109. embedded_sup:stop(SupPid),
  110. ok.
  111. do_set_sup_frequencies(Sups, Intensity, Period) ->
  112. StateFun = fun (S) -> setelement(7, setelement(6, S, Intensity), Period) end,
  113. _ = [sys:replace_state(Sup, StateFun) || Sup <- Sups],
  114. ok.
  115. do_connect(0, _, _, _) ->
  116. ok;
  117. do_connect(N, Transport, Port, Timeout) ->
  118. {ok, _} = Transport:connect("localhost", Port, [{active, false}], Timeout),
  119. do_connect(N - 1, Transport, Port, Timeout).
  120. do_log(Pid) when is_pid(Pid) ->
  121. ct:log(info, "~p: ~p~n", [Pid, erlang:process_info(Pid)]),
  122. true;
  123. do_log(Port) when is_port(Port) ->
  124. ct:log(info, "~p: ~p~n", [Port, erlang:port_info(Port)]),
  125. true.