|
|
@@ -19,19 +19,62 @@
|
|
|
-compile(export_all).
|
|
|
-compile(nowarn_export_all).
|
|
|
|
|
|
+-include("emqx.hrl").
|
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
+-include_lib("common_test/include/ct.hrl").
|
|
|
+-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
|
|
|
|
|
-define(ROUTER_HELPER, emqx_router_helper).
|
|
|
+-define(ROUTE_TAB, emqx_route).
|
|
|
|
|
|
all() -> emqx_common_test_helpers:all(?MODULE).
|
|
|
|
|
|
init_per_suite(Config) ->
|
|
|
+ DistPid = case net_kernel:nodename() of
|
|
|
+ ignored ->
|
|
|
+ %% calling `net_kernel:start' without `epmd'
|
|
|
+ %% running will result in a failure.
|
|
|
+ start_epmd(),
|
|
|
+ {ok, Pid} = net_kernel:start(['test@127.0.0.1', longnames]),
|
|
|
+ Pid;
|
|
|
+ _ ->
|
|
|
+ undefined
|
|
|
+ end,
|
|
|
emqx_common_test_helpers:start_apps([]),
|
|
|
- Config.
|
|
|
+ [{dist_pid, DistPid} | Config].
|
|
|
|
|
|
-end_per_suite(_Config) ->
|
|
|
+end_per_suite(Config) ->
|
|
|
+ DistPid = ?config(dist_pid, Config),
|
|
|
+ case DistPid of
|
|
|
+ Pid when is_pid(Pid) ->
|
|
|
+ net_kernel:stop();
|
|
|
+ _ ->
|
|
|
+ ok
|
|
|
+ end,
|
|
|
emqx_common_test_helpers:stop_apps([]).
|
|
|
|
|
|
+init_per_testcase(TestCase, Config)
|
|
|
+ when TestCase =:= t_cleanup_membership_mnesia_down;
|
|
|
+ TestCase =:= t_cleanup_membership_node_down;
|
|
|
+ TestCase =:= t_cleanup_monitor_node_down ->
|
|
|
+ ok = snabbkaffe:start_trace(),
|
|
|
+ Slave = start_slave(some_node),
|
|
|
+ [{slave, Slave} | Config];
|
|
|
+init_per_testcase(_TestCase, Config) ->
|
|
|
+ Config.
|
|
|
+
|
|
|
+end_per_testcase(TestCase, Config)
|
|
|
+ when TestCase =:= t_cleanup_membership_mnesia_down;
|
|
|
+ TestCase =:= t_cleanup_membership_node_down;
|
|
|
+ TestCase =:= t_cleanup_monitor_node_down ->
|
|
|
+ Slave = ?config(slave, Config),
|
|
|
+ stop_slave(Slave),
|
|
|
+ mria:transaction(?ROUTE_SHARD, fun() -> mnesia:clear_table(?ROUTE_TAB) end),
|
|
|
+ snabbkaffe:stop(),
|
|
|
+ ok;
|
|
|
+end_per_testcase(_TestCase, _Config) ->
|
|
|
+ ok.
|
|
|
+
|
|
|
t_monitor(_) ->
|
|
|
ok = emqx_router_helper:monitor({undefined, node()}),
|
|
|
emqx_router_helper:monitor(undefined).
|
|
|
@@ -44,7 +87,74 @@ t_mnesia(_) ->
|
|
|
?ROUTER_HELPER ! {membership, {mnesia, down, node()}},
|
|
|
ct:sleep(200).
|
|
|
|
|
|
+t_cleanup_membership_mnesia_down(Config) ->
|
|
|
+ Slave = ?config(slave, Config),
|
|
|
+ emqx_router:add_route(<<"a/b/c">>, Slave),
|
|
|
+ emqx_router:add_route(<<"d/e/f">>, node()),
|
|
|
+ ?assertMatch([_, _], emqx_router:topics()),
|
|
|
+ ?wait_async_action(
|
|
|
+ ?ROUTER_HELPER ! {membership, {mnesia, down, Slave}},
|
|
|
+ #{?snk_kind := emqx_router_helper_cleanup_done, node := Slave},
|
|
|
+ 1_000),
|
|
|
+ ?assertEqual([<<"d/e/f">>], emqx_router:topics()).
|
|
|
+
|
|
|
+t_cleanup_membership_node_down(Config) ->
|
|
|
+ Slave = ?config(slave, Config),
|
|
|
+ emqx_router:add_route(<<"a/b/c">>, Slave),
|
|
|
+ emqx_router:add_route(<<"d/e/f">>, node()),
|
|
|
+ ?assertMatch([_, _], emqx_router:topics()),
|
|
|
+ ?wait_async_action(
|
|
|
+ ?ROUTER_HELPER ! {membership, {node, down, Slave}},
|
|
|
+ #{?snk_kind := emqx_router_helper_cleanup_done, node := Slave},
|
|
|
+ 1_000),
|
|
|
+ ?assertEqual([<<"d/e/f">>], emqx_router:topics()).
|
|
|
+
|
|
|
+t_cleanup_monitor_node_down(Config) ->
|
|
|
+ Slave = ?config(slave, Config),
|
|
|
+ emqx_router:add_route(<<"a/b/c">>, Slave),
|
|
|
+ emqx_router:add_route(<<"d/e/f">>, node()),
|
|
|
+ ?assertMatch([_, _], emqx_router:topics()),
|
|
|
+ ?wait_async_action(
|
|
|
+ stop_slave(Slave),
|
|
|
+ #{?snk_kind := emqx_router_helper_cleanup_done, node := Slave},
|
|
|
+ 1_000),
|
|
|
+ ?assertEqual([<<"d/e/f">>], emqx_router:topics()).
|
|
|
+
|
|
|
t_message(_) ->
|
|
|
?ROUTER_HELPER ! testing,
|
|
|
gen_server:cast(?ROUTER_HELPER, testing),
|
|
|
gen_server:call(?ROUTER_HELPER, testing).
|
|
|
+
|
|
|
+%%------------------------------------------------------------------------------
|
|
|
+%% Internal functions
|
|
|
+%%------------------------------------------------------------------------------
|
|
|
+
|
|
|
+start_epmd() ->
|
|
|
+ [] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"),
|
|
|
+ ok.
|
|
|
+
|
|
|
+epmd_path() ->
|
|
|
+ case os:find_executable("epmd") of
|
|
|
+ false ->
|
|
|
+ ct:pal(critical, "Could not find epmd.~n"),
|
|
|
+ exit(epmd_not_found);
|
|
|
+ GlobalEpmd ->
|
|
|
+ GlobalEpmd
|
|
|
+ end.
|
|
|
+
|
|
|
+start_slave(Name) ->
|
|
|
+ CommonBeamOpts = "+S 1:1 ", % We want VMs to only occupy a single core
|
|
|
+ {ok, Node} = slave:start_link(host(), Name, CommonBeamOpts ++ ebin_path()),
|
|
|
+ Node.
|
|
|
+
|
|
|
+stop_slave(Node) ->
|
|
|
+ slave:stop(Node).
|
|
|
+
|
|
|
+host() ->
|
|
|
+ [_, Host] = string:tokens(atom_to_list(node()), "@"), Host.
|
|
|
+
|
|
|
+ebin_path() ->
|
|
|
+ string:join(["-pa" | lists:filter(fun is_lib/1, code:get_path())], " ").
|
|
|
+
|
|
|
+is_lib(Path) ->
|
|
|
+ string:prefix(Path, code:lib_dir()) =:= nomatch.
|