Skip to content

Commit c118172

Browse files
authored
Merge pull request #4373 from esl/refactor-mod-last-sessions_cleanup-test
Rewrite last_SUITE:sessions_cleanup
2 parents aafbc75 + 3186e4f commit c118172

File tree

1 file changed

+80
-29
lines changed

1 file changed

+80
-29
lines changed

Diff for: big_tests/tests/last_SUITE.erl

+80-29
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
-include_lib("escalus/include/escalus_xmlns.hrl").
2121
-include_lib("exml/include/exml.hrl").
2222
-include_lib("eunit/include/eunit.hrl").
23+
-include_lib("jid/include/jid.hrl").
24+
%% Import LOCATION macro
25+
-include_lib("kernel/include/logger.hrl").
2326

2427
-import(config_parser_helper, [mod_config_with_auto_backend/2]).
2528

@@ -29,11 +32,13 @@
2932

3033
all() ->
3134
[{group, valid_queries},
32-
{group, invalid_queries}].
35+
{group, invalid_queries},
36+
{group, sessions_cleanup}].
3337

3438
groups() ->
3539
[{valid_queries, [sequence], valid_test_cases()},
36-
{invalid_queries, invalid_test_cases()}].
40+
{invalid_queries, invalid_test_cases()},
41+
{sessions_cleanup, [], [sessions_cleanup]}].
3742

