Files
fluxer/fluxer_gateway/test/gateway_stall_monitor_tests.erl
T

94 lines
3.3 KiB
Erlang

%% SPDX-License-Identifier: AGPL-3.0-or-later
-module(gateway_stall_monitor_tests).
-include_lib("eunit/include/eunit.hrl").
stall_monitor_test_() ->
{foreach, fun setup/0, fun cleanup/1, [
fun installs_and_releases_system_monitor/1,
fun counts_forwarded_events_and_names_the_process/1,
fun leaves_a_foreign_system_monitor_alone/1,
fun records_late_timer_ticks/1
]}.
setup() ->
_ = erlang:system_monitor(undefined),
application:unset_env(fluxer_gateway, stall_monitor_enabled),
ok.
cleanup(_) ->
case whereis(gateway_stall_monitor) of
undefined -> ok;
Pid -> gen_server:stop(Pid)
end,
_ = erlang:system_monitor(undefined),
ok.
installs_and_releases_system_monitor(_) ->
fun() ->
{ok, Pid} = gateway_stall_monitor:start_link(),
unlink(Pid),
{Pid, Opts} = erlang:system_monitor(),
?assertEqual(200, proplists:get_value(long_schedule, Opts)),
?assertEqual(200, proplists:get_value(long_gc, Opts)),
?assertMatch(#{status := installed}, gateway_stall_monitor:snapshot()),
ok = gen_server:stop(Pid),
?assertEqual(undefined, erlang:system_monitor())
end.
counts_forwarded_events_and_names_the_process(_) ->
fun() ->
{ok, Pid} = gateway_stall_monitor:start_link(),
unlink(Pid),
Busy = spawn(fun() ->
receive
stop -> ok
end
end),
Info = [{timeout, 1500}, {in, {guild, handle_info, 2}}, {out, {guild, handle_info, 2}}],
Pid ! {monitor, Busy, long_schedule, Info},
Pid ! {monitor, Busy, long_gc, [{timeout, 300}, {heap_size, 10}, {old_heap_size, 0}]},
#{stats := Stats, recent := Recent} = gateway_stall_monitor:snapshot(),
?assertEqual(
#{count => 1, severe => 1, max_ms => 1500}, maps:get(long_schedule, Stats)
),
?assertEqual(#{count => 1, severe => 0, max_ms => 300}, maps:get(long_gc, Stats)),
[GcEvent, SchedEvent] = Recent,
?assertMatch(#{kind := long_gc, ms := 300, info := #{heap_size := 10}}, GcEvent),
?assertMatch(
#{kind := long_schedule, who := Busy, info := #{in := {guild, handle_info, 2}}},
SchedEvent
),
?assertMatch(#{who_info := #{guild_id := undefined}}, SchedEvent),
Busy ! stop
end.
leaves_a_foreign_system_monitor_alone(_) ->
fun() ->
Foreign = spawn(fun() ->
receive
stop -> ok
end
end),
_ = erlang:system_monitor(Foreign, [{long_gc, 500}]),
{ok, Pid} = gateway_stall_monitor:start_link(),
unlink(Pid),
?assertMatch(#{status := not_owner}, gateway_stall_monitor:snapshot()),
ok = gen_server:stop(Pid),
?assertMatch({Foreign, _}, erlang:system_monitor()),
Foreign ! stop
end.
records_late_timer_ticks(_) ->
fun() ->
{ok, Pid} = gateway_stall_monitor:start_link(),
unlink(Pid),
_ = sys:replace_state(Pid, fun(S) -> S#{tick_due := maps:get(tick_due, S) - 1300} end),
Pid ! tick,
#{stats := Stats} = gateway_stall_monitor:snapshot(),
#{count := Count, max_ms := Max} = maps:get(timer_late, Stats),
?assert(Count >= 1),
?assert(Max >= 1200)
end.