Files
fluxer/fluxer_gateway/test/session_dispatch_stress_tests.erl
T

105 lines
3.5 KiB
Erlang

%% SPDX-License-Identifier: AGPL-3.0-or-later
-module(session_dispatch_stress_tests).
-typing([eqwalizer]).
-include_lib("eunit/include/eunit.hrl").
-define(EVENT_COUNT, 6000).
-define(MAX_EVENT_BUFFER_SIZE, 4096).
-define(MAX_TOTAL_BUFFER_BYTES, 16777216).
message_create_flood_keeps_replay_buffer_bounded_test_() ->
{timeout, 30, fun message_create_flood_keeps_replay_buffer_bounded/0}.
pre_encoded_flood_does_not_fill_replay_buffer_test_() ->
{timeout, 30, fun pre_encoded_flood_does_not_fill_replay_buffer/0}.
guild_members_chunk_flood_does_not_fill_replay_buffer_test_() ->
{timeout, 30, fun guild_members_chunk_flood_does_not_fill_replay_buffer/0}.
message_create_flood_keeps_replay_buffer_bounded() ->
State0 = base_state(),
State1 = lists:foldl(
fun(Seq, State) ->
Data = #{
<<"id">> => integer_to_binary(Seq),
<<"content">> => <<"stress">>
},
{noreply, NextState} = session_dispatch:handle_dispatch(
message_create, Data, State
),
NextState
end,
State0,
lists:seq(1, ?EVENT_COUNT)
),
Buffer = maps:get(buffer, State1),
BufferedEvents = limited_deque:to_list(Buffer),
?assertEqual(?EVENT_COUNT, maps:get(seq, State1)),
?assertEqual(?MAX_EVENT_BUFFER_SIZE, limited_deque:size(Buffer)),
?assert(limited_deque:bytes(Buffer) =< ?MAX_TOTAL_BUFFER_BYTES),
?assertEqual(?EVENT_COUNT - ?MAX_EVENT_BUFFER_SIZE + 1, first_buffered_seq(BufferedEvents)),
?assertEqual(?EVENT_COUNT, last_buffered_seq(BufferedEvents)).
pre_encoded_flood_does_not_fill_replay_buffer() ->
Encoded = iolist_to_binary(json:encode(#{<<"content">> => <<"preencoded stress">>})),
State1 = lists:foldl(
fun(_Seq, State) ->
{noreply, NextState} = session_dispatch:handle_dispatch(
message_create, {pre_encoded, Encoded}, State
),
NextState
end,
base_state(),
lists:seq(1, ?EVENT_COUNT)
),
?assertEqual(?EVENT_COUNT, maps:get(seq, State1)),
?assertEqual(0, limited_deque:size(maps:get(buffer, State1))),
?assertEqual(0, maps:get(buffer_bytes, State1)).
guild_members_chunk_flood_does_not_fill_replay_buffer() ->
State1 = lists:foldl(
fun(Seq, State) ->
Data = #{
<<"guild_id">> => <<"123">>,
<<"chunk_index">> => Seq,
<<"chunk_count">> => ?EVENT_COUNT,
<<"members">> => []
},
{noreply, NextState} = session_dispatch:handle_dispatch(
guild_members_chunk, Data, State
),
NextState
end,
base_state(),
lists:seq(1, ?EVENT_COUNT)
),
?assertEqual(?EVENT_COUNT, maps:get(seq, State1)),
?assertEqual(0, limited_deque:size(maps:get(buffer, State1))),
?assertEqual(0, maps:get(buffer_bytes, State1)).
base_state() ->
#{
seq => 0,
user_id => 1,
buffer => limited_deque:new(?MAX_EVENT_BUFFER_SIZE, ?MAX_TOTAL_BUFFER_BYTES),
buffer_bytes => 0,
socket_pid => undefined,
channels => #{},
relationships => #{},
suppress_presence_updates => false,
pending_presences => [],
presence_pid => undefined,
ignored_events => #{},
debounce_reactions => false,
reaction_buffer => [],
reaction_buffer_timer => undefined
}.
first_buffered_seq([First | _]) ->
maps:get(seq, First).
last_buffered_seq(Events) ->
maps:get(seq, lists:last(Events)).