Files
fluxer/fluxer_gateway/test/fluxer_gateway_sup_tests.erl
T

229 lines
9.1 KiB
Erlang

%% SPDX-License-Identifier: AGPL-3.0-or-later
-module(fluxer_gateway_sup_tests).
-typing([eqwalizer]).
-include_lib("eunit/include/eunit.hrl").
cluster_children_empty_when_flag_unset_test() ->
persistent_term:put({fluxer_gateway, runtime_config}, #{}),
?assertEqual([], fluxer_gateway_sup:cluster_children()),
persistent_term:erase({fluxer_gateway, runtime_config}).
cluster_children_empty_when_flag_false_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => false}
),
?assertEqual([], fluxer_gateway_sup:cluster_children()),
persistent_term:erase({fluxer_gateway, runtime_config}).
cluster_children_populated_when_flag_true_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true}
),
[Discovery, Membership, PgScope] = fluxer_gateway_sup:cluster_children(),
?assertMatch(
#{
id := gateway_cluster_discovery,
start := {gateway_cluster_discovery, start_link, []}
},
Discovery
),
?assertMatch(
#{
id := gateway_cluster_membership,
start := {gateway_cluster_membership, start_link, []}
},
Membership
),
?assertMatch(
#{
id := gateway_pg_scope,
start := {gateway_pg_scope, start_link, []}
},
PgScope
),
persistent_term:erase({fluxer_gateway, runtime_config}).
cluster_children_only_truthy_atom_true_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => <<"true">>}
),
?assertEqual([], fluxer_gateway_sup:cluster_children()),
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => 1}
),
?assertEqual([], fluxer_gateway_sup:cluster_children()),
persistent_term:erase({fluxer_gateway, runtime_config}).
role_enabled_allows_monolith_and_exact_role_only_test() ->
?assert(fluxer_gateway_sup:role_enabled(sessions, all)),
?assert(fluxer_gateway_sup:role_enabled(guilds, guilds)),
?assertNot(fluxer_gateway_sup:role_enabled(sessions, websocket)),
?assertNot(fluxer_gateway_sup:role_enabled(push, guilds)).
invalid_gateway_role_falls_back_to_stateless_websocket_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{gateway_role => <<"guild_session_typo">>}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(gateway_rollout_config, Ids)),
?assert(lists:member(gateway_dispatch_relay, Ids)),
?assertNot(lists:member(session_manager, Ids)),
?assertNot(lists:member(guild_manager, Ids)),
?assertNot(lists:member(presence_manager, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_returns_baseline_children_without_cluster_flag_test() ->
persistent_term:put({fluxer_gateway, runtime_config}, #{}),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assertNot(lists:member(gateway_cluster_discovery, Ids)),
?assertNot(lists:member(gateway_cluster_membership, Ids)),
?assertNot(lists:member(gateway_pg_scope, Ids)),
?assertNot(lists:member(gateway_cluster_handoff, Ids)),
?assert(lists:member(gateway_rollout_config, Ids)),
?assert(lists:member(session_manager, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_websocket_role_excludes_stateful_children_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{gateway_role => websocket}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(gateway_rollout_config, Ids)),
?assert(lists:member(gateway_dispatch_relay, Ids)),
?assertNot(lists:member(presence_bus, Ids)),
?assertNot(lists:member(session_manager, Ids)),
?assertNot(lists:member(presence_manager, Ids)),
?assertNot(lists:member(guild_manager, Ids)),
?assertNot(lists:member(call_manager, Ids)),
?assertNot(lists:member(push, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_guilds_role_includes_only_guild_state_children_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true, gateway_role => guilds}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(presence_bus, Ids)),
?assert(lists:member(guild_manager, Ids)),
?assert(lists:member(guild_counts_cache, Ids)),
?assert(lists:member(voice_state_counts_sync, Ids)),
?assert(lists:member(gateway_cluster_handoff, Ids)),
?assertNot(lists:member(session_manager, Ids)),
?assertNot(lists:member(presence_manager, Ids)),
?assertNot(lists:member(call_manager, Ids)),
?assertNot(lists:member(push, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_sessions_role_includes_cluster_handoff_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true, gateway_role => sessions}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(session_manager, Ids)),
?assert(lists:member(session_state_transfer, Ids)),
?assert(lists:member(gateway_cluster_handoff, Ids)),
?assertNot(lists:member(guild_manager, Ids)),
?assertNot(lists:member(presence_manager, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_presence_role_includes_cluster_handoff_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true, gateway_role => presence}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(presence_manager, Ids)),
?assert(lists:member(presence_cache, Ids)),
?assert(lists:member(gateway_cluster_handoff, Ids)),
?assertNot(lists:member(voice_state_counts_sync, Ids)),
?assertNot(lists:member(session_manager, Ids)),
?assertNot(lists:member(guild_manager, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_calls_role_includes_voice_state_counts_sync_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true, gateway_role => calls}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(call_manager, Ids)),
?assert(lists:member(voice_state_counts_sync, Ids)),
?assert(lists:member(gateway_cluster_handoff, Ids)),
?assertNot(lists:member(guild_manager, Ids)),
?assertNot(lists:member(presence_manager, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_push_role_includes_cluster_handoff_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true, gateway_role => push}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(push_dispatcher, Ids)),
?assert(lists:member(push, Ids)),
?assert(lists:member(gateway_cluster_handoff, Ids)),
?assertNot(lists:member(session_manager, Ids)),
?assertNot(lists:member(guild_manager, Ids)),
persistent_term:erase({fluxer_gateway, runtime_config}).
init_includes_cluster_children_when_flag_set_test() ->
persistent_term:put(
{fluxer_gateway, runtime_config},
#{cluster_enabled => true}
),
{ok, {_SupFlags, Children}} = fluxer_gateway_sup:init([]),
Ids = child_ids(Children),
?assert(lists:member(gateway_cluster_discovery, Ids)),
?assert(lists:member(gateway_cluster_membership, Ids)),
?assert(lists:member(gateway_pg_scope, Ids)),
?assert(lists:member(gateway_cluster_handoff, Ids)),
DiscoveryIdx = index_of(gateway_cluster_discovery, Ids),
MembershipIdx = index_of(gateway_cluster_membership, Ids),
PgScopeIdx = index_of(gateway_pg_scope, Ids),
PresenceBusIdx = index_of(presence_bus, Ids),
GuildManagerIdx = index_of(guild_manager, Ids),
HandoffAfterGuild = index_of_after(gateway_cluster_handoff, Ids, GuildManagerIdx),
?assert(DiscoveryIdx < MembershipIdx),
?assert(MembershipIdx < PgScopeIdx),
?assert(PgScopeIdx < PresenceBusIdx),
?assert(GuildManagerIdx < HandoffAfterGuild),
?assertEqual(length(Ids), length(lists:usort(Ids))),
persistent_term:erase({fluxer_gateway, runtime_config}).
index_of(Item, List) ->
index_of(Item, List, 1).
index_of(_Item, [], _Idx) -> not_found;
index_of(Item, [Item | _], Idx) -> Idx;
index_of(Item, [_ | Rest], Idx) -> index_of(Item, Rest, Idx + 1).
index_of_after(Item, List, AfterIdx) ->
index_of_after(Item, List, AfterIdx, 1).
index_of_after(_Item, [], _AfterIdx, _Idx) ->
not_found;
index_of_after(Item, [Item | _], AfterIdx, Idx) when Idx > AfterIdx -> Idx;
index_of_after(Item, [_ | Rest], AfterIdx, Idx) ->
index_of_after(Item, Rest, AfterIdx, Idx + 1).
child_ids(Children) ->
[child_id(Child) || Child <- Children].
child_id(#{id := Id}) -> Id;
child_id({Id, _Start, _Restart, _Shutdown, _Type, _Modules}) -> Id.