1: %%============================================================================== 2: %% Copyright 2013 Erlang Solutions Ltd. 3: %% 4: %% Licensed under the Apache License, Version 2.0 (the "License"); 5: %% you may not use this file except in compliance with the License. 6: %% You may obtain a copy of the License at 7: %% 8: %% http://www.apache.org/licenses/LICENSE-2.0 9: %% 10: %% Unless required by applicable law or agreed to in writing, software 11: %% distributed under the License is distributed on an "AS IS" BASIS, 12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13: %% See the License for the specific language governing permissions and 14: %% limitations under the License. 15: %%============================================================================== 16: 17: -module(metrics_roster_SUITE). 18: -compile([export_all, nowarn_export_all]). 19: 20: -include_lib("escalus/include/escalus.hrl"). 21: -include_lib("common_test/include/ct.hrl"). 22: 23: -import(distributed_helper, [mim/0, 24: require_rpc_nodes/1, 25: rpc/4]). 26: 27: -import(metrics_helper, [assert_counter/2, 28: get_counter_value/1]). 29: 30: %%-------------------------------------------------------------------- 31: %% Suite configuration 32: %%-------------------------------------------------------------------- 33: 34: all() -> 35: [{group, roster}, 36: {group, subscriptions} 37: ]. 38: 39: groups() -> 40: [{roster, [sequence], roster_tests()}, 41: {subscriptions, [sequence], subscription_tests()}]. 42: 43: suite() -> 44: require_rpc_nodes([mim]) ++ escalus:suite(). 45: 46: roster_tests() -> [get_roster, 47: add_contact, 48: roster_push]. 49: 50: %% WARNING: Side-effects & test interference 51: %% subscribe affects subsequent tests 52: %% by sending a directed presence before the roster push 53: %% in add_sample_contact/2 54: %% TODO: investigate, fix. 55: 56: subscription_tests() -> [unsubscribe, 57: decline_subscription, 58: subscribe]. 59: %%-------------------------------------------------------------------- 60: %% Init & teardown 61: %%-------------------------------------------------------------------- 62: 63: 64: init_per_suite(Config) -> 65: 66: MongooseMetrics = [{[global, data, xmpp, received, xml_stanza_size], changed}, 67: {[global, data, xmpp, sent, xml_stanza_size], changed}, 68: {fun roster_rdbms_precondition/0, [global, data, rdbms, default], 69: [{recv_oct, '>'}, {send_oct, '>'}]}, 70: {[global, backends, mod_roster, get_subscription_lists], changed} 71: ], 72: [{mongoose_metrics, MongooseMetrics} | escalus:init_per_suite(Config)]. 73: 74: end_per_suite(Config) -> 75: escalus_fresh:clean(), 76: escalus:end_per_suite(Config). 77: 78: init_per_group(_GroupName, Config) -> 79: escalus:create_users(Config, escalus:get_users([alice, bob])). 80: 81: end_per_group(_GroupName, Config) -> 82: escalus:delete_users(Config, escalus:get_users([alice, bob])). 83: 84: init_per_testcase(CaseName, Config) -> 85: escalus:init_per_testcase(CaseName, Config). 86: 87: end_per_testcase(add_contact, Config) -> 88: [{_, UserSpec} | _] = escalus_config:get_config(escalus_users, Config), 89: remove_roster(Config, UserSpec), 90: escalus:end_per_testcase(add_contact, Config); 91: end_per_testcase(roster_push, Config) -> 92: [{_, UserSpec} | _] = escalus_config:get_config(escalus_users, Config), 93: remove_roster(Config, UserSpec), 94: escalus:end_per_testcase(roster_push, Config); 95: end_per_testcase(subscribe, Config) -> 96: end_rosters_remove(Config); 97: end_per_testcase(decline_subscription, Config) -> 98: end_rosters_remove(Config); 99: end_per_testcase(unsubscribe, Config) -> 100: end_rosters_remove(Config); 101: end_per_testcase(CaseName, Config) -> 102: escalus:end_per_testcase(CaseName, Config). 103: 104: end_rosters_remove(Config) -> 105: [{_, UserSpec1}, {_, UserSpec2} | _] = 106: escalus_config:get_config(escalus_users, Config), 107: remove_roster(Config, UserSpec1), 108: remove_roster(Config, UserSpec2), 109: escalus:end_per_testcase(subscription, Config). 110: 111: %%-------------------------------------------------------------------- 112: %% Tests 113: %%-------------------------------------------------------------------- 114: 115: get_roster(ConfigIn) -> 116: Metrics = 117: [{['_', modRosterGets], 1}, 118: {[global, backends, mod_roster, get_roster], changed} 119: ], 120: Config = mongoose_metrics(ConfigIn, Metrics), 121: 122: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice,_Bob) -> 123: escalus_client:send(Alice, escalus_stanza:roster_get()), 124: escalus_client:wait_for_stanza(Alice) 125: end). 126: 127: add_contact(ConfigIn) -> 128: Config = mongoose_metrics(ConfigIn, [{['_', modRosterSets], 1}]), 129: 130: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 131: 132: %% add contact 133: escalus_client:send(Alice, 134: escalus_stanza:roster_add_contact(Bob, 135: [<<"friends">>], 136: <<"Bobby">>)), 137: Received = escalus_client:wait_for_stanza(Alice), 138: escalus_client:send(Alice, escalus_stanza:iq_result(Received)), 139: escalus_client:wait_for_stanza(Alice) 140: 141: end). 142: 143: roster_push(ConfigIn) -> 144: Config = mongoose_metrics(ConfigIn, [{['_', modRosterSets], 1}, 145: {['_', modRosterPush], 2}]), 146: 147: escalus:fresh_story(Config, [{alice, 2}, {bob, 1}], fun(Alice1, Alice2, Bob) -> 148: 149: %% add contact 150: escalus_client:send(Alice1, 151: escalus_stanza:roster_add_contact(Bob, 152: [<<"friends">>], 153: <<"Bobby">>)), 154: Received = escalus_client:wait_for_stanza(Alice1), 155: escalus_client:send(Alice1, escalus_stanza:iq_result(Received)), 156: escalus_client:wait_for_stanza(Alice1), 157: 158: Received2 = escalus_client:wait_for_stanza(Alice2), 159: escalus_client:send(Alice2, escalus_stanza:iq_result(Received2)) 160: 161: end). 162: 163: 164: subscribe(ConfigIn) -> 165: Config = mongoose_metrics(ConfigIn, [{['_', modPresenceSubscriptions], 1}]), 166: 167: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice,Bob) -> 168: BobJid = escalus_client:short_jid(Bob), 169: AliceJid = escalus_client:short_jid(Alice), 170: 171: %% add contact 172: add_sample_contact(Alice, Bob), 173: 174: %% subscribe 175: escalus_client:send(Alice, escalus_stanza:presence_direct(BobJid, <<"subscribe">>)), 176: PushReq = escalus_client:wait_for_stanza(Alice), 177: escalus_client:send(Alice, escalus_stanza:iq_result(PushReq)), 178: 179: %% Bob receives subscription request 180: escalus_client:wait_for_stanza(Bob), 181: 182: %% Bob adds new contact to his roster 183: escalus_client:send(Bob, 184: escalus_stanza:roster_add_contact(Alice, 185: [<<"enemies">>], 186: <<"Alice">>)), 187: PushReqB = escalus_client:wait_for_stanza(Bob), 188: escalus_client:send(Bob, escalus_stanza:iq_result(PushReqB)), 189: escalus_client:wait_for_stanza(Bob), 190: 191: %% Bob sends subscribed presence 192: escalus_client:send(Bob, escalus_stanza:presence_direct(AliceJid, <<"subscribed">>)), 193: 194: %% Alice receives subscribed 195: escalus_client:wait_for_stanzas(Alice, 3), 196: 197: %% Bob receives roster push 198: escalus_client:wait_for_stanza(Bob) 199: 200: 201: end). 202: 203: decline_subscription(ConfigIn) -> 204: Config = mongoose_metrics(ConfigIn, [{['_', modPresenceUnsubscriptions], 1}]), 205: 206: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice,Bob) -> 207: BobJid = escalus_client:short_jid(Bob), 208: AliceJid = escalus_client:short_jid(Alice), 209: 210: %% add contact 211: add_sample_contact(Alice, Bob), 212: 213: %% subscribe 214: escalus_client:send(Alice, escalus_stanza:presence_direct(BobJid, <<"subscribe">>)), 215: PushReq = escalus_client:wait_for_stanza(Alice), 216: escalus_client:send(Alice, escalus_stanza:iq_result(PushReq)), 217: 218: %% Bob receives subscription request 219: escalus_client:wait_for_stanza(Bob), 220: 221: %% Bob refuses subscription 222: escalus_client:send(Bob, escalus_stanza:presence_direct(AliceJid, <<"unsubscribed">>)), 223: 224: %% Alice receives subscribed 225: escalus_client:wait_for_stanzas(Alice, 2) 226: 227: end). 228: 229: 230: unsubscribe(ConfigIn) -> 231: Config = mongoose_metrics(ConfigIn, [{['_', modPresenceUnsubscriptions], 1}]), 232: 233: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice,Bob) -> 234: BobJid = escalus_client:short_jid(Bob), 235: AliceJid = escalus_client:short_jid(Alice), 236: 237: %% add contact 238: add_sample_contact(Alice, Bob), 239: %% subscribe 240: escalus_client:send(Alice, escalus_stanza:presence_direct(BobJid, <<"subscribe">>)), 241: PushReq = escalus_client:wait_for_stanza(Alice), 242: 243: escalus_client:send(Alice, escalus_stanza:iq_result(PushReq)), 244: 245: %% Bob receives subscription request 246: escalus_client:wait_for_stanza(Bob), 247: %% Bob adds new contact to his roster 248: escalus_client:send(Bob, 249: escalus_stanza:roster_add_contact(Alice, 250: [<<"enemies">>], 251: <<"Alice">>)), 252: PushReqB = escalus_client:wait_for_stanza(Bob), 253: escalus_client:send(Bob, escalus_stanza:iq_result(PushReqB)), 254: escalus_client:wait_for_stanza(Bob), 255: 256: %% Bob sends subscribed presence 257: escalus_client:send(Bob, escalus_stanza:presence_direct(AliceJid, <<"subscribed">>)), 258: 259: %% Alice receives subscribed 260: escalus_client:wait_for_stanzas(Alice, 2), 261: 262: escalus_client:wait_for_stanza(Alice), 263: 264: %% Bob receives roster push 265: PushReqB1 = escalus_client:wait_for_stanza(Bob), 266: escalus_assert:is_roster_set(PushReqB1), 267: 268: %% Alice sends unsubscribe 269: escalus_client:send(Alice, escalus_stanza:presence_direct(BobJid, <<"unsubscribe">>)), 270: 271: PushReqA2 = escalus_client:wait_for_stanza(Alice), 272: escalus_client:send(Alice, escalus_stanza:iq_result(PushReqA2)), 273: 274: %% Bob receives unsubscribe 275: 276: escalus_client:wait_for_stanzas(Bob, 2) 277: 278: end). 279: 280: %%----------------------------------------------------------------- 281: %% Helpers 282: %%----------------------------------------------------------------- 283: 284: add_sample_contact(Alice, Bob) -> 285: add_sample_contact(Alice, Bob, [<<"friends">>], <<"generic :p name">>). 286: 287: add_sample_contact(Alice, Bob, Groups, Name) -> 288: escalus_client:send(Alice, 289: escalus_stanza:roster_add_contact(Bob, Groups, Name)), 290: RosterPush = escalus_client:wait_for_stanza(Alice), 291: escalus:assert(is_roster_set, RosterPush), 292: escalus_client:send(Alice, escalus_stanza:iq_result(RosterPush)), 293: escalus_client:wait_for_stanza(Alice). 294: 295: 296: remove_roster(Config, UserSpec) -> 297: [Username, Server, _Pass] = escalus_users:get_usp(Config, UserSpec), 298: Acc = mongoose_helper:new_mongoose_acc(Server), 299: Extra = #{host_type => domain_helper:host_type()}, 300: Params = #{jid => jid:make_bare(Username, Server)}, 301: rpc(mim(), mod_roster, remove_user, [Acc, Params, Extra]). 302: 303: mongoose_metrics(ConfigIn, Metrics) -> 304: Predefined = proplists:get_value(mongoose_metrics, ConfigIn, []), 305: MongooseMetrics = Predefined ++ Metrics, 306: [{mongoose_metrics, MongooseMetrics} | ConfigIn]. 307: 308: roster_rdbms_precondition() -> 309: mod_roster_rdbms == rpc(mim(), mongoose_backend, get_backend_name, [domain_helper:host_type(), mod_roster]).