From 3af624a6c3f8d6e1777db8e0f95ede92bfd94ee8 Mon Sep 17 00:00:00 2001 From: Feng Date: Sun, 24 Jan 2016 13:32:30 +0800 Subject: [PATCH] route tests --- test/emqttd_router_tests.erl | 103 +++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/test/emqttd_router_tests.erl b/test/emqttd_router_tests.erl index be0e0cf4c..161b84316 100644 --- a/test/emqttd_router_tests.erl +++ b/test/emqttd_router_tests.erl @@ -28,33 +28,104 @@ -include_lib("eunit/include/eunit.hrl"). --define(ROUTER, emqttd_router). +-define(R, emqttd_router). route_test_() -> - {setup, - fun() -> ?ROUTER:init([]) end, - fun(_) -> ?ROUTER:destory() end, - [?_test(t_add_routes()), + {foreach, + fun setup/0, fun teardown/1, + [?_test(t_add_route()), + ?_test(t_add_routes()), + ?_test(t_delete_route()), ?_test(t_delete_routes()), - ?_test(t_has_route()), ?_test(t_route()) ]}. +setup() -> + application:start(gproc), + ensure_tab(route, [public, named_table, duplicate_bag]), + gproc_pool:new(router, hash, [{size, 2}]), + lists:foreach(fun(I) -> + gproc_pool:add_worker(router, {router, I}, I), + {ok, R} = ?R:start_link(router, I, fun(_) -> ok end, []) + end, [1, 2]). + +ensure_tab(Tab, Opts) -> + case ets:info(Tab, name) of + undefined -> ets:new(Tab, Opts); + _ -> ok + end. + +teardown(_) -> + lists:foreach(fun(I) -> + ?R:stop(I), gproc_pool:remove_worker(router, {router, I}) + end, [1, 2]), + gproc_pool:delete(router), + ets:delete(route). + +t_add_route() -> + Self = self(), + ?R:add_route(<<"topic1">>, Self), + ?assert(?R:has_route(<<"topic1">>)), + ?R:add_route(<<"topic2">>, Self), + ?assert(?R:has_route(<<"topic2">>)), + ?assertEqual([Self], ?R:lookup_routes(<<"topic1">>)), + ?assertEqual([Self], ?R:lookup_routes(<<"topic2">>)). + t_add_routes() -> - Pid = self(), - ok. - %?ROUTER:add_routes([<<"a">>, <<"b">>], Pid), - %?assertEqual([{<<"a">>, Pid}, {<<"b">>, Pid}], lists:sort(ets:tab2list(route))), - %?assertEqual([{Pid, <<"a">>}, {Pid, <<"b">>}], lists:sort(ets:tab2list(reverse_route))). + Self = self(), + ?R:add_routes([], Self), + ?R:add_routes([<<"t0">>], Self), + ?R:add_routes([<<"t1">>,<<"t2">>,<<"t3">>], Self), + ?assert(?R:has_route(<<"t1">>)), + ?assertEqual([Self], ?R:lookup_routes(<<"t1">>)), + ?assertEqual([Self], ?R:lookup_routes(<<"t2">>)), + ?assertEqual([Self], ?R:lookup_routes(<<"t3">>)). + +t_delete_route() -> + Self = self(), + ?R:add_routes([<<"t1">>,<<"t2">>,<<"t3">>], Self), + ?assert(?R:has_route(<<"t1">>)), + ?R:delete_route(<<"t2">>, Self), + erlang:yield(), + ?debugFmt("Routes: ~p~n", [ets:tab2list(route)]), + ?assertNot(?R:has_route(<<"t2">>)), + ?assert(?R:has_route(<<"t1">>)), + ?R:delete_route(<<"t3">>, Self), + erlang:yield(), + ?assertNot(?R:has_route(<<"t3">>)). t_delete_routes() -> - ok. - -t_has_route() -> - ok. + Self = self(), + ?R:add_routes([<<"t1">>,<<"t2">>,<<"t3">>], Self), + ?R:delete_routes([<<"t3">>], Self), + erlang:yield(), %% for delete_routes is cast + ?assertNot(?R:has_route(<<"t3">>)), + ?R:delete_routes([<<"t1">>, <<"t2">>], Self), + erlang:yield(), + ?assertNot(?R:has_route(<<"t2">>)). t_route() -> - ok. + Self = self(), + Pid = spawn_link(fun() -> timer:sleep(1000) end), + ?R:add_routes([<<"$Q/1">>,<<"t/2">>,<<"t/3">>], Self), + ?R:add_routes([<<"t/2">>], Pid), + Msg1 = #mqtt_message{topic = <<"$Q/1">>, payload = <<"q">>}, + Msg2 = #mqtt_message{topic = <<"t/2">>, payload = <<"t2">>}, + Msg3 = #mqtt_message{topic = <<"t/3">>, payload = <<"t3">>}, + ?R:route(<<"$Q/1">>, Msg1), + ?R:route(<<"t/2">>, Msg2), + ?R:route(<<"t/3">>, Msg3), + ?assertEqual([Msg1, Msg2, Msg3], recv_loop([])), + ?R:add_route(<<"$Q/1">>, Pid), + ?R:route(<<"$Q/1">>, Msg1). + +recv_loop(Msgs) -> + receive + {dispatch, _Topic, Msg} -> + recv_loop([Msg|Msgs]) + after + 500 -> lists:reverse(Msgs) + end. -endif.