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

View File

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

View File

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

View File

@ -24,6 +24,7 @@
-include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl").
-include_lib("emqx/include/emqx_hooks.hrl").
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
-define(DEFAULT_CLUSTER_NAME_ATOM, emqxcl).
@ -313,6 +314,40 @@ t_cluster_name(_) ->
),
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
%%--------------------------------------------------------------------

View File

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

View File

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