Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
chrzaszcz committed Jun 17, 2024
1 parent d844d0c commit 326c6a4
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 65 deletions.
1 change: 0 additions & 1 deletion big_tests/default.spec
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
{suites, "tests", mam_send_message_SUITE}.
{suites, "tests", metrics_api_SUITE}.
{suites, "tests", metrics_c2s_SUITE}.
{suites, "tests", metrics_register_SUITE}.
{suites, "tests", metrics_roster_SUITE}.
{suites, "tests", metrics_session_SUITE}.
{suites, "tests", mod_blocking_SUITE}.
Expand Down
2 changes: 0 additions & 2 deletions big_tests/dynamic_domains.spec
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@

{suites, "tests", metrics_c2s_SUITE}.

{suites, "tests", metrics_register_SUITE}.

{suites, "tests", metrics_roster_SUITE}.

{suites, "tests", metrics_session_SUITE}.
Expand Down
12 changes: 8 additions & 4 deletions big_tests/tests/instrument_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

-export([declared_events/1, declared_events/2,
start/1, stop/0,
assert/3, assert/4,
assert/3, assert/4, filter/2,
wait_for/2, wait_for_new/2,
lookup/2, take/2]).

Expand Down Expand Up @@ -61,9 +61,7 @@ assert(EventName, Labels, CheckF) ->
%% This is for convenience - you only have to code one clause.
-spec assert(event_name(), labels(), [measurements()], fun((measurements()) -> boolean())) -> ok.
assert(EventName, Labels, MeasurementsList, CheckF) ->
case lists:filter(fun(Measurements) ->
try CheckF(Measurements) catch error:function_clause -> false end
end, MeasurementsList) of
case filter(CheckF, MeasurementsList) of
[] ->
ct:log("All measurements for event ~p with labels ~p:~n~p",
[EventName, Labels, MeasurementsList]),
Expand All @@ -74,6 +72,12 @@ assert(EventName, Labels, MeasurementsList, CheckF) ->
event_tested(EventName, Labels)
end.

-spec filter(fun((measurements()) -> boolean()), [measurements()]) -> [measurements()].
filter(CheckF, MeasurementsList) ->
lists:filter(fun(Measurements) ->
try CheckF(Measurements) catch error:function_clause -> false end
end, MeasurementsList).

%% @doc Remove previous events, and wait for a new one. Use for probes only.
-spec wait_for_new(event_name(), labels()) -> [measurements()].
wait_for_new(EventName, Labels) ->
Expand Down
2 changes: 1 addition & 1 deletion big_tests/tests/login_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ log_one_scram_sha224(Config) ->
log_one_scram_sha256(Config) ->
log_one([{escalus_auth_method, <<"SCRAM-SHA-256">>} | Config]).

log_one_scram_sha384(Config) ->
log_one_scram_sha384(Config) ->
log_one([{escalus_auth_method, <<"SCRAM-SHA-384">>} | Config]).

log_one_scram_sha512(Config) ->
Expand Down
8 changes: 4 additions & 4 deletions big_tests/tests/metrics_api_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ one_client_just_logs_in(Config) ->
{xmppPresenceReceived, 0 + user_alpha(1)},
{xmppStanzaSent, 0 + user_alpha(3)},
{xmppStanzaReceived, 0 + user_alpha(3)},
{sessionSuccessfulLogins, 0 + user_alpha(1)},
{sessionLogouts, 0 + user_alpha(1)}
{'sm_session.logins', 0 + user_alpha(1)},
{'sm_session.logouts', 0 + user_alpha(1)}
]).

two_clients_just_log_in(Config) ->
Expand All @@ -139,8 +139,8 @@ two_clients_just_log_in(Config) ->
{xmppPresenceReceived, 0 + user_alpha(2)},
{xmppStanzaSent, 0 + user_alpha(6)},
{xmppStanzaReceived, 0 + user_alpha(6)},
{sessionSuccessfulLogins, 0 + user_alpha(2)},
{sessionLogouts, 0 + user_alpha(2)}
{'sm_session.logins', 0 + user_alpha(2)},
{'sm_session.logouts', 0 + user_alpha(2)}
]).

