more unit tests
This commit is contained in:
parent
0d21e5c911
commit
15ad12d58d
|
@ -22,79 +22,72 @@
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
reload_acl_test() ->
|
-define(AC, emqttd_access_control).
|
||||||
with_acl(
|
|
||||||
fun() ->
|
|
||||||
?assertEqual([ok], emqttd_access_control:reload_acl())
|
|
||||||
end).
|
|
||||||
|
|
||||||
register_mod_test() ->
|
acl_test_() ->
|
||||||
with_acl(
|
{foreach,
|
||||||
fun() ->
|
fun setup/0,
|
||||||
emqttd_access_control:register_mod(acl, emqttd_acl_test_mod, []),
|
fun teardown/1,
|
||||||
?assertMatch([{emqttd_acl_test_mod, _, 0}, {emqttd_acl_internal, _, 0}],
|
[?_test(t_reload_acl()),
|
||||||
emqttd_access_control:lookup_mods(acl)),
|
?_test(t_register_mod()),
|
||||||
emqttd_access_control:register_mod(auth, emqttd_auth_anonymous_test_mod,[]),
|
?_test(t_unregister_mod()),
|
||||||
emqttd_access_control:register_mod(auth, emqttd_auth_dashboard, [], 99),
|
?_test(t_check_acl())
|
||||||
|
]}.
|
||||||
|
|
||||||
|
setup() ->
|
||||||
|
AclOpts = [
|
||||||
|
{auth, [{anonymous, []}]},
|
||||||
|
{acl, [ %% ACL config
|
||||||
|
%% Internal ACL module
|
||||||
|
{internal, [{file, "./testdata/test_acl.config"}, {nomatch, allow}]}
|
||||||
|
]}
|
||||||
|
],
|
||||||
|
?AC:start_link(AclOpts).
|
||||||
|
|
||||||
|
teardown({ok, _Pid}) ->
|
||||||
|
?AC:stop().
|
||||||
|
|
||||||
|
t_reload_acl() ->
|
||||||
|
?assertEqual([ok], ?AC:reload_acl()).
|
||||||
|
|
||||||
|
t_register_mod() ->
|
||||||
|
?AC:register_mod(acl, emqttd_acl_test_mod, []),
|
||||||
|
?assertMatch([{emqttd_acl_test_mod, _, 0},
|
||||||
|
{emqttd_acl_internal, _, 0}],
|
||||||
|
?AC:lookup_mods(acl)),
|
||||||
|
?AC:register_mod(auth, emqttd_auth_anonymous_test_mod,[]),
|
||||||
|
?AC:register_mod(auth, emqttd_auth_dashboard, [], 99),
|
||||||
?assertMatch([{emqttd_auth_dashboard, _, 99},
|
?assertMatch([{emqttd_auth_dashboard, _, 99},
|
||||||
{emqttd_auth_anonymous_test_mod, _, 0},
|
{emqttd_auth_anonymous_test_mod, _, 0},
|
||||||
{emqttd_auth_anonymous, _, 0}],
|
{emqttd_auth_anonymous, _, 0}],
|
||||||
emqttd_access_control:lookup_mods(auth))
|
?AC:lookup_mods(auth)).
|
||||||
end).
|
|
||||||
|
|
||||||
unregister_mod_test() ->
|
t_unregister_mod() ->
|
||||||
with_acl(
|
?AC:register_mod(acl, emqttd_acl_test_mod, []),
|
||||||
fun() ->
|
|
||||||
emqttd_access_control:register_mod(acl, emqttd_acl_test_mod, []),
|
|
||||||
?assertMatch([{emqttd_acl_test_mod, _, 0}, {emqttd_acl_internal, _, 0}],
|
?assertMatch([{emqttd_acl_test_mod, _, 0}, {emqttd_acl_internal, _, 0}],
|
||||||
emqttd_access_control:lookup_mods(acl)),
|
?AC:lookup_mods(acl)),
|
||||||
emqttd_access_control:unregister_mod(acl, emqttd_acl_test_mod),
|
?AC:unregister_mod(acl, emqttd_acl_test_mod),
|
||||||
timer:sleep(5),
|
timer:sleep(5),
|
||||||
?assertMatch([{emqttd_acl_internal, _, 0}], emqttd_access_control:lookup_mods(acl)),
|
?assertMatch([{emqttd_acl_internal, _, 0}], ?AC:lookup_mods(acl)),
|
||||||
|
|
||||||
emqttd_access_control:register_mod(auth, emqttd_auth_anonymous_test_mod,[]),
|
?AC:register_mod(auth, emqttd_auth_anonymous_test_mod,[]),
|
||||||
?assertMatch([{emqttd_auth_anonymous_test_mod, _, 0}, {emqttd_auth_anonymous, _, 0}],
|
?assertMatch([{emqttd_auth_anonymous_test_mod, _, 0},
|
||||||
emqttd_access_control:lookup_mods(auth)),
|
{emqttd_auth_anonymous, _, 0}],
|
||||||
|
?AC:lookup_mods(auth)),
|
||||||
|
|
||||||
emqttd_access_control:unregister_mod(auth, emqttd_auth_anonymous_test_mod),
|
?AC:unregister_mod(auth, emqttd_auth_anonymous_test_mod),
|
||||||
timer:sleep(5),
|
timer:sleep(5),
|
||||||
?assertMatch([{emqttd_auth_anonymous, _, 0}], emqttd_access_control:lookup_mods(auth))
|
?assertMatch([{emqttd_auth_anonymous, _, 0}], ?AC:lookup_mods(auth)).
|
||||||
end).
|
|
||||||
|
|
||||||
check_acl_test() ->
|
t_check_acl() ->
|
||||||
with_acl(
|
|
||||||
fun() ->
|
|
||||||
User1 = #mqtt_client{client_id = <<"client1">>, username = <<"testuser">>},
|
User1 = #mqtt_client{client_id = <<"client1">>, username = <<"testuser">>},
|
||||||
User2 = #mqtt_client{client_id = <<"client2">>, username = <<"xyz">>},
|
User2 = #mqtt_client{client_id = <<"client2">>, username = <<"xyz">>},
|
||||||
?assertEqual(allow, emqttd_access_control:check_acl(User1, subscribe, <<"users/testuser/1">>)),
|
?assertEqual(allow, ?AC:check_acl(User1, subscribe, <<"users/testuser/1">>)),
|
||||||
?assertEqual(allow, emqttd_access_control:check_acl(User1, subscribe, <<"clients/client1">>)),
|
?assertEqual(allow, ?AC:check_acl(User1, subscribe, <<"clients/client1">>)),
|
||||||
?assertEqual(deny, emqttd_access_control:check_acl(User1, subscribe, <<"clients/client1/x/y">>)),
|
?assertEqual(deny, ?AC:check_acl(User1, subscribe, <<"clients/client1/x/y">>)),
|
||||||
?assertEqual(allow, emqttd_access_control:check_acl(User1, publish, <<"users/testuser/1">>)),
|
?assertEqual(allow, ?AC:check_acl(User1, publish, <<"users/testuser/1">>)),
|
||||||
?assertEqual(allow, emqttd_access_control:check_acl(User1, subscribe, <<"a/b/c">>)),
|
?assertEqual(allow, ?AC:check_acl(User1, subscribe, <<"a/b/c">>)),
|
||||||
?assertEqual(deny, emqttd_access_control:check_acl(User2, subscribe, <<"a/b/c">>))
|
?assertEqual(deny, ?AC:check_acl(User2, subscribe, <<"a/b/c">>)).
|
||||||
end).
|
|
||||||
|
|
||||||
with_acl(Fun) ->
|
|
||||||
process_flag(trap_exit, true),
|
|
||||||
AclOpts = [
|
|
||||||
{auth, [
|
|
||||||
%% Authentication with username, password
|
|
||||||
%{username, []},
|
|
||||||
%% Authentication with clientid
|
|
||||||
%{clientid, [{password, no}, {file, "etc/clients.config"}]},
|
|
||||||
%% Allow all
|
|
||||||
{anonymous, []}
|
|
||||||
]},
|
|
||||||
%% ACL config
|
|
||||||
{acl, [
|
|
||||||
%% Internal ACL module
|
|
||||||
{internal, [{file, "../test/test_acl.config"}, {nomatch, allow}]}
|
|
||||||
]}
|
|
||||||
],
|
|
||||||
%application:set_env(emqttd, access, AclOpts),
|
|
||||||
emqttd_access_control:start_link(AclOpts),
|
|
||||||
Fun(),
|
|
||||||
emqttd_access_control:stop().
|
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
|
|
||||||
-module(emqttd_access_rule_tests).
|
-module(emqttd_access_rule_tests).
|
||||||
|
|
||||||
-import(emqttd_access_rule, [compile/1, match/3]).
|
-ifdef(TEST).
|
||||||
|
|
||||||
-include("emqttd.hrl").
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
-ifdef(TEST).
|
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-import(emqttd_access_rule, [compile/1, match/3]).
|
||||||
|
|
||||||
compile_test() ->
|
compile_test() ->
|
||||||
|
|
||||||
?assertMatch({allow, {'and', [{ipaddr, {"127.0.0.1", _I, _I}},
|
?assertMatch({allow, {'and', [{ipaddr, {"127.0.0.1", _I, _I}},
|
||||||
|
|
|
@ -24,7 +24,10 @@ gen_test() ->
|
||||||
Guid1 = emqttd_guid:gen(),
|
Guid1 = emqttd_guid:gen(),
|
||||||
Guid2 = emqttd_guid:gen(),
|
Guid2 = emqttd_guid:gen(),
|
||||||
?assertMatch(<<_:128>>, Guid1),
|
?assertMatch(<<_:128>>, Guid1),
|
||||||
?assertEqual(true, Guid2 >= Guid1).
|
?assertEqual(true, Guid2 >= Guid1),
|
||||||
|
emqttd_guid:ts(r17),
|
||||||
|
{Ts, _, 0} = Tup = emqttd_guid:new(),
|
||||||
|
?assertEqual(Ts, emqttd_guid:timestamp(emqttd_guid:bin(Tup))).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2012-2016 Feng Lee <feng@emqtt.io>.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqttd_message_tests).
|
||||||
|
|
||||||
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
|
-include("emqttd_protocol.hrl").
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-define(M, emqttd_message).
|
||||||
|
|
||||||
|
make_test() ->
|
||||||
|
Msg = ?M:make(<<"clientid">>, <<"topic">>, <<"payload">>),
|
||||||
|
?assertEqual(0, Msg#mqtt_message.qos),
|
||||||
|
?assertEqual(undefined, Msg#mqtt_message.msgid),
|
||||||
|
Msg1 = ?M:make(<<"clientid">>, qos2, <<"topic">>, <<"payload">>),
|
||||||
|
?assert(is_binary(Msg1#mqtt_message.msgid)),
|
||||||
|
?assertEqual(2, Msg1#mqtt_message.qos).
|
||||||
|
|
||||||
|
from_packet_test() ->
|
||||||
|
Msg = ?M:from_packet(?PUBLISH_PACKET(1, <<"topic">>, 10, <<"payload">>)),
|
||||||
|
?assertEqual(1, Msg#mqtt_message.qos),
|
||||||
|
?assertEqual(10, Msg#mqtt_message.pktid),
|
||||||
|
?assertEqual(<<"topic">>, Msg#mqtt_message.topic),
|
||||||
|
|
||||||
|
WillMsg = ?M:from_packet(#mqtt_packet_connect{will_flag = true,
|
||||||
|
will_topic = <<"WillTopic">>,
|
||||||
|
will_msg = <<"WillMsg">>}),
|
||||||
|
?assertEqual(<<"WillTopic">>, WillMsg#mqtt_message.topic),
|
||||||
|
?assertEqual(<<"WillMsg">>, WillMsg#mqtt_message.payload),
|
||||||
|
|
||||||
|
Msg2 = ?M:from_packet(<<"username">>, <<"clientid">>,
|
||||||
|
?PUBLISH_PACKET(1, <<"topic">>, 20, <<"payload">>)),
|
||||||
|
?assertEqual(<<"clientid">>, Msg2#mqtt_message.from),
|
||||||
|
?assertEqual(<<"username">>, Msg2#mqtt_message.sender),
|
||||||
|
?debugFmt("~s", [?M:format(Msg2)]).
|
||||||
|
|
||||||
|
flag_test() ->
|
||||||
|
Pkt = ?PUBLISH_PACKET(1, <<"t">>, 2, <<"payload">>),
|
||||||
|
Msg2 = ?M:from_packet(<<"clientid">>, Pkt),
|
||||||
|
Msg3 = ?M:set_flag(retain, Msg2),
|
||||||
|
Msg4 = ?M:set_flag(dup, Msg3),
|
||||||
|
?assert(Msg4#mqtt_message.dup),
|
||||||
|
?assert(Msg4#mqtt_message.retain),
|
||||||
|
Msg5 = ?M:set_flag(Msg4),
|
||||||
|
Msg6 = ?M:unset_flag(dup, Msg5),
|
||||||
|
Msg7 = ?M:unset_flag(retain, Msg6),
|
||||||
|
?assertNot(Msg7#mqtt_message.dup),
|
||||||
|
?assertNot(Msg7#mqtt_message.retain),
|
||||||
|
?M:unset_flag(Msg7),
|
||||||
|
?M:to_packet(Msg7).
|
||||||
|
|
||||||
|
-endif.
|
|
@ -16,17 +16,19 @@
|
||||||
|
|
||||||
-module(emqttd_mod_subscription_tests).
|
-module(emqttd_mod_subscription_tests).
|
||||||
|
|
||||||
-include("emqttd.hrl").
|
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(M, emqttd_mod_subscription).
|
-define(M, emqttd_mod_subscription).
|
||||||
|
|
||||||
rep_test() ->
|
rep_test() ->
|
||||||
?assertEqual(<<"topic/clientId">>, ?M:rep(<<"$c">>, <<"clientId">>, <<"topic/$c">>)),
|
?assertEqual(<<"topic/clientId">>,
|
||||||
?assertEqual(<<"topic/username">>, ?M:rep(<<"$u">>, <<"username">>, <<"topic/$u">>)),
|
?M:rep(<<"$c">>, <<"clientId">>, <<"topic/$c">>)),
|
||||||
|
?assertEqual(<<"topic/username">>,
|
||||||
|
?M:rep(<<"$u">>, <<"username">>, <<"topic/$u">>)),
|
||||||
?assertEqual(<<"topic/username/clientId">>,
|
?assertEqual(<<"topic/username/clientId">>,
|
||||||
?M:rep(<<"$c">>, <<"clientId">>,
|
?M:rep(<<"$c">>, <<"clientId">>,
|
||||||
?M:rep(<<"$u">>, <<"username">>, <<"topic/$u/$c">>))).
|
?M:rep(<<"$u">>, <<"username">>, <<"topic/$u/$c">>))).
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
|
|
||||||
-module(emqttd_mqueue_tests).
|
-module(emqttd_mqueue_tests).
|
||||||
|
|
||||||
-include("emqttd.hrl").
|
|
||||||
|
|
||||||
-define(Q, emqttd_mqueue).
|
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-define(Q, emqttd_mqueue).
|
||||||
|
|
||||||
in_test() ->
|
in_test() ->
|
||||||
Opts = [{max_length, 5},
|
Opts = [{max_length, 5},
|
||||||
{queue_qos0, true}],
|
{queue_qos0, true}],
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2016 Feng Lee <feng@emqtt.io>.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqttd_node_tests).
|
||||||
|
|
||||||
|
-author("Feng Lee <feng@emqtt.io>").
|
||||||
|
|
||||||
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
is_aliving_test() ->
|
||||||
|
?debugFmt("Node: ~p~n", [node()]),
|
||||||
|
?assert(emqttd_node:is_aliving(node())),
|
||||||
|
?assertNot(emqttd_node:is_aliving('x@127.0.0.1')).
|
||||||
|
|
||||||
|
parse_name_test() ->
|
||||||
|
?assertEqual('a@127.0.0.1', emqttd_node:parse_name("a@127.0.0.1")),
|
||||||
|
?assertEqual('b@127.0.0.1', emqttd_node:parse_name("b")).
|
||||||
|
|
||||||
|
-endif.
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
merge_test() ->
|
merge_test() ->
|
||||||
Opts = emqttd_opts:merge(?SOCKOPTS, [raw,
|
Opts = emqttd_opts:merge(?SOCKOPTS, [raw,
|
||||||
|
binary,
|
||||||
{backlog, 1024},
|
{backlog, 1024},
|
||||||
{nodelay, false},
|
{nodelay, false},
|
||||||
{max_clients, 1024},
|
{max_clients, 1024},
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2012-2016 Feng Lee <feng@emqtt.io>.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqttd_packet_tests).
|
||||||
|
|
||||||
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include("emqttd_protocol.hrl").
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-define(P, emqttd_packet).
|
||||||
|
|
||||||
|
protocol_name_test() ->
|
||||||
|
?assertEqual(<<"MQIsdp">>, ?P:protocol_name(3)),
|
||||||
|
?assertEqual(<<"MQTT">>, ?P:protocol_name(4)).
|
||||||
|
|
||||||
|
type_name_test() ->
|
||||||
|
?assertEqual( 'CONNECT', ?P:type_name(?CONNECT) ),
|
||||||
|
?assertEqual( 'UNSUBSCRIBE', ?P:type_name(?UNSUBSCRIBE) ).
|
||||||
|
|
||||||
|
connack_name_test() ->
|
||||||
|
?assertEqual( 'CONNACK_ACCEPT', ?P:connack_name(?CONNACK_ACCEPT) ),
|
||||||
|
?assertEqual( 'CONNACK_PROTO_VER', ?P:connack_name(?CONNACK_PROTO_VER) ),
|
||||||
|
?assertEqual( 'CONNACK_INVALID_ID', ?P:connack_name(?CONNACK_INVALID_ID) ),
|
||||||
|
?assertEqual( 'CONNACK_SERVER', ?P:connack_name(?CONNACK_SERVER) ),
|
||||||
|
?assertEqual( 'CONNACK_CREDENTIALS', ?P:connack_name(?CONNACK_CREDENTIALS) ),
|
||||||
|
?assertEqual( 'CONNACK_AUTH', ?P:connack_name(?CONNACK_AUTH) ).
|
||||||
|
|
||||||
|
format_test() ->
|
||||||
|
?debugFmt("~s", [?P:format(?CONNECT_PACKET(#mqtt_packet_connect{}))]),
|
||||||
|
?debugFmt("~s", [?P:format(?CONNACK_PACKET(?CONNACK_SERVER))]),
|
||||||
|
?debugFmt("~s", [?P:format(?PUBLISH_PACKET(?QOS_1, 1))]),
|
||||||
|
?debugFmt("~s", [?P:format(?PUBLISH_PACKET(?QOS_2, <<"topic">>, 10, <<"payload">>))]),
|
||||||
|
?debugFmt("~s", [?P:format(?PUBACK_PACKET(?PUBACK, 98))]),
|
||||||
|
?debugFmt("~s", [?P:format(?PUBREL_PACKET(99))]),
|
||||||
|
?debugFmt("~s", [?P:format(?SUBSCRIBE_PACKET(15, [{<<"topic">>, ?QOS0}, {<<"topic1">>, ?QOS1}]))]),
|
||||||
|
?debugFmt("~s", [?P:format(?SUBACK_PACKET(40, [?QOS0, ?QOS1]))]),
|
||||||
|
?debugFmt("~s", [?P:format(?UNSUBSCRIBE_PACKET(89, [<<"t">>, <<"t2">>]))]),
|
||||||
|
?debugFmt("~s", [?P:format(?UNSUBACK_PACKET(90))]).
|
||||||
|
|
||||||
|
-endif.
|
||||||
|
|
|
@ -16,15 +16,14 @@
|
||||||
|
|
||||||
-module(emqttd_retainer_tests).
|
-module(emqttd_retainer_tests).
|
||||||
|
|
||||||
-include("emqttd.hrl").
|
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
retain_test() ->
|
retain_test() ->
|
||||||
mnesia:start(),
|
mnesia:start(),
|
||||||
emqttd_retainer:mnesia(boot),
|
emqttd_retainer:mnesia(boot).
|
||||||
mnesia:stop().
|
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
|
@ -16,31 +16,35 @@
|
||||||
|
|
||||||
-module(emqttd_router_tests).
|
-module(emqttd_router_tests).
|
||||||
|
|
||||||
-include("emqttd.hrl").
|
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-define(R, emqttd_router).
|
-define(R, emqttd_router).
|
||||||
|
|
||||||
route_test_() ->
|
route_test_() ->
|
||||||
{foreach,
|
{timeout, 60,
|
||||||
fun setup/0, fun teardown/1,
|
[{setup,
|
||||||
[?_test(t_add_route()),
|
fun setup/0,
|
||||||
?_test(t_add_routes()),
|
fun teardown/1,
|
||||||
?_test(t_delete_route()),
|
[?_test(t_add_del_route()),
|
||||||
?_test(t_delete_routes()),
|
?_test(t_add_del_routes()),
|
||||||
?_test(t_route())
|
?_test(t_route())
|
||||||
|
]}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
setup() ->
|
setup() ->
|
||||||
application:start(gproc),
|
application:start(gproc),
|
||||||
ensure_tab(route, [public, named_table, duplicate_bag]),
|
application:start(mnesia),
|
||||||
|
emqttd_pubsub:create_table(topic, ram_copies),
|
||||||
|
emqttd_trie:mnesia(boot),
|
||||||
|
emqttd_pubsub_sup:create_tab(route),
|
||||||
gproc_pool:new(router, hash, [{size, 2}]),
|
gproc_pool:new(router, hash, [{size, 2}]),
|
||||||
lists:foreach(fun(I) ->
|
lists:foreach(fun(I) ->
|
||||||
gproc_pool:add_worker(router, {router, I}, I),
|
gproc_pool:add_worker(router, {router, I}, I),
|
||||||
{ok, R} = ?R:start_link(router, I, fun(_) -> ok end, [])
|
{ok, R} = ?R:start_link(router, I, fun(_) -> ok end, [{route_aging, 2}])
|
||||||
end, [1, 2]).
|
end, [1, 2]).
|
||||||
|
|
||||||
ensure_tab(Tab, Opts) ->
|
ensure_tab(Tab, Opts) ->
|
||||||
|
@ -54,18 +58,29 @@ teardown(_) ->
|
||||||
?R:stop(I), gproc_pool:remove_worker(router, {router, I})
|
?R:stop(I), gproc_pool:remove_worker(router, {router, I})
|
||||||
end, [1, 2]),
|
end, [1, 2]),
|
||||||
gproc_pool:delete(router),
|
gproc_pool:delete(router),
|
||||||
ets:delete(route).
|
ets:delete(route),
|
||||||
|
application:stop(gproc).
|
||||||
|
|
||||||
t_add_route() ->
|
t_add_del_route() ->
|
||||||
Self = self(),
|
Self = self(),
|
||||||
?R:add_route(<<"topic1">>, Self),
|
?R:add_route(<<"topic1">>, Self),
|
||||||
?assert(?R:has_route(<<"topic1">>)),
|
?assert(?R:has_route(<<"topic1">>)),
|
||||||
?R:add_route(<<"topic2">>, Self),
|
?R:add_route(<<"topic2">>, Self),
|
||||||
?assert(?R:has_route(<<"topic2">>)),
|
?assert(?R:has_route(<<"topic2">>)),
|
||||||
?assertEqual([Self], ?R:lookup_routes(<<"topic1">>)),
|
?assertEqual([Self], ?R:lookup_routes(<<"topic1">>)),
|
||||||
?assertEqual([Self], ?R:lookup_routes(<<"topic2">>)).
|
?assertEqual([Self], ?R:lookup_routes(<<"topic2">>)),
|
||||||
|
%% Del topic1
|
||||||
|
?R:delete_route(<<"topic1">>, Self),
|
||||||
|
erlang:yield(),
|
||||||
|
timer:sleep(10),
|
||||||
|
?assertNot(?R:has_route(<<"topic1">>)),
|
||||||
|
%% Del topic2
|
||||||
|
?R:delete_route(<<"topic2">>, Self),
|
||||||
|
erlang:yield(),
|
||||||
|
timer:sleep(10),
|
||||||
|
?assertNot(?R:has_route(<<"topic2">>)).
|
||||||
|
|
||||||
t_add_routes() ->
|
t_add_del_routes() ->
|
||||||
Self = self(),
|
Self = self(),
|
||||||
?R:add_routes([], Self),
|
?R:add_routes([], Self),
|
||||||
?R:add_routes([<<"t0">>], Self),
|
?R:add_routes([<<"t0">>], Self),
|
||||||
|
@ -73,29 +88,16 @@ t_add_routes() ->
|
||||||
?assert(?R:has_route(<<"t1">>)),
|
?assert(?R:has_route(<<"t1">>)),
|
||||||
?assertEqual([Self], ?R:lookup_routes(<<"t1">>)),
|
?assertEqual([Self], ?R:lookup_routes(<<"t1">>)),
|
||||||
?assertEqual([Self], ?R:lookup_routes(<<"t2">>)),
|
?assertEqual([Self], ?R:lookup_routes(<<"t2">>)),
|
||||||
?assertEqual([Self], ?R:lookup_routes(<<"t3">>)).
|
?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(),
|
|
||||||
?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() ->
|
|
||||||
Self = self(),
|
|
||||||
?R:add_routes([<<"t1">>,<<"t2">>,<<"t3">>], Self),
|
|
||||||
?R:delete_routes([<<"t3">>], Self),
|
?R:delete_routes([<<"t3">>], Self),
|
||||||
erlang:yield(), %% for delete_routes is cast
|
?R:delete_routes([<<"t0">>, <<"t1">>], Self),
|
||||||
?assertNot(?R:has_route(<<"t3">>)),
|
|
||||||
?R:delete_routes([<<"t1">>, <<"t2">>], Self),
|
|
||||||
erlang:yield(),
|
erlang:yield(),
|
||||||
?assertNot(?R:has_route(<<"t2">>)).
|
timer:sleep(10),
|
||||||
|
?assertNot(?R:has_route(<<"t0">>)),
|
||||||
|
?assertNot(?R:has_route(<<"t1">>)),
|
||||||
|
?assert(?R:has_route(<<"t2">>)),
|
||||||
|
?assertNot(?R:has_route(<<"t3">>)).
|
||||||
|
|
||||||
t_route() ->
|
t_route() ->
|
||||||
Self = self(),
|
Self = self(),
|
||||||
|
|
|
@ -25,7 +25,15 @@
|
||||||
-import(emqttd_serializer, [serialize/1]).
|
-import(emqttd_serializer, [serialize/1]).
|
||||||
|
|
||||||
serialize_connect_test() ->
|
serialize_connect_test() ->
|
||||||
serialize(?CONNECT_PACKET(#mqtt_packet_connect{})).
|
serialize(?CONNECT_PACKET(#mqtt_packet_connect{})),
|
||||||
|
serialize(?CONNECT_PACKET(#mqtt_packet_connect{
|
||||||
|
client_id = <<"clientId">>,
|
||||||
|
will_qos = ?QOS1,
|
||||||
|
will_flag = true,
|
||||||
|
will_retain = true,
|
||||||
|
will_topic = <<"will">>,
|
||||||
|
will_msg = <<"haha">>,
|
||||||
|
clean_sess = true})).
|
||||||
|
|
||||||
serialize_connack_test() ->
|
serialize_connack_test() ->
|
||||||
ConnAck = #mqtt_packet{header = #mqtt_packet_header{type = ?CONNACK},
|
ConnAck = #mqtt_packet{header = #mqtt_packet_header{type = ?CONNACK},
|
||||||
|
@ -34,7 +42,8 @@ serialize_connack_test() ->
|
||||||
|
|
||||||
serialize_publish_test() ->
|
serialize_publish_test() ->
|
||||||
serialize(?PUBLISH_PACKET(?QOS_0, <<"Topic">>, undefined, <<"Payload">>)),
|
serialize(?PUBLISH_PACKET(?QOS_0, <<"Topic">>, undefined, <<"Payload">>)),
|
||||||
serialize(?PUBLISH_PACKET(?QOS_1, <<"Topic">>, 938, <<"Payload">>)).
|
serialize(?PUBLISH_PACKET(?QOS_1, <<"Topic">>, 938, <<"Payload">>)),
|
||||||
|
serialize(?PUBLISH_PACKET(?QOS_2, <<"Topic">>, 99, long_payload())).
|
||||||
|
|
||||||
serialize_puback_test() ->
|
serialize_puback_test() ->
|
||||||
serialize(?PUBACK_PACKET(?PUBACK, 10384)).
|
serialize(?PUBACK_PACKET(?PUBACK, 10384)).
|
||||||
|
@ -64,5 +73,8 @@ serialize_pingresp_test() ->
|
||||||
serialize_disconnect_test() ->
|
serialize_disconnect_test() ->
|
||||||
serialize(?PACKET(?DISCONNECT)).
|
serialize(?PACKET(?DISCONNECT)).
|
||||||
|
|
||||||
|
long_payload() ->
|
||||||
|
iolist_to_binary(["payload." || _I <- lists:seq(1, 100)]).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
|
@ -20,5 +20,12 @@
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
start_stop_test() ->
|
||||||
|
application:start(lager),
|
||||||
|
application:ensure_all_started(emqttd),
|
||||||
|
application:stop(emqttd),
|
||||||
|
application:stop(esockd),
|
||||||
|
application:stop(gproc).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
test_() ->
|
all_test() ->
|
||||||
emqttd_time:seed(),
|
emqttd_time:seed(),
|
||||||
emqttd_time:now_to_secs(),
|
emqttd_time:now_to_secs(),
|
||||||
emqttd_time:now_to_ms().
|
emqttd_time:now_to_ms().
|
||||||
|
|
|
@ -20,9 +20,10 @@
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
-import(emqttd_topic, [validate/1, wildcard/1, match/2, triples/1, words/1]).
|
-import(emqttd_topic, [validate/1, wildcard/1, match/2, triples/1, words/1,
|
||||||
|
join/1, feed_var/3, is_queue/1, systop/1]).
|
||||||
|
|
||||||
-define(N, 100000).
|
-define(N, 10000).
|
||||||
|
|
||||||
validate_test() ->
|
validate_test() ->
|
||||||
?assert( validate({filter, <<"sport/tennis/#">>}) ),
|
?assert( validate({filter, <<"sport/tennis/#">>}) ),
|
||||||
|
@ -30,6 +31,8 @@ validate_test() ->
|
||||||
?assert( validate({filter, <<"/a/b">>}) ),
|
?assert( validate({filter, <<"/a/b">>}) ),
|
||||||
?assert( validate({filter, <<"/+/x">>}) ),
|
?assert( validate({filter, <<"/+/x">>}) ),
|
||||||
?assert( validate({filter, <<"/a/b/c/#">>}) ),
|
?assert( validate({filter, <<"/a/b/c/#">>}) ),
|
||||||
|
?assert( validate({filter, <<"x">>}) ),
|
||||||
|
?assertNot( validate({name, <<>>}) ),
|
||||||
?assertNot( validate({filter, <<"a/#/c">>}) ),
|
?assertNot( validate({filter, <<"a/#/c">>}) ),
|
||||||
?assertNot( validate({filter, <<"sport/tennis#">>}) ),
|
?assertNot( validate({filter, <<"sport/tennis#">>}) ),
|
||||||
?assertNot( validate({filter, <<"sport/tennis/#/ranking">>}) ).
|
?assertNot( validate({filter, <<"sport/tennis/#/ranking">>}) ).
|
||||||
|
@ -51,7 +54,16 @@ match_test() ->
|
||||||
%% paho test
|
%% paho test
|
||||||
?assert( match(<<"Topic/C">>, <<"+/+">>) ),
|
?assert( match(<<"Topic/C">>, <<"+/+">>) ),
|
||||||
?assert( match(<<"TopicA/B">>, <<"+/+">>) ),
|
?assert( match(<<"TopicA/B">>, <<"+/+">>) ),
|
||||||
?assert( match(<<"TopicA/C">>, <<"+/+">>) ).
|
?assert( match(<<"TopicA/C">>, <<"+/+">>) ),
|
||||||
|
|
||||||
|
?assert( match(<<"abc">>, <<"+">>) ),
|
||||||
|
?assert( match(<<"a/b/c">>, <<"a/b/c">>) ),
|
||||||
|
?assertNot( match(<<"a/b/c">>, <<"a/c/d">>) ),
|
||||||
|
?assertNot( match(<<"$shared/x/y">>, <<"+">>) ),
|
||||||
|
?assertNot( match(<<"$shared/x/y">>, <<"+/x/y">>) ),
|
||||||
|
?assertNot( match(<<"$shared/x/y">>, <<"#">>) ),
|
||||||
|
?assertNot( match(<<"$shared/x/y">>, <<"+/+/#">>) ),
|
||||||
|
?assertNot( match(<<"house/1/sensor/0">>, <<"house/+">>) ).
|
||||||
|
|
||||||
sigle_level_match_test() ->
|
sigle_level_match_test() ->
|
||||||
?assert( match(<<"sport/tennis/player1">>, <<"sport/tennis/+">>) ),
|
?assert( match(<<"sport/tennis/player1">>, <<"sport/tennis/+">>) ),
|
||||||
|
@ -103,6 +115,7 @@ type_test() ->
|
||||||
?assertEqual(true, wildcard(<<"/a/b/#">>)).
|
?assertEqual(true, wildcard(<<"/a/b/#">>)).
|
||||||
|
|
||||||
words_test() ->
|
words_test() ->
|
||||||
|
?assertEqual(['', <<"a">>, '+', '#'], words(<<"/a/+/#">>) ),
|
||||||
?assertMatch(['', <<"abkc">>, <<"19383">>, '+', <<"akakdkkdkak">>, '#'], words(<<"/abkc/19383/+/akakdkkdkak/#">>)),
|
?assertMatch(['', <<"abkc">>, <<"19383">>, '+', <<"akakdkkdkak">>, '#'], words(<<"/abkc/19383/+/akakdkkdkak/#">>)),
|
||||||
{Time, _} = timer:tc(fun() ->
|
{Time, _} = timer:tc(fun() ->
|
||||||
[words(<<"/abkc/19383/+/akakdkkdkak/#">>) || _I <- lists:seq(1, ?N)]
|
[words(<<"/abkc/19383/+/akakdkkdkak/#">>) || _I <- lists:seq(1, ?N)]
|
||||||
|
@ -114,11 +127,32 @@ words_test() ->
|
||||||
?debugFmt("Time for binary:split: ~p(micro)", [Time2/?N]),
|
?debugFmt("Time for binary:split: ~p(micro)", [Time2/?N]),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
is_queue_test() ->
|
||||||
|
?assert( is_queue(<<"$Q/queue">>) ),
|
||||||
|
?assert( is_queue(<<"$q/queue">>) ),
|
||||||
|
?assertNot( is_queue(<<"xyz/queue">>) ).
|
||||||
|
|
||||||
|
systop_test() ->
|
||||||
|
?assertEqual( iolist_to_binary(["$SYS/brokers/", atom_to_list(node()), "/xyz"]), systop('xyz') ),
|
||||||
|
?assertEqual( iolist_to_binary(["$SYS/brokers/", atom_to_list(node()), "/abc"]), systop(<<"abc">>) ).
|
||||||
|
|
||||||
feed_var_test() ->
|
feed_var_test() ->
|
||||||
?assertEqual(<<"$Q/client/clientId">>, emqttd_topic:feed_var(<<"$c">>, <<"clientId">>, <<"$Q/client/$c">>)).
|
?assertEqual(<<"$Q/client/clientId">>, feed_var(<<"$c">>, <<"clientId">>, <<"$Q/client/$c">>)),
|
||||||
|
?assertEqual(<<"username/test/client/x">>,
|
||||||
|
feed_var(<<"%u">>, <<"test">>, <<"username/%u/client/x">>)),
|
||||||
|
?assertEqual(<<"username/test/client/clientId">>,
|
||||||
|
feed_var(<<"%c">>, <<"clientId">>, <<"username/test/client/%c">>)).
|
||||||
|
|
||||||
join_test() ->
|
join_test() ->
|
||||||
?assertEqual(<<"/ab/cd/ef/">>, emqttd_topic:join(words(<<"/ab/cd/ef/">>))),
|
?assertEqual(<<"/ab/cd/ef/">>, join(words(<<"/ab/cd/ef/">>))),
|
||||||
?assertEqual(<<"ab/+/#">>, emqttd_topic:join(words(<<"ab/+/#">>))).
|
?assertEqual(<<"ab/+/#">>, join(words(<<"ab/+/#">>))),
|
||||||
|
?assertEqual( <<"x/y/z/+">>, join([<<"x">>, <<"y">>, <<"z">>, '+']) ),
|
||||||
|
?assertEqual( <<>>, join([]) ),
|
||||||
|
?assertEqual( <<"x">>, join([<<"x">>]) ),
|
||||||
|
?assertEqual( <<"#">>, join(['#']) ),
|
||||||
|
?assertEqual( <<"+//#">>, join(['+', '', '#']) ).
|
||||||
|
|
||||||
|
long_topic() ->
|
||||||
|
iolist_to_binary([[integer_to_list(I), "/"] || I <- lists:seq(0, 10000)]).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
{allow, {ipaddr, "127.0.0.1"}, subscribe, ["$SYS/#", "#"]}.
|
|
||||||
|
|
||||||
{allow, {user, "testuser"}, subscribe, ["a/b/c", "d/e/f/#"]}.
|
|
||||||
|
|
||||||
{allow, {user, "admin"}, pubsub, ["a/b/c", "d/e/f/#"]}.
|
|
||||||
|
|
||||||
{allow, {client, "testClient"}, subscribe, ["testTopics/testClient"]}.
|
|
||||||
|
|
||||||
{allow, all, subscribe, ["clients/$c"]}.
|
|
||||||
|
|
||||||
{allow, all, pubsub, ["users/$u/#"]}.
|
|
||||||
|
|
||||||
{deny, all, subscribe, ["$SYS/#", "#"]}.
|
|
||||||
|
|
||||||
{deny, all}.
|
|
||||||
|
|
Loading…
Reference in New Issue