emqx_node_rebalance_cli_SUITE.erl 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2022-2023 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%%--------------------------------------------------------------------
  4. -module(emqx_node_rebalance_cli_SUITE).
  5. -compile(export_all).
  6. -compile(nowarn_export_all).
  7. -include_lib("eunit/include/eunit.hrl").
  8. -include_lib("common_test/include/ct.hrl").
  9. -import(
  10. emqx_eviction_agent_test_helpers,
  11. [emqtt_connect_many/2, stop_many/1, case_specific_node_name/3]
  12. ).
  13. -define(START_APPS, [emqx_eviction_agent, emqx_node_rebalance]).
  14. all() ->
  15. emqx_common_test_helpers:all(?MODULE).
  16. init_per_suite(Config) ->
  17. emqx_common_test_helpers:start_apps(?START_APPS),
  18. Config.
  19. end_per_suite(Config) ->
  20. emqx_common_test_helpers:stop_apps(lists:reverse(?START_APPS)),
  21. Config.
  22. init_per_testcase(Case = t_rebalance, Config) ->
  23. _ = emqx_node_rebalance_evacuation:stop(),
  24. ClusterNodes = emqx_eviction_agent_test_helpers:start_cluster(
  25. [
  26. {case_specific_node_name(?MODULE, Case, '_donor'), 2883},
  27. {case_specific_node_name(?MODULE, Case, '_recipient'), 3883}
  28. ],
  29. ?START_APPS
  30. ),
  31. [{cluster_nodes, ClusterNodes} | Config];
  32. init_per_testcase(_Case, Config) ->
  33. _ = emqx_node_rebalance_evacuation:stop(),
  34. _ = emqx_node_rebalance:stop(),
  35. Config.
  36. end_per_testcase(t_rebalance, Config) ->
  37. _ = emqx_node_rebalance_evacuation:stop(),
  38. _ = emqx_node_rebalance:stop(),
  39. _ = emqx_eviction_agent_test_helpers:stop_cluster(
  40. ?config(cluster_nodes, Config),
  41. ?START_APPS
  42. );
  43. end_per_testcase(_Case, _Config) ->
  44. _ = emqx_node_rebalance_evacuation:stop(),
  45. _ = emqx_node_rebalance:stop().
  46. %%--------------------------------------------------------------------
  47. %% Tests
  48. %%--------------------------------------------------------------------
  49. t_evacuation(_Config) ->
  50. %% usage
  51. ok = emqx_node_rebalance_cli:cli(["foobar"]),
  52. %% status
  53. ok = emqx_node_rebalance_cli:cli(["status"]),
  54. ok = emqx_node_rebalance_cli:cli(["node-status"]),
  55. ok = emqx_node_rebalance_cli:cli(["node-status", atom_to_list(node())]),
  56. %% start with invalid args
  57. ?assertNot(
  58. emqx_node_rebalance_cli:cli(["start", "--evacuation", "--foo-bar"])
  59. ),
  60. ?assertNot(
  61. emqx_node_rebalance_cli:cli(["start", "--evacuation", "--conn-evict-rate", "foobar"])
  62. ),
  63. ?assertNot(
  64. emqx_node_rebalance_cli:cli(["start", "--evacuation", "--sess-evict-rate", "foobar"])
  65. ),
  66. ?assertNot(
  67. emqx_node_rebalance_cli:cli(["start", "--evacuation", "--wait-takeover", "foobar"])
  68. ),
  69. ?assertNot(
  70. emqx_node_rebalance_cli:cli([
  71. "start",
  72. "--evacuation",
  73. "--migrate-to",
  74. "nonexistent@node"
  75. ])
  76. ),
  77. ?assertNot(
  78. emqx_node_rebalance_cli:cli([
  79. "start",
  80. "--evacuation",
  81. "--migrate-to",
  82. ""
  83. ])
  84. ),
  85. ?assertNot(
  86. emqx_node_rebalance_cli:cli([
  87. "start",
  88. "--evacuation",
  89. "--unknown-arg"
  90. ])
  91. ),
  92. ?assert(
  93. emqx_node_rebalance_cli:cli([
  94. "start",
  95. "--evacuation",
  96. "--conn-evict-rate",
  97. "10",
  98. "--sess-evict-rate",
  99. "10",
  100. "--wait-takeover",
  101. "10",
  102. "--migrate-to",
  103. atom_to_list(node()),
  104. "--redirect-to",
  105. "srv"
  106. ])
  107. ),
  108. %% status
  109. ok = emqx_node_rebalance_cli:cli(["status"]),
  110. ok = emqx_node_rebalance_cli:cli(["node-status"]),
  111. ok = emqx_node_rebalance_cli:cli(["node-status", atom_to_list(node())]),
  112. ?assertMatch(
  113. {enabled, #{}},
  114. emqx_node_rebalance_evacuation:status()
  115. ),
  116. %% already enabled
  117. ?assertNot(
  118. emqx_node_rebalance_cli:cli([
  119. "start",
  120. "--evacuation",
  121. "--conn-evict-rate",
  122. "10",
  123. "--redirect-to",
  124. "srv"
  125. ])
  126. ),
  127. %% stop
  128. true = emqx_node_rebalance_cli:cli(["stop"]),
  129. false = emqx_node_rebalance_cli:cli(["stop"]),
  130. ?assertEqual(
  131. disabled,
  132. emqx_node_rebalance_evacuation:status()
  133. ).
  134. t_rebalance(Config) ->
  135. process_flag(trap_exit, true),
  136. [{DonorNode, DonorPort}, {RecipientNode, _}] = ?config(cluster_nodes, Config),
  137. %% start with invalid args
  138. ?assertNot(
  139. emqx_node_rebalance_cli(DonorNode, ["start", "--foo-bar"])
  140. ),
  141. ?assertNot(
  142. emqx_node_rebalance_cli(DonorNode, ["start", "--conn-evict-rate", "foobar"])
  143. ),
  144. ?assertNot(
  145. emqx_node_rebalance_cli(DonorNode, ["start", "--abs-conn-threshold", "foobar"])
  146. ),
  147. ?assertNot(
  148. emqx_node_rebalance_cli(DonorNode, ["start", "--rel-conn-threshold", "foobar"])
  149. ),
  150. ?assertNot(
  151. emqx_node_rebalance_cli(DonorNode, ["start", "--sess-evict-rate", "foobar"])
  152. ),
  153. ?assertNot(
  154. emqx_node_rebalance_cli(DonorNode, ["start", "--abs-sess-threshold", "foobar"])
  155. ),
  156. ?assertNot(
  157. emqx_node_rebalance_cli(DonorNode, ["start", "--rel-sess-threshold", "foobar"])
  158. ),
  159. ?assertNot(
  160. emqx_node_rebalance_cli(DonorNode, ["start", "--wait-takeover", "foobar"])
  161. ),
  162. ?assertNot(
  163. emqx_node_rebalance_cli(DonorNode, ["start", "--wait-health-check", "foobar"])
  164. ),
  165. ?assertNot(
  166. emqx_node_rebalance_cli(DonorNode, [
  167. "start",
  168. "--nodes",
  169. "nonexistent@node"
  170. ])
  171. ),
  172. ?assertNot(
  173. emqx_node_rebalance_cli(DonorNode, [
  174. "start",
  175. "--nodes",
  176. ""
  177. ])
  178. ),
  179. ?assertNot(
  180. emqx_node_rebalance_cli(DonorNode, [
  181. "start",
  182. "--nodes",
  183. atom_to_list(RecipientNode)
  184. ])
  185. ),
  186. ?assertNot(
  187. emqx_node_rebalance_cli(DonorNode, [
  188. "start",
  189. "--unknown-arg"
  190. ])
  191. ),
  192. Conns = emqtt_connect_many(DonorPort, 20),
  193. ?assert(
  194. emqx_node_rebalance_cli(DonorNode, [
  195. "start",
  196. "--conn-evict-rate",
  197. "10",
  198. "--abs-conn-threshold",
  199. "10",
  200. "--rel-conn-threshold",
  201. "1.1",
  202. "--sess-evict-rate",
  203. "10",
  204. "--abs-sess-threshold",
  205. "10",
  206. "--rel-sess-threshold",
  207. "1.1",
  208. "--wait-takeover",
  209. "10",
  210. "--nodes",
  211. atom_to_list(DonorNode) ++ "," ++
  212. atom_to_list(RecipientNode)
  213. ])
  214. ),
  215. %% status
  216. ok = emqx_node_rebalance_cli(DonorNode, ["status"]),
  217. ok = emqx_node_rebalance_cli(DonorNode, ["node-status"]),
  218. ok = emqx_node_rebalance_cli(DonorNode, ["node-status", atom_to_list(DonorNode)]),
  219. ?assertMatch(
  220. {enabled, #{}},
  221. rpc:call(DonorNode, emqx_node_rebalance, status, [])
  222. ),
  223. %% already enabled
  224. ?assertNot(
  225. emqx_node_rebalance_cli(DonorNode, ["start"])
  226. ),
  227. %% stop
  228. true = emqx_node_rebalance_cli(DonorNode, ["stop"]),
  229. false = emqx_node_rebalance_cli(DonorNode, ["stop"]),
  230. ?assertEqual(
  231. disabled,
  232. rpc:call(DonorNode, emqx_node_rebalance, status, [])
  233. ),
  234. ok = stop_many(Conns).
  235. %%--------------------------------------------------------------------
  236. %% Helpers
  237. %%--------------------------------------------------------------------
  238. emqx_node_rebalance_cli(Node, Args) ->
  239. case rpc:call(Node, emqx_node_rebalance_cli, cli, [Args]) of
  240. {badrpc, Reason} ->
  241. error(Reason);
  242. Result ->
  243. Result
  244. end.