Przeglądaj źródła

fix: flaky test when stopping dashboard listener

Zhongwen Deng 2 lat temu
rodzic
commit
5690469896

+ 1 - 0
apps/emqx/src/emqx_listeners.erl

@@ -57,6 +57,7 @@
 ]).
 
 -export([pre_config_update/3, post_config_update/5]).
+-export([wait_listener_stopped/1]).
 
 -export([format_bind/1]).
 

+ 4 - 3
apps/emqx_dashboard/src/emqx_dashboard.erl

@@ -111,14 +111,15 @@ stop_listeners(Listeners) ->
         begin
             case minirest:stop(Name) of
                 ok ->
+                    _ = emqx_listeners:wait_listener_stopped(Bind),
                     ?ULOG("Stop listener ~ts on ~ts successfully.~n", [
-                        Name, emqx_listeners:format_bind(Port)
+                        Name, emqx_listeners:format_bind(Bind)
                     ]);
                 {error, not_found} ->
-                    ?SLOG(warning, #{msg => "stop_listener_failed", name => Name, port => Port})
+                    ?SLOG(warning, #{msg => "stop_listener_failed", name => Name, bind => Bind})
             end
         end
-     || {Name, _, Port, _, _} <- listeners(Listeners)
+     || {Name, _, Bind, _, _} <- listeners(Listeners)
     ],
     ok.
 

+ 2 - 0
apps/emqx_dashboard/test/emqx_dashboard_SUITE.erl

@@ -234,6 +234,8 @@ do_request_dashboard(Method, Request) ->
         ->
             {ok, Return};
         {ok, {Reason, _, _}} ->
+            {error, Reason};
+        {error, Reason} ->
             {error, Reason}
     end.
 

+ 79 - 4
apps/emqx_dashboard/test/emqx_dashboard_https_SUITE.erl

@@ -21,9 +21,11 @@
 
 -include_lib("eunit/include/eunit.hrl").
 -include("emqx_dashboard.hrl").
+-include_lib("snabbkaffe/include/snabbkaffe.hrl").
 
 -define(NAME, 'https:dashboard').
--define(HOST, "https://127.0.0.1:18084").
+-define(HOST_HTTPS, "https://127.0.0.1:18084").
+-define(HOST_HTTP, "http://127.0.0.1:18083").
 -define(BASE_PATH, "/api/v5").
 -define(OVERVIEWS, [
     "alarms",
@@ -44,6 +46,76 @@ end_per_suite(_Config) -> emqx_mgmt_api_test_util:end_suite([emqx_management]).
 init_per_testcase(_TestCase, Config) -> Config.
 end_per_testcase(_TestCase, _Config) -> emqx_mgmt_api_test_util:end_suite([emqx_management]).
 
+t_update_conf(_Config) ->
+    Conf = #{
+        dashboard => #{
+            listeners => #{
+                https => #{bind => 18084, enable => true},
+                http => #{bind => 18083, enable => true}
+            }
+        }
+    },
+    emqx_common_test_helpers:load_config(emqx_dashboard_schema, Conf),
+    emqx_mgmt_api_test_util:init_suite([emqx_management], fun(X) -> X end),
+    Headers = emqx_dashboard_SUITE:auth_header_(),
+    {ok, Client1} = emqx_dashboard_SUITE:request_dashboard(
+        get, https_api_path(["clients"]), Headers
+    ),
+    {ok, Client2} = emqx_dashboard_SUITE:request_dashboard(
+        get, http_api_path(["clients"]), Headers
+    ),
+    Raw = emqx:get_raw_config([<<"dashboard">>]),
+    ?assertEqual(Client1, Client2),
+    ?check_trace(
+        begin
+            Raw1 = emqx_utils_maps:deep_put(
+                [<<"listeners">>, <<"https">>, <<"enable">>], Raw, false
+            ),
+            ?assertMatch({ok, _}, emqx:update_config([<<"dashboard">>], Raw1)),
+            ?assertEqual(Raw1, emqx:get_raw_config([<<"dashboard">>])),
+            {ok, _} = ?block_until(#{?snk_kind := regenerate_minirest_dispatch}, 10000),
+            ok
+        end,
+        fun(ok, Trace) ->
+            %% Don't start new listener, so is empty
+            ?assertMatch([#{listeners := []}], ?of_kind(regenerate_minirest_dispatch, Trace))
+        end
+    ),
+    {ok, Client3} = emqx_dashboard_SUITE:request_dashboard(
+        get, http_api_path(["clients"]), Headers
+    ),
+    ?assertEqual(Client1, Client3),
+    ?assertMatch(
+        {error,
+            {failed_connect, [
+                _,
+                {inet, [inet], econnrefused}
+            ]}},
+        emqx_dashboard_SUITE:request_dashboard(get, https_api_path(["clients"]), Headers)
+    ),
+    %% reset
+    ?check_trace(
+        begin
+            ?assertMatch({ok, _}, emqx:update_config([<<"dashboard">>], Raw)),
+            ?assertEqual(Raw, emqx:get_raw_config([<<"dashboard">>])),
+            {ok, _} = ?block_until(#{?snk_kind := regenerate_minirest_dispatch}, 10000),
+            ok
+        end,
+        fun(ok, Trace) ->
+            %% start new listener('https:dashboard')
+            ?assertMatch(
+                [#{listeners := ['https:dashboard']}], ?of_kind(regenerate_minirest_dispatch, Trace)
+            )
+        end
+    ),
+    {ok, Client1} = emqx_dashboard_SUITE:request_dashboard(
+        get, https_api_path(["clients"]), Headers
+    ),
+    {ok, Client2} = emqx_dashboard_SUITE:request_dashboard(
+        get, http_api_path(["clients"]), Headers
+    ),
+    emqx_mgmt_api_test_util:end_suite([emqx_management]).
+
 t_default_ssl_cert(_Config) ->
     Conf = #{dashboard => #{listeners => #{https => #{bind => 18084, enable => true}}}},
     validate_https(Conf, 512, default_ssl_cert(), verify_none),
@@ -188,7 +260,7 @@ assert_https_request() ->
     Headers = emqx_dashboard_SUITE:auth_header_(),
     lists:foreach(
         fun(Path) ->
-            ApiPath = api_path([Path]),
+            ApiPath = https_api_path([Path]),
             ?assertMatch(
                 {ok, _},
                 emqx_dashboard_SUITE:request_dashboard(get, ApiPath, Headers)
@@ -197,8 +269,11 @@ assert_https_request() ->
         ?OVERVIEWS
     ).
 
-api_path(Parts) ->
-    ?HOST ++ filename:join([?BASE_PATH | Parts]).
+https_api_path(Parts) ->
+    ?HOST_HTTPS ++ filename:join([?BASE_PATH | Parts]).
+
+http_api_path(Parts) ->
+    ?HOST_HTTP ++ filename:join([?BASE_PATH | Parts]).
 
 naive_env_interpolation(Str0) ->
     Str1 = emqx_schema:naive_env_interpolation(Str0),