test(conf): respect `init_config_load_done` in emqx_conf itself

This should make task of configuring various applications (emqx_conf
/ emqx) during testsuites setup much simpler.
This commit is contained in:
Andrew Mayorov 2023-06-21 23:16:38 +02:00
parent f76f3b77d7
commit fe0b8cfbaf
No known key found for this signature in database
GPG Key ID: 2837C62ACFBFED5D
9 changed files with 50 additions and 35 deletions

View File

@ -24,17 +24,14 @@
stop/1,
get_description/0,
get_release/0,
set_init_config_load_done/0,
get_init_config_load_done/0,
set_config_loader/1,
get_config_loader/0,
set_init_tnx_id/1,
get_init_tnx_id/0
]).
-include("emqx.hrl").
-include("logger.hrl").
-define(APP, emqx).
%%--------------------------------------------------------------------
%% Application callbacks
%%--------------------------------------------------------------------
@ -62,11 +59,11 @@ stop(_State) -> ok.
%% @doc Call this function to make emqx boot without loading config,
%% in case we want to delegate the config load to a higher level app
%% which manages emqx app.
set_init_config_load_done() ->
application:set_env(emqx, init_config_load_done, true).
set_config_loader(Module) when is_atom(Module) ->
application:set_env(emqx, config_loader, Module).
get_init_config_load_done() ->
application:get_env(emqx, init_config_load_done, false).
get_config_loader() ->
application:get_env(emqx, config_loader, emqx).
%% @doc Set the transaction id from which this node should start applying after boot.
%% The transaction ID is received from the core node which we just copied the latest
@ -79,9 +76,15 @@ get_init_tnx_id() ->
application:get_env(emqx, cluster_rpc_init_tnx_id, -1).
maybe_load_config() ->
case get_init_config_load_done() of
true -> ok;
false -> emqx_config:init_load(emqx_schema)
case get_config_loader() of
emqx ->
emqx_config:init_load(emqx_schema);
Module ->
?SLOG(debug, #{
msg => "skip_init_config_load",
reason => "Some application has set another config loader",
loader => Module
})
end.
maybe_start_listeners() ->

View File