3843
valid_test_cases() -> [online_user_query,
3944
last_online_user,
@@ -43,9 +48,11 @@ valid_test_cases() -> [online_user_query,
4348
invalid_test_cases() -> [user_not_subscribed_receives_error].
4449

4550
suite() ->
46-
escalus:suite().
51+
distributed_helper:require_rpc_nodes([mim, mim2]) ++ escalus:suite().
4752

4853
init_per_suite(Config0) ->
54+
mongoose_helper:inject_module(distributed_helper:mim2(), ?MODULE, reload),
55+
distributed_helper:add_node_to_cluster(distributed_helper:mim2(), Config0),
4956
HostType = domain_helper:host_type(),
5057
Config1 = dynamic_modules:save_modules(HostType, Config0),
5158
dynamic_modules:ensure_modules(HostType, required_modules()),
@@ -68,6 +75,8 @@ init_per_group(valid_queries, Config0) ->
6875
mongoose_helper:kick_everyone(),
6976
Config2;
7077
init_per_group(invalid_queries, Config) ->
78+
Config;
79+
init_per_group(sessions_cleanup, Config) ->
7180
Config.
7281

7382
end_per_group(_GroupName, _Config) ->
@@ -170,41 +179,83 @@ user_not_subscribed_receives_error(Config) ->
170179
ok
171180
end).
172181

173-
%% This test is disabled on CI, because it puts the system in an inconsistent state.
174-
%% The sessions are created with Pids from the test node, which is incorrect.
175-
%% This incorrectly generates 'sm_session' events, leading to inconsistent session count metrics.
182+
%% Runs sessions_cleanup and check if it was done by checking last_seen timestamp.
176183
sessions_cleanup(_Config) ->
177-
N = distributed_helper:mim(),
184+
%% 345 would test 3 types of insert queries (insert 1, 10, 100).
185+
%% For load testing, increase NumberOfUsers to big number like 500000
186+
%% and check "node cleanup" time.
187+
NumberOfUsers = 345,
188+
Node1 = distributed_helper:mim(),
189+
Node2 = distributed_helper:mim2(),
190+
#{node := Node2Atom} = Node2,
191+
LongNode1 = Node1#{timeout => timer:minutes(1)},
192+
LongNode2 = Node2#{timeout => timer:minutes(1)},
178193
HostType = domain_helper:host_type(),
179194
Server = domain_helper:domain(),
180-
CreateUser = fun(Name) ->
181-
SID = {erlang:system_time(microsecond), spawn(fun() -> ok end)},
182-
JID = mongoose_helper:make_jid(Name, Server, <<"res">>),
183-
Priority = 0,
184-
Info = #{},
185-
distributed_helper:rpc(N, ejabberd_sm, open_session, [HostType, SID, JID, Priority, Info])
186-
end,
187-
Names = [<<"user", (list_to_binary((integer_to_list(X))))/binary>> || X <- lists:seq(1, 345)],
188-
measure("create users", fun() ->
189-
lists:foreach(CreateUser, Names)
195+
OldTS = 1714000000,
196+
Jid3 = create_user_and_set_lastseen(Node1, Server, <<"user3">>, OldTS),
197+
Sessions = measure("create users", fun() ->
198+
distributed_helper:rpc(LongNode2, ?MODULE, create_sessions,
199+
[HostType, Server, NumberOfUsers])
190200
end),
191-
%% Check that user3 is properly updated
192-
%% User should be registered if we want to use mod_last_api
193-
{ok, _} = distributed_helper:rpc(N, mongoose_account_api, register_user, [<<"user3">>, Server, <<"secret123">>]),
194-
Jid3 = mongoose_helper:make_jid(<<"user3">>, Server, <<>>),
195-
{ok, _} = distributed_helper:rpc(N, mod_last_api, set_last, [Jid3, 1714000000, <<"old status">>]),
196-
{ok, #{timestamp := 1714000000}} = distributed_helper:rpc(N, mod_last_api, get_last, [Jid3]),
201+
NumberOfUsers = length(Sessions),
197202
measure("node cleanup", fun() ->
198-
distributed_helper:rpc(N#{timeout => timer:minutes(1)}, mongoose_hooks, node_cleanup, [node()])
203+
Res = distributed_helper:rpc(LongNode1, mongoose_hooks,
204+
node_cleanup, [Node2Atom]),
205+
ct:pal("node_cleanup result ~p", [Res])
199206
end),
200-
{ok, #{timestamp := TS, status := Status} = Data} = distributed_helper:rpc(N, mod_last_api, get_last, [Jid3]),
201-
?assertNotEqual(TS, 1714000000, Data),
207+
{ok, #{timestamp := TS, status := Status} = Data} =
208+
distributed_helper:rpc(Node1, mod_last_api, get_last, [Jid3]),
209+
?assertNotEqual(TS, OldTS, Data),
202210
?assertEqual(Status, <<>>, Data),
203-
{ok, _} = distributed_helper:rpc(N, mongoose_account_api, unregister_user, [<<"user3">>, Server]).
211+
{ok, _} = distributed_helper:rpc(Node1, mongoose_account_api, unregister_user,
212+
[<<"user3">>, Server]),
213+
measure("close sessions", fun() ->
214+
distributed_helper:rpc(LongNode2, ?MODULE, close_sessions,
215+
[HostType, Sessions])
216+
end).
204217

205218
%%-----------------------------------------------------------------
206219
%% Helpers
207220
%%-----------------------------------------------------------------
221+
222+
create_sessions(HostType, Server, NumberOfUsers) ->
223+
[create_session(HostType, Server, Num)
224+
|| Num <- lists:seq(1, NumberOfUsers)].
225+
226+
close_sessions(HostType, Sessions) ->
227+
lists:foreach(fun(Session) -> close_session(HostType, Session) end, Sessions).
228+
229+
create_session(HostType, Server, Num) ->
230+
Name = <<"user", (list_to_binary((integer_to_list(Num))))/binary>>,
231+
SID = {erlang:system_time(microsecond), spawn(fun() -> ok end)},
232+
JID = jid:make(Name, Server, <<"res">>),
233+
Priority = 0,
234+
Info = #{},
235+
ejabberd_sm:open_session(HostType, SID, JID, Priority, Info),
236+
#{sid => SID, jid => JID}.
237+
238+
close_session(HostType, #{sid := SID, jid := JID}) ->
239+
#jid{lserver = LServer} = JID,
240+
Reason = normal,
241+
Acc = mongoose_acc:new(#{location => ?LOCATION,
242+
host_type => HostType,
243+
lserver => LServer}),
244+
Info = #{},
245+
ejabberd_sm:close_session(Acc, SID, JID, Reason, Info).
246+
247+
create_user_and_set_lastseen(Node, Server, User, TS) ->
248+
Jid = mongoose_helper:make_jid(User, Server, <<>>),
249+
%% User should be registered if we want to use mod_last_api
250+
%% Check that user3's last seen timestamp is properly updated
251+
{ok, _} = distributed_helper:rpc(Node, mongoose_account_api, register_user,
252+
[User, Server, <<"secret123">>]),
253+
{ok, _} = distributed_helper:rpc(Node, mod_last_api, set_last,
254+
[Jid, TS, <<"old status">>]),
255+
{ok, #{timestamp := TS}} =
256+
distributed_helper:rpc(Node, mod_last_api, get_last, [Jid]),
257+
Jid.
258+
208259
get_last_activity(Stanza) ->
209260
S = exml_query:path(Stanza, [{element, <<"query">>}, {attr, <<"seconds">>}]),
210261
list_to_integer(binary_to_list(S)).
@@ -227,6 +278,6 @@ required_modules() ->
227278
[{mod_last, mod_config_with_auto_backend(mod_last, #{iqdisc => one_queue})}].
228279

229280
measure(Text, F) ->
230-
{Time, _} = timer:tc(F),
281+
{Time, Val} = timer:tc(F),
231282
ct:pal("Time ~ts = ~p", [Text, Time]),
232-
ok.
283+
Val.

0 commit comments

Comments
 (0)