Jelajahi Sumber

fix(retainer): ensure API call is safe when disabled the retainer

firest 1 tahun lalu
induk
melakukan
7c6c192eca

+ 9 - 6
apps/emqx_retainer/src/emqx_retainer.erl

@@ -83,10 +83,12 @@
 
 -type backend_state() :: term().
 
--type context() :: #{
-    module := module(),
-    state := backend_state()
-}.
+-type context() ::
+    #{
+        module := module(),
+        state := backend_state()
+    }
+    | undefined.
 
 -type topic() :: emqx_types:topic().
 -type message() :: emqx_types:message().
@@ -506,8 +508,9 @@ config_backend_module(Config) ->
         #{module := Module} -> Module
     end.
 
--spec backend_module(context()) -> module().
-backend_module(#{module := Module}) -> Module.
+-spec backend_module(context()) -> module() | undefined.
+backend_module(#{module := Module}) -> Module;
+backend_module(undefined) -> undefined.
 
 -spec backend_state(context()) -> backend_state().
 backend_state(#{state := State}) -> State.

+ 36 - 19
apps/emqx_retainer/test/emqx_retainer_SUITE.erl

@@ -31,7 +31,8 @@ all() ->
         {group, mnesia_without_indices},
         {group, mnesia_with_indices},
         {group, mnesia_reindex},
-        {group, test_disable_then_start}
+        {group, test_disable_then_start},
+        {group, disabled}
     ].
 
 groups() ->
@@ -39,7 +40,8 @@ groups() ->
         {mnesia_without_indices, [sequence], common_tests()},
         {mnesia_with_indices, [sequence], common_tests()},
         {mnesia_reindex, [sequence], [t_reindex]},
-        {test_disable_then_start, [sequence], [test_disable_then_start]}
+        {test_disable_then_start, [sequence], [test_disable_then_start]},
+        {disabled, [test_disabled]}
     ].
 
 common_tests() ->
@@ -65,29 +67,27 @@ retainer {
 }
 ">>).
 
+%% erlfmt-ignore
+-define(DISABLED_CONF, <<"
+retainer {
+  enable = false
+}
+">>).
+
 %%--------------------------------------------------------------------
 %% Setups
 %%--------------------------------------------------------------------
 
-init_per_suite(Config) ->
-    Apps = emqx_cth_suite:start(
-        [emqx, emqx_conf, app_spec()],
-        #{work_dir => emqx_cth_suite:work_dir(Config)}
-    ),
-    [{suite_apps, Apps} | Config].
-
-end_per_suite(Config) ->
-    emqx_cth_suite:stop(?config(suite_apps, Config)).
-
-init_per_group(mnesia_without_indices, Config) ->
-    [{index, false} | Config];
-init_per_group(mnesia_reindex, Config) ->
-    Config;
-init_per_group(_, Config) ->
-    Config.
+init_per_group(mnesia_without_indices = Group, Config) ->
+    start_apps(Group, [{index, false} | Config]);
+init_per_group(mnesia_reindex = Group, Config) ->
+    start_apps(Group, Config);
+init_per_group(Group, Config) ->
+    start_apps(Group, Config).
 
 end_per_group(_Group, Config) ->
     emqx_retainer_mnesia:populate_index_meta(),
+    stop_apps(Config),
     Config.
 
 init_per_testcase(_TestCase, Config) ->
@@ -107,9 +107,21 @@ end_per_testcase(t_cursor_cleanup, _Config) ->
 end_per_testcase(_TestCase, _Config) ->
     ok.
 
-app_spec() ->
+app_spec(disabled) ->
+    {emqx_retainer, ?DISABLED_CONF};
+app_spec(_) ->
     {emqx_retainer, ?BASE_CONF}.
 
+start_apps(Group, Config) ->
+    Apps = emqx_cth_suite:start(
+        [emqx, emqx_conf, app_spec(Group)],
+        #{work_dir => emqx_cth_suite:work_dir(Config)}
+    ),
+    [{suite_apps, Apps} | Config].
+
+stop_apps(Config) ->
+    emqx_cth_suite:stop(?config(suite_apps, Config)).
+
 %%--------------------------------------------------------------------
 %% Test Cases
 %%--------------------------------------------------------------------
@@ -768,6 +780,11 @@ test_disable_then_start(_Config) ->
     ?assertNotEqual([], gproc_pool:active_workers(emqx_retainer_dispatcher)),
     ok.
 
+test_disabled(_Config) ->
+    ?assertEqual(false, emqx_retainer:enabled()),
+    ?assertEqual(ok, emqx_retainer:clean()),
+    ?assertEqual({ok, false, []}, emqx_retainer:page_read(undefined, 1, 100)).
+
 t_deliver_when_banned(_) ->
     Client1 = <<"c1">>,
     Client2 = <<"c2">>,

+ 2 - 0
changes/ce/fix-14215.en.md

@@ -0,0 +1,2 @@
+Fixed an issue that calls to retainer(via REST or CLI) will throw an exception if it is disabled.
+