diff --git a/src/emqx_plugins.erl b/src/emqx_plugins.erl index 4a597fda6..d17053894 100644 --- a/src/emqx_plugins.erl +++ b/src/emqx_plugins.erl @@ -32,6 +32,10 @@ , load_expand_plugin/1 ]). +-ifdef(TEST). +-compile(export_all). +-compile(nowarn_export_all). +-endif. %%-------------------------------------------------------------------- %% APIs %%-------------------------------------------------------------------- @@ -82,7 +86,7 @@ load_expand_plugin(PluginDir) -> init_expand_plugin_config(PluginDir), Ebin = filename:join([PluginDir, "ebin"]), code:add_patha(Ebin), - Modules = filelib:wildcard(filename:join([Ebin ++ "*.beam"])), + Modules = filelib:wildcard(filename:join([Ebin, "*.beam"])), lists:foreach(fun(Mod) -> Module = list_to_atom(filename:basename(Mod, ".beam")), code:load_file(Module) diff --git a/src/emqx_sup.erl b/src/emqx_sup.erl index f95e79b6d..915eff938 100644 --- a/src/emqx_sup.erl +++ b/src/emqx_sup.erl @@ -43,7 +43,7 @@ start_link() -> supervisor:start_link({local, ?SUP}, ?MODULE, []). -spec(start_child(supervisor:child_spec()) -> startchild_ret()). -start_child(ChildSpec) when is_tuple(ChildSpec) -> +start_child(ChildSpec) when is_map(ChildSpec) -> supervisor:start_child(?SUP, ChildSpec). -spec(start_child(module(), worker | supervisor) -> startchild_ret()). diff --git a/src/emqx_sys.erl b/src/emqx_sys.erl index 66c3d2dc1..23a18896b 100644 --- a/src/emqx_sys.erl +++ b/src/emqx_sys.erl @@ -45,6 +45,11 @@ , terminate/2 ]). +-ifdef(TEST). +-compile(export_all). +-compile(nowarn_export_all). +-endif. + -import(emqx_topic, [systop/1]). -import(emqx_misc, [start_timer/2]). @@ -192,7 +197,7 @@ uptime(hours, H) when H < 24 -> uptime(hours, H) -> [uptime(days, H div 24), integer_to_list(H rem 24), " hours, "]; uptime(days, D) -> - [integer_to_list(D), " days,"]. + [integer_to_list(D), " days, "]. publish(uptime, Uptime) -> safe_publish(systop(uptime), Uptime); diff --git a/test/emqx_SUITE.erl b/test/emqx_SUITE.erl index b612b100b..be6ee8833 100644 --- a/test/emqx_SUITE.erl +++ b/test/emqx_SUITE.erl @@ -32,6 +32,13 @@ init_per_suite(Config) -> end_per_suite(_Config) -> emqx_ct_helpers:stop_apps([]). +t_restart(_) -> + ConfFile = "test.config", + Data = "[{emqx_statsd,[{interval,15000},{push_gateway,\"http://127.0.0.1:9091\"}]}].", + file:write_file(ConfFile, list_to_binary(Data)), + emqx:restart(ConfFile), + file:delete(ConfFile). + t_stop_start(_) -> emqx:stop(), false = emqx:is_running(node()), diff --git a/test/emqx_access_control_SUITE.erl b/test/emqx_access_control_SUITE.erl index 53bdba35d..8629c6e28 100644 --- a/test/emqx_access_control_SUITE.erl +++ b/test/emqx_access_control_SUITE.erl @@ -19,22 +19,52 @@ -compile(export_all). -compile(nowarn_export_all). +-include("emqx_mqtt.hrl"). -include_lib("eunit/include/eunit.hrl"). all() -> emqx_ct:all(?MODULE). -init_per_testcase(_TestCase, Config) -> +init_per_suite(Config) -> + emqx_ct_helpers:boot_modules([router, broker]), + emqx_ct_helpers:start_apps([]), Config. -end_per_testcase(_TestCase, Config) -> - Config. +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([]). -% t_authenticate(_) -> -% error('TODO'). +t_authenticate(_) -> + emqx_zone:set_env(zone, allow_anonymous, false), + ?assertMatch({error, _}, emqx_access_control:authenticate(clientinfo())), + emqx_zone:set_env(zone, allow_anonymous, true), + ?assertMatch({ok, _}, emqx_access_control:authenticate(clientinfo())). -% t_check_acl(_) -> -% error('TODO'). +t_check_acl(_) -> + emqx_zone:set_env(zone, acl_nomatch, deny), + application:set_env(emqx, enable_acl_cache, false), + Publish = ?PUBLISH_PACKET(?QOS_0, <<"t">>, 1, <<"payload">>), + ?assertEqual(deny, emqx_access_control:check_acl(clientinfo(), Publish, <<"t">>)), -% t_reload_acl(_) -> -% error('TODO'). + emqx_zone:set_env(zone, acl_nomatch, allow), + application:set_env(emqx, enable_acl_cache, true), + Publish = ?PUBLISH_PACKET(?QOS_0, <<"t">>, 1, <<"payload">>), + ?assertEqual(allow, emqx_access_control:check_acl(clientinfo(), Publish, <<"t">>)). +t_reload_acl(_) -> + ?assertEqual(ok, emqx_access_control:reload_acl()). + +%%-------------------------------------------------------------------- +%% Helper functions +%%-------------------------------------------------------------------- + +clientinfo() -> clientinfo(#{}). +clientinfo(InitProps) -> + maps:merge(#{zone => zone, + protocol => mqtt, + peerhost => {127,0,0,1}, + clientid => <<"clientid">>, + username => <<"username">>, + password => <<"passwd">>, + is_superuser => false, + peercert => undefined, + mountpoint => undefined + }, InitProps). diff --git a/test/emqx_access_rule_SUITE.erl b/test/emqx_access_rule_SUITE.erl index 667df5bc2..ce1b0b812 100644 --- a/test/emqx_access_rule_SUITE.erl +++ b/test/emqx_access_rule_SUITE.erl @@ -23,15 +23,75 @@ all() -> emqx_ct:all(?MODULE). -init_per_testcase(_TestCase, Config) -> +init_per_suite(Config) -> + emqx_ct_helpers:boot_modules([router, broker]), + emqx_ct_helpers:start_apps([]), Config. -end_per_testcase(_TestCase, Config) -> - Config. +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([]). -% t_compile(_) -> -% error('TODO'). +t_compile(_) -> + Rule1 = {allow, all, pubsub, <<"%u">>}, + Compile1 = {allow, all, pubsub, [{pattern,[<<"%u">>]}]}, -% t_match(_) -> -% error('TODO'). + Rule2 = {allow, {ipaddr, "127.0.0.1"}, pubsub, <<"%c">>}, + Compile2 = {allow, {ipaddr, {{127,0,0,1}, {127,0,0,1}, 32}}, pubsub, [{pattern,[<<"%c">>]}]}, + Rule3 = {allow, {'and', [{client, <<"testClient">>}, {user, <<"testUser">>}]}, pubsub, [<<"testTopics1">>, <<"testTopics2">>]}, + Compile3 = {allow, {'and', [{client, <<"testClient">>}, {user, <<"testUser">>}]}, pubsub, [[<<"testTopics1">>], [<<"testTopics2">>]]}, + + Rule4 = {allow, {'or', [{client, all}, {user, all}]}, pubsub, [ <<"testTopics1">>, <<"testTopics2">>]}, + Compile4 = {allow, {'or', [{client, all}, {user, all}]}, pubsub, [[<<"testTopics1">>], [<<"testTopics2">>]]}, + + ?assertEqual(Compile1, emqx_access_rule:compile(Rule1)), + ?assertEqual(Compile2, emqx_access_rule:compile(Rule2)), + ?assertEqual(Compile3, emqx_access_rule:compile(Rule3)), + ?assertEqual(Compile4, emqx_access_rule:compile(Rule4)). + +t_match(_) -> + ClientInfo1 = #{zone => external, + clientid => <<"testClient">>, + username => <<"TestUser">>, + peerhost => {127,0,0,1} + }, + ClientInfo2 = #{zone => external, + clientid => <<"testClient">>, + username => <<"TestUser">>, + peerhost => {192,168,0,10} + }, + ClientInfo3 = #{zone => external, + clientid => <<"testClient">>, + username => <<"TestUser">>, + peerhost => undefined + }, + ?assertEqual({matched, deny}, emqx_access_rule:match([], [], {deny, all})), + ?assertEqual({matched, allow}, emqx_access_rule:match([], [], {allow, all})), + ?assertEqual(nomatch, emqx_access_rule:match(ClientInfo1, <<"Test/Topic">>, + emqx_access_rule:compile({allow, {user, all}, pubsub, []}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"Test/Topic">>, + emqx_access_rule:compile({allow, {client, all}, pubsub, ["$SYS/#", "#"]}))), + ?assertEqual(nomatch, emqx_access_rule:match(ClientInfo3, <<"Test/Topic">>, + emqx_access_rule:compile({allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"Test/Topic">>, + emqx_access_rule:compile({allow, {ipaddr, "127.0.0.1"}, subscribe, ["$SYS/#", "#"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo2, <<"Test/Topic">>, + emqx_access_rule:compile({allow, {ipaddr, "192.168.0.1/24"}, subscribe, ["$SYS/#", "#"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"d/e/f/x">>, + emqx_access_rule:compile({allow, {user, "TestUser"}, subscribe, ["a/b/c", "d/e/f/#"]}))), + ?assertEqual(nomatch, emqx_access_rule:match(ClientInfo1, <<"d/e/f/x">>, + emqx_access_rule:compile({allow, {user, "admin"}, pubsub, ["d/e/f/#"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"testTopics/testClient">>, + emqx_access_rule:compile({allow, {client, "testClient"}, publish, ["testTopics/testClient"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"clients/testClient">>, + emqx_access_rule:compile({allow, all, pubsub, ["clients/%c"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(#{username => <<"user2">>}, <<"users/user2/abc/def">>, + emqx_access_rule:compile({allow, all, subscribe, ["users/%u/#"]}))), + ?assertEqual({matched, deny}, emqx_access_rule:match(ClientInfo1, <<"d/e/f">>, + emqx_access_rule:compile({deny, all, subscribe, ["$SYS/#", "#"]}))), + ?assertEqual(nomatch, emqx_access_rule:match(ClientInfo1, <<"Topic">>, + emqx_access_rule:compile({allow, {'and', [{ipaddr, "127.0.0.1"}, {user, <<"WrongUser">>}]}, publish, <<"Topic">>}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"Topic">>, + emqx_access_rule:compile({allow, {'and', [{ipaddr, "127.0.0.1"}, {user, <<"TestUser">>}]}, publish, <<"Topic">>}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"Topic">>, + emqx_access_rule:compile({allow, {'or', [{ipaddr, "127.0.0.1"}, {user, <<"WrongUser">>}]}, publish, ["Topic"]}))). diff --git a/test/emqx_cm_locker_SUITE.erl b/test/emqx_cm_locker_SUITE.erl index f476c99ac..47b197a2a 100644 --- a/test/emqx_cm_locker_SUITE.erl +++ b/test/emqx_cm_locker_SUITE.erl @@ -23,21 +23,23 @@ 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([]), Config. -end_per_testcase(_TestCase, Config) -> - Config. +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([]). -% t_start_link(_) -> -% error('TODO'). +t_start_link(_) -> + emqx_cm_locker:start_link(). -% t_trans(_) -> -% error('TODO'). - -% t_lock(_) -> -% error('TODO'). - -% t_unlock(_) -> -% error('TODO'). +t_trans(_) -> + ok = emqx_cm_locker:trans(undefined, fun(_) -> ok end, []), + ok = emqx_cm_locker:trans(<<"clientid">>, fun(_) -> ok end). +t_lock_unlocak(_) -> + {true, _Nodes} = emqx_cm_locker:lock(<<"clientid">>), + {true, _Nodes} = emqx_cm_locker:lock(<<"clientid">>), + {true, _Nodes} = emqx_cm_locker:unlock(<<"clientid">>), + {true, _Nodes} = emqx_cm_locker:unlock(<<"clientid">>). diff --git a/test/emqx_mod_acl_internal_SUITE.erl b/test/emqx_mod_acl_internal_SUITE.erl index 05b406f7a..e854fb831 100644 --- a/test/emqx_mod_acl_internal_SUITE.erl +++ b/test/emqx_mod_acl_internal_SUITE.erl @@ -19,28 +19,53 @@ -compile(export_all). -compile(nowarn_export_all). +-include("emqx_mqtt.hrl"). -include_lib("eunit/include/eunit.hrl"). 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]), Config. -end_per_testcase(_TestCase, Config) -> - Config. +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([emqx]). -% t_load(_) -> -% error('TODO'). +t_load_unload(_) -> + ?assertEqual({error,already_exists}, emqx_mod_acl_internal:load([])), + ?assertEqual(ok, emqx_mod_acl_internal:unload([])), + ?assertEqual(ok, emqx_mod_acl_internal:load([])). -% t_unload(_) -> -% error('TODO'). +t_all_rules(_) -> + application:set_env(emqx, acl_file, ""), + ?assertMatch(#{}, emqx_mod_acl_internal:all_rules()), -% t_all_rules(_) -> -% error('TODO'). + application:set_env(emqx, acl_file, emqx_ct_helpers:deps_path(emqx, "etc/acl.conf")), + ?assertMatch(#{publish := _, subscribe := _}, emqx_mod_acl_internal:all_rules()). -% t_check_acl(_) -> -% error('TODO'). +t_check_acl(_) -> + Rules=#{publish => [{allow,all}], subscribe => [{deny, all}]}, + ?assertEqual({ok, allow}, emqx_mod_acl_internal:check_acl(clientinfo(), publish, <<"t">>, [], Rules)), + ?assertEqual({ok, deny}, emqx_mod_acl_internal:check_acl(clientinfo(), subscribe, <<"t">>, [], Rules)), + ?assertEqual(ok, emqx_mod_acl_internal:check_acl(clientinfo(), connect, <<"t">>, [], Rules)). -% t_reload_acl(_) -> -% error('TODO'). +t_reload_acl(_) -> + ?assertEqual(ok, emqx_mod_acl_internal:reload_acl()). +%%-------------------------------------------------------------------- +%% Helper functions +%%-------------------------------------------------------------------- + +clientinfo() -> clientinfo(#{}). +clientinfo(InitProps) -> + maps:merge(#{zone => zone, + protocol => mqtt, + peerhost => {127,0,0,1}, + clientid => <<"clientid">>, + username => <<"username">>, + password => <<"passwd">>, + is_superuser => false, + peercert => undefined, + mountpoint => undefined + }, InitProps). diff --git a/test/emqx_mod_subscription_SUITE.erl b/test/emqx_mod_subscription_SUITE.erl index ed5acc3d6..644e303dd 100644 --- a/test/emqx_mod_subscription_SUITE.erl +++ b/test/emqx_mod_subscription_SUITE.erl @@ -19,22 +19,44 @@ -compile(export_all). -compile(nowarn_export_all). +-include("emqx_mqtt.hrl"). -include_lib("eunit/include/eunit.hrl"). 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]), Config. -end_per_testcase(_TestCase, Config) -> - Config. +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([emqx]). -% t_load(_) -> -% error('TODO'). +t_load(_) -> + ?assertEqual(ok, emqx_mod_subscription:load([{<<"connected/%c/%u">>, ?QOS_0}])). -% t_on_client_connected(_) -> -% error('TODO'). +t_on_client_connected(_) -> + {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). -% t_unload(_) -> -% error('TODO'). +t_unload(_) -> + ?assertEqual(ok, emqx_mod_subscription:unload([{<<"connected/%c/%u">>, ?QOS_0}])). + +%%-------------------------------------------------------------------- +%% Internal functions +%%-------------------------------------------------------------------- + +receive_publish(Timeout) -> + receive + {publish, Publish} -> {ok, Publish} + after + Timeout -> {error, timeout} + end. diff --git a/test/emqx_plugins_SUITE.erl b/test/emqx_plugins_SUITE.erl index 402a0887a..29d3d5964 100644 --- a/test/emqx_plugins_SUITE.erl +++ b/test/emqx_plugins_SUITE.erl @@ -19,6 +19,7 @@ -compile(export_all). -compile(nowarn_export_all). +-include("emqx.hrl"). -include_lib("eunit/include/eunit.hrl"). all() -> emqx_ct:all(?MODULE). @@ -30,7 +31,7 @@ init_per_suite(Config) -> DataPath = proplists:get_value(data_dir, Config), AppPath = filename:join([DataPath, "emqx_mini_plugin"]), - Cmd = lists:flatten(io_lib:format("cd ~s && make", [AppPath])), + Cmd = lists:flatten(io_lib:format("cd ~s && make && cp -r etc _build/default/lib/emqx_mini_plugin/", [AppPath])), ct:pal("Executing ~s~n", [Cmd]), ct:pal("~n ~s~n", [os:cmd(Cmd)]), @@ -43,21 +44,6 @@ init_per_suite(Config) -> Config. -% t_load_expand_plugin(_) -> -% error('TODO'). - -% t_list(_) -> -% error('TODO'). - -% t_find_plugin(_) -> -% error('TODO'). - -% t_unload(_) -> -% error('TODO'). - -% t_init(_) -> -% error('TODO'). - set_sepecial_cfg(_) -> ExpandPath = filename:dirname(code:lib_dir(emqx_mini_plugin)), @@ -69,8 +55,92 @@ end_per_suite(_Config) -> emqx_ct_helpers:stop_apps([]). t_load(_) -> - {error, load_app_fail} = emqx_plugins:load_expand_plugin("./not_existed_path/"), + ?assertEqual([], emqx_plugins:load()), + ?assertEqual([], emqx_plugins:unload()), + + ?assertEqual({error, not_found}, emqx_plugins:load(not_existed_plugin)), + ?assertMatch({ok, _}, emqx_plugins:load(emqx_mini_plugin)), + ?assertEqual({error, already_started}, emqx_plugins:load(emqx_mini_plugin)), + ?assertEqual(ok, emqx_plugins:unload(emqx_mini_plugin)), + ?assertEqual({error, not_started}, emqx_plugins:unload(emqx_mini_plugin)), + + application:set_env(emqx, expand_plugins_dir, undefined), + application:set_env(emqx, plugins_loaded_file, undefined), + ?assertEqual(ignore, emqx_plugins:load()), + ?assertEqual(ignore, emqx_plugins:unload()). + + +t_init_config(_) -> + ConfFile = "emqx_mini_plugin.config", + Data = "[{emqx_mini_plugin,[{mininame ,test}]}].", + file:write_file(ConfFile, list_to_binary(Data)), + ?assertEqual(ok, emqx_plugins:init_config(ConfFile)), + file:delete(ConfFile), + ?assertEqual({ok,test}, application:get_env(emqx_mini_plugin, mininame)). + +t_load_expand_plugin(_) -> + ?assertEqual({error, load_app_fail}, emqx_plugins:load_expand_plugin("./not_existed_path/")). + +t_list(_) -> + ?assertMatch([{plugin, _, _, _, _, _, _, _, _} | _ ], emqx_plugins:list()). + +t_find_plugin(_) -> + ?assertMatch({plugin, emqx_mini_plugin, _, _, _, _, _, _, _}, emqx_plugins:find_plugin(emqx_mini_plugin)). + +t_plugin_type(_) -> + ?assertEqual(auth, emqx_plugins:plugin_type(auth)), + ?assertEqual(protocol, emqx_plugins:plugin_type(protocol)), + ?assertEqual(backend, emqx_plugins:plugin_type(backend)), + ?assertEqual(bridge, emqx_plugins:plugin_type(bridge)), + ?assertEqual(feature, emqx_plugins:plugin_type(undefined)). + +t_with_loaded_file(_) -> + ?assertMatch({error, _}, emqx_plugins:with_loaded_file("./not_existed_path/", fun(_) -> ok end)). + +t_plugin_loaded(_) -> + ?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_mini_plugin, false)), + ?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_mini_plugin, true)). + +t_plugin_unloaded(_) -> + ?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin, false)), + ?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin, true)). + +t_plugin(_) -> + try + emqx_plugins:plugin(not_existed_plugin, undefined) + catch + _Error:Reason:_Stacktrace -> + ?assertEqual({plugin_not_found,not_existed_plugin}, Reason) + end, + ?assertMatch({plugin, emqx_mini_plugin, _, _, _, _, _, _, _}, emqx_plugins:plugin(emqx_mini_plugin, undefined)). + +t_filter_plugins(_) -> + ?assertEqual([name1, name2], emqx_plugins:filter_plugins([name1, {name2,true}, {name3, false}])). + +t_load_plugin(_) -> + ok = meck:new(application, [unstick, non_strict, passthrough, no_history]), + ok = meck:expect(application, load, fun(already_loaded_app) -> {error, {already_loaded, already_loaded_app}}; + (error_app) -> {error, error}; + (_) -> ok end), + ok = meck:expect(application, ensure_all_started, fun(already_loaded_app) -> {error, {already_loaded_app, already_loaded}}; + (error_app) -> {error, error}; + (App) -> {ok, App} end), + + ?assertMatch({error, _}, emqx_plugins:load_plugin(#plugin{name = already_loaded_app}, true)), + ?assertMatch({ok, _}, emqx_plugins:load_plugin(#plugin{name = normal}, true)), + ?assertMatch({error,_}, emqx_plugins:load_plugin(#plugin{name = error_app}, true)), + + ok = meck:unload(application). + +t_unload_plugin(_) -> + ok = meck:new(application, [unstick, non_strict, passthrough, no_history]), + ok = meck:expect(application, stop, fun(not_started_app) -> {error, {not_started, not_started_app}}; + (error_app) -> {error, error}; + (_) -> ok end), + + ?assertEqual(ok, emqx_plugins:unload_plugin(not_started_app, true)), + ?assertEqual(ok, emqx_plugins:unload_plugin(normal, true)), + ?assertEqual({error,error}, emqx_plugins:unload_plugin(error_app, true)), + + ok = meck:unload(application). - {error, not_started} = emqx_plugins:unload(emqx_mini_plugin), - {ok, _} = emqx_plugins:load(emqx_mini_plugin), - ok = emqx_plugins:unload(emqx_mini_plugin). diff --git a/test/emqx_shared_sub_SUITE.erl b/test/emqx_shared_sub_SUITE.erl index 23b282832..dcaa8b32c 100644 --- a/test/emqx_shared_sub_SUITE.erl +++ b/test/emqx_shared_sub_SUITE.erl @@ -29,6 +29,9 @@ emqx_ct_helpers:wait_for( ?FUNCTION_NAME, ?LINE, fun() -> For end, Timeout)). +-define(ack, shared_sub_ack). +-define(no_ack, no_ack). + all() -> emqx_ct:all(?SUITE). init_per_suite(Config) -> @@ -39,17 +42,22 @@ init_per_suite(Config) -> end_per_suite(_Config) -> emqx_ct_helpers:stop_apps([]). -% t_is_ack_required(_) -> -% error('TODO'). +t_is_ack_required(_) -> + ?assertEqual(false, emqx_shared_sub:is_ack_required(#message{headers = #{}})). -% t_maybe_nack_dropped(_) -> -% error('TODO'). +t_maybe_nack_dropped(_) -> + ?assertEqual(ok, emqx_shared_sub:maybe_nack_dropped(#message{headers = #{}})), + ?assertEqual(ok, emqx_shared_sub:maybe_nack_dropped(#message{headers = #{shared_dispatch_ack => {self(), for_test}}})), + ?assertEqual(ok,receive {for_test, {shared_sub_nack, dropped}} -> ok after 100 -> timeout end). -% t_nack_no_connection(_) -> -% error('TODO'). +t_nack_no_connection(_) -> + ?assertEqual(ok, emqx_shared_sub:nack_no_connection(#message{headers = #{shared_dispatch_ack => {self(), for_test}}})), + ?assertEqual(ok,receive {for_test, {shared_sub_nack, no_connection}} -> ok after 100 -> timeout end). -% t_maybe_ack(_) -> -% error('TODO'). +t_maybe_ack(_) -> + ?assertEqual(#message{headers = #{}}, emqx_shared_sub:maybe_ack(#message{headers = #{}})), + ?assertEqual(#message{headers = #{shared_dispatch_ack => ?no_ack}}, emqx_shared_sub:maybe_ack(#message{headers = #{shared_dispatch_ack => {self(), for_test}}})), + ?assertEqual(ok,receive {for_test, ?ack} -> ok after 100 -> timeout end). % t_subscribers(_) -> % error('TODO'). @@ -239,14 +247,23 @@ last_message(ExpectedPayload, Pids) -> <<"not yet?">> end. -% t_dispatch(_) -> -% error('TODO'). +t_dispatch(_) -> + ok = ensure_config(random), + Topic = <<"foo">>, + ?assertEqual({error, no_subscribers}, emqx_shared_sub:dispatch(<<"group1">>, Topic, #delivery{message = #message{}})), + emqx:subscribe(Topic, #{qos => 2, share => <<"group1">>}), + ?assertEqual(ok, emqx_shared_sub:dispatch(<<"group1">>, Topic, #delivery{message = #message{}})). % t_unsubscribe(_) -> % error('TODO'). % t_subscribe(_) -> % error('TODO'). +t_uncovered_func(_) -> + ignored = gen_server:call(emqx_shared_sub, ignored), + ok = gen_server:cast(emqx_shared_sub, ignored), + ignored = emqx_shared_sub ! ignored, + {mnesia_table_event, []} = emqx_shared_sub ! {mnesia_table_event, []}. %%-------------------------------------------------------------------- %% help functions diff --git a/test/emqx_sup_SUITE.erl b/test/emqx_sup_SUITE.erl new file mode 100644 index 000000000..4d2386bde --- /dev/null +++ b/test/emqx_sup_SUITE.erl @@ -0,0 +1,39 @@ +%%-------------------------------------------------------------------- +%% 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_sup_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +-include_lib("eunit/include/eunit.hrl"). + +all() -> emqx_ct:all(?MODULE). + +init_per_suite(Config) -> + emqx_ct_helpers:boot_modules(all), + emqx_ct_helpers:start_apps([]), + Config. + +end_per_suite(_Config) -> + emqx_ct_helpers:stop_apps([]). + +t_child(_) -> + ?assertMatch({error, _}, emqx_sup:start_child(undef, worker)), + ?assertMatch({error, not_found}, emqx_sup:stop_child(undef)), + ?assertMatch({error, _}, emqx_sup:start_child(emqx_broker_sup, supervisor)), + ?assertEqual(ok, emqx_sup:stop_child(emqx_broker_sup)), + ?assertMatch({ok, _}, emqx_sup:start_child(emqx_broker_sup, supervisor)). \ No newline at end of file diff --git a/test/emqx_sys_SUITE.erl b/test/emqx_sys_SUITE.erl index ff8645936..dc8c1e865 100644 --- a/test/emqx_sys_SUITE.erl +++ b/test/emqx_sys_SUITE.erl @@ -49,8 +49,11 @@ end_per_suite(_Config) -> % t_sysdescr(_) -> % error('TODO'). -% t_uptime(_) -> -% error('TODO'). +t_uptime(_) -> + ?assertEqual(<<"1 seconds">>, iolist_to_binary(emqx_sys:uptime(seconds, 1))), + ?assertEqual(<<"1 minutes, 0 seconds">>, iolist_to_binary(emqx_sys:uptime(seconds, 60))), + ?assertEqual(<<"1 hours, 0 minutes, 0 seconds">>, iolist_to_binary(emqx_sys:uptime(seconds, 3600))), + ?assertEqual(<<"1 days, 0 hours, 0 minutes, 0 seconds">>, iolist_to_binary(emqx_sys:uptime(seconds, 86400))). % t_datetime(_) -> % error('TODO'). diff --git a/test/emqx_sys_mon_SUITE.erl b/test/emqx_sys_mon_SUITE.erl index 99b63ae7f..ca02305b9 100644 --- a/test/emqx_sys_mon_SUITE.erl +++ b/test/emqx_sys_mon_SUITE.erl @@ -69,11 +69,25 @@ init_per_testcase(t_sys_mon2, Config) -> ok; (_) -> ok end), + Config; +init_per_testcase(_, Config) -> + emqx_ct_helpers:boot_modules(all), + emqx_ct_helpers:start_apps([]), Config. end_per_testcase(_, _Config) -> emqx_ct_helpers:stop_apps([]). +t_procinfo(_) -> + ok = meck:new(emqx_vm, [passthrough, no_history]), + ok = meck:expect(emqx_vm, get_process_info, fun(_) -> undefined end), + ok = meck:expect(emqx_vm, get_process_gc, fun(_) -> ok end), + ?assertEqual(undefined, emqx_sys_mon:procinfo([])), + ok = meck:expect(emqx_vm, get_process_info, fun(_) -> ok end), + ok = meck:expect(emqx_vm, get_process_gc, fun(_) -> undefined end), + ?assertEqual(undefined, emqx_sys_mon:procinfo([])), + ok = meck:unload(emqx_vm). + t_sys_mon(_Config) -> lists:foreach( fun({PidOrPort, SysMonName,ValidateInfo, InfoOrPort}) ->