chore(gw): fix mqtt-sn test cases

This commit is contained in:
JianBo He 2021-07-12 15:42:45 +08:00
parent fc5baf8fd4
commit 980c7d91db
8 changed files with 108 additions and 79 deletions

View File

@ -5,6 +5,7 @@
## TODO: ## TODO:
emqx_gateway: { emqx_gateway: {
stomp.1: { stomp.1: {
frame: { frame: {
max_headers: 10 max_headers: 10

View File

@ -68,7 +68,7 @@ on_insta_create(_Insta = #{ id := InstaId,
true -> true ->
%% FIXME: %% FIXME:
Port = 1884, Port = 1884,
_ = emqx_sn_broadcast:start_link(SnGwId, Port) _ = emqx_sn_broadcast:start_link(SnGwId, Port), ok
end, end,
PredefTopics = maps:get(predefined, RawConf), PredefTopics = maps:get(predefined, RawConf),

View File

@ -201,8 +201,13 @@ handle_call({register, ClientId, TopicName}, _From,
end; end;
handle_call({unregister, ClientId}, _From, State = #state{tabname = Tab}) -> handle_call({unregister, ClientId}, _From, State = #state{tabname = Tab}) ->
Registry = mnesia:dirty_match_object({Tab, {ClientId, '_'}, '_'}), Registry = mnesia:dirty_match_object(
lists:foreach(fun(R) -> ekka_mnesia:dirty_delete_object(Tab, R) end, Registry), Tab,
{emqx_sn_registry, {ClientId, '_'}, '_'}
),
lists:foreach(fun(R) ->
ekka_mnesia:dirty_delete_object(Tab, R)
end, Registry),
{reply, ok, State}; {reply, ok, State};
handle_call(name, _From, State = #state{tabname = Tab}) -> handle_call(name, _From, State = #state{tabname = Tab}) ->

View File

@ -19,7 +19,7 @@
-compile(export_all). -compile(export_all).
-compile(nowarn_export_all). -compile(nowarn_export_all).
-include_lib("emqx_sn/include/emqx_sn.hrl"). -include_lib("emqx_gateway/src/mqttsn/include/emqx_sn.hrl").
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-import(emqx_sn_frame, [ parse/1 -import(emqx_sn_frame, [ parse/1

View File

@ -19,7 +19,7 @@
-compile(export_all). -compile(export_all).
-compile(nowarn_export_all). -compile(nowarn_export_all).
-include_lib("emqx_sn/include/emqx_sn.hrl"). -include_lib("emqx_gateway/src/mqttsn/include/emqx_sn.hrl").
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
@ -59,23 +59,41 @@ all() ->
init_per_suite(Config) -> init_per_suite(Config) ->
logger:set_module_level(emqx_sn_gateway, debug), logger:set_module_level(emqx_sn_gateway, debug),
emqx_ct_helpers:start_apps([emqx_sn], fun set_special_confs/1), emqx_ct_helpers:start_apps([emqx_gateway], fun set_special_confs/1),
Config. Config.
end_per_suite(_) -> end_per_suite(_) ->
emqx_ct_helpers:stop_apps([emqx_sn]). emqx_ct_helpers:stop_apps([emqx_gateway]).
set_special_confs(emqx) -> set_special_confs(emqx) ->
application:set_env(emqx, plugins_loaded_file, application:set_env(emqx, plugins_loaded_file,
emqx_ct_helpers:deps_path(emqx, "test/emqx_SUITE_data/loaded_plugins")); emqx_ct_helpers:deps_path(emqx, "test/emqx_SUITE_data/loaded_plugins"));
set_special_confs(emqx_sn) -> set_special_confs(emqx_gateway) ->
application:set_env(emqx_sn, enable_qos3, ?ENABLE_QOS3), emqx_config:put(
application:set_env(emqx_sn, enable_stats, true), [emqx_gateway],
application:set_env(emqx_sn, username, <<"user1">>), #{ mqttsn =>
application:set_env(emqx_sn, password, <<"pw123">>), #{'1' =>
application:set_env(emqx_sn, predefined, #{broadcast => true,
[{?PREDEF_TOPIC_ID1, ?PREDEF_TOPIC_NAME1}, clientinfo_override =>
{?PREDEF_TOPIC_ID2, ?PREDEF_TOPIC_NAME2}]); #{password => "pw123",
username => "user1"
},
enable_qos3 => true,
enable_stats => true,
gateway_id => 1,
idle_timeout => 30000,
listener =>
#{udp =>
#{'1' =>
#{acceptors => 8,active_n => 100,backlog => 1024,bind => 1884,
high_watermark => 1048576,max_conn_rate => 1000,
max_connections => 10240000,send_timeout => 15000,
send_timeout_close => true}}},
predefined =>
[#{id => ?PREDEF_TOPIC_ID1, topic => ?PREDEF_TOPIC_NAME1},
#{id => ?PREDEF_TOPIC_ID2, topic => ?PREDEF_TOPIC_NAME2}]}}
});
set_special_confs(_App) -> set_special_confs(_App) ->
ok. ok.
@ -87,7 +105,7 @@ set_special_confs(_App) ->
%% Connect %% Connect
t_connect(_) -> t_connect(_) ->
SockName = {'mqttsn:udp', {{0,0,0,0}, 1884}}, SockName = {'mqttsn#1:udp', 1884},
?assertEqual(true, lists:keymember(SockName, 1, esockd:listeners())), ?assertEqual(true, lists:keymember(SockName, 1, esockd:listeners())),
{ok, Socket} = gen_udp:open(0, [binary]), {ok, Socket} = gen_udp:open(0, [binary]),
@ -170,7 +188,6 @@ t_subscribe_case02(_) ->
ReturnCode = 0, ReturnCode = 0,
{ok, Socket} = gen_udp:open(0, [binary]), {ok, Socket} = gen_udp:open(0, [binary]),
ClientId = ?CLIENTID,
send_connect_msg(Socket, ?CLIENTID), send_connect_msg(Socket, ?CLIENTID),
?assertEqual(<<3, ?SN_CONNACK, 0>>, receive_response(Socket)), ?assertEqual(<<3, ?SN_CONNACK, 0>>, receive_response(Socket)),

View File

@ -23,8 +23,10 @@
-define(REGISTRY, emqx_sn_registry). -define(REGISTRY, emqx_sn_registry).
-define(MAX_PREDEF_ID, 2). -define(MAX_PREDEF_ID, 2).
-define(PREDEF_TOPICS, [{1, <<"/predefined/topic/name/hello">>}, -define(PREDEF_TOPICS, [#{id => 1, topic => <<"/predefined/topic/name/hello">>},
{2, <<"/predefined/topic/name/nice">>}]). #{id => 2, topic => <<"/predefined/topic/name/nice">>}]).
-define(INSTA_ID, 'mqttsn#1').
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Setups %% Setups
@ -34,88 +36,92 @@ all() ->
emqx_ct:all(?MODULE). emqx_ct:all(?MODULE).
init_per_suite(Config) -> init_per_suite(Config) ->
_ = application:set_env(emqx_sn, predefined, ?PREDEF_TOPICS), application:ensure_all_started(ekka),
ekka_mnesia:start(),
Config. Config.
end_per_suite(_Config) -> end_per_suite(_Config) ->
application:stop(ekka),
ok. ok.
init_per_testcase(_TestCase, Config) -> init_per_testcase(_TestCase, Config) ->
application:set_env(ekka, strict_mode, true), {ok, Pid} = ?REGISTRY:start_link(?INSTA_ID, ?PREDEF_TOPICS),
ekka_mnesia:start(), {Tab, Pid} = ?REGISTRY:lookup_name(Pid),
emqx_sn_registry:mnesia(boot), [{reg, {Tab, Pid}} | Config].
ekka_mnesia:clear_table(emqx_sn_registry),
PredefTopics = application:get_env(emqx_sn, predefined, []),
{ok, _Pid} = ?REGISTRY:start_link(PredefTopics),
Config.
end_per_testcase(_TestCase, Config) -> end_per_testcase(_TestCase, Config) ->
?REGISTRY:stop(), {Tab, _Pid} = proplists:get_value(reg, Config),
ekka_mnesia:clear_table(Tab),
Config. Config.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Test cases %% Test cases
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
t_register(_Config) -> t_register(Config) ->
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(<<"ClientId">>, <<"Topic1">>)), Reg = proplists:get_value(reg, Config),
?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:register_topic(<<"ClientId">>, <<"Topic2">>)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"Topic1">>)),
?assertEqual(<<"Topic1">>, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+1)), ?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"Topic2">>)),
?assertEqual(<<"Topic2">>, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+2)), ?assertEqual(<<"Topic1">>, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+1)),
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic1">>)), ?assertEqual(<<"Topic2">>, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+2)),
?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic2">>)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic1">>)),
emqx_sn_registry:unregister_topic(<<"ClientId">>), ?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic2">>)),
?assertEqual(undefined, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+1)), emqx_sn_registry:unregister_topic(Reg, <<"ClientId">>),
?assertEqual(undefined, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+2)), ?assertEqual(undefined, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+1)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic1">>)), ?assertEqual(undefined, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+2)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic2">>)). ?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic1">>)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic2">>)).
t_register_case2(_Config) -> t_register_case2(Config) ->
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(<<"ClientId">>, <<"Topic1">>)), Reg = proplists:get_value(reg, Config),
?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:register_topic(<<"ClientId">>, <<"Topic2">>)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"Topic1">>)),
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(<<"ClientId">>, <<"Topic1">>)), ?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"Topic2">>)),
?assertEqual(<<"Topic1">>, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+1)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"Topic1">>)),
?assertEqual(<<"Topic2">>, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+2)), ?assertEqual(<<"Topic1">>, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+1)),
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic1">>)), ?assertEqual(<<"Topic2">>, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+2)),
?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic2">>)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic1">>)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic3">>)), ?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic2">>)),
?REGISTRY:unregister_topic(<<"ClientId">>), ?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic3">>)),
?assertEqual(undefined, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+1)), ?REGISTRY:unregister_topic(Reg, <<"ClientId">>),
?assertEqual(undefined, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+2)), ?assertEqual(undefined, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+1)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic1">>)), ?assertEqual(undefined, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+2)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, <<"Topic2">>)). ?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic1">>)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, <<"Topic2">>)).
t_reach_maximum(_Config) -> t_reach_maximum(Config) ->
register_a_lot(?MAX_PREDEF_ID+1, 16#ffff), Reg = proplists:get_value(reg, Config),
?assertEqual({error, too_large}, ?REGISTRY:register_topic(<<"ClientId">>, <<"TopicABC">>)), register_a_lot(?MAX_PREDEF_ID+1, 16#ffff, Reg),
?assertEqual({error, too_large}, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"TopicABC">>)),
Topic1 = iolist_to_binary(io_lib:format("Topic~p", [?MAX_PREDEF_ID+1])), Topic1 = iolist_to_binary(io_lib:format("Topic~p", [?MAX_PREDEF_ID+1])),
Topic2 = iolist_to_binary(io_lib:format("Topic~p", [?MAX_PREDEF_ID+2])), Topic2 = iolist_to_binary(io_lib:format("Topic~p", [?MAX_PREDEF_ID+2])),
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:lookup_topic_id(<<"ClientId">>, Topic1)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, Topic1)),
?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:lookup_topic_id(<<"ClientId">>, Topic2)), ?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, Topic2)),
?REGISTRY:unregister_topic(<<"ClientId">>), ?REGISTRY:unregister_topic(Reg, <<"ClientId">>),
?assertEqual(undefined, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+1)), ?assertEqual(undefined, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+1)),
?assertEqual(undefined, ?REGISTRY:lookup_topic(<<"ClientId">>, ?MAX_PREDEF_ID+2)), ?assertEqual(undefined, ?REGISTRY:lookup_topic(Reg, <<"ClientId">>, ?MAX_PREDEF_ID+2)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, Topic1)), ?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, Topic1)),
?assertEqual(undefined, ?REGISTRY:lookup_topic_id(<<"ClientId">>, Topic2)). ?assertEqual(undefined, ?REGISTRY:lookup_topic_id(Reg, <<"ClientId">>, Topic2)).
t_register_case4(_Config) -> t_register_case4(Config) ->
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(<<"ClientId">>, <<"TopicA">>)), Reg = proplists:get_value(reg, Config),
?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:register_topic(<<"ClientId">>, <<"TopicB">>)), ?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"TopicA">>)),
?assertEqual(?MAX_PREDEF_ID+3, ?REGISTRY:register_topic(<<"ClientId">>, <<"TopicC">>)), ?assertEqual(?MAX_PREDEF_ID+2, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"TopicB">>)),
?REGISTRY:unregister_topic(<<"ClientId">>), ?assertEqual(?MAX_PREDEF_ID+3, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"TopicC">>)),
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(<<"ClientId">>, <<"TopicD">>)). ?REGISTRY:unregister_topic(Reg, <<"ClientId">>),
?assertEqual(?MAX_PREDEF_ID+1, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"TopicD">>)).
t_deny_wildcard_topic(_Config) -> t_deny_wildcard_topic(Config) ->
?assertEqual({error, wildcard_topic}, ?REGISTRY:register_topic(<<"ClientId">>, <<"/TopicA/#">>)), Reg = proplists:get_value(reg, Config),
?assertEqual({error, wildcard_topic}, ?REGISTRY:register_topic(<<"ClientId">>, <<"/+/TopicB">>)). ?assertEqual({error, wildcard_topic}, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"/TopicA/#">>)),
?assertEqual({error, wildcard_topic}, ?REGISTRY:register_topic(Reg, <<"ClientId">>, <<"/+/TopicB">>)).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Helper funcs %% Helper funcs
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
register_a_lot(Max, Max) -> register_a_lot(Max, Max, _Reg) ->
ok; ok;
register_a_lot(N, Max) when N < Max -> register_a_lot(N, Max, Reg) when N < Max ->
Topic = iolist_to_binary(["Topic", integer_to_list(N)]), Topic = iolist_to_binary(["Topic", integer_to_list(N)]),
?assertEqual(N, ?REGISTRY:register_topic(<<"ClientId">>, Topic)), ?assertEqual(N, ?REGISTRY:register_topic(Reg, <<"ClientId">>, Topic)),
register_a_lot(N+1, Max). register_a_lot(N+1, Max, Reg).

View File

@ -16,7 +16,7 @@
-module(emqx_sn_proper_types). -module(emqx_sn_proper_types).
-include_lib("emqx_sn/include/emqx_sn.hrl"). -include_lib("emqx_gateway/src/mqttsn/include/emqx_sn.hrl").
-include_lib("proper/include/proper.hrl"). -include_lib("proper/include/proper.hrl").
-compile({no_auto_import, [register/1]}). -compile({no_auto_import, [register/1]}).

View File

@ -16,7 +16,7 @@
-module(prop_emqx_sn_frame). -module(prop_emqx_sn_frame).
-include_lib("emqx_sn/include/emqx_sn.hrl"). -include_lib("src/mqttsn/include/emqx_sn.hrl").
-include_lib("proper/include/proper.hrl"). -include_lib("proper/include/proper.hrl").
-compile({no_auto_import, [register/1]}). -compile({no_auto_import, [register/1]}).