one_message_sent(Config) ->
Expand Down
2 changes: 1 addition & 1 deletion big_tests/tests/metrics_roster_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ declared_events() ->
declared_backend_events() ++ declared_sm_events() ++ instrument_helper:declared_events(mod_roster).

declared_sm_events() ->
[{sm_presence_subscription, #{}}].
[{sm_presence_subscription, #{host_type => host_type()}}].

declared_backend_events() ->
BackendMod = backend_mod(),
Expand Down
79 changes: 49 additions & 30 deletions big_tests/tests/metrics_session_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@
-module(metrics_session_SUITE).
-compile([export_all, nowarn_export_all]).

-include_lib("escalus/include/escalus.hrl").
-include_lib("common_test/include/ct.hrl").

-define(RT_WINDOW, 3). % seconds
-include_lib("stdlib/include/assert.hrl").

-import(metrics_helper, [assert_counter/2,
assert_counter/3,
get_counter_value/1,
wait_for_counter/2,
wait_for_counter/3]).
-import(domain_helper, [host_type/0]).

%%--------------------------------------------------------------------
%% Suite configuration
%%--------------------------------------------------------------------
Expand All @@ -36,7 +35,7 @@ all() ->
{group, session_global}].

groups() ->
[{session, [sequence], [login_one,
[{session, [parallel], [login_one,
login_many,
auth_failed]},
{session_global, [sequence], [session_global,
Expand All @@ -50,10 +49,14 @@ suite() ->
%%--------------------------------------------------------------------

init_per_suite(Config) ->
instrument_helper:start([{sm_session, #{host_type => host_type()}},
{c2s_auth_failed, #{host_type => host_type()}}]),
escalus:init_per_suite(Config).

end_per_suite(Config) ->
escalus:end_per_suite(Config).
escalus_fresh:clean(),
escalus:end_per_suite(Config),
instrument_helper:stop().

init_per_group(_GroupName, Config) ->
escalus:create_users(Config, escalus:get_users([alice, bob])).
Expand All @@ -71,39 +74,31 @@ end_per_testcase(CaseName, Config) ->
%% Tests
%%--------------------------------------------------------------------


login_one(Config) ->
{value, Logins} = get_counter_value(sessionSuccessfulLogins),
escalus:story(Config, [{alice, 1}], fun(Alice) ->

assert_counter(1, sessionCount),
assert_counter(Logins + 1, sessionSuccessfulLogins),

{value, Logouts} = get_counter_value(sessionLogouts),
escalus_client:stop(Config, Alice),
wait_for_counter(0, sessionCount),
wait_for_counter(Logouts + 1, sessionLogouts)
escalus:fresh_story(Config, [{alice, 1}], fun login_one_story/1).

end).
login_one_story(Alice) ->
assert_sm_login_event(Alice),
sm_helper:stop_client_and_wait_for_termination(Alice),
assert_sm_logout_event(Alice).

login_many(Config) ->
{value, Logins} = get_counter_value(sessionSuccessfulLogins),
escalus:story(Config, [{alice, 1}, {bob, 1}], fun(_Alice, _Bob) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun login_many_story/2).

assert_counter(2, sessionCount),
assert_counter(Logins + 2, sessionSuccessfulLogins)

end).
login_many_story(Alice, Bob) ->
assert_sm_login_event(Alice),
assert_sm_login_event(Bob),
sm_helper:stop_client_and_wait_for_termination(Alice),
assert_sm_logout_event(Alice),
sm_helper:stop_client_and_wait_for_termination(Bob),
assert_sm_logout_event(Bob).

auth_failed(Config) ->
{value, AuthFails} = get_counter_value(sessionAuthFails),

[{_, UserSpec} | _] = escalus_config:get_config(escalus_users, Config),
UserSpec = escalus_fresh:create_fresh_user(Config, alice),
UserSpecM = proplists:delete(password, UserSpec) ++ [{password, <<"mazabe">>}],

{error, _} = escalus_client:start(Config, UserSpecM, <<"res1">>),
assert_counter(0, sessionCount),
assert_counter(AuthFails + 1, sessionAuthFails).
assert_no_sm_login_event(UserSpec),
assert_c2s_auth_failed(UserSpec).

%% Global

Expand All @@ -120,3 +115,27 @@ session_unique(Config) ->
wait_for_counter(global, 1, uniqueSessionCount),
wait_for_counter(global, 2, totalSessionCount)
end).

%% Instrumentation events

assert_sm_login_event(Client) ->
JID = jid:from_binary(escalus_client:full_jid(Client)),
F = fun(M) -> M =:= #{logins => 1, count => 1, jid => JID} end,
instrument_helper:assert(sm_session, #{host_type => host_type()}, F).

assert_no_sm_login_event(UserSpec) ->
LUser = jid:nodeprep(proplists:get_value(username, UserSpec)),
LoginEvents = instrument_helper:lookup(sm_session, #{host_type => host_type()}),
F = fun(#{jid := JID}) -> jid:luser(JID) =:= LUser end,
?assertEqual([], instrument_helper:filter(F, LoginEvents)).

assert_sm_logout_event(Client) ->
JID = jid:from_binary(escalus_client:full_jid(Client)),
F = fun(M) -> M =:= #{logouts => 1, count => -1, jid => JID} end,
instrument_helper:assert(sm_session, #{host_type => host_type()}, F).

assert_c2s_auth_failed(UserSpec) ->
Server = proplists:get_value(server, UserSpec),
UserName = proplists:get_value(username, UserSpec),
F = fun(M) -> M =:= #{count => 1, server => Server, username => UserName} end,
instrument_helper:assert(c2s_auth_failed, #{host_type => host_type()}, F).
4 changes: 2 additions & 2 deletions big_tests/tests/roster_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set_versioning(Versioning, VersionStore, Config) ->
store_current_id => VersionStore}}]),
Config.

%% Intrumentation events
%% Instrumentation events

assert_roster_event(Client, Event) ->
ClientJid = jid:from_binary(escalus_utils:get_jid(Client)),
Expand All @@ -23,7 +23,7 @@ assert_subscription_event(FromClient, ToClient, CheckF) ->
FromClientJid = jid:from_binary(escalus_utils:get_short_jid(FromClient)),
ToClientJid = jid:from_binary(escalus_utils:get_short_jid(ToClient)),
instrument_helper:assert(
sm_presence_subscription, #{},
sm_presence_subscription, #{host_type => host_type()},
fun(#{from_jid := FromJid, to_jid := ToJid} = M) ->
FromClientJid =:= FromJid andalso ToClientJid =:= ToJid andalso CheckF(M)
end).
2 changes: 2 additions & 0 deletions src/c2s/mongoose_c2s.erl
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ handle_sasl_failure(#c2s_data{host_type = HostType, lserver = LServer} = StateDa
?LOG_INFO(#{what => auth_failed, text => <<"Failed SASL authentication">>,
username => Username, lserver => LServer, c2s_state => StateData}),
mongoose_hooks:auth_failed(HostType, LServer, Username),
mongoose_instrument:execute(c2s_auth_failed, #{host_type => HostType},

Check warning on line 464 in src/c2s/mongoose_c2s.erl

View check run for this annotation

Codecov / codecov/patch

src/c2s/mongoose_c2s.erl#L464

Added line #L464 was not covered by tests
#{count => 1, server => LServer, username => Username}),
El = mongoose_c2s_stanzas:sasl_failure_stanza(ServerOut),
NewSaslAcc = send_acc_from_server_jid(StateData, SaslAcc, El),
maybe_retry_state(StateData, {wait_for_feature_before_auth, NewSaslAcc, Retries}).
Expand Down
12 changes: 11 additions & 1 deletion src/c2s/mongoose_c2s_listener.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
-include("mongoose.hrl").

-behaviour(mongoose_listener).
-export([start_listener/1]).
-export([start_listener/1,
instrumentation/1]).

-behaviour(ranch_protocol).
-export([start_link/3]).
Expand Down Expand Up @@ -108,3 +109,12 @@ maybe_reuseport(true) -> [{raw, 1, 15, <<1:32/native>>}].

num_listen_sockets(false) -> 1;
num_listen_sockets(true) -> erlang:system_info(schedulers_online).

-spec instrumentation(options()) -> [mongoose_instrument:spec()].
instrumentation(_Opts) ->
lists:flatmap(fun host_type_instrumentation/1, ?ALL_HOST_TYPES).

-spec host_type_instrumentation(mongooseim:host_type()) -> [mongoose_instrument:spec()].
host_type_instrumentation(HostType) ->
[{c2s_auth_failed, #{host_type => HostType},
#{metrics => #{count => spiral}}}].
6 changes: 4 additions & 2 deletions src/ejabberd_sm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ make_new_sid() ->
open_session(HostType, SID, JID, Priority, Info) ->
set_session(SID, JID, Priority, Info),
ReplacedPIDs = check_for_sessions_to_replace(HostType, JID),
mongoose_instrument:execute(sm_session, #{host_type => HostType}, #{logins => 1, count => 1}),
mongoose_instrument:execute(sm_session, #{host_type => HostType},
#{jid => JID, logins => 1, count => 1}),
mongoose_hooks:sm_register_connection(HostType, SID, JID, Info),
ReplacedPIDs.

Expand All @@ -205,7 +206,8 @@ close_session(Acc, SID, JID, Reason, Info) ->
#jid{luser = LUser, lserver = LServer, lresource = LResource} = JID,
ejabberd_sm_backend:delete_session(SID, LUser, LServer, LResource),
HostType = mongoose_acc:host_type(Acc),
mongoose_instrument:execute(sm_session, #{host_type => HostType}, #{logouts => 1, count => -1}),
mongoose_instrument:execute(sm_session, #{host_type => HostType},
#{jid => JID, logouts => 1, count => -1}),
mongoose_hooks:sm_remove_connection(Acc, SID, JID, Info, Reason).

-spec store_info(jid:jid(), sid(), info_key(), any()) -> ok.
Expand Down
3 changes: 0 additions & 3 deletions src/metrics/mongoose_metrics_definitions.hrl
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
-define(GENERAL_SPIRALS, [
sessionSuccessfulLogins,
sessionAuthFails,
sessionLogouts,
xmppMessageSent,
xmppMessageReceived,
xmppMessageBounced,
Expand Down
16 changes: 2 additions & 14 deletions src/metrics/mongoose_metrics_hooks.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
%%-------------------
%% Internal exports
%%-------------------
-export([auth_failed/3,
user_send_packet/3,
-export([user_send_packet/3,
user_open_session/3,
xmpp_bounce_message/3,
xmpp_stanza_dropped/3,
Expand All @@ -30,8 +29,7 @@
%% @doc Here will be declared which hooks should be registered
-spec get_hooks(_) -> [gen_hook:hook_tuple(), ...].
get_hooks(HostType) ->
[ {auth_failed, HostType, fun ?MODULE:auth_failed/3, #{}, 50},
{xmpp_stanza_dropped, HostType, fun ?MODULE:xmpp_stanza_dropped/3, #{}, 50},
[ {xmpp_stanza_dropped, HostType, fun ?MODULE:xmpp_stanza_dropped/3, #{}, 50},
{xmpp_bounce_message, HostType, fun ?MODULE:xmpp_bounce_message/3, #{}, 50},
{xmpp_send_element, HostType, fun ?MODULE:xmpp_send_element/3, #{}, 50}
| c2s_hooks(HostType)].
Expand All @@ -41,16 +39,6 @@ c2s_hooks(HostType) ->
[{user_send_packet, HostType, fun ?MODULE:user_send_packet/3, #{}, 50},
{user_open_session, HostType, fun ?MODULE:user_open_session/3, #{}, 50}].

-spec auth_failed(Acc, Params, Extra) -> {ok, Acc} when
Acc :: any(),
Params :: #{server := jid:server()},
Extra :: map().
auth_failed(Acc, #{server := Server}, _) ->
LServer = jid:nameprep(Server),
{ok, HostType} = mongoose_domain_api:get_host_type(LServer),
mongoose_metrics:update(HostType, sessionAuthFails, 1),
{ok, Acc}.

-spec user_send_packet(mongoose_acc:t(), mongoose_c2s_hooks:params(), map()) ->
mongoose_c2s_hooks:result().
user_send_packet(Acc, _Params, #{host_type := HostType}) ->
Expand Down

0 comments on commit 326c6a4

Please sign in to comment.