diff options
Diffstat (limited to 'test/carbons_tests.erl')
-rw-r--r-- | test/carbons_tests.erl | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/test/carbons_tests.erl b/test/carbons_tests.erl new file mode 100644 index 000000000..2780dab66 --- /dev/null +++ b/test/carbons_tests.erl @@ -0,0 +1,202 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% @copyright (C) 2016, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%%------------------------------------------------------------------- +-module(carbons_tests). + +%% API +-compile(export_all). +-import(suite, [is_feature_advertised/2, disconnect/1, send_recv/2, + recv_presence/1, send/2, get_event/1, recv_message/1, + my_jid/1, wait_for_slave/1, wait_for_master/1, + put_event/2]). + +-include("suite.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +%%%=================================================================== +%%% Single user tests +%%%=================================================================== +single_cases() -> + {carbons_single, [sequence], + [single_test(feature_enabled), + single_test(unsupported_iq)]}. + +feature_enabled(Config) -> + true = is_feature_advertised(Config, ?NS_CARBONS_2), + disconnect(Config). + +unsupported_iq(Config) -> + lists:foreach( + fun({Type, SubEl}) -> + #iq{type = error} = + send_recv(Config, #iq{type = Type, sub_els = [SubEl]}) + end, [{Type, SubEl} || + Type <- [get, set], + SubEl <- [#carbons_sent{forwarded = #forwarded{}}, + #carbons_received{forwarded = #forwarded{}}, + #carbons_private{}]] ++ + [{get, SubEl} || SubEl <- [#carbons_enable{}, #carbons_disable{}]]), + disconnect(Config). + +%%%=================================================================== +%%% Master-slave tests +%%%=================================================================== +master_slave_cases() -> + {carbons_master_slave, [sequence], + [master_slave_test(send_recv), + master_slave_test(enable_disable)]}. + +send_recv_master(Config) -> + Peer = ?config(peer, Config), + prepare_master(Config), + ct:comment("Waiting for the peer to be ready"), + ready = get_event(Config), + send_messages(Config), + ct:comment("Waiting for the peer to disconnect"), + #presence{from = Peer, type = unavailable} = recv_presence(Config), + disconnect(Config). + +send_recv_slave(Config) -> + prepare_slave(Config), + ok = enable(Config), + put_event(Config, ready), + recv_carbons(Config), + disconnect(Config). + +enable_disable_master(Config) -> + prepare_master(Config), + ct:comment("Waiting for the peer to be ready"), + ready = get_event(Config), + send_messages(Config), + disconnect(Config). + +enable_disable_slave(Config) -> + Peer = ?config(peer, Config), + prepare_slave(Config), + ok = enable(Config), + ok = disable(Config), + put_event(Config, ready), + ct:comment("Waiting for the peer to disconnect"), + #presence{from = Peer, type = unavailable} = recv_presence(Config), + disconnect(Config). + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +single_test(T) -> + list_to_atom("carbons_" ++ atom_to_list(T)). + +master_slave_test(T) -> + {list_to_atom("carbons_" ++ atom_to_list(T)), [parallel], + [list_to_atom("carbons_" ++ atom_to_list(T) ++ "_master"), + list_to_atom("carbons_" ++ atom_to_list(T) ++ "_slave")]}. + +prepare_master(Config) -> + MyJID = my_jid(Config), + Peer = ?config(peer, Config), + #presence{from = MyJID} = send_recv(Config, #presence{priority = 10}), + wait_for_slave(Config), + ct:comment("Receiving initial presence from the peer"), + #presence{from = Peer} = recv_presence(Config), + Config. + +prepare_slave(Config) -> + Peer = ?config(peer, Config), + MyJID = my_jid(Config), + ok = enable(Config), + wait_for_master(Config), + #presence{from = MyJID} = send_recv(Config, #presence{priority = 5}), + ct:comment("Receiving initial presence from the peer"), + #presence{from = Peer} = recv_presence(Config), + Config. + +send_messages(Config) -> + Server = ?config(server, Config), + MyJID = my_jid(Config), + JID = jid:make(randoms:get_string(), Server), + lists:foreach( + fun({send, #message{type = Type} = Msg}) -> + I = send(Config, Msg#message{to = JID}), + if Type /= error -> + #message{id = I, type = error} = recv_message(Config); + true -> + ok + end; + ({recv, #message{} = Msg}) -> + ejabberd_router:route( + JID, MyJID, Msg#message{from = JID, to = MyJID}), + ct:comment("Receiving message ~s", [xmpp:pp(Msg)]), + #message{} = recv_message(Config) + end, message_iterator(Config)). + +recv_carbons(Config) -> + Peer = ?config(peer, Config), + BarePeer = jid:remove_resource(Peer), + MyJID = my_jid(Config), + lists:foreach( + fun({_, #message{sub_els = [#hint{type = 'no-copy'}]}}) -> + ok; + ({_, #message{sub_els = [#carbons_private{}]}}) -> + ok; + ({_, #message{sub_els = [#carbons_sent{}]}}) -> + ok; + ({_, #message{sub_els = [#carbons_received{}]}}) -> + ok; + ({_, #message{type = T}}) when T /= normal, T /= chat -> + ok; + ({Dir, #message{type = T, body = Body} = M}) + when (T == chat) or (T == normal andalso Body /= []) -> + ct:comment("Receiving carbon ~s", [xmpp:pp(M)]), + #message{from = BarePeer, to = MyJID} = CarbonMsg = + recv_message(Config), + case Dir of + send -> + #carbons_sent{forwarded = #forwarded{xml_els = [El]}} = + xmpp:get_subtag(CarbonMsg, #carbons_sent{}), + #message{body = Body} = xmpp:decode(El); + recv -> + #carbons_received{forwarded = #forwarded{xml_els = [El]}}= + xmpp:get_subtag(CarbonMsg, #carbons_received{}), + #message{body = Body} = xmpp:decode(El) + end; + (_) -> + false + end, message_iterator(Config)). + +enable(Config) -> + case send_recv( + Config, #iq{type = set, + sub_els = [#carbons_enable{}]}) of + #iq{type = result, sub_els = []} -> + ok; + #iq{type = error} = Err -> + xmpp:get_error(Err) + end. + +disable(Config) -> + case send_recv( + Config, #iq{type = set, + sub_els = [#carbons_disable{}]}) of + #iq{type = result, sub_els = []} -> + ok; + #iq{type = error} = Err -> + xmpp:get_error(Err) + end. + +message_iterator(_Config) -> + [{Dir, #message{type = Type, body = Body, sub_els = Els}} + || Dir <- [send, recv], + Type <- [error, chat, normal, groupchat, headline], + Body <- [[], xmpp:mk_text(<<"body">>)], + Els <- [[], + [#hint{type = 'no-copy'}], + [#carbons_private{}], + [#carbons_sent{forwarded = #forwarded{}}], + [#carbons_received{forwarded = #forwarded{}}]]]. |