test: ensure hooks has unloaded if grpc is blocked

This commit is contained in:
JianBo He 2022-09-02 10:26:14 +08:00
parent dfc6e34680
commit ebb2824e15
6 changed files with 46 additions and 6 deletions

View File

@ -21,6 +21,7 @@
-include("emqx_exhook.hrl"). -include("emqx_exhook.hrl").
-include_lib("emqx/include/logger.hrl"). -include_lib("emqx/include/logger.hrl").
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
%% APIs %% APIs
-export([start_link/0]). -export([start_link/0]).
@ -297,7 +298,7 @@ handle_info(refresh_tick, State) ->
handle_info(_Info, State) -> handle_info(_Info, State) ->
{noreply, State}. {noreply, State}.
terminate(_Reason, State = #{servers := Servers}) -> terminate(Reason, State = #{servers := Servers}) ->
_ = unload_exhooks(), _ = unload_exhooks(),
_ = maps:fold( _ = maps:fold(
fun(Name, _, AccIn) -> fun(Name, _, AccIn) ->
@ -306,6 +307,7 @@ terminate(_Reason, State = #{servers := Servers}) ->
State, State,
Servers Servers
), ),
?tp(info, exhook_mgr_terminated, #{reason => Reason, servers => Servers}),
ok. ok.
code_change(_OldVsn, State, _Extra) -> code_change(_OldVsn, State, _Extra) ->

View File

@ -185,9 +185,9 @@ unload(#{name := Name, options := ReqOpts, hookspec := HookSpecs}) ->
ok. ok.
do_deinit(Name, ReqOpts) -> do_deinit(Name, ReqOpts) ->
%% Using shorter timeout to deinit grpc server to avoid emqx_exhook_mgr %% Override the request timeout to deinit grpc server to
%% force killed by upper supervisor %% avoid emqx_exhook_mgr force killed by upper supervisor
_ = do_call(Name, undefined, 'on_provider_unloaded', #{}, ReqOpts#{timeout => 3000}), _ = do_call(Name, undefined, 'on_provider_unloaded', #{}, ReqOpts#{timeout => 5000}),
ok. ok.
do_init(ChannName, ReqOpts) -> do_init(ChannName, ReqOpts) ->

View File

@ -32,6 +32,7 @@
id => Mod, id => Mod,
start => {Mod, start_link, Args}, start => {Mod, start_link, Args},
type => Type, type => Type,
%% long timeout for emqx_exhook_mgr
shutdown => 15000 shutdown => 15000
}). }).

View File

@ -24,6 +24,7 @@
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
-include_lib("emqx/include/emqx_hooks.hrl"). -include_lib("emqx/include/emqx_hooks.hrl").
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl). -define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
@ -313,6 +314,40 @@ t_cluster_name(_) ->
), ),
emqx_exhook_mgr:disable(<<"default">>). emqx_exhook_mgr:disable(<<"default">>).
t_stop_timeout(_) ->
snabbkaffe:start_trace(),
meck:new(emqx_exhook_demo_svr, [passthrough, no_history]),
meck:expect(
emqx_exhook_demo_svr,
on_provider_unloaded,
fun(Req, Md) ->
%% ensure sleep time greater than emqx_exhook_mgr shutdown timeout
timer:sleep(20000),
meck:passthrough([Req, Md])
end
),
%% stop application
application:stop(emqx_exhook),
?block_until(#{?snk_kind := exhook_mgr_terminated}, 20000),
%% all exhook hooked point should be unloaded
Mods = lists:flatten(
lists:map(
fun({hook, _, Cbs}) ->
lists:map(fun({callback, {M, _, _}, _, _}) -> M end, Cbs)
end,
ets:tab2list(emqx_hooks)
)
),
?assertEqual(false, lists:any(fun(M) -> M == emqx_exhook_handler end, Mods)),
%% ensure started for other tests
emqx_common_test_helpers:start_apps([emqx_exhook]),
snabbkaffe:stop(),
meck:unload(emqx_exhook_demo_svr).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Cases Helpers %% Cases Helpers
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

View File

@ -80,7 +80,10 @@ stop() ->
stop(Name) -> stop(Name) ->
grpc:stop_server(Name), grpc:stop_server(Name),
to_atom_name(Name) ! stop. case whereis(to_atom_name(Name)) of
undefined -> ok;
Pid -> Pid ! stop
end.
take() -> take() ->
to_atom_name(?NAME) ! {take, self()}, to_atom_name(?NAME) ! {take, self()},

View File

@ -640,7 +640,6 @@ handle_timeout(
Keepalive, Keepalive,
State = #state{ State = #state{
chann_mod = ChannMod, chann_mod = ChannMod,
socket = Socket,
channel = Channel channel = Channel
} }
) when ) when