1: -module(xep_0352_csi_SUITE). 2: 3: -include_lib("escalus/include/escalus.hrl"). 4: 5: -compile([export_all, nowarn_export_all]). 6: 7: -import(domain_helper, [host_type/0]). 8: -import(config_parser_helper, [default_mod_config/1, mod_config/2]). 9: 10: -define(CSI_BUFFER_MAX, 10). 11: 12: all() -> 13: [{group, basic}]. 14: 15: 16: groups() -> 17: [{basic, [parallel], all_tests()}]. 18: 19: all_tests() -> 20: [ 21: server_announces_csi, 22: alice_is_inactive_and_no_stanza_arrived, 23: inactive_twice_does_not_reset_buffer, 24: alice_gets_msgs_after_activate, 25: alice_gets_msgs_after_activate_in_order, 26: alice_gets_message_after_buffer_overflow, 27: alice_gets_buffered_messages_after_reconnection_with_sm, 28: alice_gets_buffered_messages_after_stream_resumption, 29: bob_gets_msgs_from_inactive_alice, 30: alice_is_inactive_but_sends_sm_req_and_recives_ack, 31: invalid_csi_request_returns_error 32: ]. 33: 34: suite() -> 35: escalus:suite(). 36: 37: init_per_suite(Config) -> 38: NewConfig = dynamic_modules:save_modules(host_type(), Config), 39: Backend = mongoose_helper:mnesia_or_rdbms_backend(), 40: dynamic_modules:ensure_modules( 41: host_type(), [{mod_offline, mod_config(mod_offline, #{backend => Backend})}, 42: {mod_csi, mod_config(mod_csi, #{buffer_max => ?CSI_BUFFER_MAX})}]), 43: [{escalus_user_db, {module, escalus_ejabberd}} | escalus:init_per_suite(NewConfig)]. 44: 45: end_per_suite(Config) -> 46: escalus_fresh:clean(), 47: dynamic_modules:restore_modules(Config), 48: escalus:end_per_suite(Config). 49: 50: init_per_group(_, Config) -> 51: escalus_users:update_userspec(Config, alice, stream_management, true). 52: 53: end_per_group(_Group, Config) -> 54: Config. 55: 56: init_per_testcase(CaseName, Config) -> 57: escalus:init_per_testcase(CaseName, Config). 58: 59: end_per_testcase(CaseName, Config) -> 60: escalus:end_per_testcase(CaseName, Config). 61: 62: server_announces_csi(Config) -> 63: NewConfig = escalus_fresh:create_users(Config, [{alice, 1}]), 64: Spec = escalus_users:get_userspec(NewConfig, alice), 65: Steps = [start_stream, stream_features, maybe_use_ssl, authenticate, bind, session], 66: {ok, _Client, Features} = escalus_connection:start(Spec, Steps), 67: true = proplists:get_value(client_state_indication, Features). 68: 69: invalid_csi_request_returns_error(Config) -> 70: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 71: escalus:send(Alice, csi_helper:csi_stanza(<<"invalid">>)), 72: Stanza = escalus:wait_for_stanza(Alice), 73: escalus:assert(is_error, [<<"modify">>, <<"bad-request">>], Stanza) 74: end). 75: 76: alice_is_inactive_and_no_stanza_arrived(Config) -> 77: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 78: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 79: csi_helper:given_messages_are_sent(Alice, Bob, 1), 80: csi_helper:then_client_does_not_receive_any_message(Alice) 81: end). 82: 83: alice_gets_msgs_after_activate(Config) -> 84: alice_gets_msgs_after_activate(Config, 1). 85: 86: alice_gets_msgs_after_activate_in_order(Config) -> 87: alice_gets_msgs_after_activate(Config, 3). 88: 89: alice_gets_msgs_after_activate(Config, N) -> 90: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 91: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 92: Msgs = csi_helper:given_messages_are_sent(Alice, Bob, N), 93: csi_helper:given_client_is_active(Alice), 94: csi_helper:then_client_receives_message(Alice, Msgs) 95: end). 96: 97: inactive_twice_does_not_reset_buffer(Config) -> 98: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 99: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 100: Msgs = csi_helper:given_messages_are_sent(Alice, Bob, 2), 101: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 102: csi_helper:given_client_is_active(Alice), 103: csi_helper:then_client_receives_message(Alice, Msgs) 104: end). 105: 106: alice_gets_buffered_messages_after_reconnection_with_sm(Config) -> 107: NewConfig = escalus_fresh:create_users(Config, [{alice, 1}, {bob, 1}]), 108: AliceSpec = escalus_users:get_userspec(NewConfig, alice), 109: BobSpec = escalus_users:get_userspec(NewConfig, bob), 110: {ok, Alice0 = #client{props = AliceProps}, _} = escalus_connection:start(AliceSpec), 111: JID = make_jid_from_spec(AliceProps), 112: Alice = Alice0#client{jid = JID}, 113: {ok, Bob, _} = escalus_connection:start(BobSpec), 114: 115: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 116: 117: MsgsToAlice = csi_helper:given_messages_are_sent(Alice, Bob, 5), 118: 119: %% then Alice disconnects 120: 121: escalus_connection:kill(Alice), 122: 123: ConnSteps = [start_stream, stream_features, authenticate, bind, session], 124: {ok, Alice2, _} = escalus_connection:start(AliceSpec, ConnSteps), 125: 126: csi_helper:then_client_receives_message(Alice2, MsgsToAlice), 127: escalus_connection:stop(Alice2), 128: escalus_connection:stop(Bob). 129: 130: alice_gets_buffered_messages_after_stream_resumption(Config) -> 131: ConnSteps = [start_stream, stream_features, authenticate, bind, session, stream_resumption], 132: NewConfig = escalus_fresh:create_users(Config, [{alice, 1}, {bob, 1}]), 133: AliceSpec = escalus_users:get_userspec(NewConfig, alice), 134: BobSpec = escalus_users:get_userspec(NewConfig, bob), 135: {ok, Alice0 = #client{props = AliceProps}, _} = escalus_connection:start(AliceSpec, ConnSteps), 136: JID = make_jid_from_spec(AliceProps), 137: Alice = Alice0#client{jid = JID}, 138: 139: escalus_connection:send(Alice, escalus_stanza:presence(<<"available">>)), 140: escalus:wait_for_stanza(Alice), 141: {ok, Bob, _} = escalus_connection:start(BobSpec), 142: 143: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 144: MsgsToAlice = csi_helper:given_messages_are_sent(Alice, Bob, 5), 145: csi_helper:then_client_does_not_receive_any_message(Alice), 146: 147: %% then Alice loses connection and resumes it 148: escalus_connection:kill(Alice), 149: SMID = proplists:get_value(smid, AliceProps), 150: ResumeSession = [start_stream, stream_features, authenticate, mk_resume_stream(SMID, 1)], 151: {ok, Alice2, _} = escalus_connection:start(AliceSpec, ResumeSession), 152: 153: csi_helper:then_client_receives_message(Alice2, MsgsToAlice), 154: escalus_connection:stop(Alice2), 155: escalus_connection:stop(Bob). 156: 157: make_jid_from_spec(AliceProps) -> 158: AliceUsername = proplists:get_value(username, AliceProps), 159: AliceServer = proplists:get_value(server, AliceProps), 160: <<AliceUsername/binary, "@", AliceServer/binary>>. 161: 162: mk_resume_stream(SMID, PrevH) -> 163: fun (Conn = #client{props = Props}, Features) -> 164: escalus_connection:send(Conn, escalus_stanza:resume(SMID, PrevH)), 165: Resumed = escalus_connection:get_stanza(Conn, get_resumed), 166: true = escalus_pred:is_sm_resumed(SMID, Resumed), 167: {Conn#client{props = [{smid, SMID} | Props]}, Features} 168: end. 169: 170: alice_gets_message_after_buffer_overflow(Config) -> 171: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 172: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 173: Msgs = csi_helper:given_messages_are_sent(Alice, Bob, ?CSI_BUFFER_MAX + 5), 174: {Flushed, Awaiting} = lists:split(?CSI_BUFFER_MAX+1, Msgs), 175: csi_helper:then_client_receives_message(Alice, Flushed), 176: %% and no other stanza 177: csi_helper:then_client_does_not_receive_any_message(Alice), 178: %% Alice activates 179: csi_helper:given_client_is_active(Alice), 180: %% ands gets remaining stanzas 181: csi_helper:then_client_receives_message(Alice, Awaiting) 182: end). 183: 184: bob_gets_msgs_from_inactive_alice(Config) -> 185: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 186: given_client_is_inactive_but_sends_messages(Alice, Bob, 1), 187: escalus:assert(is_chat_message, escalus:wait_for_stanza(Bob)) 188: end). 189: 190: alice_is_inactive_but_sends_sm_req_and_recives_ack(Config) -> 191: escalus:fresh_story(Config, [{alice,1}], fun(Alice) -> 192: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 193: escalus:send(Alice, escalus_stanza:sm_request()), 194: escalus:assert(is_sm_ack, escalus:wait_for_stanza(Alice)) 195: 196: end). 197: 198: given_client_is_inactive_but_sends_messages(Alice, Bob, N) -> 199: %%Given 200: csi_helper:given_client_is_inactive_and_no_messages_arrive(Alice), 201: MsgsToAlice = csi_helper:given_messages_are_sent(Alice, Bob, N), 202: MsgsToBob = csi_helper:gen_msgs(<<"Hi, Bob">>, N), 203: csi_helper:send_msgs(Alice, Bob, MsgsToBob), 204: timer:sleep(1), 205: {MsgsToAlice, MsgsToBob}.