From fe0b8cfbaf1d3026cffd3c6fc02d837189df8aa1 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Wed, 21 Jun 2023 23:16:38 +0200 Subject: [PATCH] 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. --- apps/emqx/src/emqx_app.erl | 27 ++++++++++--------- apps/emqx/src/emqx_listeners.erl | 4 +-- apps/emqx/test/emqx_common_test_helpers.erl | 4 +-- apps/emqx/test/emqx_cth_suite.erl | 8 +++--- apps/emqx/test/emqx_shared_sub_SUITE.erl | 2 +- apps/emqx_conf/src/emqx_conf_app.erl | 25 ++++++++++++++--- apps/emqx_conf/test/emqx_conf_app_SUITE.erl | 3 +-- .../test/emqx_mgmt_api_listeners_SUITE.erl | 9 +++---- apps/emqx_plugins/test/emqx_plugins_SUITE.erl | 3 --- 9 files changed, 50 insertions(+), 35 deletions(-) diff --git a/apps/emqx/src/emqx_app.erl b/apps/emqx/src/emqx_app.erl index 1fb2feb87..ffb4e3d1e 100644 --- a/apps/emqx/src/emqx_app.erl +++ b/apps/emqx/src/emqx_app.erl @@ -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() -> diff --git a/apps/emqx/src/emqx_listeners.erl b/apps/emqx/src/emqx_listeners.erl index 1c21d1d2e..aaee3b64e 100644 --- a/apps/emqx/src/emqx_listeners.erl +++ b/apps/emqx/src/emqx_listeners.erl @@ -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], #{}), diff --git a/apps/emqx/test/emqx_common_test_helpers.erl b/apps/emqx/test/emqx_common_test_helpers.erl index 26ada4f1a..b004b139e 100644 --- a/apps/emqx/test/emqx_common_test_helpers.erl +++ b/apps/emqx/test/emqx_common_test_helpers.erl @@ -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 diff --git a/apps/emqx/test/emqx_cth_suite.erl b/apps/emqx/test/emqx_cth_suite.erl index 6f4674a37..7a0fb89ac 100644 --- a/apps/emqx/test/emqx_cth_suite.erl +++ b/apps/emqx/test/emqx_cth_suite.erl @@ -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) -> #{ diff --git a/apps/emqx/test/emqx_shared_sub_SUITE.erl b/apps/emqx/test/emqx_shared_sub_SUITE.erl index d4bb9bbea..e280f4fe5 100644 --- a/apps/emqx/test/emqx_shared_sub_SUITE.erl +++ b/apps/emqx/test/emqx_shared_sub_SUITE.erl @@ -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}), diff --git a/apps/emqx_conf/src/emqx_conf_app.erl b/apps/emqx_conf/src/emqx_conf_app.erl index 459e13676..c92c28971 100644 --- a/apps/emqx_conf/src/emqx_conf_app.erl +++ b/apps/emqx_conf/src/emqx_conf_app.erl @@ -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()]. diff --git a/apps/emqx_conf/test/emqx_conf_app_SUITE.erl b/apps/emqx_conf/test/emqx_conf_app_SUITE.erl index 34bf5c702..2e3b40b87 100644 --- a/apps/emqx_conf/test/emqx_conf_app_SUITE.erl +++ b/apps/emqx_conf/test/emqx_conf_app_SUITE.erl @@ -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, [ diff --git a/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl b/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl index e86a76e1c..862d81ab8 100644 --- a/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl +++ b/apps/emqx_management/test/emqx_mgmt_api_listeners_SUITE.erl @@ -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 diff --git a/apps/emqx_plugins/test/emqx_plugins_SUITE.erl b/apps/emqx_plugins/test/emqx_plugins_SUITE.erl index 8d168ec8b..d6dee2c1e 100644 --- a/apps/emqx_plugins/test/emqx_plugins_SUITE.erl +++ b/apps/emqx_plugins/test/emqx_plugins_SUITE.erl @@ -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