Merge pull request #12508 from keynslug/fix/explicit-tab-mgmt
feat: manage mria tables explicitly during apps startup
This commit is contained in:
commit
a945892c52
|
@ -21,12 +21,9 @@
|
||||||
-include("emqx.hrl").
|
-include("emqx.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
-export([create_tables/0]).
|
||||||
-export([mnesia/1]).
|
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([
|
-export([
|
||||||
activate/1,
|
activate/1,
|
||||||
|
@ -86,7 +83,7 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(
|
ok = mria:create_table(
|
||||||
?ACTIVATED_ALARM,
|
?ACTIVATED_ALARM,
|
||||||
[
|
[
|
||||||
|
@ -106,7 +103,8 @@ mnesia(boot) ->
|
||||||
{record_name, deactivated_alarm},
|
{record_name, deactivated_alarm},
|
||||||
{attributes, record_info(fields, deactivated_alarm)}
|
{attributes, record_info(fields, deactivated_alarm)}
|
||||||
]
|
]
|
||||||
).
|
),
|
||||||
|
[?ACTIVATED_ALARM, ?DEACTIVATED_ALARM].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% API
|
%% API
|
||||||
|
|
|
@ -25,9 +25,7 @@
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
-export([mnesia/1]).
|
-export([create_tables/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-export([start_link/0, stop/0]).
|
-export([start_link/0, stop/0]).
|
||||||
|
|
||||||
|
@ -79,7 +77,7 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
Options = [
|
Options = [
|
||||||
{type, set},
|
{type, set},
|
||||||
{rlog_shard, ?COMMON_SHARD},
|
{rlog_shard, ?COMMON_SHARD},
|
||||||
|
@ -89,7 +87,8 @@ mnesia(boot) ->
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
||||||
],
|
],
|
||||||
ok = mria:create_table(?BANNED_INDIVIDUAL_TAB, Options),
|
ok = mria:create_table(?BANNED_INDIVIDUAL_TAB, Options),
|
||||||
ok = mria:create_table(?BANNED_RULE_TAB, Options).
|
ok = mria:create_table(?BANNED_RULE_TAB, Options),
|
||||||
|
[?BANNED_INDIVIDUAL_TAB, ?BANNED_RULE_TAB].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Data backup
|
%% Data backup
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
-export([init/1]).
|
-export([init/1]).
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
|
ok = mria:wait_for_tables(
|
||||||
|
emqx_shared_sub:create_tables() ++
|
||||||
|
emqx_exclusive_subscription:create_tables()
|
||||||
|
),
|
||||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
|
ok = mria:wait_for_tables(emqx_banned:create_tables()),
|
||||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -22,14 +22,11 @@
|
||||||
-logger_header("[exclusive]").
|
-logger_header("[exclusive]").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
-export([mnesia/1]).
|
-export([create_tables/0]).
|
||||||
|
|
||||||
%% For upgrade
|
%% For upgrade
|
||||||
-export([on_add_module/0, on_delete_module/0]).
|
-export([on_add_module/0, on_delete_module/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
-copy_mnesia({mnesia, [copy]}).
|
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
check_subscribe/2,
|
check_subscribe/2,
|
||||||
unsubscribe/2,
|
unsubscribe/2,
|
||||||
|
@ -53,7 +50,7 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
StoreProps = [
|
StoreProps = [
|
||||||
{ets, [
|
{ets, [
|
||||||
{read_concurrency, true},
|
{read_concurrency, true},
|
||||||
|
@ -68,14 +65,14 @@ mnesia(boot) ->
|
||||||
{attributes, record_info(fields, exclusive_subscription)},
|
{attributes, record_info(fields, exclusive_subscription)},
|
||||||
{storage_properties, StoreProps}
|
{storage_properties, StoreProps}
|
||||||
]),
|
]),
|
||||||
ok = mria_rlog:wait_for_shards([?EXCLUSIVE_SHARD], infinity).
|
[?TAB].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Upgrade
|
%% Upgrade
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
on_add_module() ->
|
on_add_module() ->
|
||||||
mnesia(boot).
|
mria:wait_for_tables(create_tables()).
|
||||||
|
|
||||||
on_delete_module() ->
|
on_delete_module() ->
|
||||||
clear().
|
clear().
|
||||||
|
|
|
@ -24,9 +24,7 @@
|
||||||
-include_lib("emqx/include/emqx_router.hrl").
|
-include_lib("emqx/include/emqx_router.hrl").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
-export([mnesia/1]).
|
-export([create_tables/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-export([start_link/2]).
|
-export([start_link/2]).
|
||||||
|
|
||||||
|
@ -123,7 +121,7 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
mria_config:set_dirty_shard(?ROUTE_SHARD, true),
|
mria_config:set_dirty_shard(?ROUTE_SHARD, true),
|
||||||
ok = mria:create_table(?ROUTE_TAB, [
|
ok = mria:create_table(?ROUTE_TAB, [
|
||||||
{type, bag},
|
{type, bag},
|
||||||
|
@ -151,7 +149,8 @@ mnesia(boot) ->
|
||||||
{decentralized_counters, true}
|
{decentralized_counters, true}
|
||||||
]}
|
]}
|
||||||
]}
|
]}
|
||||||
]).
|
]),
|
||||||
|
[?ROUTE_TAB, ?ROUTE_TAB_FILTERS].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Start a router
|
%% Start a router
|
||||||
|
|
|
@ -25,9 +25,7 @@
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
-export([mnesia/1]).
|
-export([create_tables/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([
|
-export([
|
||||||
|
@ -63,7 +61,7 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?ROUTING_NODE, [
|
ok = mria:create_table(?ROUTING_NODE, [
|
||||||
{type, set},
|
{type, set},
|
||||||
{rlog_shard, ?ROUTE_SHARD},
|
{rlog_shard, ?ROUTE_SHARD},
|
||||||
|
@ -71,7 +69,8 @@ mnesia(boot) ->
|
||||||
{record_name, routing_node},
|
{record_name, routing_node},
|
||||||
{attributes, record_info(fields, routing_node)},
|
{attributes, record_info(fields, routing_node)},
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
||||||
]).
|
]),
|
||||||
|
[?ROUTING_NODE].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% API
|
%% API
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
%% Init and log routing table type
|
%% Init and log routing table type
|
||||||
|
ok = mria:wait_for_tables(
|
||||||
|
emqx_trie:create_trie() ++
|
||||||
|
emqx_router:create_tables() ++
|
||||||
|
emqx_router_helper:create_tables()
|
||||||
|
),
|
||||||
ok = emqx_router:init_schema(),
|
ok = emqx_router:init_schema(),
|
||||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@
|
||||||
-include("types.hrl").
|
-include("types.hrl").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
-export([mnesia/1]).
|
-export([create_tables/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
%% APIs
|
%% APIs
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
|
@ -107,14 +105,15 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{type, bag},
|
{type, bag},
|
||||||
{rlog_shard, ?SHARED_SUB_SHARD},
|
{rlog_shard, ?SHARED_SUB_SHARD},
|
||||||
{storage, ram_copies},
|
{storage, ram_copies},
|
||||||
{record_name, emqx_shared_subscription},
|
{record_name, emqx_shared_subscription},
|
||||||
{attributes, record_info(fields, emqx_shared_subscription)}
|
{attributes, record_info(fields, emqx_shared_subscription)}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% API
|
%% API
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
-export([init/1]).
|
-export([init/1]).
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
|
_ = mria:wait_for_tables(emqx_alarm:create_tables()),
|
||||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
|
|
|
@ -20,13 +20,11 @@
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
-export([
|
-export([
|
||||||
mnesia/1,
|
create_trie/0,
|
||||||
wait_for_tables/0,
|
wait_for_tables/0,
|
||||||
create_session_trie/1
|
create_session_trie/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
%% Trie APIs
|
%% Trie APIs
|
||||||
-export([
|
-export([
|
||||||
insert/1,
|
insert/1,
|
||||||
|
@ -65,8 +63,8 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Create or replicate topics table.
|
%% @doc Create or replicate topics table.
|
||||||
-spec mnesia(boot | copy) -> ok.
|
-spec create_trie() -> [mria:table()].
|
||||||
mnesia(boot) ->
|
create_trie() ->
|
||||||
%% Optimize storage
|
%% Optimize storage
|
||||||
StoreProps = [
|
StoreProps = [
|
||||||
{ets, [
|
{ets, [
|
||||||
|
@ -80,7 +78,8 @@ mnesia(boot) ->
|
||||||
{attributes, record_info(fields, ?TRIE)},
|
{attributes, record_info(fields, ?TRIE)},
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
{storage_properties, StoreProps}
|
{storage_properties, StoreProps}
|
||||||
]).
|
]),
|
||||||
|
[?TRIE].
|
||||||
|
|
||||||
create_session_trie(Type) ->
|
create_session_trie(Type) ->
|
||||||
Storage =
|
Storage =
|
||||||
|
|
|
@ -93,15 +93,22 @@ default_auth_header() ->
|
||||||
create_default_app() ->
|
create_default_app() ->
|
||||||
Now = erlang:system_time(second),
|
Now = erlang:system_time(second),
|
||||||
ExpiredAt = Now + timer:minutes(10),
|
ExpiredAt = Now + timer:minutes(10),
|
||||||
emqx_mgmt_auth:create(
|
case
|
||||||
?DEFAULT_APP_ID,
|
emqx_mgmt_auth:create(
|
||||||
?DEFAULT_APP_KEY,
|
?DEFAULT_APP_ID,
|
||||||
?DEFAULT_APP_SECRET,
|
?DEFAULT_APP_KEY,
|
||||||
true,
|
?DEFAULT_APP_SECRET,
|
||||||
ExpiredAt,
|
true,
|
||||||
<<"default app key for test">>,
|
ExpiredAt,
|
||||||
?ROLE_API_SUPERUSER
|
<<"default app key for test">>,
|
||||||
).
|
?ROLE_API_SUPERUSER
|
||||||
|
)
|
||||||
|
of
|
||||||
|
{ok, App} ->
|
||||||
|
{ok, App};
|
||||||
|
{error, name_already_existed} ->
|
||||||
|
{ok, _} = emqx_mgmt_auth:read(?DEFAULT_APP_ID)
|
||||||
|
end.
|
||||||
|
|
||||||
delete_default_app() ->
|
delete_default_app() ->
|
||||||
emqx_mgmt_auth:delete(?DEFAULT_APP_ID).
|
emqx_mgmt_auth:delete(?DEFAULT_APP_ID).
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
%% in `end_per_suite/1` or `end_per_group/2`) with the result from step 2.
|
%% in `end_per_suite/1` or `end_per_group/2`) with the result from step 2.
|
||||||
-module(emqx_cth_cluster).
|
-module(emqx_cth_cluster).
|
||||||
|
|
||||||
-export([start/1, start/2, restart/2]).
|
-export([start/1, start/2, restart/1, restart/2]).
|
||||||
-export([stop/1, stop_node/1]).
|
-export([stop/1, stop_node/1]).
|
||||||
|
|
||||||
-export([start_bare_nodes/1, start_bare_nodes/2]).
|
-export([start_bare_nodes/1, start_bare_nodes/2]).
|
||||||
|
@ -162,6 +162,9 @@ wait_clustered([Node | Nodes] = All, Check, Deadline) ->
|
||||||
wait_clustered(All, Check, Deadline)
|
wait_clustered(All, Check, Deadline)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
restart(NodeSpec) ->
|
||||||
|
restart(maps:get(name, NodeSpec), NodeSpec).
|
||||||
|
|
||||||
restart(Node, Spec) ->
|
restart(Node, Spec) ->
|
||||||
ct:pal("Stopping peer node ~p", [Node]),
|
ct:pal("Stopping peer node ~p", [Node]),
|
||||||
ok = emqx_cth_peer:stop(Node),
|
ok = emqx_cth_peer:stop(Node),
|
||||||
|
|
|
@ -177,10 +177,9 @@ load_appspec({App, _Opts}) ->
|
||||||
load_app_deps(App).
|
load_app_deps(App).
|
||||||
|
|
||||||
load_app_deps(App) ->
|
load_app_deps(App) ->
|
||||||
AlreadyLoaded = [A || {A, _, _} <- application:loaded_applications()],
|
|
||||||
case application:get_key(App, applications) of
|
case application:get_key(App, applications) of
|
||||||
{ok, Deps} ->
|
{ok, Deps} ->
|
||||||
Apps = Deps -- AlreadyLoaded,
|
Apps = [D || D <- Deps, application:get_key(D, id) == undefined],
|
||||||
ok = lists:foreach(fun emqx_common_test_helpers:load/1, Apps),
|
ok = lists:foreach(fun emqx_common_test_helpers:load/1, Apps),
|
||||||
ok = lists:foreach(fun load_app_deps/1, Apps);
|
ok = lists:foreach(fun load_app_deps/1, Apps);
|
||||||
undefined ->
|
undefined ->
|
||||||
|
@ -471,9 +470,12 @@ clean_suite_state() ->
|
||||||
|
|
||||||
app_schema(App) ->
|
app_schema(App) ->
|
||||||
Mod = list_to_atom(atom_to_list(App) ++ "_schema"),
|
Mod = list_to_atom(atom_to_list(App) ++ "_schema"),
|
||||||
try is_list(Mod:roots()) of
|
try
|
||||||
true -> {ok, Mod};
|
Exports = Mod:module_info(exports),
|
||||||
false -> {error, schema_no_roots}
|
case lists:member({roots, 0}, Exports) of
|
||||||
|
true -> {ok, Mod};
|
||||||
|
false -> {error, schema_no_roots}
|
||||||
|
end
|
||||||
catch
|
catch
|
||||||
error:undef ->
|
error:undef ->
|
||||||
{error, schema_not_found}
|
{error, schema_not_found}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
[
|
[
|
||||||
|
@ -43,14 +44,14 @@ end_per_group(_, _) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
application:load(emqx),
|
Apps = emqx_cth_suite:start(
|
||||||
ok = ekka:start(),
|
[{emqx, #{override_env => [{boot_modules, [broker]}]}}],
|
||||||
Config.
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(Config) ->
|
||||||
ekka:stop(),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema().
|
|
||||||
|
|
||||||
init_per_testcase(_TestCase, Config) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
clear_tables(),
|
clear_tables(),
|
||||||
|
@ -185,7 +186,8 @@ t_delete3(_) ->
|
||||||
?assertEqual([], ?TRIE:match(<<"sensor">>)),
|
?assertEqual([], ?TRIE:match(<<"sensor">>)),
|
||||||
?assertEqual([], ?TRIE:lookup_topic(<<"sensor/+">>, ?TRIE)).
|
?assertEqual([], ?TRIE:lookup_topic(<<"sensor/+">>, ?TRIE)).
|
||||||
|
|
||||||
clear_tables() -> emqx_trie:clear_tables().
|
clear_tables() ->
|
||||||
|
emqx_trie:clear_tables().
|
||||||
|
|
||||||
trans(Fun) ->
|
trans(Fun) ->
|
||||||
mria:transaction(?ROUTE_SHARD, Fun).
|
mria:transaction(?ROUTE_SHARD, Fun).
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
ok = emqx_authz_mnesia:init_tables(),
|
ok = emqx_authz_mnesia:init_tables(),
|
||||||
ok = emqx_authn_mnesia:init_tables(),
|
ok = emqx_authn_mnesia:init_tables(),
|
||||||
|
ok = emqx_authn_scram_mnesia:init_tables(),
|
||||||
ok = emqx_authz:register_source(?AUTHZ_TYPE, emqx_authz_mnesia),
|
ok = emqx_authz:register_source(?AUTHZ_TYPE, emqx_authz_mnesia),
|
||||||
ok = emqx_authn:register_provider(?AUTHN_TYPE_SIMPLE, emqx_authn_mnesia),
|
ok = emqx_authn:register_provider(?AUTHN_TYPE_SIMPLE, emqx_authn_mnesia),
|
||||||
ok = emqx_authn:register_provider(?AUTHN_TYPE_SCRAM, emqx_authn_scram_mnesia),
|
ok = emqx_authn:register_provider(?AUTHN_TYPE_SCRAM, emqx_authn_scram_mnesia),
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
do_update_user/3
|
do_update_user/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([mnesia/1, init_tables/0]).
|
-export([init_tables/0]).
|
||||||
|
|
||||||
-export([backup_tables/0]).
|
-export([backup_tables/0]).
|
||||||
|
|
||||||
|
@ -69,8 +69,6 @@
|
||||||
is_superuser :: boolean()
|
is_superuser :: boolean()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-define(TAB, ?MODULE).
|
-define(TAB, ?MODULE).
|
||||||
-define(AUTHN_QSCHEMA, [
|
-define(AUTHN_QSCHEMA, [
|
||||||
{<<"like_user_id">>, binary},
|
{<<"like_user_id">>, binary},
|
||||||
|
@ -83,8 +81,8 @@
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Create or replicate tables.
|
%% @doc Create or replicate tables.
|
||||||
-spec mnesia(boot | copy) -> ok.
|
-spec create_tables() -> [mria:table()].
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{rlog_shard, ?AUTHN_SHARD},
|
{rlog_shard, ?AUTHN_SHARD},
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
|
@ -92,12 +90,13 @@ mnesia(boot) ->
|
||||||
{record_name, user_info},
|
{record_name, user_info},
|
||||||
{attributes, record_info(fields, user_info)},
|
{attributes, record_info(fields, user_info)},
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
%% Init
|
%% Init
|
||||||
-spec init_tables() -> ok.
|
-spec init_tables() -> ok.
|
||||||
init_tables() ->
|
init_tables() ->
|
||||||
ok = mria_rlog:wait_for_shards([?AUTHN_SHARD], infinity).
|
ok = mria:wait_for_tables(create_tables()).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Data backup
|
%% Data backup
|
||||||
|
|
|
@ -65,9 +65,7 @@
|
||||||
|
|
||||||
-type user_group() :: binary().
|
-type user_group() :: binary().
|
||||||
|
|
||||||
-export([mnesia/1]).
|
-export([init_tables/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-record(user_info, {
|
-record(user_info, {
|
||||||
user_id,
|
user_id,
|
||||||
|
@ -84,8 +82,8 @@
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Create or replicate tables.
|
%% @doc Create or replicate tables.
|
||||||
-spec mnesia(boot | copy) -> ok.
|
-spec create_tables() -> [mria:table()].
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{rlog_shard, ?AUTHN_SHARD},
|
{rlog_shard, ?AUTHN_SHARD},
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
|
@ -93,7 +91,12 @@ mnesia(boot) ->
|
||||||
{record_name, user_info},
|
{record_name, user_info},
|
||||||
{attributes, record_info(fields, user_info)},
|
{attributes, record_info(fields, user_info)},
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
|
-spec init_tables() -> ok.
|
||||||
|
init_tables() ->
|
||||||
|
mria:wait_for_tables(create_tables()).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Data backup
|
%% Data backup
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
|
|
||||||
%% Management API
|
%% Management API
|
||||||
-export([
|
-export([
|
||||||
mnesia/1,
|
|
||||||
init_tables/0,
|
init_tables/0,
|
||||||
store_rules/2,
|
store_rules/2,
|
||||||
purge_rules/0,
|
purge_rules/0,
|
||||||
|
@ -74,17 +73,16 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
-spec create_tables() -> [mria:table()].
|
||||||
|
create_tables() ->
|
||||||
-spec mnesia(boot | copy) -> ok.
|
|
||||||
mnesia(boot) ->
|
|
||||||
ok = mria:create_table(?ACL_TABLE, [
|
ok = mria:create_table(?ACL_TABLE, [
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
{rlog_shard, ?ACL_SHARDED},
|
{rlog_shard, ?ACL_SHARDED},
|
||||||
{storage, disc_copies},
|
{storage, disc_copies},
|
||||||
{attributes, record_info(fields, ?ACL_TABLE)},
|
{attributes, record_info(fields, ?ACL_TABLE)},
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
||||||
]).
|
]),
|
||||||
|
[?ACL_TABLE].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% emqx_authz callbacks
|
%% emqx_authz callbacks
|
||||||
|
@ -138,7 +136,7 @@ backup_tables() -> [?ACL_TABLE].
|
||||||
%% Init
|
%% Init
|
||||||
-spec init_tables() -> ok.
|
-spec init_tables() -> ok.
|
||||||
init_tables() ->
|
init_tables() ->
|
||||||
ok = mria_rlog:wait_for_shards([?ACL_SHARDED], infinity).
|
ok = mria:wait_for_tables(create_tables()).
|
||||||
|
|
||||||
%% @doc Update authz rules
|
%% @doc Update authz rules
|
||||||
-spec store_rules(who(), rules()) -> ok.
|
-spec store_rules(who(), rules()) -> ok.
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start_link/0, mnesia/1]).
|
-export([start_link/0, create_tables/0]).
|
||||||
|
|
||||||
%% Note: multicall functions are statically checked by
|
%% Note: multicall functions are statically checked by
|
||||||
%% `emqx_bapi_trans' and `emqx_bpapi_static_checks' modules. Don't
|
%% `emqx_bapi_trans' and `emqx_bpapi_static_checks' modules. Don't
|
||||||
|
@ -65,8 +65,6 @@
|
||||||
|
|
||||||
-export_type([tnx_id/0, succeed_num/0]).
|
-export_type([tnx_id/0, succeed_num/0]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
-include("emqx_conf.hrl").
|
-include("emqx_conf.hrl").
|
||||||
|
@ -99,7 +97,8 @@
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
mnesia(boot) ->
|
|
||||||
|
create_tables() ->
|
||||||
ok = mria:create_table(?CLUSTER_MFA, [
|
ok = mria:create_table(?CLUSTER_MFA, [
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
{rlog_shard, ?CLUSTER_RPC_SHARD},
|
{rlog_shard, ?CLUSTER_RPC_SHARD},
|
||||||
|
@ -113,7 +112,11 @@ mnesia(boot) ->
|
||||||
{storage, disc_copies},
|
{storage, disc_copies},
|
||||||
{record_name, cluster_rpc_commit},
|
{record_name, cluster_rpc_commit},
|
||||||
{attributes, record_info(fields, cluster_rpc_commit)}
|
{attributes, record_info(fields, cluster_rpc_commit)}
|
||||||
]).
|
]),
|
||||||
|
[
|
||||||
|
?CLUSTER_MFA,
|
||||||
|
?CLUSTER_COMMIT
|
||||||
|
].
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
start_link(node(), ?MODULE, get_retry_ms()).
|
start_link(node(), ?MODULE, get_retry_ms()).
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{vsn, "0.1.34"},
|
{vsn, "0.1.34"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_conf_app, []}},
|
{mod, {emqx_conf_app, []}},
|
||||||
{applications, [kernel, stdlib, emqx_ctl]},
|
{applications, [kernel, stdlib]},
|
||||||
{env, []},
|
{env, []},
|
||||||
{modules, []}
|
{modules, []}
|
||||||
]}.
|
]}.
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
-include("emqx_conf.hrl").
|
-include("emqx_conf.hrl").
|
||||||
|
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
|
ok = mria:wait_for_tables(emqx_cluster_rpc:create_tables()),
|
||||||
try
|
try
|
||||||
ok = init_conf()
|
ok = init_conf()
|
||||||
catch
|
catch
|
||||||
|
|
|
@ -42,10 +42,8 @@ suite() -> [{timetrap, {minutes, 5}}].
|
||||||
groups() -> [].
|
groups() -> [].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
application:load(emqx_conf),
|
|
||||||
ok = ekka:start(),
|
|
||||||
ok = emqx_common_test_helpers:start_apps([]),
|
ok = emqx_common_test_helpers:start_apps([]),
|
||||||
ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
|
ok = mria:wait_for_tables(emqx_cluster_rpc:create_tables()),
|
||||||
ok = emqx_config:put([node, cluster_call, retry_interval], 1000),
|
ok = emqx_config:put([node, cluster_call, retry_interval], 1000),
|
||||||
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
||||||
meck:expect(emqx_alarm, activate, 3, ok),
|
meck:expect(emqx_alarm, activate, 3, ok),
|
||||||
|
@ -56,10 +54,6 @@ init_per_suite(Config) ->
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
ok = emqx_common_test_helpers:stop_apps([]),
|
ok = emqx_common_test_helpers:stop_apps([]),
|
||||||
ekka:stop(),
|
|
||||||
mria:stop(),
|
|
||||||
meck:unload(mria),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
meck:unload(emqx_alarm),
|
meck:unload(emqx_alarm),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,10 @@ all() ->
|
||||||
|
|
||||||
t_copy_conf_override_on_restarts(Config) ->
|
t_copy_conf_override_on_restarts(Config) ->
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
|
||||||
Cluster = cluster(
|
Cluster = cluster(
|
||||||
[cluster_spec({core, 1}), cluster_spec({core, 2}), cluster_spec({core, 3})], Config
|
?FUNCTION_NAME,
|
||||||
|
[cluster_spec({core, 1}), cluster_spec({core, 2}), cluster_spec({core, 3})],
|
||||||
|
Config
|
||||||
),
|
),
|
||||||
|
|
||||||
%% 1. Start all nodes
|
%% 1. Start all nodes
|
||||||
|
@ -42,7 +43,7 @@ t_copy_conf_override_on_restarts(Config) ->
|
||||||
|
|
||||||
%% 3. Restart nodes in the same order. This should not
|
%% 3. Restart nodes in the same order. This should not
|
||||||
%% crash and eventually all nodes should be ready.
|
%% crash and eventually all nodes should be ready.
|
||||||
start_cluster_async(Cluster),
|
restart_cluster_async(Cluster),
|
||||||
|
|
||||||
timer:sleep(15000),
|
timer:sleep(15000),
|
||||||
|
|
||||||
|
@ -54,11 +55,12 @@ t_copy_conf_override_on_restarts(Config) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
t_copy_new_data_dir(Config) ->
|
t_copy_new_data_dir(Config) ->
|
||||||
net_kernel:start(['master1@127.0.0.1', longnames]),
|
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
snabbkaffe:fix_ct_logging(),
|
||||||
Cluster = cluster(
|
Cluster = cluster(
|
||||||
[cluster_spec({core, 4}), cluster_spec({core, 5}), cluster_spec({core, 6})], Config
|
?FUNCTION_NAME,
|
||||||
|
[cluster_spec({core, 4}), cluster_spec({core, 5}), cluster_spec({core, 6})],
|
||||||
|
Config
|
||||||
),
|
),
|
||||||
|
|
||||||
%% 1. Start all nodes
|
%% 1. Start all nodes
|
||||||
|
@ -81,11 +83,11 @@ t_copy_new_data_dir(Config) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
t_copy_deprecated_data_dir(Config) ->
|
t_copy_deprecated_data_dir(Config) ->
|
||||||
net_kernel:start(['master2@127.0.0.1', longnames]),
|
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
|
||||||
Cluster = cluster(
|
Cluster = cluster(
|
||||||
[cluster_spec({core, 7}), cluster_spec({core, 8}), cluster_spec({core, 9})], Config
|
?FUNCTION_NAME,
|
||||||
|
[cluster_spec({core, 7}), cluster_spec({core, 8}), cluster_spec({core, 9})],
|
||||||
|
Config
|
||||||
),
|
),
|
||||||
|
|
||||||
%% 1. Start all nodes
|
%% 1. Start all nodes
|
||||||
|
@ -108,11 +110,11 @@ t_copy_deprecated_data_dir(Config) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
t_no_copy_from_newer_version_node(Config) ->
|
t_no_copy_from_newer_version_node(Config) ->
|
||||||
net_kernel:start(['master2@127.0.0.1', longnames]),
|
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
|
||||||
Cluster = cluster(
|
Cluster = cluster(
|
||||||
[cluster_spec({core, 10}), cluster_spec({core, 11}), cluster_spec({core, 12})], Config
|
?FUNCTION_NAME,
|
||||||
|
[cluster_spec({core, 10}), cluster_spec({core, 11}), cluster_spec({core, 12})],
|
||||||
|
Config
|
||||||
),
|
),
|
||||||
OKs = [ok, ok, ok],
|
OKs = [ok, ok, ok],
|
||||||
[First | Rest] = Nodes = start_cluster(Cluster),
|
[First | Rest] = Nodes = start_cluster(Cluster),
|
||||||
|
@ -222,39 +224,29 @@ assert_config_load_done(Nodes) ->
|
||||||
).
|
).
|
||||||
|
|
||||||
stop_cluster(Nodes) ->
|
stop_cluster(Nodes) ->
|
||||||
emqx_utils:pmap(fun emqx_common_test_helpers:stop_peer/1, Nodes).
|
emqx_cth_cluster:stop(Nodes).
|
||||||
|
|
||||||
start_cluster(Specs) ->
|
start_cluster(Specs) ->
|
||||||
[emqx_common_test_helpers:start_peer(Name, Opts) || {Name, Opts} <- Specs].
|
emqx_cth_cluster:start(Specs).
|
||||||
|
|
||||||
start_cluster_async(Specs) ->
|
restart_cluster_async(Specs) ->
|
||||||
[
|
[
|
||||||
begin
|
begin
|
||||||
Opts1 = maps:remove(join_to, Opts),
|
_Pid = spawn_link(emqx_cth_cluster, restart, [Spec]),
|
||||||
spawn_link(fun() -> emqx_common_test_helpers:start_peer(Name, Opts1) end),
|
timer:sleep(1_000)
|
||||||
timer:sleep(7_000)
|
|
||||||
end
|
end
|
||||||
|| {Name, Opts} <- Specs
|
|| Spec <- Specs
|
||||||
].
|
].
|
||||||
|
|
||||||
cluster(Specs, Config) ->
|
cluster(TC, Specs, Config) ->
|
||||||
PrivDataDir = ?config(priv_dir, Config),
|
Apps = [
|
||||||
Env = [
|
{emqx, #{override_env => [{boot_modules, [broker]}]}},
|
||||||
{emqx, boot_modules, []}
|
{emqx_conf, #{}}
|
||||||
],
|
],
|
||||||
emqx_common_test_helpers:emqx_cluster(Specs, [
|
emqx_cth_cluster:mk_nodespecs(
|
||||||
{env, Env},
|
[{Name, #{role => Role, apps => Apps}} || {Role, Name} <- Specs],
|
||||||
{apps, [emqx_conf]},
|
#{work_dir => emqx_cth_suite:work_dir(TC, Config)}
|
||||||
{load_schema, false},
|
).
|
||||||
{priv_data_dir, PrivDataDir},
|
|
||||||
{env_handler, fun
|
|
||||||
(emqx) ->
|
|
||||||
application:set_env(emqx, boot_modules, []),
|
|
||||||
ok;
|
|
||||||
(_) ->
|
|
||||||
ok
|
|
||||||
end}
|
|
||||||
]).
|
|
||||||
|
|
||||||
cluster_spec({Type, Num}) ->
|
cluster_spec({Type, Num}) ->
|
||||||
{Type, list_to_atom(atom_to_list(?MODULE) ++ integer_to_list(Num))}.
|
{Type, list_to_atom(atom_to_list(?MODULE) ++ integer_to_list(Num))}.
|
||||||
|
|
|
@ -22,12 +22,9 @@
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("stdlib/include/ms_transform.hrl").
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-behaviour(emqx_db_backup).
|
-behaviour(emqx_db_backup).
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
-export([create_tables/0]).
|
||||||
-export([mnesia/1]).
|
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
add_user/4,
|
add_user/4,
|
||||||
|
@ -70,7 +67,7 @@
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?ADMIN, [
|
ok = mria:create_table(?ADMIN, [
|
||||||
{type, set},
|
{type, set},
|
||||||
{rlog_shard, ?DASHBOARD_SHARD},
|
{rlog_shard, ?DASHBOARD_SHARD},
|
||||||
|
@ -83,7 +80,8 @@ mnesia(boot) ->
|
||||||
{write_concurrency, true}
|
{write_concurrency, true}
|
||||||
]}
|
]}
|
||||||
]}
|
]}
|
||||||
]).
|
]),
|
||||||
|
[?ADMIN].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Data backup
|
%% Data backup
|
||||||
|
|
|
@ -26,7 +26,12 @@
|
||||||
-include("emqx_dashboard.hrl").
|
-include("emqx_dashboard.hrl").
|
||||||
|
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
ok = mria_rlog:wait_for_shards([?DASHBOARD_SHARD], infinity),
|
Tables = lists:append([
|
||||||
|
emqx_dashboard_admin:create_tables(),
|
||||||
|
emqx_dashboard_token:create_tables(),
|
||||||
|
emqx_dashboard_monitor:create_tables()
|
||||||
|
]),
|
||||||
|
ok = mria:wait_for_tables(Tables),
|
||||||
{ok, Sup} = emqx_dashboard_sup:start_link(),
|
{ok, Sup} = emqx_dashboard_sup:start_link(),
|
||||||
case emqx_dashboard:start_listeners() of
|
case emqx_dashboard:start_listeners() of
|
||||||
ok ->
|
ok ->
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
|
|
||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
-export([create_tables/0]).
|
||||||
|
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
@ -35,8 +34,6 @@
|
||||||
code_change/3
|
code_change/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([mnesia/1]).
|
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
samplers/0,
|
samplers/0,
|
||||||
samplers/2,
|
samplers/2,
|
||||||
|
@ -67,14 +64,15 @@
|
||||||
data :: map()
|
data :: map()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{type, set},
|
{type, set},
|
||||||
{local_content, true},
|
{local_content, true},
|
||||||
{storage, disc_copies},
|
{storage, disc_copies},
|
||||||
{record_name, emqx_monit},
|
{record_name, emqx_monit},
|
||||||
{attributes, record_info(fields, emqx_monit)}
|
{attributes, record_info(fields, emqx_monit)}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
%% -------------------------------------------------------------------------------------------------
|
%% -------------------------------------------------------------------------------------------------
|
||||||
%% API
|
%% API
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
-include("emqx_dashboard.hrl").
|
-include("emqx_dashboard.hrl").
|
||||||
|
|
||||||
|
-export([create_tables/0]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
sign/2,
|
sign/2,
|
||||||
verify/2,
|
verify/2,
|
||||||
|
@ -27,10 +29,6 @@
|
||||||
destroy_by_username/1
|
destroy_by_username/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-export([mnesia/1]).
|
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
-export([lookup_by_username/1, clean_expired_jwt/1]).
|
-export([lookup_by_username/1, clean_expired_jwt/1]).
|
||||||
-endif.
|
-endif.
|
||||||
|
@ -87,7 +85,7 @@ salt() ->
|
||||||
<<X:16/big-unsigned-integer>> = crypto:strong_rand_bytes(2),
|
<<X:16/big-unsigned-integer>> = crypto:strong_rand_bytes(2),
|
||||||
iolist_to_binary(io_lib:format("~4.16.0b", [X])).
|
iolist_to_binary(io_lib:format("~4.16.0b", [X])).
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{type, set},
|
{type, set},
|
||||||
{rlog_shard, ?DASHBOARD_SHARD},
|
{rlog_shard, ?DASHBOARD_SHARD},
|
||||||
|
@ -100,7 +98,8 @@ mnesia(boot) ->
|
||||||
{write_concurrency, true}
|
{write_concurrency, true}
|
||||||
]}
|
]}
|
||||||
]}
|
]}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% jwt apply
|
%% jwt apply
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
-include_lib("emqx_dashboard/include/emqx_dashboard.hrl").
|
-include_lib("emqx_dashboard/include/emqx_dashboard.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
-import(emqx_dashboard_sso_cli, [admins/1]).
|
-import(emqx_dashboard_sso_cli, [admins/1]).
|
||||||
|
@ -24,15 +25,19 @@
|
||||||
all() -> [t_add, t_passwd, t_del].
|
all() -> [t_add, t_passwd, t_del].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_config:save_schema_mod_and_names(emqx_dashboard_schema),
|
[
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_dashboard, emqx_dashboard_sso]),
|
emqx,
|
||||||
Config.
|
emqx_conf,
|
||||||
|
emqx_dashboard,
|
||||||
|
emqx_dashboard_sso
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(Config) ->
|
||||||
All = emqx_dashboard_admin:all_users(),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
[emqx_dashboard_admin:remove_user(Name) || #{username := Name} <- All],
|
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_dashboard_sso]).
|
|
||||||
|
|
||||||
t_add(_) ->
|
t_add(_) ->
|
||||||
admins(["add", "user1", "password1"]),
|
admins(["add", "user1", "password1"]),
|
||||||
|
|
|
@ -44,31 +44,28 @@ all() ->
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_config:save_schema_mod_and_names(emqx_dashboard_schema),
|
[
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_dashboard, emqx_dashboard_sso]),
|
emqx,
|
||||||
Config.
|
emqx_conf,
|
||||||
|
emqx_management,
|
||||||
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"},
|
||||||
|
emqx_dashboard_sso
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
_ = emqx_common_test_http:create_default_app(),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(Config) ->
|
||||||
All = emqx_dashboard_admin:all_users(),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
[emqx_dashboard_admin:remove_user(Name) || #{username := Name} <- All],
|
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_dashboard_sso]).
|
|
||||||
|
|
||||||
init_per_testcase(Case, Config) ->
|
init_per_testcase(Case, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
|
||||||
?MODULE:Case({init, Config}),
|
?MODULE:Case({init, Config}),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_testcase(Case, Config) ->
|
end_per_testcase(Case, Config) ->
|
||||||
?MODULE:Case({'end', Config}),
|
?MODULE:Case({'end', Config}).
|
||||||
case erlang:whereis(node()) of
|
|
||||||
undefined ->
|
|
||||||
ok;
|
|
||||||
P ->
|
|
||||||
erlang:unlink(P),
|
|
||||||
erlang:exit(P, kill)
|
|
||||||
end,
|
|
||||||
ok.
|
|
||||||
|
|
||||||
t_bad_create({init, Config}) ->
|
t_bad_create({init, Config}) ->
|
||||||
Config;
|
Config;
|
||||||
|
|
|
@ -24,16 +24,11 @@
|
||||||
-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").
|
||||||
-include_lib("emqx/include/emqx_hooks.hrl").
|
-include_lib("emqx/include/emqx_hooks.hrl").
|
||||||
-include_lib("emqx_conf/include/emqx_conf.hrl").
|
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
|
|
||||||
|
|
||||||
-define(OTHER_CLUSTER_NAME_ATOM, test_emqx_cluster).
|
|
||||||
-define(OTHER_CLUSTER_NAME_STRING, "test_emqx_cluster").
|
-define(OTHER_CLUSTER_NAME_STRING, "test_emqx_cluster").
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<
|
-define(CONF_DEFAULT, <<
|
||||||
"\n"
|
|
||||||
"exhook {\n"
|
"exhook {\n"
|
||||||
" servers = [\n"
|
" servers = [\n"
|
||||||
" { name = default,\n"
|
" { name = default,\n"
|
||||||
|
@ -54,8 +49,6 @@
|
||||||
"}\n"
|
"}\n"
|
||||||
>>).
|
>>).
|
||||||
|
|
||||||
-import(emqx_common_test_helpers, [on_exit/1]).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Setups
|
%% Setups
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -63,47 +56,30 @@
|
||||||
all() -> emqx_common_test_helpers:all(?MODULE).
|
all() -> emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Cfg) ->
|
init_per_suite(Cfg) ->
|
||||||
application:load(emqx_conf),
|
|
||||||
ok = ekka:start(),
|
|
||||||
application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
|
|
||||||
ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
|
|
||||||
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
|
||||||
meck:expect(emqx_alarm, activate, 3, ok),
|
|
||||||
meck:expect(emqx_alarm, deactivate, 3, ok),
|
|
||||||
|
|
||||||
_ = emqx_exhook_demo_svr:start(),
|
_ = emqx_exhook_demo_svr:start(),
|
||||||
load_cfg(?CONF_DEFAULT),
|
|
||||||
emqx_common_test_helpers:start_apps([emqx_exhook]),
|
|
||||||
Cfg.
|
Cfg.
|
||||||
|
|
||||||
end_per_suite(_Cfg) ->
|
end_per_suite(_Cfg) ->
|
||||||
application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
|
|
||||||
ekka:stop(),
|
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
meck:unload(emqx_alarm),
|
|
||||||
|
|
||||||
emqx_common_test_helpers:stop_apps([emqx_exhook]),
|
|
||||||
emqx_exhook_demo_svr:stop().
|
emqx_exhook_demo_svr:stop().
|
||||||
|
|
||||||
init_per_testcase(_, Config) ->
|
init_per_testcase(TC, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
Apps = emqx_cth_suite:start(
|
||||||
timer:sleep(200),
|
[
|
||||||
Config.
|
emqx,
|
||||||
|
{emqx_conf, emqx_conf(TC)},
|
||||||
|
{emqx_exhook, ?CONF_DEFAULT}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(TC, Config)}
|
||||||
|
),
|
||||||
|
[{tc_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_testcase(_, _Config) ->
|
end_per_testcase(_, Config) ->
|
||||||
case erlang:whereis(node()) of
|
ok = emqx_cth_suite:stop(?config(tc_apps, Config)).
|
||||||
undefined ->
|
|
||||||
ok;
|
|
||||||
P ->
|
|
||||||
erlang:unlink(P),
|
|
||||||
erlang:exit(P, kill)
|
|
||||||
end,
|
|
||||||
emqx_common_test_helpers:call_janitor(),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
load_cfg(Cfg) ->
|
emqx_conf(t_cluster_name) ->
|
||||||
ok = emqx_common_test_helpers:load_config(emqx_exhook_schema, Cfg).
|
io_lib:format("cluster.name = ~p", [?OTHER_CLUSTER_NAME_STRING]);
|
||||||
|
emqx_conf(_) ->
|
||||||
|
#{}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Test cases
|
%% Test cases
|
||||||
|
@ -320,23 +296,6 @@ t_misc_test(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_cluster_name(_) ->
|
t_cluster_name(_) ->
|
||||||
SetEnvFun =
|
|
||||||
fun
|
|
||||||
(emqx) ->
|
|
||||||
application:set_env(ekka, cluster_name, ?OTHER_CLUSTER_NAME_ATOM);
|
|
||||||
(emqx_exhook) ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
|
|
||||||
stop_apps([emqx, emqx_exhook]),
|
|
||||||
emqx_common_test_helpers:start_apps([emqx, emqx_exhook], SetEnvFun),
|
|
||||||
on_exit(fun() ->
|
|
||||||
stop_apps([emqx, emqx_exhook]),
|
|
||||||
load_cfg(?CONF_DEFAULT),
|
|
||||||
emqx_common_test_helpers:start_apps([emqx_exhook]),
|
|
||||||
mria:wait_for_tables([?CLUSTER_MFA, ?CLUSTER_COMMIT])
|
|
||||||
end),
|
|
||||||
|
|
||||||
?assertEqual(?OTHER_CLUSTER_NAME_STRING, emqx_sys:cluster_name()),
|
?assertEqual(?OTHER_CLUSTER_NAME_STRING, emqx_sys:cluster_name()),
|
||||||
|
|
||||||
emqx_exhook_mgr:disable(<<"default">>),
|
emqx_exhook_mgr:disable(<<"default">>),
|
||||||
|
@ -364,7 +323,7 @@ t_stop_timeout(_) ->
|
||||||
),
|
),
|
||||||
|
|
||||||
%% stop application
|
%% stop application
|
||||||
application:stop(emqx_exhook),
|
ok = application:stop(emqx_exhook),
|
||||||
?block_until(#{?snk_kind := exhook_mgr_terminated}, 20000),
|
?block_until(#{?snk_kind := exhook_mgr_terminated}, 20000),
|
||||||
|
|
||||||
%% all exhook hooked point should be unloaded
|
%% all exhook hooked point should be unloaded
|
||||||
|
@ -379,7 +338,7 @@ t_stop_timeout(_) ->
|
||||||
?assertEqual(false, lists:any(fun(M) -> M == emqx_exhook_handler end, Mods)),
|
?assertEqual(false, lists:any(fun(M) -> M == emqx_exhook_handler end, Mods)),
|
||||||
|
|
||||||
%% ensure started for other tests
|
%% ensure started for other tests
|
||||||
emqx_common_test_helpers:start_apps([emqx_exhook]),
|
{ok, _} = application:ensure_all_started(emqx_exhook),
|
||||||
|
|
||||||
snabbkaffe:stop(),
|
snabbkaffe:stop(),
|
||||||
meck:unload(emqx_exhook_demo_svr).
|
meck:unload(emqx_exhook_demo_svr).
|
||||||
|
@ -510,10 +469,6 @@ data_file(Name) ->
|
||||||
cert_file(Name) ->
|
cert_file(Name) ->
|
||||||
data_file(filename:join(["certs", Name])).
|
data_file(filename:join(["certs", Name])).
|
||||||
|
|
||||||
%% FIXME: this creates inter-test dependency
|
|
||||||
stop_apps(Apps) ->
|
|
||||||
emqx_common_test_helpers:stop_apps(Apps, #{erase_all_configs => false}).
|
|
||||||
|
|
||||||
shuffle(List) ->
|
shuffle(List) ->
|
||||||
Sorted = lists:sort(lists:map(fun(L) -> {rand:uniform(), L} end, List)),
|
Sorted = lists:sort(lists:map(fun(L) -> {rand:uniform(), L} end, List)),
|
||||||
lists:map(fun({_, L}) -> L end, Sorted).
|
lists:map(fun({_, L}) -> L end, Sorted).
|
||||||
|
|
|
@ -20,16 +20,13 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(HOST, "http://127.0.0.1:18083/").
|
-define(HOST, "http://127.0.0.1:18083/").
|
||||||
-define(API_VERSION, "v5").
|
-define(API_VERSION, "v5").
|
||||||
-define(BASE_PATH, "api").
|
-define(BASE_PATH, "api").
|
||||||
-define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
|
|
||||||
|
|
||||||
-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
|
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<
|
-define(CONF_DEFAULT, <<
|
||||||
"\n"
|
|
||||||
"exhook {\n"
|
"exhook {\n"
|
||||||
" servers =\n"
|
" servers =\n"
|
||||||
" [ { name = default,\n"
|
" [ { name = default,\n"
|
||||||
|
@ -56,54 +53,34 @@ all() ->
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
application:load(emqx_conf),
|
|
||||||
ok = ekka:start(),
|
|
||||||
application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
|
|
||||||
ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
|
|
||||||
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
|
||||||
meck:expect(emqx_alarm, activate, 3, ok),
|
|
||||||
meck:expect(emqx_alarm, deactivate, 3, ok),
|
|
||||||
|
|
||||||
_ = emqx_exhook_demo_svr:start(),
|
_ = emqx_exhook_demo_svr:start(),
|
||||||
load_cfg(?CONF_DEFAULT),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_exhook]),
|
[
|
||||||
|
emqx,
|
||||||
|
emqx_conf,
|
||||||
|
emqx_management,
|
||||||
|
{emqx_exhook, ?CONF_DEFAULT},
|
||||||
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
{ok, _} = emqx_common_test_http:create_default_app(),
|
||||||
[Conf] = emqx:get_raw_config([exhook, servers]),
|
[Conf] = emqx:get_raw_config([exhook, servers]),
|
||||||
[{template, Conf} | Config].
|
[{suite_apps, Apps}, {template, Conf} | Config].
|
||||||
|
|
||||||
end_per_suite(Config) ->
|
end_per_suite(Config) ->
|
||||||
application:set_env(ekka, cluster_name, ?DEFAULT_CLUSTER_NAME_ATOM),
|
|
||||||
ekka:stop(),
|
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
meck:unload(emqx_alarm),
|
|
||||||
|
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_exhook]),
|
|
||||||
emqx_exhook_demo_svr:stop(),
|
emqx_exhook_demo_svr:stop(),
|
||||||
emqx_exhook_demo_svr:stop(<<"test1">>),
|
emqx_exhook_demo_svr:stop(<<"test1">>),
|
||||||
Config.
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
init_per_testcase(t_add, Config) ->
|
init_per_testcase(t_add, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
|
||||||
_ = emqx_exhook_demo_svr:start(<<"test1">>, 9001),
|
_ = emqx_exhook_demo_svr:start(<<"test1">>, 9001),
|
||||||
timer:sleep(200),
|
|
||||||
Config;
|
Config;
|
||||||
init_per_testcase(_, Config) ->
|
init_per_testcase(_, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
|
||||||
timer:sleep(200),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_testcase(_, Config) ->
|
end_per_testcase(_, _Config) ->
|
||||||
case erlang:whereis(node()) of
|
ok.
|
||||||
undefined ->
|
|
||||||
ok;
|
|
||||||
P ->
|
|
||||||
erlang:unlink(P),
|
|
||||||
erlang:exit(P, kill)
|
|
||||||
end,
|
|
||||||
Config.
|
|
||||||
|
|
||||||
load_cfg(Cfg) ->
|
|
||||||
ok = emqx_common_test_helpers:load_config(emqx_exhook_schema, Cfg).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Test cases
|
%% Test cases
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
-define(TARGET_HOOK, 'message.publish').
|
-define(TARGET_HOOK, 'message.publish').
|
||||||
|
|
||||||
-define(CONF, <<
|
-define(CONF, <<
|
||||||
"\n"
|
|
||||||
"exhook {\n"
|
"exhook {\n"
|
||||||
" servers = [\n"
|
" servers = [\n"
|
||||||
" { name = succed,\n"
|
" { name = succed,\n"
|
||||||
|
@ -48,24 +47,24 @@
|
||||||
all() -> emqx_common_test_helpers:all(?MODULE).
|
all() -> emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Cfg) ->
|
init_per_suite(Cfg) ->
|
||||||
application:load(emqx_conf),
|
|
||||||
meck:new(emqx_exhook_mgr, [non_strict, passthrough, no_link]),
|
meck:new(emqx_exhook_mgr, [non_strict, passthrough, no_link]),
|
||||||
meck:new(emqx_exhook_demo_svr, [non_strict, passthrough, no_link]),
|
meck:new(emqx_exhook_demo_svr, [non_strict, passthrough, no_link]),
|
||||||
meck:expect(emqx_exhook_mgr, refresh_tick, fun() -> ok end),
|
meck:expect(emqx_exhook_mgr, refresh_tick, fun() -> ok end),
|
||||||
init_injections(hook_injects()),
|
init_injections(hook_injects()),
|
||||||
|
|
||||||
emqx_exhook_SUITE:load_cfg(?CONF),
|
|
||||||
_ = emqx_exhook_demo_svr:start(),
|
_ = emqx_exhook_demo_svr:start(),
|
||||||
_ = emqx_exhook_demo_svr:start(failed, 9001),
|
_ = emqx_exhook_demo_svr:start(failed, 9001),
|
||||||
emqx_common_test_helpers:start_apps([emqx_exhook]),
|
Apps = emqx_cth_suite:start(
|
||||||
Cfg.
|
[emqx, {emqx_exhook, ?CONF}],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Cfg)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Cfg].
|
||||||
|
|
||||||
end_per_suite(_Cfg) ->
|
end_per_suite(Cfg) ->
|
||||||
meck:unload(emqx_exhook_demo_svr),
|
meck:unload(emqx_exhook_demo_svr),
|
||||||
meck:unload(emqx_exhook_mgr),
|
meck:unload(emqx_exhook_mgr),
|
||||||
emqx_exhook_demo_svr:stop(),
|
emqx_exhook_demo_svr:stop(),
|
||||||
emqx_exhook_demo_svr:stop(failed),
|
emqx_exhook_demo_svr:stop(failed),
|
||||||
emqx_common_test_helpers:stop_apps([emqx_exhook]).
|
ok = emqx_cth_suite:stop(?config(suite_apps, Cfg)).
|
||||||
|
|
||||||
init_per_testcase(_, Config) ->
|
init_per_testcase(_, Config) ->
|
||||||
clear_metrics(),
|
clear_metrics(),
|
||||||
|
|
|
@ -17,121 +17,32 @@ all() ->
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_license_test_lib:mock_parser(),
|
emqx_license_test_lib:mock_parser(),
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_config:save_schema_mod_and_names(emqx_license_schema),
|
[
|
||||||
emqx_common_test_helpers:start_apps([emqx_license], fun set_special_configs/1),
|
emqx,
|
||||||
Config.
|
emqx_conf,
|
||||||
|
{emqx_license, "license { key = \"default\" }"}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_license_test_lib:unmock_parser(),
|
emqx_license_test_lib:unmock_parser(),
|
||||||
emqx_common_test_helpers:stop_apps([emqx_license]),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
ok.
|
|
||||||
|
|
||||||
init_per_testcase(Case, Config) ->
|
init_per_testcase(Case, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
|
setup_test(Case, Config) ++ Config.
|
||||||
Paths = set_override_paths(Case),
|
|
||||||
Config0 = setup_test(Case, Config),
|
|
||||||
Paths ++ Config0 ++ Config.
|
|
||||||
|
|
||||||
end_per_testcase(Case, Config) ->
|
end_per_testcase(Case, Config) ->
|
||||||
clean_overrides(Case, Config),
|
teardown_test(Case, Config).
|
||||||
teardown_test(Case, Config),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
set_override_paths(_TestCase) ->
|
|
||||||
[].
|
|
||||||
|
|
||||||
clean_overrides(_TestCase, _Config) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
setup_test(TestCase, Config) when
|
|
||||||
TestCase =:= t_update_file_cluster_backup
|
|
||||||
->
|
|
||||||
DataDir = ?config(data_dir, Config),
|
|
||||||
{LicenseKey, _License} = mk_license(
|
|
||||||
[
|
|
||||||
%% license format version
|
|
||||||
"220111",
|
|
||||||
%% license type
|
|
||||||
"0",
|
|
||||||
%% customer type
|
|
||||||
"10",
|
|
||||||
%% customer name
|
|
||||||
"Foo",
|
|
||||||
%% customer email
|
|
||||||
"contact@foo.com",
|
|
||||||
%% deplayment name
|
|
||||||
"bar-deployment",
|
|
||||||
%% start date
|
|
||||||
"20220111",
|
|
||||||
%% days
|
|
||||||
"100000",
|
|
||||||
%% max connections
|
|
||||||
"19"
|
|
||||||
]
|
|
||||||
),
|
|
||||||
Cluster = emqx_common_test_helpers:emqx_cluster(
|
|
||||||
[core, core],
|
|
||||||
[
|
|
||||||
{apps, [emqx_conf, emqx_license]},
|
|
||||||
{load_schema, false},
|
|
||||||
{schema_mod, emqx_enterprise_schema},
|
|
||||||
{env_handler, fun
|
|
||||||
(emqx) ->
|
|
||||||
emqx_config:save_schema_mod_and_names(emqx_enterprise_schema),
|
|
||||||
%% emqx_config:save_schema_mod_and_names(emqx_license_schema),
|
|
||||||
application:set_env(emqx, boot_modules, []),
|
|
||||||
application:set_env(
|
|
||||||
emqx,
|
|
||||||
data_dir,
|
|
||||||
filename:join([
|
|
||||||
DataDir,
|
|
||||||
TestCase,
|
|
||||||
node()
|
|
||||||
])
|
|
||||||
),
|
|
||||||
ok;
|
|
||||||
(emqx_conf) ->
|
|
||||||
emqx_config:save_schema_mod_and_names(emqx_enterprise_schema),
|
|
||||||
%% emqx_config:save_schema_mod_and_names(emqx_license_schema),
|
|
||||||
application:set_env(
|
|
||||||
emqx,
|
|
||||||
data_dir,
|
|
||||||
filename:join([
|
|
||||||
DataDir,
|
|
||||||
TestCase,
|
|
||||||
node()
|
|
||||||
])
|
|
||||||
),
|
|
||||||
ok;
|
|
||||||
(emqx_license) ->
|
|
||||||
set_special_configs(emqx_license),
|
|
||||||
ok;
|
|
||||||
(_) ->
|
|
||||||
ok
|
|
||||||
end}
|
|
||||||
]
|
|
||||||
),
|
|
||||||
Nodes = [emqx_common_test_helpers:start_peer(Name, Opts) || {Name, Opts} <- Cluster],
|
|
||||||
[{nodes, Nodes}, {cluster, Cluster}, {old_license, LicenseKey}];
|
|
||||||
setup_test(_TestCase, _Config) ->
|
setup_test(_TestCase, _Config) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
teardown_test(_TestCase, _Config) ->
|
teardown_test(_TestCase, _Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
set_special_configs(emqx_license) ->
|
|
||||||
Config = #{key => default},
|
|
||||||
emqx_config:put([license], Config),
|
|
||||||
RawConfig = #{<<"key">> => <<"default">>},
|
|
||||||
emqx_config:put_raw([<<"license">>], RawConfig);
|
|
||||||
set_special_configs(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
assert_on_nodes(Nodes, RunFun, CheckFun) ->
|
|
||||||
Res = [{N, erpc:call(N, RunFun)} || N <- Nodes],
|
|
||||||
lists:foreach(CheckFun, Res).
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Tests
|
%% Tests
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
|
@ -14,34 +14,35 @@
|
||||||
all() ->
|
all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(CtConfig) ->
|
init_per_suite(Config) ->
|
||||||
_ = application:load(emqx_conf),
|
|
||||||
emqx_license_test_lib:mock_parser(),
|
emqx_license_test_lib:mock_parser(),
|
||||||
ok = emqx_common_test_helpers:start_apps([emqx_license], fun set_special_configs/1),
|
Apps = emqx_cth_suite:start(
|
||||||
CtConfig.
|
[
|
||||||
|
emqx,
|
||||||
|
emqx_conf,
|
||||||
|
{emqx_license, #{
|
||||||
|
config => #{license => #{key => emqx_license_test_lib:default_test_license()}}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_license_test_lib:unmock_parser(),
|
emqx_license_test_lib:unmock_parser(),
|
||||||
ok = emqx_common_test_helpers:stop_apps([emqx_license]).
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
init_per_testcase(t_default_limits, Config) ->
|
init_per_testcase(t_default_limits, Config) ->
|
||||||
ok = emqx_common_test_helpers:stop_apps([emqx_license]),
|
ok = application:stop(emqx_license),
|
||||||
Config;
|
Config;
|
||||||
init_per_testcase(_Case, Config) ->
|
init_per_testcase(_Case, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_testcase(t_default_limits, _Config) ->
|
end_per_testcase(t_default_limits, _Config) ->
|
||||||
ok = emqx_common_test_helpers:start_apps([emqx_license], fun set_special_configs/1);
|
{ok, _} = application:ensure_all_started(emqx_license);
|
||||||
end_per_testcase(_Case, _Config) ->
|
end_per_testcase(_Case, _Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
set_special_configs(emqx_license) ->
|
|
||||||
Config = #{key => emqx_license_test_lib:default_test_license()},
|
|
||||||
emqx_config:put([license], Config);
|
|
||||||
set_special_configs(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Tests
|
%% Tests
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
|
@ -14,32 +14,29 @@ all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_config:save_schema_mod_and_names(emqx_license_schema),
|
[
|
||||||
emqx_common_test_helpers:start_apps([emqx_license], fun set_special_configs/1),
|
emqx,
|
||||||
Config.
|
emqx_conf,
|
||||||
|
{emqx_license, #{
|
||||||
|
config => #{license => #{key => emqx_license_test_lib:default_license()}}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:stop_apps([emqx_license]),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
ok.
|
|
||||||
|
|
||||||
init_per_testcase(_Case, Config) ->
|
init_per_testcase(_Case, Config) ->
|
||||||
emqx_license_test_lib:mock_parser(),
|
emqx_license_test_lib:mock_parser(),
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_testcase(_Case, _Config) ->
|
end_per_testcase(_Case, _Config) ->
|
||||||
emqx_license_test_lib:unmock_parser(),
|
emqx_license_test_lib:unmock_parser(),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
set_special_configs(emqx_license) ->
|
|
||||||
Config = #{key => emqx_license_test_lib:default_license()},
|
|
||||||
emqx_config:put([license], Config),
|
|
||||||
RawConfig = #{<<"key">> => emqx_license_test_lib:default_license()},
|
|
||||||
emqx_config:put_raw([<<"license">>], RawConfig);
|
|
||||||
set_special_configs(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Tests
|
%% Tests
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
|
|
||||||
-include_lib("emqx/include/emqx_mqtt.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").
|
||||||
|
|
||||||
|
@ -20,41 +19,34 @@ all() ->
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_license_test_lib:mock_parser(),
|
emqx_license_test_lib:mock_parser(),
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_config:save_schema_mod_and_names(emqx_license_schema),
|
[
|
||||||
emqx_common_test_helpers:start_apps([emqx_license, emqx_dashboard], fun set_special_configs/1),
|
emqx,
|
||||||
Config.
|
emqx_conf,
|
||||||
|
{emqx_license, #{
|
||||||
|
config => #{
|
||||||
|
license => #{
|
||||||
|
key => emqx_license_test_lib:make_license(#{max_connections => "100"}),
|
||||||
|
connection_low_watermark => <<"75%">>,
|
||||||
|
connection_high_watermark => <<"80%">>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{emqx_dashboard,
|
||||||
|
"dashboard {"
|
||||||
|
"\n listeners.http { enable = true, bind = 18083 }"
|
||||||
|
"\n default_username = \"license_admin\""
|
||||||
|
"\n}"}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:stop_apps([emqx_license, emqx_dashboard]),
|
|
||||||
LicenseKey = emqx_license_test_lib:make_license(#{max_connections => "100"}),
|
|
||||||
Config = #{key => LicenseKey},
|
|
||||||
emqx_config:put([license], Config),
|
|
||||||
RawConfig = #{<<"key">> => LicenseKey},
|
|
||||||
emqx_config:put_raw([<<"license">>], RawConfig),
|
|
||||||
emqx_license_test_lib:unmock_parser(),
|
emqx_license_test_lib:unmock_parser(),
|
||||||
ok.
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
set_special_configs(emqx_dashboard) ->
|
|
||||||
emqx_dashboard_api_test_helpers:set_default_config(<<"license_admin">>);
|
|
||||||
set_special_configs(emqx_license) ->
|
|
||||||
LicenseKey = emqx_license_test_lib:make_license(#{max_connections => "100"}),
|
|
||||||
Config = #{
|
|
||||||
key => LicenseKey, connection_low_watermark => 0.75, connection_high_watermark => 0.8
|
|
||||||
},
|
|
||||||
emqx_config:put([license], Config),
|
|
||||||
RawConfig = #{
|
|
||||||
<<"key">> => LicenseKey,
|
|
||||||
<<"connection_low_watermark">> => <<"75%">>,
|
|
||||||
<<"connection_high_watermark">> => <<"80%">>
|
|
||||||
},
|
|
||||||
emqx_config:put_raw([<<"license">>], RawConfig),
|
|
||||||
ok;
|
|
||||||
set_special_configs(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
init_per_testcase(_TestCase, Config) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_testcase(_TestCase, _Config) ->
|
end_per_testcase(_TestCase, _Config) ->
|
||||||
|
|
|
@ -14,26 +14,20 @@ all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_common_test_helpers:start_apps([emqx_license], fun set_special_configs/1),
|
[
|
||||||
Config.
|
emqx,
|
||||||
|
emqx_conf,
|
||||||
|
{emqx_license, #{
|
||||||
|
config => #{license => #{key => emqx_license_test_lib:default_license()}}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:stop_apps([emqx_license]),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
ok.
|
|
||||||
|
|
||||||
init_per_testcase(_Case, Config) ->
|
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
|
|
||||||
Config.
|
|
||||||
|
|
||||||
end_per_testcase(_Case, _Config) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
set_special_configs(emqx_license) ->
|
|
||||||
Config = #{key => emqx_license_test_lib:default_license()},
|
|
||||||
emqx_config:put([license], Config);
|
|
||||||
set_special_configs(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Tests
|
%% Tests
|
||||||
|
|
|
@ -15,26 +15,20 @@ all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
_ = application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_common_test_helpers:start_apps([emqx_license], fun set_special_configs/1),
|
[
|
||||||
Config.
|
emqx,
|
||||||
|
emqx_conf,
|
||||||
|
{emqx_license, #{
|
||||||
|
config => #{license => #{key => emqx_license_test_lib:default_license()}}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:stop_apps([emqx_license]),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
ok.
|
|
||||||
|
|
||||||
init_per_testcase(_Case, Config) ->
|
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
|
|
||||||
Config.
|
|
||||||
|
|
||||||
end_per_testcase(_Case, _Config) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
set_special_configs(emqx_license) ->
|
|
||||||
Config = #{key => emqx_license_test_lib:default_license()},
|
|
||||||
emqx_config:put([license], Config);
|
|
||||||
set_special_configs(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Tests
|
%% Tests
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
-include("emqx_mgmt.hrl").
|
-include("emqx_mgmt.hrl").
|
||||||
|
|
||||||
start(_Type, _Args) ->
|
start(_Type, _Args) ->
|
||||||
|
ok = mria:wait_for_tables(emqx_mgmt_auth:create_tables()),
|
||||||
case emqx_mgmt_auth:init_bootstrap_file() of
|
case emqx_mgmt_auth:init_bootstrap_file() of
|
||||||
ok ->
|
ok ->
|
||||||
emqx_conf:add_handler([api_key], emqx_mgmt_auth),
|
emqx_conf:add_handler([api_key], emqx_mgmt_auth),
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
-behaviour(emqx_db_backup).
|
-behaviour(emqx_db_backup).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([mnesia/1]).
|
-export([create_tables/0]).
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
-behaviour(emqx_config_handler).
|
-behaviour(emqx_config_handler).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
-define(DEFAULT_HASH_LEN, 16).
|
-define(DEFAULT_HASH_LEN, 16).
|
||||||
|
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
Fields = record_info(fields, ?APP),
|
Fields = record_info(fields, ?APP),
|
||||||
ok = mria:create_table(?APP, [
|
ok = mria:create_table(?APP, [
|
||||||
{type, set},
|
{type, set},
|
||||||
|
@ -78,7 +78,8 @@ mnesia(boot) ->
|
||||||
{storage, disc_copies},
|
{storage, disc_copies},
|
||||||
{record_name, ?APP},
|
{record_name, ?APP},
|
||||||
{attributes, Fields}
|
{attributes, Fields}
|
||||||
]).
|
]),
|
||||||
|
[?APP].
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Data backup
|
%% Data backup
|
||||||
|
|
|
@ -37,13 +37,27 @@ end_per_suite(_) ->
|
||||||
%% cases
|
%% cases
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
t_cluster_query(_Config) ->
|
t_cluster_query(Config) ->
|
||||||
net_kernel:start(['master@127.0.0.1', longnames]),
|
net_kernel:start(['master@127.0.0.1', longnames]),
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
snabbkaffe:fix_ct_logging(),
|
||||||
[{Name, Opts}, {Name1, Opts1}] = cluster_specs(),
|
ListenerConf = fun(Port) ->
|
||||||
Node1 = emqx_common_test_helpers:start_peer(Name, Opts),
|
io_lib:format(
|
||||||
Node2 = emqx_common_test_helpers:start_peer(Name1, Opts1),
|
"\n listeners.tcp.default.bind = ~p"
|
||||||
|
"\n listeners.ssl.default.enable = false"
|
||||||
|
"\n listeners.ws.default.enable = false"
|
||||||
|
"\n listeners.wss.default.enable = false",
|
||||||
|
[Port]
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
Nodes =
|
||||||
|
[Node1, Node2] = emqx_cth_cluster:start(
|
||||||
|
[
|
||||||
|
{corenode1, #{role => core, apps => [{emqx, ListenerConf(2883)}, emqx_management]}},
|
||||||
|
{corenode2, #{role => core, apps => [{emqx, ListenerConf(3883)}, emqx_management]}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)}
|
||||||
|
),
|
||||||
try
|
try
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
ClientLs1 = [start_emqtt_client(Node1, I, 2883) || I <- lists:seq(1, 10)],
|
ClientLs1 = [start_emqtt_client(Node1, I, 2883) || I <- lists:seq(1, 10)],
|
||||||
|
@ -168,13 +182,19 @@ t_cluster_query(_Config) ->
|
||||||
_ = lists:foreach(fun(C) -> emqtt:disconnect(C) end, ClientLs1),
|
_ = lists:foreach(fun(C) -> emqtt:disconnect(C) end, ClientLs1),
|
||||||
_ = lists:foreach(fun(C) -> emqtt:disconnect(C) end, ClientLs2)
|
_ = lists:foreach(fun(C) -> emqtt:disconnect(C) end, ClientLs2)
|
||||||
after
|
after
|
||||||
emqx_common_test_helpers:stop_peer(Node1),
|
emqx_cth_cluster:stop(Nodes)
|
||||||
emqx_common_test_helpers:stop_peer(Node2)
|
end.
|
||||||
end,
|
|
||||||
ok.
|
|
||||||
|
|
||||||
t_bad_rpc(_) ->
|
t_bad_rpc(Config) ->
|
||||||
emqx_mgmt_api_test_util:init_suite(),
|
Apps = emqx_cth_suite:start(
|
||||||
|
[
|
||||||
|
emqx,
|
||||||
|
emqx_management,
|
||||||
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)}
|
||||||
|
),
|
||||||
|
{ok, _} = emqx_common_test_http:create_default_app(),
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
ClientLs1 = [start_emqtt_client(node(), I, 1883) || I <- lists:seq(1, 10)],
|
ClientLs1 = [start_emqtt_client(node(), I, 1883) || I <- lists:seq(1, 10)],
|
||||||
Path = emqx_mgmt_api_test_util:api_path(["clients?limit=2&page=2"]),
|
Path = emqx_mgmt_api_test_util:api_path(["clients?limit=2&page=2"]),
|
||||||
|
@ -187,35 +207,13 @@ t_bad_rpc(_) ->
|
||||||
after
|
after
|
||||||
_ = lists:foreach(fun(C) -> emqtt:disconnect(C) end, ClientLs1),
|
_ = lists:foreach(fun(C) -> emqtt:disconnect(C) end, ClientLs1),
|
||||||
meck:unload(emqx),
|
meck:unload(emqx),
|
||||||
emqx_mgmt_api_test_util:end_suite()
|
emqx_cth_suite:stop(Apps)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% helpers
|
%% helpers
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
cluster_specs() ->
|
|
||||||
Specs =
|
|
||||||
%% default listeners port
|
|
||||||
[
|
|
||||||
{core, corenode1, #{listener_ports => [{tcp, 2883}]}},
|
|
||||||
{core, corenode2, #{listener_ports => [{tcp, 3883}]}}
|
|
||||||
],
|
|
||||||
CommOpts =
|
|
||||||
[
|
|
||||||
{env, [{emqx, boot_modules, all}]},
|
|
||||||
{apps, []},
|
|
||||||
{conf, [
|
|
||||||
{[listeners, ssl, default, enable], false},
|
|
||||||
{[listeners, ws, default, enable], false},
|
|
||||||
{[listeners, wss, default, enable], false}
|
|
||||||
]}
|
|
||||||
],
|
|
||||||
emqx_common_test_helpers:emqx_cluster(
|
|
||||||
Specs,
|
|
||||||
CommOpts
|
|
||||||
).
|
|
||||||
|
|
||||||
start_emqtt_client(Node0, N, Port) ->
|
start_emqtt_client(Node0, N, Port) ->
|
||||||
Node = atom_to_binary(Node0),
|
Node = atom_to_binary(Node0),
|
||||||
ClientId = iolist_to_binary([Node, "-", integer_to_binary(N)]),
|
ClientId = iolist_to_binary([Node, "-", integer_to_binary(N)]),
|
||||||
|
|
|
@ -27,14 +27,19 @@
|
||||||
all() ->
|
all() ->
|
||||||
[
|
[
|
||||||
{group, with_defaults_in_file},
|
{group, with_defaults_in_file},
|
||||||
{group, without_defaults_in_file}
|
{group, without_defaults_in_file},
|
||||||
|
{group, max_connections}
|
||||||
].
|
].
|
||||||
|
|
||||||
groups() ->
|
groups() ->
|
||||||
AllTests = emqx_common_test_helpers:all(?MODULE),
|
AllTests = emqx_common_test_helpers:all(?MODULE),
|
||||||
|
MaxConnTests = [
|
||||||
|
t_max_connection_default
|
||||||
|
],
|
||||||
[
|
[
|
||||||
{with_defaults_in_file, AllTests},
|
{with_defaults_in_file, AllTests -- MaxConnTests},
|
||||||
{without_defaults_in_file, AllTests}
|
{without_defaults_in_file, AllTests -- MaxConnTests},
|
||||||
|
{max_connections, MaxConnTests}
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
|
@ -44,29 +49,39 @@ end_per_suite(_Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_group(without_defaults_in_file, Config) ->
|
init_per_group(without_defaults_in_file, Config) ->
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_conf]),
|
init_group_apps(#{}, Config);
|
||||||
Config;
|
|
||||||
init_per_group(with_defaults_in_file, Config) ->
|
init_per_group(with_defaults_in_file, Config) ->
|
||||||
%% we have to materialize the config file with default values for this test group
|
%% we have to materialize the config file with default values for this test group
|
||||||
%% because we want to test the deletion of non-existing listener
|
%% because we want to test the deletion of non-existing listener
|
||||||
%% if there is no config file, the such deletion would result in a deletion
|
%% if there is no config file, the such deletion would result in a deletion
|
||||||
%% of the default listener.
|
%% of the default listener.
|
||||||
Name = atom_to_list(?MODULE) ++ "-default-listeners",
|
PrivDir = ?config(priv_dir, Config),
|
||||||
TmpConfFullPath = inject_tmp_config_content(Name, default_listeners_hocon_text()),
|
FileName = filename:join([PrivDir, "etc", atom_to_list(?MODULE) ++ "-default-listeners"]),
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_conf]),
|
ok = filelib:ensure_dir(FileName),
|
||||||
[{injected_conf_file, TmpConfFullPath} | Config].
|
ok = file:write_file(FileName, default_listeners_hocon_text()),
|
||||||
|
init_group_apps("include \"" ++ FileName ++ "\"", Config);
|
||||||
|
init_per_group(max_connections, Config) ->
|
||||||
|
init_group_apps(
|
||||||
|
io_lib:format("listeners.tcp.max_connection_test {bind = \"0.0.0.0:~p\"}", [?PORT]),
|
||||||
|
Config
|
||||||
|
).
|
||||||
|
|
||||||
end_per_group(Group, Config) ->
|
init_group_apps(Config, CTConfig) ->
|
||||||
emqx_conf:tombstone([listeners, tcp, new], #{override_to => cluster}),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_conf:tombstone([listeners, tcp, new1], #{override_to => local}),
|
[
|
||||||
case Group =:= with_defaults_in_file of
|
{emqx_conf, Config},
|
||||||
true ->
|
emqx_management,
|
||||||
{_, File} = lists:keyfind(injected_conf_file, 1, Config),
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||||
ok = file:delete(File);
|
],
|
||||||
false ->
|
#{
|
||||||
ok
|
work_dir => emqx_cth_suite:work_dir(CTConfig)
|
||||||
end,
|
}
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_conf]).
|
),
|
||||||
|
{ok, _} = emqx_common_test_http:create_default_app(),
|
||||||
|
[{suite_apps, Apps} | CTConfig].
|
||||||
|
|
||||||
|
end_per_group(_Group, Config) ->
|
||||||
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
init_per_testcase(Case, Config) ->
|
init_per_testcase(Case, Config) ->
|
||||||
try
|
try
|
||||||
|
@ -84,16 +99,6 @@ end_per_testcase(Case, Config) ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
t_max_connection_default({init, Config}) ->
|
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_conf]),
|
|
||||||
Port = integer_to_binary(?PORT),
|
|
||||||
Bin = <<"listeners.tcp.max_connection_test {bind = \"0.0.0.0:", Port/binary, "\"}">>,
|
|
||||||
TmpConfName = atom_to_list(?FUNCTION_NAME) ++ ".conf",
|
|
||||||
TmpConfFullPath = inject_tmp_config_content(TmpConfName, Bin),
|
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_conf]),
|
|
||||||
[{tmp_config_file, TmpConfFullPath} | Config];
|
|
||||||
t_max_connection_default({'end', Config}) ->
|
|
||||||
ok = file:delete(proplists:get_value(tmp_config_file, Config));
|
|
||||||
t_max_connection_default(Config) when is_list(Config) ->
|
t_max_connection_default(Config) when is_list(Config) ->
|
||||||
#{<<"listeners">> := Listeners} = emqx_mgmt_api_listeners:do_list_listeners(),
|
#{<<"listeners">> := Listeners} = emqx_mgmt_api_listeners:do_list_listeners(),
|
||||||
Target = lists:filter(
|
Target = lists:filter(
|
||||||
|
@ -189,13 +194,19 @@ t_wss_crud_listeners_by_id(Config) when is_list(Config) ->
|
||||||
crud_listeners_by_id(ListenerId, NewListenerId, MinListenerId, BadId, Type, 34000).
|
crud_listeners_by_id(ListenerId, NewListenerId, MinListenerId, BadId, Type, 34000).
|
||||||
|
|
||||||
t_api_listeners_list_not_ready(Config) when is_list(Config) ->
|
t_api_listeners_list_not_ready(Config) when is_list(Config) ->
|
||||||
net_kernel:start(['listeners@127.0.0.1', longnames]),
|
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
Apps = [
|
||||||
Cluster = [{Name, Opts}, {Name1, Opts1}] = cluster([core, core]),
|
{emqx, #{after_start => fun() -> emqx_app:set_config_loader(emqx) end}},
|
||||||
ct:pal("Starting ~p", [Cluster]),
|
{emqx_conf, #{}}
|
||||||
Node1 = emqx_common_test_helpers:start_peer(Name, Opts),
|
],
|
||||||
Node2 = emqx_common_test_helpers:start_peer(Name1, Opts1),
|
Nodes =
|
||||||
|
[Node1, Node2] = emqx_cth_cluster:start(
|
||||||
|
[
|
||||||
|
{t_api_listeners_list_not_ready1, #{role => core, apps => Apps}},
|
||||||
|
{t_api_listeners_list_not_ready2, #{role => core, apps => Apps}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)}
|
||||||
|
),
|
||||||
try
|
try
|
||||||
L1 = get_tcp_listeners(Node1),
|
L1 = get_tcp_listeners(Node1),
|
||||||
|
|
||||||
|
@ -214,8 +225,7 @@ t_api_listeners_list_not_ready(Config) when is_list(Config) ->
|
||||||
?assert(length(L1) > length(L2), Comment),
|
?assert(length(L1) > length(L2), Comment),
|
||||||
?assertEqual(length(L2), length(L3), Comment)
|
?assertEqual(length(L2), length(L3), Comment)
|
||||||
after
|
after
|
||||||
emqx_common_test_helpers:stop_peer(Node1),
|
emqx_cth_cluster:stop(Nodes)
|
||||||
emqx_common_test_helpers:stop_peer(Node2)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
t_clear_certs(Config) when is_list(Config) ->
|
t_clear_certs(Config) when is_list(Config) ->
|
||||||
|
@ -296,25 +306,6 @@ assert_config_load_not_done(Node) ->
|
||||||
Prio = rpc:call(Node, emqx_app, get_config_loader, []),
|
Prio = rpc:call(Node, emqx_app, get_config_loader, []),
|
||||||
?assertEqual(emqx, Prio, #{node => Node}).
|
?assertEqual(emqx, Prio, #{node => Node}).
|
||||||
|
|
||||||
cluster(Specs) ->
|
|
||||||
Env = [
|
|
||||||
{emqx, boot_modules, []}
|
|
||||||
],
|
|
||||||
emqx_common_test_helpers:emqx_cluster(Specs, [
|
|
||||||
{env, Env},
|
|
||||||
{apps, [emqx_conf]},
|
|
||||||
{load_schema, false},
|
|
||||||
{env_handler, fun
|
|
||||||
(emqx) ->
|
|
||||||
application:set_env(emqx, boot_modules, []),
|
|
||||||
%% test init_config not ready.
|
|
||||||
emqx_app:set_config_loader(emqx),
|
|
||||||
ok;
|
|
||||||
(_) ->
|
|
||||||
ok
|
|
||||||
end}
|
|
||||||
]).
|
|
||||||
|
|
||||||
crud_listeners_by_id(ListenerId, NewListenerId, MinListenerId, BadId, Type, PortBase) ->
|
crud_listeners_by_id(ListenerId, NewListenerId, MinListenerId, BadId, Type, PortBase) ->
|
||||||
OriginPath = emqx_mgmt_api_test_util:api_path(["listeners", ListenerId]),
|
OriginPath = emqx_mgmt_api_test_util:api_path(["listeners", ListenerId]),
|
||||||
NewPath = emqx_mgmt_api_test_util:api_path(["listeners", NewListenerId]),
|
NewPath = emqx_mgmt_api_test_util:api_path(["listeners", NewListenerId]),
|
||||||
|
@ -529,15 +520,3 @@ default_listeners_hocon_text() ->
|
||||||
Listeners = hocon_tconf:make_serializable(Sc, #{}, #{}),
|
Listeners = hocon_tconf:make_serializable(Sc, #{}, #{}),
|
||||||
Config = #{<<"listeners">> => Listeners},
|
Config = #{<<"listeners">> => Listeners},
|
||||||
hocon_pp:do(Config, #{}).
|
hocon_pp:do(Config, #{}).
|
||||||
|
|
||||||
%% inject a 'include' at the end of emqx.conf.all
|
|
||||||
%% the 'include' can be kept after test,
|
|
||||||
%% as long as the file has been deleted it is a no-op
|
|
||||||
inject_tmp_config_content(TmpFile, Content) ->
|
|
||||||
Etc = filename:join(["etc", "emqx.conf.all"]),
|
|
||||||
Inc = filename:join(["etc", TmpFile]),
|
|
||||||
ConfFile = emqx_common_test_helpers:app_path(emqx_conf, Etc),
|
|
||||||
TmpFileFullPath = emqx_common_test_helpers:app_path(emqx_conf, Inc),
|
|
||||||
ok = file:write_file(TmpFileFullPath, Content),
|
|
||||||
ok = file:write_file(ConfFile, ["\ninclude \"", TmpFileFullPath, "\"\n"], [append]),
|
|
||||||
TmpFileFullPath.
|
|
||||||
|
|
|
@ -19,16 +19,25 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_management]),
|
Apps = emqx_cth_suite:start(
|
||||||
Config.
|
[
|
||||||
|
emqx_conf,
|
||||||
|
emqx_management,
|
||||||
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
{ok, _} = emqx_common_test_http:create_default_app(),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_management, emqx_conf]).
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
init_per_testcase(t_log_path, Config) ->
|
init_per_testcase(t_log_path, Config) ->
|
||||||
emqx_config_logger:add_handler(),
|
emqx_config_logger:add_handler(),
|
||||||
|
@ -121,16 +130,17 @@ t_node_metrics_api(_) ->
|
||||||
emqx_mgmt_api_test_util:request_api(get, BadNodePath)
|
emqx_mgmt_api_test_util:request_api(get, BadNodePath)
|
||||||
).
|
).
|
||||||
|
|
||||||
t_multiple_nodes_api(_) ->
|
t_multiple_nodes_api(Config) ->
|
||||||
net_kernel:start(['node_api@127.0.0.1', longnames]),
|
|
||||||
ct:timetrap({seconds, 120}),
|
ct:timetrap({seconds, 120}),
|
||||||
snabbkaffe:fix_ct_logging(),
|
snabbkaffe:fix_ct_logging(),
|
||||||
Seq1 = list_to_atom(atom_to_list(?MODULE) ++ "1"),
|
Nodes =
|
||||||
Seq2 = list_to_atom(atom_to_list(?MODULE) ++ "2"),
|
[Node1, Node2] = emqx_cth_cluster:start(
|
||||||
Cluster = [{Name, Opts}, {Name1, Opts1}] = cluster([{core, Seq1}, {core, Seq2}]),
|
[
|
||||||
ct:pal("Starting ~p", [Cluster]),
|
{t_multiple_nodes_api1, #{role => core, apps => [emqx_conf, emqx_management]}},
|
||||||
Node1 = emqx_common_test_helpers:start_peer(Name, Opts),
|
{t_multiple_nodes_api2, #{role => core, apps => [emqx_conf, emqx_management]}}
|
||||||
Node2 = emqx_common_test_helpers:start_peer(Name1, Opts1),
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)}
|
||||||
|
),
|
||||||
try
|
try
|
||||||
{200, NodesList} = rpc:call(Node1, emqx_mgmt_api_nodes, nodes, [get, #{}]),
|
{200, NodesList} = rpc:call(Node1, emqx_mgmt_api_nodes, nodes, [get, #{}]),
|
||||||
All = [Node1, Node2],
|
All = [Node1, Node2],
|
||||||
|
@ -148,22 +158,6 @@ t_multiple_nodes_api(_) ->
|
||||||
]),
|
]),
|
||||||
?assertMatch(#{node := Node1}, Node11)
|
?assertMatch(#{node := Node1}, Node11)
|
||||||
after
|
after
|
||||||
emqx_common_test_helpers:stop_peer(Node1),
|
emqx_cth_cluster:stop(Nodes)
|
||||||
emqx_common_test_helpers:stop_peer(Node2)
|
|
||||||
end,
|
end,
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
cluster(Specs) ->
|
|
||||||
Env = [{emqx, boot_modules, []}],
|
|
||||||
emqx_common_test_helpers:emqx_cluster(Specs, [
|
|
||||||
{env, Env},
|
|
||||||
{apps, [emqx_conf, emqx_management]},
|
|
||||||
{load_schema, false},
|
|
||||||
{env_handler, fun
|
|
||||||
(emqx) ->
|
|
||||||
application:set_env(emqx, boot_modules, []),
|
|
||||||
ok;
|
|
||||||
(_) ->
|
|
||||||
ok
|
|
||||||
end}
|
|
||||||
]).
|
|
||||||
|
|
|
@ -30,8 +30,9 @@ init_suite(Apps, SetConfigs) when is_function(SetConfigs) ->
|
||||||
init_suite(Apps, SetConfigs, #{}).
|
init_suite(Apps, SetConfigs, #{}).
|
||||||
|
|
||||||
init_suite(Apps, SetConfigs, Opts) ->
|
init_suite(Apps, SetConfigs, Opts) ->
|
||||||
application:load(emqx_management),
|
emqx_common_test_helpers:start_apps(
|
||||||
emqx_common_test_helpers:start_apps(Apps ++ [emqx_dashboard], SetConfigs, Opts),
|
Apps ++ [emqx_management, emqx_dashboard], SetConfigs, Opts
|
||||||
|
),
|
||||||
_ = emqx_common_test_http:create_default_app(),
|
_ = emqx_common_test_http:create_default_app(),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -40,8 +41,7 @@ end_suite() ->
|
||||||
|
|
||||||
end_suite(Apps) ->
|
end_suite(Apps) ->
|
||||||
emqx_common_test_http:delete_default_app(),
|
emqx_common_test_http:delete_default_app(),
|
||||||
emqx_common_test_helpers:stop_apps(Apps ++ [emqx_dashboard]),
|
emqx_common_test_helpers:stop_apps(Apps ++ [emqx_management, emqx_dashboard]),
|
||||||
application:unload(emqx_management),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
set_special_configs(emqx_dashboard) ->
|
set_special_configs(emqx_dashboard) ->
|
||||||
|
|
|
@ -25,12 +25,8 @@
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
-include_lib("emqx/include/emqx_hooks.hrl").
|
-include_lib("emqx/include/emqx_hooks.hrl").
|
||||||
|
|
||||||
%% Mnesia bootstrap
|
|
||||||
-export([mnesia/1]).
|
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
create_tables/0,
|
||||||
start_link/0,
|
start_link/0,
|
||||||
on_message_publish/1
|
on_message_publish/1
|
||||||
]).
|
]).
|
||||||
|
@ -118,14 +114,16 @@
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Mnesia bootstrap
|
%% Mnesia bootstrap
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
mnesia(boot) ->
|
|
||||||
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
{storage, disc_copies},
|
{storage, disc_copies},
|
||||||
{local_content, true},
|
{local_content, true},
|
||||||
{record_name, delayed_message},
|
{record_name, delayed_message},
|
||||||
{attributes, record_info(fields, delayed_message)}
|
{attributes, record_info(fields, delayed_message)}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Hooks
|
%% Hooks
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
]).
|
]).
|
||||||
|
|
||||||
start(_Type, _Args) ->
|
start(_Type, _Args) ->
|
||||||
|
ok = mria:wait_for_tables(emqx_delayed:create_tables()),
|
||||||
{ok, Sup} = emqx_modules_sup:start_link(),
|
{ok, Sup} = emqx_modules_sup:start_link(),
|
||||||
maybe_enable_modules(),
|
maybe_enable_modules(),
|
||||||
{ok, Sup}.
|
{ok, Sup}.
|
||||||
|
|
|
@ -73,23 +73,21 @@ end_per_group(_Group, _Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
WorkDir = proplists:get_value(data_dir, Config),
|
WorkDir = emqx_cth_suite:work_dir(Config),
|
||||||
filelib:ensure_path(WorkDir),
|
InstallDir = filename:join([WorkDir, "plugins"]),
|
||||||
OrigInstallDir = emqx_plugins:get_config(install_dir, undefined),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_common_test_helpers:start_apps([emqx_conf, emqx_plugins]),
|
[
|
||||||
emqx_plugins:put_config(install_dir, WorkDir),
|
emqx_conf,
|
||||||
[{orig_install_dir, OrigInstallDir} | Config].
|
emqx_ctl,
|
||||||
|
{emqx_plugins, #{config => #{plugins => #{install_dir => InstallDir}}}}
|
||||||
|
],
|
||||||
|
#{work_dir => WorkDir}
|
||||||
|
),
|
||||||
|
ok = filelib:ensure_path(InstallDir),
|
||||||
|
[{suite_apps, Apps}, {install_dir, InstallDir} | Config].
|
||||||
|
|
||||||
end_per_suite(Config) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:boot_modules(all),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
emqx_config:erase(plugins),
|
|
||||||
%% restore config
|
|
||||||
case proplists:get_value(orig_install_dir, Config) of
|
|
||||||
undefined -> ok;
|
|
||||||
OrigInstallDir -> emqx_plugins:put_config(install_dir, OrigInstallDir)
|
|
||||||
end,
|
|
||||||
emqx_common_test_helpers:stop_apps([emqx_plugins, emqx_conf]),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
init_per_testcase(TestCase, Config) ->
|
init_per_testcase(TestCase, Config) ->
|
||||||
emqx_plugins:put_configured([]),
|
emqx_plugins:put_configured([]),
|
||||||
|
@ -206,7 +204,7 @@ t_demo_install_start_stop_uninstall(Config) ->
|
||||||
%% but since we are using hocon:load to load it
|
%% but since we are using hocon:load to load it
|
||||||
%% ad-hoc test files can be in hocon format
|
%% ad-hoc test files can be in hocon format
|
||||||
write_info_file(Config, NameVsn, Content) ->
|
write_info_file(Config, NameVsn, Content) ->
|
||||||
WorkDir = proplists:get_value(data_dir, Config),
|
WorkDir = proplists:get_value(install_dir, Config),
|
||||||
InfoFile = filename:join([WorkDir, NameVsn, "release.json"]),
|
InfoFile = filename:join([WorkDir, NameVsn, "release.json"]),
|
||||||
ok = filelib:ensure_dir(InfoFile),
|
ok = filelib:ensure_dir(InfoFile),
|
||||||
ok = file:write_file(InfoFile, Content).
|
ok = file:write_file(InfoFile, Content).
|
||||||
|
@ -371,7 +369,7 @@ t_bad_tar_gz({init, Config}) ->
|
||||||
t_bad_tar_gz({'end', _Config}) ->
|
t_bad_tar_gz({'end', _Config}) ->
|
||||||
ok;
|
ok;
|
||||||
t_bad_tar_gz(Config) ->
|
t_bad_tar_gz(Config) ->
|
||||||
WorkDir = proplists:get_value(data_dir, Config),
|
WorkDir = proplists:get_value(install_dir, Config),
|
||||||
FakeTarTz = filename:join([WorkDir, "fake-vsn.tar.gz"]),
|
FakeTarTz = filename:join([WorkDir, "fake-vsn.tar.gz"]),
|
||||||
ok = file:write_file(FakeTarTz, "a\n"),
|
ok = file:write_file(FakeTarTz, "a\n"),
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
|
@ -396,7 +394,7 @@ t_bad_tar_gz(Config) ->
|
||||||
%% create with incomplete info file
|
%% create with incomplete info file
|
||||||
%% failed install attempts should not leave behind extracted dir
|
%% failed install attempts should not leave behind extracted dir
|
||||||
t_bad_tar_gz2({init, Config}) ->
|
t_bad_tar_gz2({init, Config}) ->
|
||||||
WorkDir = proplists:get_value(data_dir, Config),
|
WorkDir = proplists:get_value(install_dir, Config),
|
||||||
NameVsn = "foo-0.2",
|
NameVsn = "foo-0.2",
|
||||||
%% this an invalid info file content (description missing)
|
%% this an invalid info file content (description missing)
|
||||||
BadInfo = "name=foo, rel_vsn=\"0.2\", rel_apps=[foo]",
|
BadInfo = "name=foo, rel_vsn=\"0.2\", rel_apps=[foo]",
|
||||||
|
@ -422,7 +420,7 @@ t_bad_tar_gz2(Config) ->
|
||||||
%% test that we even cleanup content that doesn't match the expected name-vsn
|
%% test that we even cleanup content that doesn't match the expected name-vsn
|
||||||
%% pattern
|
%% pattern
|
||||||
t_tar_vsn_content_mismatch({init, Config}) ->
|
t_tar_vsn_content_mismatch({init, Config}) ->
|
||||||
WorkDir = proplists:get_value(data_dir, Config),
|
WorkDir = proplists:get_value(install_dir, Config),
|
||||||
NameVsn = "bad_tar-0.2",
|
NameVsn = "bad_tar-0.2",
|
||||||
%% this an invalid info file content
|
%% this an invalid info file content
|
||||||
BadInfo = "name=foo, rel_vsn=\"0.2\", rel_apps=[\"foo-0.2\"], description=\"lorem ipsum\"",
|
BadInfo = "name=foo, rel_vsn=\"0.2\", rel_apps=[\"foo-0.2\"], description=\"lorem ipsum\"",
|
||||||
|
@ -606,7 +604,7 @@ t_load_config_from_cli(Config) when is_list(Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
group_t_copy_plugin_to_a_new_node({init, Config}) ->
|
group_t_copy_plugin_to_a_new_node({init, Config}) ->
|
||||||
WorkDir = proplists:get_value(data_dir, Config),
|
WorkDir = proplists:get_value(install_dir, Config),
|
||||||
FromInstallDir = filename:join(WorkDir, atom_to_list(plugins_copy_from)),
|
FromInstallDir = filename:join(WorkDir, atom_to_list(plugins_copy_from)),
|
||||||
file:del_dir_r(FromInstallDir),
|
file:del_dir_r(FromInstallDir),
|
||||||
ok = filelib:ensure_path(FromInstallDir),
|
ok = filelib:ensure_path(FromInstallDir),
|
||||||
|
@ -614,25 +612,25 @@ group_t_copy_plugin_to_a_new_node({init, Config}) ->
|
||||||
file:del_dir_r(ToInstallDir),
|
file:del_dir_r(ToInstallDir),
|
||||||
ok = filelib:ensure_path(ToInstallDir),
|
ok = filelib:ensure_path(ToInstallDir),
|
||||||
#{package := Package, release_name := PluginName} = get_demo_plugin_package(FromInstallDir),
|
#{package := Package, release_name := PluginName} = get_demo_plugin_package(FromInstallDir),
|
||||||
[{CopyFrom, CopyFromOpts}, {CopyTo, CopyToOpts}] =
|
Apps = [
|
||||||
emqx_common_test_helpers:emqx_cluster(
|
emqx,
|
||||||
|
emqx_conf,
|
||||||
|
emqx_ctl,
|
||||||
|
emqx_plugins
|
||||||
|
],
|
||||||
|
[SpecCopyFrom, SpecCopyTo] =
|
||||||
|
emqx_cth_cluster:mk_nodespecs(
|
||||||
[
|
[
|
||||||
{core, plugins_copy_from},
|
{plugins_copy_from, #{role => core, apps => Apps}},
|
||||||
{core, plugins_copy_to}
|
{plugins_copy_to, #{role => core, apps => Apps}}
|
||||||
],
|
],
|
||||||
#{
|
#{
|
||||||
apps => [emqx_conf, emqx_plugins],
|
work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)
|
||||||
env => [
|
|
||||||
{emqx, boot_modules, []}
|
|
||||||
],
|
|
||||||
load_schema => false
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
CopyFromNode = emqx_common_test_helpers:start_peer(
|
[CopyFromNode] = emqx_cth_cluster:start([SpecCopyFrom#{join_to => undefined}]),
|
||||||
CopyFrom, maps:remove(join_to, CopyFromOpts)
|
|
||||||
),
|
|
||||||
ok = rpc:call(CopyFromNode, emqx_plugins, put_config, [install_dir, FromInstallDir]),
|
ok = rpc:call(CopyFromNode, emqx_plugins, put_config, [install_dir, FromInstallDir]),
|
||||||
CopyToNode = emqx_common_test_helpers:start_peer(CopyTo, maps:remove(join_to, CopyToOpts)),
|
[CopyToNode] = emqx_cth_cluster:start([SpecCopyTo#{join_to => undefined}]),
|
||||||
ok = rpc:call(CopyToNode, emqx_plugins, put_config, [install_dir, ToInstallDir]),
|
ok = rpc:call(CopyToNode, emqx_plugins, put_config, [install_dir, ToInstallDir]),
|
||||||
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
||||||
ok = rpc:call(CopyFromNode, emqx_plugins, ensure_installed, [NameVsn]),
|
ok = rpc:call(CopyFromNode, emqx_plugins, ensure_installed, [NameVsn]),
|
||||||
|
@ -656,16 +654,9 @@ group_t_copy_plugin_to_a_new_node({init, Config}) ->
|
||||||
| Config
|
| Config
|
||||||
];
|
];
|
||||||
group_t_copy_plugin_to_a_new_node({'end', Config}) ->
|
group_t_copy_plugin_to_a_new_node({'end', Config}) ->
|
||||||
CopyFromNode = proplists:get_value(copy_from_node, Config),
|
CopyFromNode = ?config(copy_from_node, Config),
|
||||||
CopyToNode = proplists:get_value(copy_to_node, Config),
|
CopyToNode = ?config(copy_to_node, Config),
|
||||||
ok = rpc:call(CopyFromNode, emqx_config, delete_override_conf_files, []),
|
ok = emqx_cth_cluster:stop([CopyFromNode, CopyToNode]);
|
||||||
ok = rpc:call(CopyToNode, emqx_config, delete_override_conf_files, []),
|
|
||||||
rpc:call(CopyToNode, ekka, leave, []),
|
|
||||||
rpc:call(CopyFromNode, ekka, leave, []),
|
|
||||||
ok = emqx_common_test_helpers:stop_peer(CopyToNode),
|
|
||||||
ok = emqx_common_test_helpers:stop_peer(CopyFromNode),
|
|
||||||
ok = file:del_dir_r(proplists:get_value(to_install_dir, Config)),
|
|
||||||
ok = file:del_dir_r(proplists:get_value(from_install_dir, Config));
|
|
||||||
group_t_copy_plugin_to_a_new_node(Config) ->
|
group_t_copy_plugin_to_a_new_node(Config) ->
|
||||||
CopyFromNode = proplists:get_value(copy_from_node, Config),
|
CopyFromNode = proplists:get_value(copy_from_node, Config),
|
||||||
CopyToNode = proplists:get_value(copy_to_node, Config),
|
CopyToNode = proplists:get_value(copy_to_node, Config),
|
||||||
|
@ -706,62 +697,48 @@ group_t_copy_plugin_to_a_new_node(Config) ->
|
||||||
|
|
||||||
%% checks that we can start a cluster with a lone node.
|
%% checks that we can start a cluster with a lone node.
|
||||||
group_t_copy_plugin_to_a_new_node_single_node({init, Config}) ->
|
group_t_copy_plugin_to_a_new_node_single_node({init, Config}) ->
|
||||||
PrivDataDir = ?config(priv_dir, Config),
|
WorkDir = ?config(install_dir, Config),
|
||||||
ToInstallDir = filename:join(PrivDataDir, "plugins_copy_to"),
|
ToInstallDir = filename:join(WorkDir, "plugins_copy_to"),
|
||||||
file:del_dir_r(ToInstallDir),
|
file:del_dir_r(ToInstallDir),
|
||||||
ok = filelib:ensure_path(ToInstallDir),
|
ok = filelib:ensure_path(ToInstallDir),
|
||||||
#{package := Package, release_name := PluginName} = get_demo_plugin_package(ToInstallDir),
|
#{package := Package, release_name := PluginName} = get_demo_plugin_package(ToInstallDir),
|
||||||
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
||||||
[{CopyTo, CopyToOpts}] =
|
Apps = [
|
||||||
emqx_common_test_helpers:emqx_cluster(
|
emqx,
|
||||||
[
|
emqx_conf,
|
||||||
{core, plugins_copy_to}
|
emqx_ctl,
|
||||||
],
|
{emqx_plugins, #{
|
||||||
#{
|
config => #{
|
||||||
apps => [emqx_conf, emqx_plugins],
|
plugins => #{
|
||||||
env => [
|
install_dir => ToInstallDir,
|
||||||
{emqx, boot_modules, []}
|
states => [#{name_vsn => NameVsn, enable => true}]
|
||||||
],
|
}
|
||||||
env_handler => fun
|
|
||||||
(emqx_plugins) ->
|
|
||||||
ok = emqx_plugins:put_config(install_dir, ToInstallDir),
|
|
||||||
%% this is to simulate an user setting the state
|
|
||||||
%% via environment variables before starting the node
|
|
||||||
ok = emqx_plugins:put_config(
|
|
||||||
states,
|
|
||||||
[#{name_vsn => NameVsn, enable => true}]
|
|
||||||
),
|
|
||||||
ok;
|
|
||||||
(_) ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
priv_data_dir => PrivDataDir,
|
|
||||||
schema_mod => emqx_conf_schema,
|
|
||||||
load_schema => true
|
|
||||||
}
|
}
|
||||||
),
|
}}
|
||||||
|
],
|
||||||
|
[CopyToNode] = emqx_cth_cluster:start(
|
||||||
|
[{plugins_copy_to, #{role => core, apps => Apps}}],
|
||||||
|
#{
|
||||||
|
work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)
|
||||||
|
}
|
||||||
|
),
|
||||||
[
|
[
|
||||||
{to_install_dir, ToInstallDir},
|
{to_install_dir, ToInstallDir},
|
||||||
{copy_to_node_name, CopyTo},
|
{copy_to_node, CopyToNode},
|
||||||
{copy_to_opts, CopyToOpts},
|
|
||||||
{name_vsn, NameVsn},
|
{name_vsn, NameVsn},
|
||||||
{plugin_name, PluginName}
|
{plugin_name, PluginName}
|
||||||
| Config
|
| Config
|
||||||
];
|
];
|
||||||
group_t_copy_plugin_to_a_new_node_single_node({'end', Config}) ->
|
group_t_copy_plugin_to_a_new_node_single_node({'end', Config}) ->
|
||||||
CopyToNode = proplists:get_value(copy_to_node_name, Config),
|
CopyToNode = proplists:get_value(copy_to_node, Config),
|
||||||
ok = emqx_common_test_helpers:stop_peer(CopyToNode),
|
ok = emqx_cth_cluster:stop([CopyToNode]);
|
||||||
ok = file:del_dir_r(proplists:get_value(to_install_dir, Config)),
|
|
||||||
ok;
|
|
||||||
group_t_copy_plugin_to_a_new_node_single_node(Config) ->
|
group_t_copy_plugin_to_a_new_node_single_node(Config) ->
|
||||||
CopyTo = ?config(copy_to_node_name, Config),
|
CopyToNode = ?config(copy_to_node, Config),
|
||||||
CopyToOpts = ?config(copy_to_opts, Config),
|
|
||||||
ToInstallDir = ?config(to_install_dir, Config),
|
ToInstallDir = ?config(to_install_dir, Config),
|
||||||
NameVsn = proplists:get_value(name_vsn, Config),
|
NameVsn = proplists:get_value(name_vsn, Config),
|
||||||
%% Start the node for the first time. The plugin should start
|
%% Start the node for the first time. The plugin should start
|
||||||
%% successfully even if it's not extracted yet. Simply starting
|
%% successfully even if it's not extracted yet. Simply starting
|
||||||
%% the node would crash if not working properly.
|
%% the node would crash if not working properly.
|
||||||
CopyToNode = emqx_common_test_helpers:start_peer(CopyTo, CopyToOpts),
|
|
||||||
ct:pal("~p config:\n ~p", [
|
ct:pal("~p config:\n ~p", [
|
||||||
CopyToNode, erpc:call(CopyToNode, emqx_plugins, get_config, [[], #{}])
|
CopyToNode, erpc:call(CopyToNode, emqx_plugins, get_config, [[], #{}])
|
||||||
]),
|
]),
|
||||||
|
@ -775,52 +752,44 @@ group_t_copy_plugin_to_a_new_node_single_node(Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
group_t_cluster_leave({init, Config}) ->
|
group_t_cluster_leave({init, Config}) ->
|
||||||
PrivDataDir = ?config(priv_dir, Config),
|
WorkDir = ?config(install_dir, Config),
|
||||||
ToInstallDir = filename:join(PrivDataDir, "plugins_copy_to"),
|
ToInstallDir = filename:join(WorkDir, "plugins_copy_to"),
|
||||||
file:del_dir_r(ToInstallDir),
|
file:del_dir_r(ToInstallDir),
|
||||||
ok = filelib:ensure_path(ToInstallDir),
|
ok = filelib:ensure_path(ToInstallDir),
|
||||||
#{package := Package, release_name := PluginName} = get_demo_plugin_package(ToInstallDir),
|
#{package := Package, release_name := PluginName} = get_demo_plugin_package(ToInstallDir),
|
||||||
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
||||||
Cluster =
|
Apps = [
|
||||||
emqx_common_test_helpers:emqx_cluster(
|
emqx,
|
||||||
[core, core],
|
emqx_conf,
|
||||||
#{
|
emqx_ctl,
|
||||||
apps => [emqx_conf, emqx_plugins],
|
{emqx_plugins, #{
|
||||||
env => [
|
config => #{
|
||||||
{emqx, boot_modules, []}
|
plugins => #{
|
||||||
],
|
install_dir => ToInstallDir,
|
||||||
env_handler => fun
|
states => [#{name_vsn => NameVsn, enable => true}]
|
||||||
(emqx_plugins) ->
|
}
|
||||||
ok = emqx_plugins:put_config(install_dir, ToInstallDir),
|
|
||||||
%% this is to simulate an user setting the state
|
|
||||||
%% via environment variables before starting the node
|
|
||||||
ok = emqx_plugins:put_config(
|
|
||||||
states,
|
|
||||||
[#{name_vsn => NameVsn, enable => true}]
|
|
||||||
),
|
|
||||||
ok;
|
|
||||||
(_) ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
priv_data_dir => PrivDataDir,
|
|
||||||
schema_mod => emqx_conf_schema,
|
|
||||||
load_schema => true
|
|
||||||
}
|
}
|
||||||
),
|
}}
|
||||||
Nodes = [emqx_common_test_helpers:start_peer(Name, Opts) || {Name, Opts} <- Cluster],
|
],
|
||||||
|
Nodes = emqx_cth_cluster:start(
|
||||||
|
[
|
||||||
|
{group_t_cluster_leave1, #{role => core, apps => Apps}},
|
||||||
|
{group_t_cluster_leave2, #{role => core, apps => Apps}}
|
||||||
|
],
|
||||||
|
#{
|
||||||
|
work_dir => emqx_cth_suite:work_dir(?FUNCTION_NAME, Config)
|
||||||
|
}
|
||||||
|
),
|
||||||
[
|
[
|
||||||
{to_install_dir, ToInstallDir},
|
{to_install_dir, ToInstallDir},
|
||||||
{cluster, Cluster},
|
|
||||||
{nodes, Nodes},
|
{nodes, Nodes},
|
||||||
{name_vsn, NameVsn},
|
{name_vsn, NameVsn},
|
||||||
{plugin_name, PluginName}
|
{plugin_name, PluginName}
|
||||||
| Config
|
| Config
|
||||||
];
|
];
|
||||||
group_t_cluster_leave({'end', Config}) ->
|
group_t_cluster_leave({'end', Config}) ->
|
||||||
Nodes = proplists:get_value(nodes, Config),
|
Nodes = ?config(nodes, Config),
|
||||||
[ok = emqx_common_test_helpers:stop_peer(N) || N <- Nodes],
|
ok = emqx_cth_cluster:stop(Nodes);
|
||||||
ok = file:del_dir_r(proplists:get_value(to_install_dir, Config)),
|
|
||||||
ok;
|
|
||||||
group_t_cluster_leave(Config) ->
|
group_t_cluster_leave(Config) ->
|
||||||
[N1, N2] = ?config(nodes, Config),
|
[N1, N2] = ?config(nodes, Config),
|
||||||
NameVsn = proplists:get_value(name_vsn, Config),
|
NameVsn = proplists:get_value(name_vsn, Config),
|
||||||
|
|
|
@ -17,13 +17,12 @@
|
||||||
-module(emqx_prometheus_SUITE).
|
-module(emqx_prometheus_SUITE).
|
||||||
|
|
||||||
-include_lib("stdlib/include/assert.hrl").
|
-include_lib("stdlib/include/assert.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
|
|
||||||
-define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
|
|
||||||
-define(LEGACY_CONF_DEFAULT, <<
|
-define(LEGACY_CONF_DEFAULT, <<
|
||||||
"\n"
|
|
||||||
"prometheus {\n"
|
"prometheus {\n"
|
||||||
" push_gateway_server = \"http://127.0.0.1:9091\"\n"
|
" push_gateway_server = \"http://127.0.0.1:9091\"\n"
|
||||||
" interval = \"1s\"\n"
|
" interval = \"1s\"\n"
|
||||||
|
@ -38,6 +37,7 @@
|
||||||
" vm_msacc_collector = disabled\n"
|
" vm_msacc_collector = disabled\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
>>).
|
>>).
|
||||||
|
|
||||||
-define(CONF_DEFAULT, #{
|
-define(CONF_DEFAULT, #{
|
||||||
<<"prometheus">> =>
|
<<"prometheus">> =>
|
||||||
#{
|
#{
|
||||||
|
@ -84,40 +84,29 @@ common_tests() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_group(new_config, Config) ->
|
init_per_group(new_config, Config) ->
|
||||||
init_group(),
|
Apps = emqx_cth_suite:start(
|
||||||
load_config(),
|
[
|
||||||
emqx_common_test_helpers:start_apps([emqx_prometheus]),
|
%% coverage olp metrics
|
||||||
%% coverage olp metrics
|
{emqx, "overload_protection.enable = true"},
|
||||||
{ok, _} = emqx:update_config([overload_protection, enable], true),
|
{emqx_license, "license.key = default"},
|
||||||
Config;
|
{emqx_prometheus, #{config => config(default)}}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config];
|
||||||
init_per_group(legacy_config, Config) ->
|
init_per_group(legacy_config, Config) ->
|
||||||
init_group(),
|
Apps = emqx_cth_suite:start(
|
||||||
load_legacy_config(),
|
[
|
||||||
emqx_common_test_helpers:start_apps([emqx_prometheus]),
|
{emqx, "overload_protection.enable = false"},
|
||||||
{ok, _} = emqx:update_config([overload_protection, enable], false),
|
{emqx_license, "license.key = default"},
|
||||||
Config.
|
{emqx_prometheus, #{config => config(legacy)}}
|
||||||
|
],
|
||||||
init_group() ->
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
application:load(emqx_conf),
|
),
|
||||||
ok = ekka:start(),
|
[{suite_apps, Apps} | Config].
|
||||||
ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
|
|
||||||
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
|
||||||
meck:expect(emqx_alarm, activate, 3, ok),
|
|
||||||
meck:expect(emqx_alarm, deactivate, 3, ok),
|
|
||||||
meck:new(emqx_license_checker, [non_strict, passthrough, no_link]),
|
|
||||||
meck:expect(emqx_license_checker, expiry_epoch, fun() -> 1859673600 end).
|
|
||||||
|
|
||||||
end_group() ->
|
|
||||||
ekka:stop(),
|
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
meck:unload(emqx_alarm),
|
|
||||||
meck:unload(emqx_license_checker),
|
|
||||||
emqx_common_test_helpers:stop_apps([emqx_prometheus]).
|
|
||||||
|
|
||||||
end_per_group(_Group, Config) ->
|
end_per_group(_Group, Config) ->
|
||||||
end_group(),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
Config.
|
|
||||||
|
|
||||||
init_per_testcase(t_assert_push, Config) ->
|
init_per_testcase(t_assert_push, Config) ->
|
||||||
meck:new(httpc, [passthrough]),
|
meck:new(httpc, [passthrough]),
|
||||||
|
@ -137,11 +126,10 @@ end_per_testcase(t_assert_push, _Config) ->
|
||||||
end_per_testcase(_Testcase, _Config) ->
|
end_per_testcase(_Testcase, _Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
load_config() ->
|
config(default) ->
|
||||||
ok = emqx_common_test_helpers:load_config(emqx_prometheus_schema, ?CONF_DEFAULT).
|
?CONF_DEFAULT;
|
||||||
|
config(legacy) ->
|
||||||
load_legacy_config() ->
|
?LEGACY_CONF_DEFAULT.
|
||||||
ok = emqx_common_test_helpers:load_config(emqx_prometheus_schema, ?LEGACY_CONF_DEFAULT).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Test cases
|
%% Test cases
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
|
|
||||||
-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").
|
||||||
-define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
|
|
||||||
|
|
||||||
-define(LOGT(Format, Args), ct:pal("TEST_SUITE: " ++ Format, Args)).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Setups
|
%% Setups
|
||||||
|
@ -41,41 +38,38 @@ groups() ->
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_prometheus_SUITE:init_group(),
|
Apps = emqx_cth_suite:start(
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_conf]),
|
[
|
||||||
Config.
|
emqx,
|
||||||
|
emqx_conf,
|
||||||
|
emqx_management,
|
||||||
|
{emqx_prometheus, #{start => false}},
|
||||||
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"},
|
||||||
|
{emqx_license, "license.key = default"}
|
||||||
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
{ok, _} = emqx_common_test_http:create_default_app(),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(Config) ->
|
end_per_suite(Config) ->
|
||||||
emqx_prometheus_SUITE:end_group(),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_conf]),
|
|
||||||
Config.
|
|
||||||
|
|
||||||
init_per_group(new_config, Config) ->
|
init_per_group(new_config, Config) ->
|
||||||
emqx_common_test_helpers:start_apps(
|
Apps = emqx_cth_suite:start_app(
|
||||||
[emqx_prometheus],
|
emqx_prometheus,
|
||||||
fun(App) -> set_special_configs(App, new_config) end
|
#{config => emqx_prometheus_SUITE:config(default)}
|
||||||
),
|
),
|
||||||
Config;
|
[{group_apps, Apps} | Config];
|
||||||
init_per_group(legacy_config, Config) ->
|
init_per_group(legacy_config, Config) ->
|
||||||
emqx_common_test_helpers:start_apps(
|
Apps = emqx_cth_suite:start_app(
|
||||||
[emqx_prometheus],
|
emqx_prometheus,
|
||||||
fun(App) -> set_special_configs(App, legacy_config) end
|
#{config => emqx_prometheus_SUITE:config(legacy)}
|
||||||
),
|
),
|
||||||
Config.
|
[{group_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_group(_Group, Config) ->
|
end_per_group(_Group, Config) ->
|
||||||
_ = application:stop(emqx_prometheus),
|
ok = emqx_cth_suite:stop_apps(?config(group_apps, Config)).
|
||||||
Config.
|
|
||||||
|
|
||||||
set_special_configs(emqx_dashboard, _) ->
|
|
||||||
emqx_dashboard_api_test_helpers:set_default_config();
|
|
||||||
set_special_configs(emqx_prometheus, new_config) ->
|
|
||||||
emqx_prometheus_SUITE:load_config(),
|
|
||||||
ok;
|
|
||||||
set_special_configs(emqx_prometheus, legacy_config) ->
|
|
||||||
emqx_prometheus_SUITE:load_legacy_config(),
|
|
||||||
ok;
|
|
||||||
set_special_configs(_App, _) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Cases
|
%% Cases
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{application, emqx_psk, [
|
{application, emqx_psk, [
|
||||||
{description, "EMQX PSK"},
|
{description, "EMQX PSK"},
|
||||||
% strict semver, bump manually!
|
% strict semver, bump manually!
|
||||||
{vsn, "5.0.5"},
|
{vsn, "5.0.6"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_psk_sup]},
|
{registered, [emqx_psk_sup]},
|
||||||
{applications, [kernel, stdlib]},
|
{applications, [kernel, stdlib]},
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
|
create_tables/0,
|
||||||
start_link/0,
|
start_link/0,
|
||||||
stop/0
|
stop/0
|
||||||
]).
|
]).
|
||||||
|
@ -63,10 +64,6 @@
|
||||||
extra :: term()
|
extra :: term()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-export([mnesia/1]).
|
|
||||||
|
|
||||||
-boot_mnesia({mnesia, [boot]}).
|
|
||||||
|
|
||||||
-include("emqx_psk.hrl").
|
-include("emqx_psk.hrl").
|
||||||
|
|
||||||
-define(CR, 13).
|
-define(CR, 13).
|
||||||
|
@ -81,8 +78,8 @@
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Create or replicate tables.
|
%% @doc Create or replicate tables.
|
||||||
-spec mnesia(boot | copy) -> ok.
|
-spec create_tables() -> [mria:table()].
|
||||||
mnesia(boot) ->
|
create_tables() ->
|
||||||
ok = mria:create_table(?TAB, [
|
ok = mria:create_table(?TAB, [
|
||||||
{rlog_shard, ?PSK_SHARD},
|
{rlog_shard, ?PSK_SHARD},
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
|
@ -90,7 +87,8 @@ mnesia(boot) ->
|
||||||
{record_name, psk_entry},
|
{record_name, psk_entry},
|
||||||
{attributes, record_info(fields, psk_entry)},
|
{attributes, record_info(fields, psk_entry)},
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}
|
||||||
]).
|
]),
|
||||||
|
[?TAB].
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Data backup
|
%% Data backup
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
-include("emqx_psk.hrl").
|
-include("emqx_psk.hrl").
|
||||||
|
|
||||||
start(_Type, _Args) ->
|
start(_Type, _Args) ->
|
||||||
ok = mria:wait_for_tables([?TAB]),
|
ok = mria:wait_for_tables(emqx_psk:create_tables()),
|
||||||
emqx_conf:add_handler([?PSK_KEY], emqx_psk),
|
emqx_conf:add_handler([?PSK_KEY], emqx_psk),
|
||||||
{ok, Sup} = emqx_psk_sup:start_link(),
|
{ok, Sup} = emqx_psk_sup:start_link(),
|
||||||
{ok, Sup}.
|
{ok, Sup}.
|
||||||
|
|
|
@ -34,30 +34,25 @@ groups() ->
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
meck:new(emqx_config, [non_strict, passthrough, no_history, no_link]),
|
Apps = emqx_cth_suite:start(
|
||||||
meck:expect(emqx_config, get, fun
|
[
|
||||||
([psk_authentication, enable]) -> true;
|
emqx,
|
||||||
([psk_authentication, chunk_size]) -> 50;
|
{emqx_psk, #{
|
||||||
(KeyPath) -> meck:passthrough([KeyPath])
|
config => #{
|
||||||
end),
|
psk_authentication => #{
|
||||||
meck:expect(emqx_config, get, fun
|
enable => true,
|
||||||
([psk_authentication, init_file], _) ->
|
init_file => filename:join(?config(data_dir, Config), "init.psk"),
|
||||||
filename:join([
|
separator => <<":">>
|
||||||
code:lib_dir(emqx_psk, test),
|
}
|
||||||
"data/init.psk"
|
}
|
||||||
]);
|
}}
|
||||||
([psk_authentication, separator], _) ->
|
],
|
||||||
<<":">>;
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
(KeyPath, Default) ->
|
),
|
||||||
meck:passthrough([KeyPath, Default])
|
[{suite_apps, Apps} | Config].
|
||||||
end),
|
|
||||||
emqx_common_test_helpers:start_apps([emqx_psk]),
|
|
||||||
Config.
|
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(Config) ->
|
||||||
meck:unload(emqx_config),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
emqx_common_test_helpers:stop_apps([emqx_psk]),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
t_psk_lookup(_) ->
|
t_psk_lookup(_) ->
|
||||||
PSKIdentity1 = <<"myclient1">>,
|
PSKIdentity1 = <<"myclient1">>,
|
||||||
|
|
|
@ -47,8 +47,6 @@ common_tests() ->
|
||||||
emqx_common_test_helpers:all(?MODULE) -- [t_reindex].
|
emqx_common_test_helpers:all(?MODULE) -- [t_reindex].
|
||||||
|
|
||||||
-define(BASE_CONF, <<
|
-define(BASE_CONF, <<
|
||||||
""
|
|
||||||
"\n"
|
|
||||||
"retainer {\n"
|
"retainer {\n"
|
||||||
" enable = true\n"
|
" enable = true\n"
|
||||||
" msg_clear_interval = 0s\n"
|
" msg_clear_interval = 0s\n"
|
||||||
|
@ -64,7 +62,6 @@ common_tests() ->
|
||||||
" max_retained_messages = 0\n"
|
" max_retained_messages = 0\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}"
|
"}"
|
||||||
""
|
|
||||||
>>).
|
>>).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -72,18 +69,14 @@ common_tests() ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:start_apps([emqx_conf]),
|
Apps = emqx_cth_suite:start(
|
||||||
load_conf(),
|
[emqx, emqx_conf, app_spec()],
|
||||||
emqx_limiter_sup:start_link(),
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
timer:sleep(200),
|
),
|
||||||
ok = application:ensure_started(?APP),
|
[{suite_apps, Apps} | Config].
|
||||||
Config.
|
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(Config) ->
|
||||||
ekka:stop(),
|
emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
emqx_common_test_helpers:stop_apps([?APP, emqx_conf]).
|
|
||||||
|
|
||||||
init_per_group(mnesia_without_indices, Config) ->
|
init_per_group(mnesia_without_indices, Config) ->
|
||||||
mnesia:clear_table(?TAB_INDEX_META),
|
mnesia:clear_table(?TAB_INDEX_META),
|
||||||
|
@ -113,10 +106,8 @@ init_per_testcase(t_get_basic_usage_info, Config) ->
|
||||||
init_per_testcase(_TestCase, Config) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
load_conf() ->
|
app_spec() ->
|
||||||
ok = emqx_config:delete_override_conf_files(),
|
{emqx_retainer, ?BASE_CONF}.
|
||||||
emqx_ratelimiter_SUITE:init_config(),
|
|
||||||
ok = emqx_config:init_load(emqx_retainer_schema, ?BASE_CONF).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Test Cases
|
%% Test Cases
|
||||||
|
|
|
@ -22,18 +22,20 @@
|
||||||
-include("emqx_retainer.hrl").
|
-include("emqx_retainer.hrl").
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
all() -> emqx_common_test_helpers:all(?MODULE).
|
all() -> emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_retainer_SUITE:load_conf(),
|
Apps = emqx_cth_suite:start(
|
||||||
%% Start Apps
|
[emqx, emqx_conf, emqx_retainer_SUITE:app_spec()],
|
||||||
emqx_common_test_helpers:start_apps([emqx_retainer]),
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
Config.
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:stop_apps([emqx_retainer]).
|
emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
t_reindex_status(_Config) ->
|
t_reindex_status(_Config) ->
|
||||||
ok = emqx_retainer_mnesia_cli:retainer(["reindex", "status"]).
|
ok = emqx_retainer_mnesia_cli:retainer(["reindex", "status"]).
|
||||||
|
|
|
@ -20,17 +20,19 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
all() -> emqx_common_test_helpers:all(?MODULE).
|
all() -> emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_retainer_SUITE:load_conf(),
|
Apps = emqx_cth_suite:start(
|
||||||
%% Start Apps
|
[emqx, emqx_conf, emqx_retainer_SUITE:app_spec()],
|
||||||
emqx_common_test_helpers:start_apps([emqx_retainer]),
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
Config.
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:stop_apps([emqx_retainer]).
|
emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
|
|
||||||
client_info(Key, Client) ->
|
client_info(Key, Client) ->
|
||||||
maps:get(Key, maps:from_list(emqtt:info(Client)), undefined).
|
maps:get(Key, maps:from_list(emqtt:info(Client)), undefined).
|
||||||
|
|
|
@ -20,76 +20,51 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx_slow_subs/include/emqx_slow_subs.hrl").
|
-include_lib("emqx_slow_subs/include/emqx_slow_subs.hrl").
|
||||||
|
|
||||||
-define(NOW, erlang:system_time(millisecond)).
|
-define(NOW, erlang:system_time(millisecond)).
|
||||||
-define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
|
|
||||||
-define(LANTENCY, 101).
|
-define(LANTENCY, 101).
|
||||||
|
|
||||||
-define(BASE_CONF, <<
|
-define(BASE_CONF, <<
|
||||||
""
|
|
||||||
"\n"
|
|
||||||
"slow_subs {\n"
|
"slow_subs {\n"
|
||||||
" enable = true\n"
|
" enable = true\n"
|
||||||
" top_k_num = 5\n"
|
" top_k_num = 5\n"
|
||||||
" threshold = 100ms\n"
|
" threshold = 100ms\n"
|
||||||
" expire_interval = 5m\n"
|
" expire_interval = 5m\n"
|
||||||
" stats_type = whole\n"
|
" stats_type = whole\n"
|
||||||
" }"
|
"}"
|
||||||
""
|
|
||||||
>>).
|
>>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
ok = ekka:start(),
|
[
|
||||||
ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
|
emqx,
|
||||||
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
emqx_conf,
|
||||||
meck:expect(emqx_alarm, activate, 3, ok),
|
{emqx_slow_subs, ?BASE_CONF}
|
||||||
meck:expect(emqx_alarm, deactivate, 3, ok),
|
],
|
||||||
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
|
),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
ok = emqx_common_test_helpers:load_config(emqx_slow_subs_schema, ?BASE_CONF),
|
end_per_suite(Config) ->
|
||||||
emqx_common_test_helpers:start_apps([emqx_slow_subs]),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
Config.
|
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
|
||||||
ekka:stop(),
|
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
meck:unload(emqx_alarm),
|
|
||||||
|
|
||||||
emqx_common_test_helpers:stop_apps([emqx_slow_subs]).
|
|
||||||
|
|
||||||
init_per_testcase(t_expire, Config) ->
|
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
|
||||||
update_config(<<"expire_interval">>, <<"1500ms">>),
|
|
||||||
Config;
|
|
||||||
init_per_testcase(_, Config) ->
|
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
|
||||||
Config.
|
|
||||||
|
|
||||||
end_per_testcase(_, _) ->
|
|
||||||
case erlang:whereis(node()) of
|
|
||||||
undefined ->
|
|
||||||
ok;
|
|
||||||
P ->
|
|
||||||
erlang:unlink(P),
|
|
||||||
erlang:exit(P, kill)
|
|
||||||
end,
|
|
||||||
ok.
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Test Cases
|
%% Test Cases
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
t_pub(_) ->
|
t_pub(_) ->
|
||||||
_ = [stats_with_type(Type) || Type <- [whole, internal, response]],
|
_ = [stats_with_type(Type) || Type <- [whole, internal, response]],
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_expire(_) ->
|
t_expire(_) ->
|
||||||
|
_ = update_config(<<"expire_interval">>, <<"1500ms">>),
|
||||||
Now = ?NOW,
|
Now = ?NOW,
|
||||||
Each = fun(I) ->
|
Each = fun(I) ->
|
||||||
ClientId = erlang:list_to_binary(io_lib:format("test_~p", [I])),
|
ClientId = erlang:list_to_binary(io_lib:format("test_~p", [I])),
|
||||||
|
|
|
@ -20,10 +20,8 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
|
||||||
-include_lib("emqx_management/include/emqx_mgmt.hrl").
|
|
||||||
-include_lib("emqx_slow_subs/include/emqx_slow_subs.hrl").
|
-include_lib("emqx_slow_subs/include/emqx_slow_subs.hrl").
|
||||||
|
|
||||||
-define(HOST, "http://127.0.0.1:18083/").
|
-define(HOST, "http://127.0.0.1:18083/").
|
||||||
|
@ -32,63 +30,43 @@
|
||||||
|
|
||||||
-define(BASE_PATH, "api").
|
-define(BASE_PATH, "api").
|
||||||
-define(NOW, erlang:system_time(millisecond)).
|
-define(NOW, erlang:system_time(millisecond)).
|
||||||
-define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
|
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<
|
-define(CONF_DEFAULT, <<
|
||||||
""
|
"slow_subs {\n"
|
||||||
"\n"
|
|
||||||
"slow_subs\n"
|
|
||||||
"{\n"
|
|
||||||
" enable = true\n"
|
" enable = true\n"
|
||||||
" top_k_num = 5,\n"
|
" top_k_num = 5,\n"
|
||||||
" expire_interval = 60s\n"
|
" expire_interval = 60s\n"
|
||||||
" stats_type = whole\n"
|
" stats_type = whole\n"
|
||||||
"}"
|
"}"
|
||||||
""
|
|
||||||
>>).
|
>>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_common_test_helpers:all(?MODULE).
|
emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
application:load(emqx_conf),
|
Apps = emqx_cth_suite:start(
|
||||||
ok = ekka:start(),
|
[
|
||||||
ok = mria_rlog:wait_for_shards([?CLUSTER_RPC_SHARD], infinity),
|
emqx,
|
||||||
meck:new(emqx_alarm, [non_strict, passthrough, no_link]),
|
emqx_auth,
|
||||||
meck:expect(emqx_alarm, activate, 3, ok),
|
emqx_conf,
|
||||||
meck:expect(emqx_alarm, deactivate, 3, ok),
|
emqx_management,
|
||||||
|
{emqx_slow_subs, ?CONF_DEFAULT},
|
||||||
ok = emqx_common_test_helpers:load_config(emqx_slow_subs_schema, ?CONF_DEFAULT),
|
{emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"}
|
||||||
emqx_mgmt_api_test_util:init_suite([emqx_slow_subs]),
|
],
|
||||||
{ok, _} = application:ensure_all_started(emqx_auth),
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
||||||
Config.
|
),
|
||||||
|
_ = emqx_common_test_http:create_default_app(),
|
||||||
|
[{suite_apps, Apps} | Config].
|
||||||
|
|
||||||
end_per_suite(Config) ->
|
end_per_suite(Config) ->
|
||||||
ekka:stop(),
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
||||||
mria:stop(),
|
|
||||||
mria_mnesia:delete_schema(),
|
|
||||||
meck:unload(emqx_alarm),
|
|
||||||
|
|
||||||
application:stop(emqx_auth),
|
|
||||||
emqx_mgmt_api_test_util:end_suite([emqx_slow_subs]),
|
|
||||||
Config.
|
|
||||||
|
|
||||||
init_per_testcase(_, Config) ->
|
init_per_testcase(_, Config) ->
|
||||||
{ok, _} = emqx_cluster_rpc:start_link(),
|
{ok, _} = application:ensure_all_started(emqx_slow_subs),
|
||||||
application:ensure_all_started(emqx_slow_subs),
|
|
||||||
timer:sleep(500),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_testcase(_, Config) ->
|
end_per_testcase(_, _Config) ->
|
||||||
application:stop(emqx_slow_subs),
|
ok = application:stop(emqx_slow_subs).
|
||||||
case erlang:whereis(node()) of
|
|
||||||
undefined ->
|
|
||||||
ok;
|
|
||||||
P ->
|
|
||||||
erlang:unlink(P),
|
|
||||||
erlang:exit(P, kill)
|
|
||||||
end,
|
|
||||||
Config.
|
|
||||||
|
|
||||||
t_get_history(_) ->
|
t_get_history(_) ->
|
||||||
Now = ?NOW,
|
Now = ?NOW,
|
||||||
|
|
Loading…
Reference in New Issue