1: -module(mongoose_cleanup_SUITE). 2: 3: -include_lib("eunit/include/eunit.hrl"). 4: -include("mongoose.hrl"). 5: 6: -export([all/0, 7: init_per_suite/1, end_per_suite/1, 8: init_per_testcase/2, end_per_testcase/2]). 9: -export([cleaner_runs_hook_on_nodedown/1, notify_self_hook/3]). 10: -export([auth_anonymous/1, 11: last/1, 12: stream_management/1, 13: local/1, 14: s2s/1, 15: bosh/1 16: ]). 17: 18: -define(HOST, <<"localhost">>). 19: -define(NS_CC_2, <<"urn:xmpp:carbons:2">>). 20: 21: %% ----------------------------------------------------- 22: %% CT callbacks 23: %% ----------------------------------------------------- 24: 25: all() -> 26: [ 27: cleaner_runs_hook_on_nodedown, 28: auth_anonymous, 29: last, 30: stream_management, 31: local, 32: s2s, 33: bosh 34: ]. 35: 36: init_per_suite(Config) -> 37: {ok, _} = application:ensure_all_started(jid), 38: ok = mnesia:create_schema([node()]), 39: ok = mnesia:start(), 40: [mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts()], 41: Config. 42: 43: end_per_suite(Config) -> 44: [mongoose_config:unset_opt(Key) || {Key, _Value} <- opts()], 45: mnesia:stop(), 46: mnesia:delete_schema([node()]), 47: Config. 48: 49: opts() -> 50: [{hosts, []}, 51: {host_types, []}, 52: {all_metrics_are_global, false}]. 53: 54: init_per_testcase(T, Config) -> 55: {ok, _HooksServer} = gen_hook:start_link(), 56: ok = mongoose_lazy_routing:start(), 57: setup_meck(meck_mods(T)), 58: Config. 59: 60: end_per_testcase(T, Config) -> 61: mongoose_lazy_routing:stop(), 62: unload_meck(meck_mods(T)), 63: Config. 64: 65: meck_mods(bosh) -> [exometer, mod_bosh_socket]; 66: meck_mods(s2s) -> [exometer, ejabberd_commands, mongoose_bin]; 67: meck_mods(local) -> [exometer]; 68: meck_mods(_) -> [exometer, ejabberd_sm, ejabberd_local]. 69: 70: %% ----------------------------------------------------- 71: %% Tests 72: %% ----------------------------------------------------- 73: 74: cleaner_runs_hook_on_nodedown(_Config) -> 75: meck:expect(gen_hook, error_running_hook, fun(_, _, _, _, _) -> ok end), 76: {ok, Cleaner} = mongoose_cleaner:start_link(), 77: gen_hook:add_handler(node_cleanup, global, 78: fun ?MODULE:notify_self_hook/3, 79: #{self => self()}, 50), 80: 81: FakeNode = fakename@fakehost, 82: Cleaner ! {nodedown, FakeNode}, 83: 84: receive 85: {got_nodedown, FakeNode} -> ok 86: after timer:seconds(1) -> 87: ct:fail({timeout, got_nodedown}) 88: end, 89: ?assertEqual(false, meck:called(gen_hook, error_running_hook, 90: ['_', '_', '_', '_', '_'])). 91: 92: notify_self_hook(Acc, #{node := Node}, #{self := Self}) -> 93: Self ! {got_nodedown, Node}, 94: {ok, Acc}. 95: 96: auth_anonymous(_Config) -> 97: HostType = host_type(), 98: {U, S, R, JID, SID} = get_fake_session(), 99: ejabberd_auth_anonymous:start(HostType), 100: Info = #{auth_module => cyrsasl_anonymous}, 101: ejabberd_auth_anonymous:register_connection(#{}, HostType, SID, JID, Info), 102: true = ejabberd_auth_anonymous:does_user_exist(HostType, U, S), 103: mongoose_hooks:session_cleanup(S, new_acc(S), U, R, SID), 104: false = ejabberd_auth_anonymous:does_user_exist(HostType, U, S). 105: 106: last(_Config) -> 107: HostType = host_type(), 108: {U, S, R, _JID, SID} = get_fake_session(), 109: mod_last:start(HostType, [{backend, mnesia}, {iqdisc, no_queue}]), 110: not_found = mod_last:get_last_info(HostType, U, S), 111: Status1 = <<"status1">>, 112: #{} = mod_last:on_presence_update(new_acc(S), U, S, R, Status1), 113: {ok, TS1, Status1} = mod_last:get_last_info(HostType, U, S), 114: async_helper:wait_until( 115: fun() -> 116: mongoose_hooks:session_cleanup(S, new_acc(S), U, R, SID), 117: {ok, TS2, <<>>} = mod_last:get_last_info(HostType, U, S), 118: TS2 - TS1 > 0 119: end, 120: true). 121: 122: stream_management(_Config) -> 123: HostType = host_type(), 124: {U, S, R, _JID, SID} = get_fake_session(), 125: mod_stream_management:start(HostType, []), 126: SMID = <<"123">>, 127: mod_stream_management:register_smid(SMID, SID), 128: {sid, SID} = mod_stream_management:get_sid(SMID), 129: mongoose_hooks:session_cleanup(S, new_acc(S), U, R, SID), 130: {error, smid_not_found} = mod_stream_management:get_sid(SMID). 131: 132: local(_Config) -> 133: ejabberd_local:start_link(), 134: Self = self(), 135: SelfNotify = fun(_, _, _, Arg) -> Self ! Arg end, 136: ID = <<"abc123">>, 137: 138: ejabberd_local:register_iq_response_handler(?HOST, ID, undefined, SelfNotify, 50), 139: receive 140: timeout -> ok 141: after 142: 2000 -> ct:fail({timeout, valid_iq_timeout}) 143: end, 144: 145: ejabberd_local:register_iq_response_handler(?HOST, ID, undefined, SelfNotify, 2000), 146: {ok, undefined, _F} = ejabberd_local:get_iq_callback(ID), 147: mongoose_hooks:node_cleanup(node()), 148: error = ejabberd_local:get_iq_callback(ID). 149: 150: s2s(_Config) -> 151: ejabberd_s2s:start_link(), 152: FromTo = {?HOST, <<"foreign">>}, 153: ejabberd_s2s:try_register(FromTo), 154: Self = self(), 155: [Self] = ejabberd_s2s:get_connections_pids(FromTo), 156: mongoose_hooks:node_cleanup(node()), 157: [] = ejabberd_s2s:get_connections_pids(FromTo). 158: 159: bosh(_Config) -> 160: mod_bosh:start(?HOST, []), 161: SID = <<"sid">>, 162: Self = self(), 163: {error, _} = mod_bosh:get_session_socket(SID), 164: mod_bosh:store_session(SID, Self), 165: {ok, Self} = mod_bosh:get_session_socket(SID), 166: mongoose_hooks:node_cleanup(node()), 167: {error, _} = mod_bosh:get_session_socket(SID), 168: ok. 169: 170: %% ----------------------------------------------------- 171: %% Internal 172: %% ----------------------------------------------------- 173: 174: setup_meck([exometer | R]) -> 175: meck:new(exometer), 176: meck:expect(exometer, info, fun(_, _) -> undefined end), 177: meck:expect(exometer, new, fun(_, _) -> ok end), 178: meck:expect(exometer, update, fun(_, _) -> ok end), 179: setup_meck(R); 180: setup_meck([ejabberd_sm | R]) -> 181: meck:new(ejabberd_sm), 182: meck:expect(ejabberd_sm, register_iq_handler, 183: fun(_A1, _A2, _A3) -> ok end), 184: setup_meck(R); 185: setup_meck([ejabberd_local | R]) -> 186: meck:new(ejabberd_local), 187: meck:expect(ejabberd_local, register_iq_handler, 188: fun(_A1, _A2, _A3) -> ok end), 189: setup_meck(R); 190: setup_meck([ejabberd_commands | R]) -> 191: meck:new(ejabberd_commands), 192: meck:expect(ejabberd_commands, register_commands, fun(_) -> ok end), 193: setup_meck(R); 194: setup_meck([mongoose_bin | R]) -> 195: meck:new(mongoose_bin, [passthrough]), 196: meck:expect(mongoose_bin, gen_from_crypto, fun() -> <<"123456">> end), 197: setup_meck(R); 198: setup_meck([mod_bosh_socket | R]) -> 199: meck:new(mod_bosh_socket), 200: meck:expect(mod_bosh_socket, start_supervisor, fun() -> {ok, self()} end), 201: setup_meck(R); 202: setup_meck([]) -> 203: ok. 204: 205: unload_meck(Mods) -> 206: [ {meck:validate(Mod), meck:unload(Mod)} || 207: Mod <- Mods ]. 208: 209: -spec get_fake_session() -> 210: {U :: binary(), S :: binary(), R :: binary(), 211: JID :: jid:jid(), SID :: ejabberd_sm:sid()}. 212: get_fake_session() -> 213: U = <<"someuser">>, 214: S = ?HOST, 215: R = <<"someresource">>, 216: JID = jid:make(U, S, R), 217: SID = {os:timestamp(), self()}, 218: {U, S, R, JID, SID}. 219: 220: new_acc(Server) -> 221: mongoose_acc:new(#{location => ?LOCATION, 222: lserver => Server, 223: host_type => host_type(), 224: element => undefined}). 225: 226: host_type() -> 227: <<"test host type">>.