@ -17,8 +17,6 @@
%% @doc Start/Stop MQTT listeners.
-module(emqx_listeners).
-elvis([{elvis_style, dont_repeat_yourself, #{min_complexity => 10000}}]).
-include("emqx_mqtt.hrl").
-include("emqx_schema.hrl").
-include("logger.hrl").
@ -98,7 +96,7 @@ format_list(Listener) ->
do_list_raw() ->
%% GET /listeners from other nodes returns [] when init config is not loaded.
case emqx_app:get_init_config_load_done() of
case emqx_app:get_config_loader() =/= emqx of
true ->
Key = <<"listeners">>,
Raw = emqx_config:get_raw([Key], #{}),

View File

@ -349,7 +349,7 @@ stop_apps(Apps, Opts) ->
[application:stop(App) || App <- Apps ++ [emqx, ekka, mria, mnesia]],
ok = mria_mnesia:delete_schema(),
%% to avoid inter-suite flakiness
application:unset_env(emqx, init_config_load_done),
application:unset_env(emqx, config_loader),
application:unset_env(emqx, boot_modules),
persistent_term:erase(?EMQX_AUTHENTICATION_SCHEMA_MODULE_PT_KEY),
case Opts of
@ -911,7 +911,7 @@ setup_node(Node, Opts) when is_map(Opts) ->
set_env_once("EMQX_NODE__DATA_DIR", NodeDataDir),
set_env_once("EMQX_NODE__COOKIE", Cookie),
emqx_config:init_load(SchemaMod),
application:set_env(emqx, init_config_load_done, true)
emqx_app:set_config_loader(emqx_conf)
end,
%% Need to set this otherwise listeners will conflict between each other

View File

@ -271,9 +271,11 @@ default_appspec(emqx_conf, SuiteOpts) ->
}
},
% NOTE
% We mark config loaded before starting `emqx_conf` so that it won't
% overwrite evenrything with a default configuration.
before_start => fun emqx_app:set_init_config_load_done/0
% We inform `emqx` of our config loader before starting `emqx_conf` sothat it won't
% overwrite everything with a default configuration.
before_start => fun() ->
emqx_app:set_config_loader(?MODULE)
end
};
default_appspec(emqx_dashboard, _SuiteOpts) ->
#{

View File

@ -1114,7 +1114,7 @@ setup_node(Node, Port) ->
%% We load configuration, and than set the special enviroment variable
%% which says that emqx shouldn't load configuration at startup
emqx_config:init_load(emqx_schema),
application:set_env(emqx, init_config_load_done, true),
emqx_app:set_config_loader(?MODULE),
ok = emqx_config:put([listeners, tcp, default, bind], {{127, 0, 0, 1}, Port}),
ok = emqx_config:put([listeners, ssl, default, bind], {{127, 0, 0, 1}, Port + 1}),

View File

@ -22,6 +22,9 @@
-export([get_override_config_file/0]).
-export([sync_data_from_node/0]).
%% Test purposes
-export([init_load_done/0]).
-include_lib("emqx/include/logger.hrl").
-include("emqx_conf.hrl").
@ -46,7 +49,7 @@ stop(_State) ->
%% This function is named 'override' due to historical reasons.
get_override_config_file() ->
Node = node(),
case emqx_app:get_init_config_load_done() of
case init_load_done() of
false ->
{error, #{node => Node, msg => "init_conf_load_not_done"}};
true ->
@ -91,7 +94,22 @@ sync_data_from_node() ->
%% ------------------------------------------------------------------------------
init_load() ->
emqx_config:init_load(emqx_conf:schema_module()).
case emqx_app:get_config_loader() of
Module when Module == emqx; Module == emqx_conf ->
ok = emqx_config:init_load(emqx_conf:schema_module()),
ok = emqx_app:set_config_loader(emqx_conf),
ok;
Module ->
?SLOG(debug, #{
msg => "skip_init_config_load",
reason => "Some application has set another config loader",
loader => Module
})
end.
init_load_done() ->
% NOTE: Either us or some higher level (i.e. tests) code loaded config.
emqx_app:get_config_loader() =/= emqx.
init_conf() ->
%% Workaround for https://github.com/emqx/mria/issues/94:
@ -99,8 +117,7 @@ init_conf() ->
_ = mria:wait_for_tables([?CLUSTER_MFA, ?CLUSTER_COMMIT]),
{ok, TnxId} = sync_cluster_conf(),
_ = emqx_app:set_init_tnx_id(TnxId),
ok = init_load(),
ok = emqx_app:set_init_config_load_done().
ok = init_load().
cluster_nodes() ->
mria:cluster_nodes(cores) -- [node()].

View File

@ -215,7 +215,7 @@ assert_no_cluster_conf_copied([Node | Nodes], File) ->
assert_config_load_done(Nodes) ->
lists:foreach(
fun(Node) ->
Done = rpc:call(Node, emqx_app, get_init_config_load_done, []),
Done = rpc:call(Node, emqx_conf_app, init_load_done, []),
?assert(Done, #{node => Node})
end,
Nodes
@ -240,7 +240,6 @@ start_cluster_async(Specs) ->
cluster(Specs, Config) ->
PrivDataDir = ?config(priv_dir, Config),
Env = [
{emqx, init_config_load_done, false},
{emqx, boot_modules, []}
],
emqx_common_test_helpers:emqx_cluster(Specs, [

View File

@ -200,7 +200,7 @@ t_api_listeners_list_not_ready(Config) when is_list(Config) ->
L1 = get_tcp_listeners(Node1),
%% test init_config not ready.
_ = rpc:call(Node1, application, set_env, [emqx, init_config_load_done, false]),
_ = rpc:call(Node1, emqx_app, set_config_loader, [emqx]),
assert_config_load_not_done(Node1),
L2 = get_tcp_listeners(Node1),
@ -283,12 +283,11 @@ get_tcp_listeners(Node) ->
NodeStatus.
assert_config_load_not_done(Node) ->
Done = rpc:call(Node, emqx_app, get_init_config_load_done, []),
?assertNot(Done, #{node => Node}).
Prio = rpc:call(Node, emqx_app, get_config_loader, []),
?assertEqual(emqx, Prio, #{node => Node}).
cluster(Specs) ->
Env = [
{emqx, init_config_load_done, false},
{emqx, boot_modules, []}
],
emqx_common_test_helpers:emqx_cluster(Specs, [
@ -299,7 +298,7 @@ cluster(Specs) ->
(emqx) ->
application:set_env(emqx, boot_modules, []),
%% test init_config not ready.
application:set_env(emqx, init_config_load_done, false),
emqx_app:set_config_loader(emqx),
ok;
(_) ->
ok

View File

@ -523,7 +523,6 @@ group_t_copy_plugin_to_a_new_node({init, Config}) ->
#{
apps => [emqx_conf, emqx_plugins],
env => [
{emqx, init_config_load_done, false},
{emqx, boot_modules, []}
],
load_schema => false
@ -621,7 +620,6 @@ group_t_copy_plugin_to_a_new_node_single_node({init, Config}) ->
#{
apps => [emqx_conf, emqx_plugins],
env => [
{emqx, init_config_load_done, false},
{emqx, boot_modules, []}
],
env_handler => fun
@ -690,7 +688,6 @@ group_t_cluster_leave({init, Config}) ->
#{
apps => [emqx_conf, emqx_plugins],
env => [
{emqx, init_config_load_done, false},
{emqx, boot_modules, []}
],
env_handler => fun