Kaynağa Gözat

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.
Andrew Mayorov 2 yıl önce
ebeveyn
işleme
fe0b8cfbaf

+ 15 - 12
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() ->

+ 1 - 3
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], #{}),

+ 2 - 2
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

+ 5 - 3
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) ->
     #{

+ 1 - 1
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}),

+ 21 - 4
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()].

+ 1 - 2
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, [

+ 4 - 5
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

+ 0 - 3
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