From 2e26cd244aa80d5bedfa76e963e7203e0d78949b Mon Sep 17 00:00:00 2001 From: tigercl Date: Fri, 16 Aug 2019 18:25:49 +0800 Subject: [PATCH] Improve test coverage (#2799) * Improve test coverage * Improve test coverage for emqx_cm * Improve test coverage for emqx_cm_registry * Fix emqx_client_SUITE --- src/emqx_ctl.erl | 21 -------- src/emqx_mqtt_props.erl | 4 +- src/emqx_session.erl | 2 +- test/emqx_SUITE.erl | 81 ++++++++++++++++++++++++++++ test/emqx_client_SUITE.erl | 25 +++++++++ test/emqx_ctl_SUITE.erl | 54 +++++++++++++++++++ test/emqx_mod_subscription_SUITE.erl | 51 ++++++++++++++++++ 7 files changed, 215 insertions(+), 23 deletions(-) create mode 100644 test/emqx_SUITE.erl create mode 100644 test/emqx_ctl_SUITE.erl create mode 100644 test/emqx_mod_subscription_SUITE.erl diff --git a/src/emqx_ctl.erl b/src/emqx_ctl.erl index 08b9a56fd..60ee37039 100644 --- a/src/emqx_ctl.erl +++ b/src/emqx_ctl.erl @@ -151,24 +151,3 @@ noreply(State) -> next_seq(State = #state{seq = Seq}) -> State#state{seq = Seq + 1}. --ifdef(TEST). - --include_lib("eunit/include/eunit.hrl"). - -register_command_test_() -> - {setup, - fun() -> - {ok, InitState} = emqx_ctl:init([]), - InitState - end, - fun(State) -> - ok = emqx_ctl:terminate(shutdown, State) - end, - fun(State = #state{seq = Seq}) -> - emqx_ctl:handle_cast({register_command, test0, {?MODULE, test0}, []}, State), - [?_assertMatch([{{0,test0},{?MODULE, test0}, []}], ets:lookup(?TAB, {Seq,test0}))] - end - }. - --endif. - diff --git a/src/emqx_mqtt_props.erl b/src/emqx_mqtt_props.erl index 1b75425a7..163d9baf1 100644 --- a/src/emqx_mqtt_props.erl +++ b/src/emqx_mqtt_props.erl @@ -48,7 +48,9 @@ 16#19 => {'Request-Response-Information', 'Byte', [?CONNECT]}, 16#1A => {'Response-Information', 'UTF8-Encoded-String', [?CONNACK]}, 16#1C => {'Server-Reference', 'UTF8-Encoded-String', [?CONNACK, ?DISCONNECT]}, - 16#1F => {'Reason-String', 'UTF8-Encoded-String', 'ALL'}, + 16#1F => {'Reason-String', 'UTF8-Encoded-String', [?CONNACK, ?DISCONNECT, ?PUBACK, + ?PUBREC, ?PUBREL, ?PUBCOMP, + ?SUBACK, ?UNSUBACK, ?AUTH]}, 16#21 => {'Receive-Maximum', 'Two-Byte-Integer', [?CONNECT, ?CONNACK]}, 16#22 => {'Topic-Alias-Maximum', 'Two-Byte-Integer', [?CONNECT, ?CONNACK]}, 16#23 => {'Topic-Alias', 'Two-Byte-Integer', [?PUBLISH]}, diff --git a/src/emqx_session.erl b/src/emqx_session.erl index 2530f3a42..116f5756e 100644 --- a/src/emqx_session.erl +++ b/src/emqx_session.erl @@ -206,7 +206,7 @@ info(#session{clean_start = CleanStart, awaiting_rel => maps:size(AwaitingRel), max_awaiting_rel => MaxAwaitingRel, await_rel_timeout => AwaitRelTimeout, - expiry_interval => ExpiryInterval div 1000, + expiry_interval => ExpiryInterval, created_at => CreatedAt }. diff --git a/test/emqx_SUITE.erl b/test/emqx_SUITE.erl new file mode 100644 index 000000000..a971c7633 --- /dev/null +++ b/test/emqx_SUITE.erl @@ -0,0 +1,81 @@ +%%-------------------------------------------------------------------- +%% 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_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +-include("emqx.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-include_lib("common_test/include/ct.hrl"). + +all() -> emqx_ct:all(?MODULE). + +init_per_suite(Config) -> + emqx_ct_helpers:start_apps([]), + Config. + +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([]). + +t_emqx_pubsub_api(_) -> + emqx:start(), + true = emqx:is_running(node()), + {ok, C} = emqx_client:start_link([{host, "localhost"}, {client_id, "myclient"}]), + {ok, _} = emqx_client:connect(C), + ClientId = <<"myclient">>, + Topic = <<"mytopic">>, + Payload = <<"Hello World">>, + Topic1 = <<"mytopic1">>, + emqx:subscribe(Topic, ClientId), + ?assertEqual([Topic], emqx:topics()), + ?assertEqual([self()], emqx:subscribers(Topic)), + ?assertEqual([{Topic,#{qos => 0,subid => ClientId}}], emqx:subscriptions(self())), + ?assertEqual(true, emqx:subscribed(self(), Topic)), + ?assertEqual(true, emqx:subscribed(ClientId, Topic)), + ?assertEqual(false, emqx:subscribed(self(), Topic1)), + ?assertEqual(false, emqx:subscribed(ClientId, Topic1)), + emqx:publish(emqx_message:make(Topic, Payload)), + receive + {deliver, Topic, #message{payload = Payload}} -> + ok + after 100 -> + ct:fail("no_message") + end, + emqx:unsubscribe(Topic), + ct:sleep(20), + ?assertEqual([], emqx:topics()). + +t_emqx_hook_api(_) -> + InitArgs = ['arg2', 'arg3'], + emqx:hook('hook.run', fun run/3, InitArgs), + ok = emqx:run_hook('hook.run', ['arg1']), + emqx:unhook('hook.run', fun run/3), + + emqx:hook('hook.run_fold', fun add1/1), + emqx:hook('hook.run_fold', fun add2/1), + 4 = emqx:run_fold_hook('hook.run_fold', [], 1), + emqx:unhook('hook.run_fold', fun add1/1), + emqx:unhook('hook.run_fold', fun add2/1). + +run('arg1', 'arg2', 'arg3') -> + ok; +run(_, _, _) -> + ct:fail("no_match"). + +add1(N) -> {ok, N + 1}. +add2(N) -> {ok, N + 2}. \ No newline at end of file diff --git a/test/emqx_client_SUITE.erl b/test/emqx_client_SUITE.erl index 3ed8a5dff..17ade0616 100644 --- a/test/emqx_client_SUITE.erl +++ b/test/emqx_client_SUITE.erl @@ -54,6 +54,8 @@ groups() -> ]}, {mqttv4, [non_parallel_tests], [t_basic_v4, + t_cm, + t_cm_registry, %% t_will_message, %% t_offline_message_queueing, t_overlapping_subscriptions, @@ -88,6 +90,29 @@ t_basic_v3(_) -> t_basic_v4(_Config) -> t_basic([{proto_ver, v4}]). +t_cm(_) -> + IdleTimeout = emqx_zone:get_env(external, idle_timeout, 30000), + emqx_zone:set_env(external, idle_timeout, 1000), + ClientId = <<"myclient">>, + {ok, C} = emqx_client:start_link([{client_id, ClientId}]), + {ok, _} = emqx_client:connect(C), + #{client := #{client_id := ClientId}} = emqx_cm:get_chan_attrs(ClientId), + emqx_client:subscribe(C, <<"mytopic">>, 0), + ct:sleep(1200), + Stats = emqx_cm:get_chan_stats(ClientId), + ?assertEqual(1, proplists:get_value(subscriptions, Stats)), + emqx_zone:set_env(external, idle_timeout, IdleTimeout). + +t_cm_registry(_) -> + Info = supervisor:which_children(emqx_cm_sup), + {_, Pid, _, _} = lists:keyfind(registry, 1, Info), + ignored = gen_server:call(Pid, <<"Unexpected call">>), + gen_server:cast(Pid, <<"Unexpected cast">>), + Pid ! <<"Unexpected info">>, + ok = application:stop(mnesia), + emqx_ct_helpers:stop_apps([]), + emqx_ct_helpers:start_apps([]). + t_will_message(_Config) -> {ok, C1} = emqx_client:start_link([{clean_start, true}, {will_topic, nth(3, ?TOPICS)}, diff --git a/test/emqx_ctl_SUITE.erl b/test/emqx_ctl_SUITE.erl new file mode 100644 index 000000000..b4c3d953d --- /dev/null +++ b/test/emqx_ctl_SUITE.erl @@ -0,0 +1,54 @@ +%%-------------------------------------------------------------------- +%% 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_ctl_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +-include_lib("eunit/include/eunit.hrl"). +-include_lib("common_test/include/ct.hrl"). + +all() -> emqx_ct:all(?MODULE). + +init_per_suite(Config) -> + emqx_ct_helpers:start_apps([]), + Config. + +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([]). + +t_command(_) -> + emqx_ctl:start_link(), + emqx_ctl:register_command(test, {?MODULE, test}), + ct:sleep(50), + ?assertEqual([{emqx_ctl_SUITE,test}], emqx_ctl:lookup_command(test)), + ?assertEqual(ok, emqx_ctl:run_command(["test", "ok"])), + ?assertEqual({error, test_failed}, emqx_ctl:run_command(["test", "error"])), + ?assertEqual({error, cmd_not_found}, emqx_ctl:run_command(["test2", "ok"])), + emqx_ctl:unregister_command(test), + ct:sleep(50), + ?assertEqual([], emqx_ctl:lookup_command(test)). + +test(["ok"]) -> + ok; +test(["error"]) -> + error(test_failed); +test(_) -> + io:format("Hello world"). + + + diff --git a/test/emqx_mod_subscription_SUITE.erl b/test/emqx_mod_subscription_SUITE.erl new file mode 100644 index 000000000..f955bbbf2 --- /dev/null +++ b/test/emqx_mod_subscription_SUITE.erl @@ -0,0 +1,51 @@ +%%-------------------------------------------------------------------- +%% 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_mod_subscription_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +-include("emqx_mqtt.hrl"). +-include("emqx.hrl"). + +-include_lib("eunit/include/eunit.hrl"). +-include_lib("common_test/include/ct.hrl"). + +all() -> emqx_ct:all(?MODULE). + +init_per_suite(Config) -> + emqx_ct_helpers:start_apps([emqx]), + Config. + +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([emqx]). + +t_mod_subscription(_) -> + emqx_mod_subscription:load([{<<"connected/%c/%u">>, ?QOS_0}]), + {ok, C} = emqx_client:start_link([{host, "localhost"}, {client_id, "myclient"}, {username, "admin"}]), + {ok, _} = emqx_client:connect(C), + % ct:sleep(100), + emqx_client:publish(C, <<"connected/myclient/admin">>, <<"Hello world">>, ?QOS_0), + receive + {publish, #{topic := Topic, payload := Payload}} -> + ?assertEqual(<<"connected/myclient/admin">>, Topic), + ?assertEqual(<<"Hello world">>, Payload) + after 100 -> + ct:fail("no_message") + end, + ok = emqx_client:disconnect(C), + emqx_mod_subscription:unload([]).