From 7895432b7df688763da816eab7ab55aebd67b388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=A5=87=E6=80=AA?= Date: Sat, 7 Dec 2019 13:38:56 +0800 Subject: [PATCH] Add more test cases (#3080) --- test/emqx_mod_presence_SUITE.erl | 58 +++++++++-- test/emqx_mod_rewrite_SUITE.erl | 67 ++++++++++--- test/emqx_modules_SUITE.erl | 160 ------------------------------- 3 files changed, 101 insertions(+), 184 deletions(-) delete mode 100644 test/emqx_modules_SUITE.erl diff --git a/test/emqx_mod_presence_SUITE.erl b/test/emqx_mod_presence_SUITE.erl index abc145a2d..f571f494e 100644 --- a/test/emqx_mod_presence_SUITE.erl +++ b/test/emqx_mod_presence_SUITE.erl @@ -19,6 +19,7 @@ -compile(export_all). -compile(nowarn_export_all). +-include("emqx_mqtt.hrl"). -include_lib("eunit/include/eunit.hrl"). all() -> emqx_ct:all(?MODULE). @@ -29,16 +30,55 @@ init_per_testcase(_TestCase, Config) -> end_per_testcase(_TestCase, Config) -> Config. -% t_load(_) -> -% error('TODO'). +%% Test case for emqx_mod_presence +t_mod_presence(_) -> + ok = emqx_mod_presence:load([{qos, ?QOS_1}]), + {ok, C1} = emqtt:start_link([{clientid, <<"monsys">>}]), + {ok, _} = emqtt:connect(C1), + {ok, _Props, [?QOS_1]} = emqtt:subscribe(C1, <<"$SYS/brokers/+/clients/#">>, qos1), + %% Connected Presence + {ok, C2} = emqtt:start_link([{clientid, <<"clientid">>}, + {username, <<"username">>}]), + {ok, _} = emqtt:connect(C2), + ok = recv_and_check_presence(<<"clientid">>, <<"connected">>), + %% Disconnected Presence + ok = emqtt:disconnect(C2), + ok = recv_and_check_presence(<<"clientid">>, <<"disconnected">>), + ok = emqtt:disconnect(C1), + ok = emqx_mod_presence:unload([{qos, ?QOS_1}]). -% t_unload(_) -> -% error('TODO'). +t_mod_presence_reason(_) -> + ?assertEqual(normal, emqx_mod_presence:reason(normal)), + ?assertEqual(discarded, emqx_mod_presence:reason({shutdown, discarded})), + ?assertEqual(tcp_error, emqx_mod_presence:reason({tcp_error, einval})), + ?assertEqual(internal_error, emqx_mod_presence:reason(<<"unknown error">>)). -% t_on_client_connected(_) -> -% error('TODO'). - -% t_on_client_disconnected(_) -> -% error('TODO'). +recv_and_check_presence(ClientId, Presence) -> + {ok, #{qos := ?QOS_1, topic := Topic, payload := Payload}} = receive_publish(100), + ?assertMatch([<<"$SYS">>, <<"brokers">>, _Node, <<"clients">>, ClientId, Presence], + binary:split(Topic, <<"/">>, [global])), + case Presence of + <<"connected">> -> + ?assertMatch(#{clientid := <<"clientid">>, + username := <<"username">>, + ipaddress := <<"127.0.0.1">>, + proto_name := <<"MQTT">>, + proto_ver := ?MQTT_PROTO_V4, + connack := ?RC_SUCCESS, + clean_start := true}, emqx_json:decode(Payload, [{labels, atom}, return_maps])); + <<"disconnected">> -> + ?assertMatch(#{clientid := <<"clientid">>, + username := <<"username">>, + reason := <<"normal">>}, emqx_json:decode(Payload, [{labels, atom}, return_maps])) + end. +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- +receive_publish(Timeout) -> + receive + {publish, Publish} -> {ok, Publish} + after + Timeout -> {error, timeout} + end. diff --git a/test/emqx_mod_rewrite_SUITE.erl b/test/emqx_mod_rewrite_SUITE.erl index 7ed1cad60..ff471a39e 100644 --- a/test/emqx_mod_rewrite_SUITE.erl +++ b/test/emqx_mod_rewrite_SUITE.erl @@ -19,28 +19,65 @@ -compile(export_all). -compile(nowarn_export_all). +-include("emqx_mqtt.hrl"). -include_lib("eunit/include/eunit.hrl"). +-define(RULES, [{rewrite,<<"x/#">>,<<"^x/y/(.+)$">>,<<"z/y/$1">>}, + {rewrite,<<"y/+/z/#">>,<<"^y/(.+)/z/(.+)$">>,<<"y/z/$2">>} + ]). + all() -> emqx_ct:all(?MODULE). -init_per_testcase(_TestCase, Config) -> +init_per_suite(Config) -> + emqx_ct_helpers:boot_modules(all), + emqx_ct_helpers:start_apps([emqx]), + %% Ensure all the modules unloaded. + ok = emqx_modules:unload(), Config. -end_per_testcase(_TestCase, Config) -> - Config. +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([emqx]). -% t_load(_) -> -% error('TODO'). +%% Test case for emqx_mod_write +t_mod_rewrite(_Config) -> + ok = emqx_mod_rewrite:load(?RULES), + {ok, C} = emqtt:start_link([{clientid, <<"rewrite_client">>}]), + {ok, _} = emqtt:connect(C), + OrigTopics = [<<"x/y/2">>, <<"x/1/2">>, <<"y/a/z/b">>, <<"y/def">>], + DestTopics = [<<"z/y/2">>, <<"x/1/2">>, <<"y/z/b">>, <<"y/def">>], + %% Subscribe + {ok, _Props, _} = emqtt:subscribe(C, [{Topic, ?QOS_1} || Topic <- OrigTopics]), + timer:sleep(100), + Subscriptions = emqx_broker:subscriptions(<<"rewrite_client">>), + ?assertEqual(DestTopics, [Topic || {Topic, _SubOpts} <- Subscriptions]), + %% Publish + RecvTopics = [begin + ok = emqtt:publish(C, Topic, <<"payload">>), + {ok, #{topic := RecvTopic}} = receive_publish(100), + RecvTopic + end || Topic <- OrigTopics], + ?assertEqual(DestTopics, RecvTopics), + %% Unsubscribe + {ok, _, _} = emqtt:unsubscribe(C, OrigTopics), + timer:sleep(100), + ?assertEqual([], emqx_broker:subscriptions(<<"rewrite_client">>)), + ok = emqtt:disconnect(C), + ok = emqx_mod_rewrite:unload(?RULES). -% t_rewrite_subscribe(_) -> -% error('TODO'). +t_rewrite_rule(_Config) -> + Rules = emqx_mod_rewrite:compile(?RULES), + ?assertEqual(<<"z/y/2">>, emqx_mod_rewrite:match_and_rewrite(<<"x/y/2">>, Rules)), + ?assertEqual(<<"x/1/2">>, emqx_mod_rewrite:match_and_rewrite(<<"x/1/2">>, Rules)), + ?assertEqual(<<"y/z/b">>, emqx_mod_rewrite:match_and_rewrite(<<"y/a/z/b">>, Rules)), + ?assertEqual(<<"y/def">>, emqx_mod_rewrite:match_and_rewrite(<<"y/def">>, Rules)). -% t_rewrite_unsubscribe(_) -> -% error('TODO'). - -% t_rewrite_publish(_) -> -% error('TODO'). - -% t_unload(_) -> -% error('TODO'). +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- +receive_publish(Timeout) -> + receive + {publish, Publish} -> {ok, Publish} + after + Timeout -> {error, timeout} + end. diff --git a/test/emqx_modules_SUITE.erl b/test/emqx_modules_SUITE.erl deleted file mode 100644 index f4d18ddd7..000000000 --- a/test/emqx_modules_SUITE.erl +++ /dev/null @@ -1,160 +0,0 @@ -%%-------------------------------------------------------------------- -%% Copyright (c) 2019 EMQ Technologies Co., Ltd. All Rights Reserved. -%% -%% 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(emqx_modules_SUITE). - -%% API --compile(export_all). --compile(nowarn_export_all). - --include("emqx.hrl"). --include("emqx_mqtt.hrl"). - -%%-include_lib("proper/include/proper.hrl"). --include_lib("common_test/include/ct.hrl"). --include_lib("eunit/include/eunit.hrl"). - -%%-define(PROPTEST(M,F), true = proper:quickcheck(M:F())). - --define(RULES, [{rewrite,<<"x/#">>,<<"^x/y/(.+)$">>,<<"z/y/$1">>}, - {rewrite,<<"y/+/z/#">>,<<"^y/(.+)/z/(.+)$">>,<<"y/z/$2">>} - ]). - -all() -> emqx_ct:all(?MODULE). - -suite() -> - [{ct_hooks,[cth_surefire]}, {timetrap, {seconds, 30}}]. - -init_per_suite(Config) -> - emqx_ct_helpers:boot_modules(all), - emqx_ct_helpers:start_apps([emqx]), - %% Ensure all the modules unloaded. - ok = emqx_modules:unload(), - Config. - -end_per_suite(_Config) -> - emqx_ct_helpers:stop_apps([emqx]). - -%%-------------------------------------------------------------------- -%% Test cases -%%-------------------------------------------------------------------- - -% t_unload(_) -> -% error('TODO'). - -% t_load(_) -> -% error('TODO'). - -%% Test case for emqx_mod_presence -t_mod_presence(_) -> - ok = emqx_mod_presence:load([{qos, ?QOS_1}]), - {ok, C1} = emqtt:start_link([{clientid, <<"monsys">>}]), - {ok, _} = emqtt:connect(C1), - {ok, _Props, [?QOS_1]} = emqtt:subscribe(C1, <<"$SYS/brokers/+/clients/#">>, qos1), - %% Connected Presence - {ok, C2} = emqtt:start_link([{clientid, <<"clientid">>}, - {username, <<"username">>}]), - {ok, _} = emqtt:connect(C2), - ok = recv_and_check_presence(<<"clientid">>, <<"connected">>), - %% Disconnected Presence - ok = emqtt:disconnect(C2), - ok = recv_and_check_presence(<<"clientid">>, <<"disconnected">>), - ok = emqtt:disconnect(C1), - ok = emqx_mod_presence:unload([{qos, ?QOS_1}]). - -t_mod_presence_reason(_) -> - ?assertEqual(normal, emqx_mod_presence:reason(normal)), - ?assertEqual(discarded, emqx_mod_presence:reason({shutdown, discarded})), - ?assertEqual(tcp_error, emqx_mod_presence:reason({tcp_error, einval})), - ?assertEqual(internal_error, emqx_mod_presence:reason(<<"unknown error">>)). - -recv_and_check_presence(ClientId, Presence) -> - {ok, #{qos := ?QOS_1, topic := Topic, payload := Payload}} = receive_publish(100), - ?assertMatch([<<"$SYS">>, <<"brokers">>, _Node, <<"clients">>, ClientId, Presence], - binary:split(Topic, <<"/">>, [global])), - case Presence of - <<"connected">> -> - ?assertMatch(#{clientid := <<"clientid">>, - username := <<"username">>, - ipaddress := <<"127.0.0.1">>, - proto_name := <<"MQTT">>, - proto_ver := ?MQTT_PROTO_V4, - connack := ?RC_SUCCESS, - clean_start := true}, emqx_json:decode(Payload, [{labels, atom}, return_maps])); - <<"disconnected">> -> - ?assertMatch(#{clientid := <<"clientid">>, - username := <<"username">>, - reason := <<"normal">>}, emqx_json:decode(Payload, [{labels, atom}, return_maps])) - end. - -%% Test case for emqx_mod_subscription -t_mod_subscription(_) -> - emqx_mod_subscription:load([{<<"connected/%c/%u">>, ?QOS_0}]), - {ok, C} = emqtt:start_link([{host, "localhost"}, - {clientid, "myclient"}, - {username, "admin"}]), - {ok, _} = emqtt:connect(C), - emqtt:publish(C, <<"connected/myclient/admin">>, <<"Hello world">>, ?QOS_0), - {ok, #{topic := Topic, payload := Payload}} = receive_publish(100), - ?assertEqual(<<"connected/myclient/admin">>, Topic), - ?assertEqual(<<"Hello world">>, Payload), - ok = emqtt:disconnect(C), - emqx_mod_subscription:unload([]). - -%% Test case for emqx_mod_write -t_mod_rewrite(_Config) -> - ok = emqx_mod_rewrite:load(?RULES), - {ok, C} = emqtt:start_link([{clientid, <<"rewrite_client">>}]), - {ok, _} = emqtt:connect(C), - OrigTopics = [<<"x/y/2">>, <<"x/1/2">>, <<"y/a/z/b">>, <<"y/def">>], - DestTopics = [<<"z/y/2">>, <<"x/1/2">>, <<"y/z/b">>, <<"y/def">>], - %% Subscribe - {ok, _Props, _} = emqtt:subscribe(C, [{Topic, ?QOS_1} || Topic <- OrigTopics]), - timer:sleep(100), - Subscriptions = emqx_broker:subscriptions(<<"rewrite_client">>), - ?assertEqual(DestTopics, [Topic || {Topic, _SubOpts} <- Subscriptions]), - %% Publish - RecvTopics = [begin - ok = emqtt:publish(C, Topic, <<"payload">>), - {ok, #{topic := RecvTopic}} = receive_publish(100), - RecvTopic - end || Topic <- OrigTopics], - ?assertEqual(DestTopics, RecvTopics), - %% Unsubscribe - {ok, _, _} = emqtt:unsubscribe(C, OrigTopics), - timer:sleep(100), - ?assertEqual([], emqx_broker:subscriptions(<<"rewrite_client">>)), - ok = emqtt:disconnect(C), - ok = emqx_mod_rewrite:unload(?RULES). - -t_rewrite_rule(_Config) -> - Rules = emqx_mod_rewrite:compile(?RULES), - ?assertEqual(<<"z/y/2">>, emqx_mod_rewrite:match_and_rewrite(<<"x/y/2">>, Rules)), - ?assertEqual(<<"x/1/2">>, emqx_mod_rewrite:match_and_rewrite(<<"x/1/2">>, Rules)), - ?assertEqual(<<"y/z/b">>, emqx_mod_rewrite:match_and_rewrite(<<"y/a/z/b">>, Rules)), - ?assertEqual(<<"y/def">>, emqx_mod_rewrite:match_and_rewrite(<<"y/def">>, Rules)). - -%%-------------------------------------------------------------------- -%% Internal functions -%%-------------------------------------------------------------------- - -receive_publish(Timeout) -> - receive - {publish, Publish} -> {ok, Publish} - after - Timeout -> {error, timeout} - end. -