From 0d2dd71de5292895f69d5f08b000e03e928bdd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 8 Aug 2016 20:49:00 +0200 Subject: =?UTF-8?q?Don=E2=80=99t=20use=20!=20as=20the=20separator=20for=20?= =?UTF-8?q?nicknames,=20use=20%=20instead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s now easier to use. The distinction between a nick and a channel name is based on the first character (by default it's '#' and '&'). The user doesn’t have to worry about which separator to use anymore. fix #3066 --- tests/end_to_end/__main__.py | 44 +++++++++++++++--------------- tests/iid.cpp | 64 +++++++++++++++++++------------------------- 2 files changed, 50 insertions(+), 58 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 4348197..d438265 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -648,8 +648,8 @@ if __name__ == '__main__': # That second user sends a private message to the first one partial(send_stanza, "RELLO"), # Message is received with a server-wide JID, by the two resources behind nick_one - partial(expect_stanza, "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='RELLO']"), - partial(expect_stanza, "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='RELLO']"), + partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='RELLO']"), + partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='RELLO']"), # One resource leaves the server entirely. partial(send_stanza, ""), @@ -662,8 +662,8 @@ if __name__ == '__main__': partial(send_stanza, "first"), partial(send_stanza, "second"), # The first user receives the two messages, on the connected resource, once each - partial(expect_stanza, "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']"), - partial(expect_stanza, "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']"), + partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']"), + partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']"), ]), @@ -708,10 +708,10 @@ if __name__ == '__main__': # Send a private message, to a in-room JID partial(send_stanza, "coucou in private"), # Message is received with a server-wide JID - partial(expect_stanza, "/message[@from='{lower_nick_one}!{irc_server_one}'][@to='{jid_two}/{resource_one}'][@type='chat']/body[text()='coucou in private']"), + partial(expect_stanza, "/message[@from='{lower_nick_one}%{irc_server_one}'][@to='{jid_two}/{resource_one}'][@type='chat']/body[text()='coucou in private']"), # Respond to the message, to the server-wide JID - partial(send_stanza, "yes"), + partial(send_stanza, "yes"), # The response is received from the in-room JID partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='yes']"), @@ -729,10 +729,10 @@ if __name__ == '__main__': # Send a private message, to a in-room JID partial(send_stanza, "re in private"), # Message is received with a server-wide JID - partial(expect_stanza, "/message[@from='{lower_nick_one}!{irc_server_one}'][@to='{jid_two}/{resource_one}'][@type='chat']/body[text()='re in private']"), + partial(expect_stanza, "/message[@from='{lower_nick_one}%{irc_server_one}'][@to='{jid_two}/{resource_one}'][@type='chat']/body[text()='re in private']"), # Respond to the message, to the server-wide JID - partial(send_stanza, "re"), + partial(send_stanza, "re"), # The response is received from the in-room JID partial(expect_stanza, "/message[@from='%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='re']"), @@ -743,9 +743,9 @@ if __name__ == '__main__': "/presence[@type='unavailable']/muc_user:x/muc_user:status[@code='110']"), # The private messages from this nick should now come (again) from the server-wide JID - partial(send_stanza, "hihihoho"), + partial(send_stanza, "hihihoho"), partial(expect_stanza, - "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_one}']"), + "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}']"), ] ), Scenario("encoded_channel_join", @@ -781,10 +781,10 @@ if __name__ == '__main__': ""), # We receive our own ping request, partial(expect_stanza, - "/iq[@from='{lower_nick_one}!{irc_server_one}'][@type='get'][@to='{jid_one}/{resource_one}'][@id='gnip_tsrif']"), + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to='{jid_one}/{resource_one}'][@id='gnip_tsrif']"), # Respond to the request partial(send_stanza, - ""), + ""), partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_ping']"), @@ -802,21 +802,21 @@ if __name__ == '__main__': ""), # We receive our own ping request. Note that we don't know the to value, it could be one of our two resources. partial(expect_stanza, - "/iq[@from='{lower_nick_one}!{irc_server_one}'][@type='get'][@to][@id='gnip_dnoces']", + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to][@id='gnip_dnoces']", after = partial(save_value, "to", partial(extract_attribute, "/iq", "to"))), # Respond to the request, using the extracted 'to' value as our 'from' partial(send_stanza, - ""), + ""), partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_ping']"), ## And re-do exactly the same thing, just change the resource initiating the self ping partial(send_stanza, ""), partial(expect_stanza, - "/iq[@from='{lower_nick_one}!{irc_server_one}'][@type='get'][@to][@id='gnip_driht']", + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to][@id='gnip_driht']", after = partial(save_value, "to", partial(extract_attribute, "/iq", "to"))), partial(send_stanza, - ""), + ""), partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_two}'][@id='third_ping']"), @@ -944,11 +944,11 @@ if __name__ == '__main__': ""), # We receive our own request, partial(expect_stanza, - "/iq[@from='{lower_nick_one}!{irc_server_one}'][@type='get'][@to='{jid_one}/{resource_one}']", + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to='{jid_one}/{resource_one}']", after = partial(save_value, "id", partial(extract_attribute, "/iq", 'id'))), # Respond to the request partial(send_stanza, - "e2e test1.0Fedora"), + "e2e test1.0Fedora"), partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_version']/version:query/version:name[text()='e2e test (through the biboumi gateway) 1.0 Fedora']"), @@ -966,12 +966,12 @@ if __name__ == '__main__': ""), # We receive our own request. Note that we don't know the to value, it could be one of our two resources. partial(expect_stanza, - "/iq[@from='{lower_nick_one}!{irc_server_one}'][@type='get'][@to]", + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to]", after = (partial(save_value, "to", partial(extract_attribute, "/iq", "to")), partial(save_value, "id", partial(extract_attribute, "/iq", "id")))), # Respond to the request, using the extracted 'to' value as our 'from' partial(send_stanza, - "e2e test1.0Fedora"), + "e2e test1.0Fedora"), partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_two}'][@id='second_version']"), @@ -980,12 +980,12 @@ if __name__ == '__main__': ""), # We receive our own request. Note that we don't know the to value, it could be one of our two resources. partial(expect_stanza, - "/iq[@from='{lower_nick_one}!{irc_server_one}'][@type='get'][@to]", + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to]", after = (partial(save_value, "to", partial(extract_attribute, "/iq", "to")), partial(save_value, "id", partial(extract_attribute, "/iq", "id")))), # Respond to the request, using the extracted 'to' value as our 'from' partial(send_stanza, - "e2e test1.0Fedora"), + "e2e test1.0Fedora"), partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_version']"), ]), diff --git a/tests/iid.cpp b/tests/iid.cpp index 74d010d..b42b9e5 100644 --- a/tests/iid.cpp +++ b/tests/iid.cpp @@ -47,66 +47,60 @@ namespace Catch TEST_CASE("Iid creation") { - Iid iid1("foo!irc.example.org"); - CHECK(std::to_string(iid1) == "foo!irc.example.org"); + const std::set chantypes {'#', '&'}; + Iid iid1("foo%irc.example.org", chantypes); + CHECK(std::to_string(iid1) == "foo%irc.example.org"); CHECK(iid1.get_local() == "foo"); CHECK(iid1.get_server() == "irc.example.org"); - CHECK(!iid1.is_channel); - CHECK(iid1.is_user); + CHECK(iid1.type == Iid::Type::User); - Iid iid2("#test%irc.example.org"); + Iid iid2("#test%irc.example.org", chantypes); CHECK(std::to_string(iid2) == "#test%irc.example.org"); CHECK(iid2.get_local() == "#test"); CHECK(iid2.get_server() == "irc.example.org"); - CHECK(iid2.is_channel); - CHECK(!iid2.is_user); + CHECK(iid2.type == Iid::Type::Channel); - Iid iid3("%irc.example.org"); + Iid iid3("%irc.example.org", chantypes); CHECK(std::to_string(iid3) == "%irc.example.org"); - CHECK(iid3.get_local() == ""); + CHECK(iid3.get_local().empty()); CHECK(iid3.get_server() == "irc.example.org"); - CHECK(iid3.is_channel); - CHECK(!iid3.is_user); + CHECK(iid3.type == Iid::Type::Channel); - Iid iid4("irc.example.org"); + Iid iid4("irc.example.org", chantypes); CHECK(std::to_string(iid4) == "irc.example.org"); CHECK(iid4.get_local() == ""); CHECK(iid4.get_server() == "irc.example.org"); - CHECK(!iid4.is_channel); - CHECK(!iid4.is_user); + CHECK(iid4.type == Iid::Type::Server); - Iid iid5("nick!"); - CHECK(std::to_string(iid5) == "nick!"); + Iid iid5("nick%", chantypes); + CHECK(std::to_string(iid5) == "nick%"); CHECK(iid5.get_local() == "nick"); CHECK(iid5.get_server() == ""); - CHECK(!iid5.is_channel); - CHECK(iid5.is_user); + CHECK(iid5.type == Iid::Type::User); - Iid iid6("##channel%"); + Iid iid6("##channel%", chantypes); CHECK(std::to_string(iid6) == "##channel%"); CHECK(iid6.get_local() == "##channel"); CHECK(iid6.get_server() == ""); - CHECK(iid6.is_channel); - CHECK(!iid6.is_user); + CHECK(iid6.type == Iid::Type::Channel); } TEST_CASE("Iid creation in fixed_server mode") { Config::set("fixed_irc_server", "fixed.example.com", false); - Iid iid1("foo!irc.example.org"); - CHECK(std::to_string(iid1) == "foo!"); - CHECK(iid1.get_local() == "foo"); + const std::set chantypes {'#', '&'}; + Iid iid1("foo%irc.example.org", chantypes); + CHECK(std::to_string(iid1) == "foo%irc.example.org"); + CHECK(iid1.get_local() == "foo%irc.example.org"); CHECK(iid1.get_server() == "fixed.example.com"); - CHECK(!iid1.is_channel); - CHECK(iid1.is_user); + CHECK(iid1.type == Iid::Type::User); - Iid iid2("#test%irc.example.org"); + Iid iid2("#test%irc.example.org", chantypes); CHECK(std::to_string(iid2) == "#test%irc.example.org"); CHECK(iid2.get_local() == "#test%irc.example.org"); CHECK(iid2.get_server() == "fixed.example.com"); - CHECK(iid2.is_channel); - CHECK(!iid2.is_user); + CHECK(iid2.type == Iid::Type::Channel); // Note that it is impossible to adress the IRC server directly, or to // use the virtual channel, in that mode @@ -114,17 +108,15 @@ TEST_CASE("Iid creation in fixed_server mode") // Iid iid3("%irc.example.org"); // Iid iid4("irc.example.org"); - Iid iid5("nick!"); - CHECK(std::to_string(iid5) == "nick!"); + Iid iid5("nick", chantypes); + CHECK(std::to_string(iid5) == "nick"); CHECK(iid5.get_local() == "nick"); CHECK(iid5.get_server() == "fixed.example.com"); - CHECK(!iid5.is_channel); - CHECK(iid5.is_user); + CHECK(iid5.type == Iid::Type::User); - Iid iid6("##channel%"); + Iid iid6("##channel%", chantypes); CHECK(std::to_string(iid6) == "##channel%"); CHECK(iid6.get_local() == "##channel%"); CHECK(iid6.get_server() == "fixed.example.com"); - CHECK(iid6.is_channel); - CHECK(!iid6.is_user); + CHECK(iid6.type == Iid::Type::Channel); } -- cgit v1.2.3 From a4ab1db55f8ca8e130528eed01eeee04ffc8369d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 16 Aug 2016 16:18:08 +0200 Subject: e2e test self invite --- tests/end_to_end/__main__.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index d438265..4a3abfb 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -989,6 +989,24 @@ if __name__ == '__main__': partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_version']"), ]), + Scenario("self_invite", + [ + handshake_sequence(), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + partial(send_stanza, + ""), + partial(expect_stanza, + "/message/body[text()='{nick_one} is already on channel #foo']") + ]) ) failures = 0 -- cgit v1.2.3 From 5406de35a39c935a19460da06bf3dcd3948a00d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 17 Aug 2016 20:44:00 +0200 Subject: On a client error, do not QUIT, just make the resource leave all channels This should fix #3205 --- tests/end_to_end/__main__.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 4a3abfb..21718f6 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1006,6 +1006,39 @@ if __name__ == '__main__': ""), partial(expect_stanza, "/message/body[text()='{nick_one} is already on channel #foo']") + ]), + Scenario("client_error", + [ + handshake_sequence(), + # First resource + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + # Second resource, same channel + partial(send_stanza, + ""), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"), + + # Now the first resource has an error + partial(send_stanza, + ""), + # Receive a leave only to the leaving resource + partial(expect_stanza, + ("/presence[@type='unavailable'][@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:status[@code='110']", + "/presence/status[text()='Biboumi note: 1 resources are still in this channel.']") + ), ]) ) -- cgit v1.2.3 From c97e3498216e24ceb4633a5fdce0847ea0609103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 20 Aug 2016 02:36:41 +0200 Subject: =?UTF-8?q?Remove=20dns=20unit=20tests,=20because=20they=20are=20n?= =?UTF-8?q?ot=20*unit*=20test=20(depends=20on=20network=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/dns.cpp | 91 ----------------------------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 tests/dns.cpp (limited to 'tests') diff --git a/tests/dns.cpp b/tests/dns.cpp deleted file mode 100644 index c3eda7b..0000000 --- a/tests/dns.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "catch.hpp" - -#include -#include -#include - -#include - -TEST_CASE("DNS resolver") -{ - Resolver resolver; - Resolver resolver2; - Resolver resolver3; - - /** - * If we are using cares, we need to run a poller loop until each - * resolution is finished. Without cares we get the result before - * resolve() returns because it’s blocking. - */ -#ifdef CARES_FOUND - auto p = std::make_shared(); - - const auto loop = [&p]() - { - do - { - DNSHandler::instance.watch_dns_sockets(p); - } - while (p->poll(utils::no_timeout) != -1); - }; -#else - // We don’t need to do anything if we are not using cares. - const auto loop = [](){}; -#endif - - std::string hostname; - std::string port = "6667"; - - bool success = true; - - const auto error_cb = [&success](const std::string& hostname) - { - return [&success, hostname](const char *msg) - { - INFO("Failed to resolve " << hostname << ":" << msg); - success = false; - }; - }; - const auto success_cb = [&success](const std::string& hostname) - { - return [&success, hostname](const struct addrinfo *addr) - { - INFO("Successfully resolved " << hostname << ": " << addr_to_string(addr)); - success = true; - }; - }; - - hostname = "example.com"; - resolver.resolve(hostname, port, - success_cb(hostname), error_cb(hostname)); - hostname = "poez.io"; - resolver2.resolve(hostname, port, - success_cb(hostname), error_cb(hostname)); - hostname = "louiz.org"; - resolver3.resolve(hostname, port, - success_cb(hostname), error_cb(hostname)); - loop(); - CHECK(success); - - hostname = "this.should.fail.because.it.is..misformatted"; - resolver.resolve(hostname, port, - success_cb(hostname), error_cb(hostname)); - loop(); - CHECK(!success); - - hostname = "this.should.fail.because.it.is.does.not.exist.invalid"; - resolver.resolve(hostname, port, - success_cb(hostname), error_cb(hostname)); - loop(); - CHECK(!success); - - hostname = "localhost"; - resolver.resolve(hostname, port, - success_cb(hostname), error_cb(hostname)); - loop(); - CHECK(success); - -#ifdef CARES_FOUND - DNSHandler::instance.destroy(); -#endif -} -- cgit v1.2.3 From 992fa938951558f4515145c9b82af0123c979a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 21 Aug 2016 01:04:32 +0200 Subject: Add get_first_non_empty and use it into Database to simplify a little bit --- tests/utils.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tests') diff --git a/tests/utils.cpp b/tests/utils.cpp index 01d070e..e7ba415 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -6,6 +6,9 @@ #include #include #include +#include + +using namespace std::string_literals; TEST_CASE("String split") { @@ -100,3 +103,11 @@ TEST_CASE("string cut") CHECK(res[0] == "rhello, "); CHECK(res[1] == "♥"); } + +TEST_CASE("first non-empty string") +{ + CHECK(get_first_non_empty(""s, ""s, "hello"s, "world"s) == "hello"s); + CHECK(get_first_non_empty(""s, ""s, ""s, ""s) == ""s); + CHECK(get_first_non_empty("first"s) == "first"s); + CHECK(get_first_non_empty(0, 1, 2, 3) == 1); +} -- cgit v1.2.3 From f7fa34436a4d0f92d8d454ceb48d3df111c822b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 22 Aug 2016 21:30:59 +0200 Subject: Delete the database before each e2e test, to start fresh --- tests/end_to_end/__main__.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 21718f6..dbbbe88 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -254,6 +254,8 @@ class BiboumiTest: with open("test.conf", "w") as fd: fd.write(confs[scenario.conf]) + os.remove("e2e_test.sqlite") + # Start the XMPP component and biboumi biboumi = BiboumiRunner(scenario.name, with_valgrind) xmpp = XMPPComponent(self.scenario, biboumi) -- cgit v1.2.3 From 20b187daa02a2fc4eda708ac3be406b88060c06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 23 Aug 2016 20:57:57 +0200 Subject: Do not fail e2e if the database cannot be removed because it's not there --- tests/end_to_end/__main__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index dbbbe88..c534608 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -254,7 +254,10 @@ class BiboumiTest: with open("test.conf", "w") as fd: fd.write(confs[scenario.conf]) - os.remove("e2e_test.sqlite") + try: + os.remove("e2e_test.sqlite") + except FileNotFoundError: + pass # Start the XMPP component and biboumi biboumi = BiboumiRunner(scenario.name, with_valgrind) -- cgit v1.2.3 From 7536a1b3f38fbf093c1629b0db209754ada0c906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 25 Aug 2016 19:43:51 +0200 Subject: Respond to MAM requests on a channel JID At the moment, result-set-management is not implemented, the whole history (well, at most 1024 messages) is returned. --- tests/end_to_end/__main__.py | 50 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index c534608..57e91c9 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -74,7 +74,7 @@ class XMPPComponent(slixmpp.BaseXMPP): self.scenario.steps = [] self.failed = True - def on_end_session(self, event): + def on_end_session(self, _): self.loop.stop() def handle_incoming_stanza(self, stanza): @@ -113,7 +113,11 @@ def match(stanza, xpath): 'disco_items': 'http://jabber.org/protocol/disco#items', 'commands': 'http://jabber.org/protocol/commands', 'dataform': 'jabber:x:data', - 'version': 'jabber:iq:version'}) + 'version': 'jabber:iq:version', + 'mam': 'urn:xmpp:mam:1', + 'delay': 'urn:xmpp:delay', + 'forward': 'urn:xmpp:forward:0', + 'client': 'jabber:client'}) return matched @@ -1044,7 +1048,47 @@ if __name__ == '__main__': ("/presence[@type='unavailable'][@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:status[@code='110']", "/presence/status[text()='Biboumi note: 1 resources are still in this channel.']") ), - ]) + ]), + Scenario("simple_mam", + [ + handshake_sequence(), + # First user joins + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + # Send two channel messages + partial(send_stanza, "coucou"), + # Receive the message, forwarded to the two users + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), + + partial(send_stanza, "coucou 2"), + # Receive the message, forwarded to the two users + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']"), + + # Retrieve the complete archive + partial(send_stanza, ""), + + partial(expect_stanza, + ("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay", + "/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou']") + ), + partial(expect_stanza, + ("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay", + "/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou 2']") + ), + + partial(expect_stanza, + "/iq[@type='result'][@id='id1'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']") + + ]), ) failures = 0 -- cgit v1.2.3 From 2a4905df0153c47656555a21f3d57bbad6f3ffe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 31 Aug 2016 01:17:45 +0200 Subject: Fix to_string(time_t) and write a unit test for it --- tests/utils.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tests') diff --git a/tests/utils.cpp b/tests/utils.cpp index e7ba415..abe7ef7 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace std::string_literals; @@ -111,3 +112,12 @@ TEST_CASE("first non-empty string") CHECK(get_first_non_empty("first"s) == "first"s); CHECK(get_first_non_empty(0, 1, 2, 3) == 1); } + +TEST_CASE("time_to_string") +{ + const std::time_t stamp = 1472480968; + const std::string result = "2016-08-29T14:29:28Z"; + CHECK(utils::to_string(stamp) == result); + CHECK(utils::to_string(stamp).size() == result.size()); + CHECK(utils::to_string(0) == "1970-01-01T00:00:00Z"); +} -- cgit v1.2.3 From 1140db3b88bb70cbcab044efa729707bd5a442f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 31 Aug 2016 01:58:13 +0200 Subject: Add parse_datetime --- tests/utils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/utils.cpp b/tests/utils.cpp index abe7ef7..084a048 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -121,3 +121,11 @@ TEST_CASE("time_to_string") CHECK(utils::to_string(stamp).size() == result.size()); CHECK(utils::to_string(0) == "1970-01-01T00:00:00Z"); } + +TEST_CASE("parse_datetime") +{ + const auto time = utils::parse_datetime("1970-01-01T00:00:00Z"); + CHECK(time == 0); + CHECK(utils::parse_datetime("2016-08-29T14:29:28Z") == 1472480968); + CHECK(utils::parse_datetime("blah") == -1); +} \ No newline at end of file -- cgit v1.2.3 From 3047bd41b212390da8e3a4dbcf351e79879042dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 4 Sep 2016 21:04:21 +0200 Subject: MAM results can be filtered by start and end dates --- tests/end_to_end/__main__.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 57e91c9..e1779de 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1086,8 +1086,32 @@ if __name__ == '__main__': ), partial(expect_stanza, - "/iq[@type='result'][@id='id1'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']") + "/iq[@type='result'][@id='id1'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']"), + # Retrieve an empty archive by specifying an early “end” date + partial(send_stanza, """ + + + urn:xmpp:mam:1 + 2000-06-07T00:00:00Z + + """), + + partial(expect_stanza, + "/iq[@type='result'][@id='id2'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']"), + + # Retrieve an empty archive by specifying a late “start” date + # (note that this test will break in ~1000 years) + partial(send_stanza, """ + + + urn:xmpp:mam:1 + 3016-06-07T00:00:00Z + + """), + + partial(expect_stanza, + "/iq[@type='result'][@id='id3'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']"), ]), ) -- cgit v1.2.3 From aaa2ca670ab5f19390e77a1f5ea88017b312ceaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 17 Sep 2016 00:34:28 +0200 Subject: Fix the parse_datetime by using %Z instead of %z If anybody knows why fedora accepts both, but it only works with %z on debian, please tell me. --- tests/utils.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/utils.cpp b/tests/utils.cpp index 084a048..5913f8d 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -127,5 +127,7 @@ TEST_CASE("parse_datetime") const auto time = utils::parse_datetime("1970-01-01T00:00:00Z"); CHECK(time == 0); CHECK(utils::parse_datetime("2016-08-29T14:29:28Z") == 1472480968); + CHECK(utils::parse_datetime("2016-08-29T14:29:28UT") == 1472480968); + CHECK(utils::parse_datetime("2016-08-29T14:29:28GMT") == 1472480968); CHECK(utils::parse_datetime("blah") == -1); } \ No newline at end of file -- cgit v1.2.3 From 93ebf45f3050681f94497aac889d30885a503a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 20 Sep 2016 19:02:12 +0200 Subject: Make history messages work with fixed_irc_server fix #3209 --- tests/end_to_end/__main__.py | 106 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index e1779de..a893935 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1052,7 +1052,6 @@ if __name__ == '__main__': Scenario("simple_mam", [ handshake_sequence(), - # First user joins partial(send_stanza, ""), connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), @@ -1066,11 +1065,9 @@ if __name__ == '__main__': # Send two channel messages partial(send_stanza, "coucou"), - # Receive the message, forwarded to the two users partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), partial(send_stanza, "coucou 2"), - # Receive the message, forwarded to the two users partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']"), # Retrieve the complete archive @@ -1113,6 +1110,109 @@ if __name__ == '__main__': partial(expect_stanza, "/iq[@type='result'][@id='id3'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']"), ]), + Scenario("mam_on_fixed_server", + [ + handshake_sequence(), + + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"), + + partial(send_stanza, "coucou"), + partial(expect_stanza, "/message[@from='#foo@{biboumi_host}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), + + partial(send_stanza, "coucou 2"), + partial(expect_stanza, "/message[@from='#foo@{biboumi_host}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']"), + + # Retrieve the complete archive + partial(send_stanza, ""), + + partial(expect_stanza, + ("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay", + "/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo@{biboumi_host}/{nick_one}'][@type='groupchat']/client:body[text()='coucou']") + ), + partial(expect_stanza, + ("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay", + "/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo@{biboumi_host}/{nick_one}'][@type='groupchat']/client:body[text()='coucou 2']") + ), + ], conf="fixed_server"), + Scenario("channel_history_on_fixed_server", + [ + handshake_sequence(), + # First user join + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"), + + # Send one channel message + partial(send_stanza, "coucou"), + partial(expect_stanza, "/message[@from='#foo@{biboumi_host}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), + + # Second user joins + partial(send_stanza, + ""), + # connection_sequence("irc.localhost", '{jid_one}/{resource_two}'), + # partial(expect_stanza, + # "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + # Receive the history message + partial(expect_stanza, ("/message[@from='#foo@{biboumi_host}/{nick_one}']/body[text()='coucou']", + "/message/delay:delay[@from='#foo@{biboumi_host}']")), + + partial(expect_stanza, "/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"), + ], conf="fixed_server"), + Scenario("channel_history", + [ + handshake_sequence(), + # First user join + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + # Send one channel message + partial(send_stanza, "coucou"), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), + + # Second user joins + partial(send_stanza, + ""), + # connection_sequence("irc.localhost", '{jid_one}/{resource_two}'), + # partial(expect_stanza, + # "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + # Receive the history message + partial(expect_stanza, ("/message[@from='#foo%{irc_server_one}/{nick_one}']/body[text()='coucou']", + "/message/delay:delay[@from='#foo%{irc_server_one}']")), + + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + ]) ) failures = 0 -- cgit v1.2.3 From ffad4306b9e9c6065a01a5fcaca668d70af0db8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 2 Oct 2016 12:56:04 +0200 Subject: =?UTF-8?q?Use=20LIST=20*=20instead=20of=20just=20LIST,=20because?= =?UTF-8?q?=20some=20servers=20don=E2=80=99t=20accept=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also add a e2e test for the list query --- tests/end_to_end/__main__.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index a893935..d498ba7 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1212,7 +1212,39 @@ if __name__ == '__main__': "/message/delay:delay[@from='#foo%{irc_server_one}']")), partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), - ]) + ]), + Scenario("simple_channel_list", + [ + handshake_sequence(), + + partial(log_message, "Join first channel #foo"), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + partial(log_message, "Join second channel #bar"), + partial(send_stanza, + ""), + partial(expect_stanza, + "/message/body[text()='Mode #bar [+nt] by {irc_host_one}']"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message[@from='#bar%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + partial(log_message, "Request the whole channel list"), + partial(send_stanza, ""), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']" + )) + ]) ) failures = 0 -- cgit v1.2.3 From 76a8189b46177eb78eee12d1cb3266f282acd380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 3 Oct 2016 00:58:21 +0200 Subject: Implement result-set-management for LIST queries ref #2948 --- tests/end_to_end/__main__.py | 193 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index d498ba7..f4decff 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -117,7 +117,8 @@ def match(stanza, xpath): 'mam': 'urn:xmpp:mam:1', 'delay': 'urn:xmpp:delay', 'forward': 'urn:xmpp:forward:0', - 'client': 'jabber:client'}) + 'client': 'jabber:client', + 'rsm': 'http://jabber.org/protocol/rsm'}) return matched @@ -1244,7 +1245,195 @@ if __name__ == '__main__': "/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']", "/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']" )) - ]) + ]), + Scenario("channel_list_with_rsm", + [ + handshake_sequence(), + + partial(log_message, "Join first channel #foo"), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + partial(log_message, "Join second channel #bar"), + partial(send_stanza, + ""), + partial(expect_stanza, + "/message/body[text()='Mode #bar [+nt] by {irc_host_one}']"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message[@from='#bar%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + partial(log_message, "Join third channel #coucou"), + partial(send_stanza, + ""), + partial(expect_stanza, + "/message/body[text()='Mode #coucou [+nt] by {irc_host_one}']"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message[@from='#coucou%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + partial(log_message, "Request with max=0"), + partial(send_stanza, "0"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + )), + + partial(log_message, "Request with max=2"), + partial(send_stanza, "2"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#bar%{irc_server_one}'][@index='0']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#coucou%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:count[text()='3']" + )), + + partial(log_message, "Request with max=12"), + partial(send_stanza, "12"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#bar%{irc_server_one}'][@index='0']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#foo%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:count[text()='3']" + )), + + partial(log_message, "Request with max=1 after=#bar"), + partial(send_stanza, "#bar%{irc_server_one}1"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#coucou%{irc_server_one}'][@index='1']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#coucou%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:count[text()='3']" + )), + + partial(log_message, "Request with max=1 after=#bar"), + partial(send_stanza, "#bar%{irc_server_one}1"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#coucou%{irc_server_one}'][@index='1']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#coucou%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:count[text()='3']" + )) + ]), + Scenario("complete_channel_list_with_pages_of_3", + [ + handshake_sequence(), + + partial(log_message, "Join 10 channels"), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, + ""), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(log_message, "Request the first page, with a limit of 3"), + partial(send_stanza, "3"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#aaa%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#bbb%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#ccc%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#aaa%{irc_server_one}'][@index='0']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#ccc%{irc_server_one}']" + )), + + partial(log_message, "Request subsequent pages"), + partial(send_stanza, "#ccc%{irc_server_one}3"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#ddd%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#eee%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#fff%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#ddd%{irc_server_one}'][@index='3']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#fff%{irc_server_one}']" + )), + + partial(send_stanza, "#fff%{irc_server_one}3"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#ggg%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#hhh%{irc_server_one}']", + "/iq/disco_items:query/disco_items:item[@jid='#iii%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#ggg%{irc_server_one}'][@index='6']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#iii%{irc_server_one}']" + )), + + partial(send_stanza, "#iii%{irc_server_one}3"), + partial(expect_stanza, ( + "/iq[@type='result']/disco_items:query", + "/iq/disco_items:query/disco_items:item[@jid='#jjj%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:first[text()='#jjj%{irc_server_one}'][@index='9']", + "/iq/disco_items:query/rsm:set/rsm:last[text()='#jjj%{irc_server_one}']", + "/iq/disco_items:query/rsm:set/rsm:count[text()='10']" + )), + ]) ) failures = 0 -- cgit v1.2.3 From b2f14f9a464f695c69dd82c30fc19034fded7065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 3 Oct 2016 01:07:56 +0200 Subject: Modify the charybdis conf to disable the LIST throttling --- tests/end_to_end/ircd.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/ircd.conf b/tests/end_to_end/ircd.conf index 7edb3a8..7327531 100644 --- a/tests/end_to_end/ircd.conf +++ b/tests/end_to_end/ircd.conf @@ -477,8 +477,8 @@ general { operspy_admin_only = no; operspy_dont_care_user_info = no; caller_id_wait = 1 minute; - pace_wait_simple = 1 second; - pace_wait = 10 seconds; + pace_wait_simple = 0 second; + pace_wait = 0 seconds; short_motd = no; ping_cookie = no; connect_timeout = 30 seconds; -- cgit v1.2.3 From e5b392ece8c90605b86d0d93f0ca6989048bc1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 3 Oct 2016 23:30:20 +0200 Subject: Fix parse_datetime by always using a 'z' as the timezone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because some plateform accept Z and z, but some only accept z… --- tests/utils.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/utils.cpp b/tests/utils.cpp index 5913f8d..a18fc81 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -124,10 +124,7 @@ TEST_CASE("time_to_string") TEST_CASE("parse_datetime") { - const auto time = utils::parse_datetime("1970-01-01T00:00:00Z"); - CHECK(time == 0); - CHECK(utils::parse_datetime("2016-08-29T14:29:28Z") == 1472480968); - CHECK(utils::parse_datetime("2016-08-29T14:29:28UT") == 1472480968); - CHECK(utils::parse_datetime("2016-08-29T14:29:28GMT") == 1472480968); + CHECK(utils::parse_datetime("1970-01-01T00:00:00z") == 0); + CHECK(utils::parse_datetime("2016-08-29T14:29:29Z") == 1472480969); CHECK(utils::parse_datetime("blah") == -1); } \ No newline at end of file -- cgit v1.2.3 From 28f1dd76548fc9a7de3920d938903f68cdfffe0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 3 Oct 2016 21:35:16 +0200 Subject: Make version requests work with global user JIDs as well fix #3210 --- tests/end_to_end/__main__.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index f4decff..25cf29c 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -999,6 +999,36 @@ if __name__ == '__main__': partial(expect_stanza, "/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_version']"), ]), + Scenario("version_on_global_nick", + [ + partial(log_message, "Joining the channel"), + handshake_sequence(), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + + partial(log_message, "Send a version request to ourself"), + partial(send_stanza, + ""), + + partial(log_message, "Receive our own request"), + partial(expect_stanza, + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to='{jid_one}/{resource_one}']", + after = partial(save_value, "id", partial(extract_attribute, "/iq", 'id'))), + partial(log_message, "Respond to the request"), + partial(send_stanza, + "e2e test1.0Fedora"), + partial(expect_stanza, + "/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_version']/version:query/version:name[text()='e2e test (through the biboumi gateway) 1.0 Fedora']"), + + ]), Scenario("self_invite", [ handshake_sequence(), -- cgit v1.2.3 From 1d197ff26ce5a88ba851969edb3ea915759c3477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 4 Oct 2016 19:32:45 +0200 Subject: Respond to muc#traffic requests fix #3069 --- tests/end_to_end/__main__.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 25cf29c..a4fc239 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -110,6 +110,8 @@ def match(stanza, xpath): tree = lxml.etree.parse(io.StringIO(str(stanza))) matched = tree.xpath(xpath, namespaces={'re': 'http://exslt.org/regular-expressions', 'muc_user': 'http://jabber.org/protocol/muc#user', + 'disco_info': 'http://jabber.org/protocol/disco#info', + 'muc_traffic': 'http://jabber.org/protocol/muc#traffic', 'disco_items': 'http://jabber.org/protocol/disco#items', 'commands': 'http://jabber.org/protocol/commands', 'dataform': 'jabber:x:data', @@ -1463,7 +1465,38 @@ if __name__ == '__main__': "/iq/disco_items:query/rsm:set/rsm:last[text()='#jjj%{irc_server_one}']", "/iq/disco_items:query/rsm:set/rsm:count[text()='10']" )), - ]) + + partial(log_message, "Leaving the 10 channels"), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(send_stanza, ""), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']"), + partial(expect_stanza, "/presence[@type='unavailable']") + ]), + Scenario("muc_traffic_info", + [ + handshake_sequence(), + + partial(send_stanza, + ""), + partial(expect_stanza, "/iq[@type='result']/disco_info:query[@node='{muc_traffic}']"), + ]), + ) failures = 0 -- cgit v1.2.3 From 6ca8cd505f0b21ea50d4124babdf57fe7d7add24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 7 Oct 2016 23:25:26 +0200 Subject: Cleanup __main__.py a little bit --- tests/end_to_end/__main__.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index a4fc239..b2aea37 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -91,11 +91,12 @@ class XMPPComponent(slixmpp.BaseXMPP): self.run_scenario() def run_scenario(self): - if scenario.steps: - step = scenario.steps.pop(0) + if self.scenario.steps: + step = self.scenario.steps.pop(0) step(self, self.biboumi) else: - self.biboumi.stop() + if self.biboumi: + self.biboumi.stop() @asyncio.coroutine def accept_routine(self): @@ -194,10 +195,11 @@ class ProcessRunner: class BiboumiRunner(ProcessRunner): - def __init__(self, name, with_valgrind): + def __init__(self, name): super().__init__() self.name = name self.fd = open("biboumi_%s_output.txt" % (name,), "w") + with_valgrind = os.environ.get("E2E_WITH_VALGRIND") is not None if with_valgrind: self.create = asyncio.create_subprocess_exec("valgrind", "--suppressions=" + (os.environ.get("E2E_BIBOUMI_SUPP_DIR") or "") + "biboumi.supp", "--leak-check=full", "--show-leak-kinds=all", "--errors-for-leak-kinds=all", "--error-exitcode=16", @@ -248,7 +250,8 @@ class BiboumiTest: self.scenario = scenario self.expected_code = expected_code - def run(self, with_valgrind=True): + def run(self): + with_valgrind = os.environ.get("E2E_WITH_VALGRIND") is not None print("Running scenario: %s%s" % (self.scenario.name, " (with valgrind)" if with_valgrind else '')) # Redirect the slixmpp logging into a specific file output_filename = "slixmpp_%s_output.txt" % (self.scenario.name,) @@ -259,7 +262,7 @@ class BiboumiTest: filename=output_filename) with open("test.conf", "w") as fd: - fd.write(confs[scenario.conf]) + fd.write(confs[self.scenario.conf]) try: os.remove("e2e_test.sqlite") @@ -267,7 +270,7 @@ class BiboumiTest: pass # Start the XMPP component and biboumi - biboumi = BiboumiRunner(scenario.name, with_valgrind) + biboumi = BiboumiRunner(self.scenario.name) xmpp = XMPPComponent(self.scenario, biboumi) asyncio.get_event_loop().run_until_complete(biboumi.start()) @@ -276,7 +279,7 @@ class BiboumiTest: xmpp.process() code = asyncio.get_event_loop().run_until_complete(biboumi.wait()) xmpp.biboumi = None - scenario.steps.clear() + self.scenario.steps.clear() failed = False if not xmpp.failed: if code != self.expected_code: @@ -1516,11 +1519,11 @@ if __name__ == '__main__': print("irc server started.") print("Running %s checks for biboumi." % (len(scenarios))) - for scenario in scenarios: - test = BiboumiTest(scenario) - if not test.run(os.getenv("E2E_BIBOUMI_VALGRIND") is not None): + for s in scenarios: + test = BiboumiTest(s) + if not test.run(): print("You can check the files slixmpp_%s_output.txt and biboumi_%s_output.txt to help you debug." % - (scenario.name, scenario.name)) + (s.name, s.name)) failures += 1 print("Waiting for irc server to exit…") -- cgit v1.2.3 From 8cf292fa446e26012cf4a8ff186105d8e762f79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 7 Oct 2016 23:26:44 +0200 Subject: e2e: add expec_unordered to be able to test things even if the arrive in a different order Also, some tests that were raising some exception and thus were not ran at all fix #3213 --- tests/end_to_end/__main__.py | 192 +++++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 89 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index b2aea37..a104ded 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -137,6 +137,29 @@ def check_xpath(xpaths, xmpp, after, stanza): else: after(stanza, xmpp) +def all_xpaths_match(stanza, xpaths): + for xpath in xpaths: + matched = match(stanza, xpath) + if not matched: + return False + return True + +def check_list_of_xpath(list_of_xpaths, xmpp, stanza): + found = None + for i, xpaths in enumerate(list_of_xpaths): + if all_xpaths_match(stanza, xpaths): + found = i + break + + if found is None: + raise StanzaError("Received stanza “%s” did not match any of the expected xpaths:\n%s" % (stanza, list_of_xpaths)) + + list_of_xpaths.pop(i) + + if list_of_xpaths: + step = partial(expect_unordered_already_formatted, list_of_xpaths) + xmpp.scenario.steps.insert(0, step) + def check_xpath_optional(xpaths, xmpp, after, stanza): try: @@ -233,6 +256,21 @@ def expect_stanza(xpaths, xmpp, biboumi, optional=False, after=None): else: print("Warning, from argument type passed to expect_stanza: %s" % (type(xpaths))) +# list_of_xpaths: [(xpath, xpath), (xpath, xpath), (xpath)] +def expect_unordered(list_of_xpaths, xmpp, biboumi): + formatted_list_of_xpaths = [] + for xpaths in list_of_xpaths: + formatted_xpaths = [] + for xpath in xpaths: + formatted_xpath = xpath.format_map(common_replacements) + formatted_xpaths.append(formatted_xpath) + formatted_list_of_xpaths.append(tuple(formatted_xpaths)) + # formatted_list_of_xpaths = [tuple(xpath.format_map(common_replacements) for xpath in xpaths) for xpaths in list_of_xpaths] + + expect_unordered_already_formatted(formatted_list_of_xpaths, xmpp, biboumi) + +def expect_unordered_already_formatted(formatted_list_of_xpaths, xmpp, biboumi): + xmpp.stanza_checker = partial(check_list_of_xpath, formatted_list_of_xpaths, xmpp) def log_message(message, xmpp, biboumi): print("%s" % (message,)) @@ -479,24 +517,13 @@ if __name__ == '__main__': partial(send_stanza, ""), connection_sequence("irc.localhost", '{jid_two}/{resource_one}'), - # Our presence, sent to the other user - partial(log_message, - "Our presence sent to the other user"), - partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",)), - # The other user presence - partial(log_message, - "The other user presence"), - partial(expect_stanza, - "/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']"), - # Our own presence - partial(log_message, - "Our own presence"), - partial(expect_stanza, - ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']", - "/presence/muc_user:x/muc_user:status[@code='110']") - ), - partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + partial(expect_unordered, [ + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant'][@jid='~bobby@localhost']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']", + "/presence/muc_user:x/muc_user:status[@code='110']",), + ("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]",), + ]), ]), Scenario("channel_custom_topic", [ @@ -527,7 +554,7 @@ if __name__ == '__main__': ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",)), # The other user presence partial(expect_stanza, - "/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']"), + "/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"), # Our own presence partial(expect_stanza, ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']", @@ -636,28 +663,29 @@ if __name__ == '__main__': partial(send_stanza, ""), # We receive our own join - partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", - "/presence/muc_user:x/muc_user:status[@code='110']") + partial(expect_unordered, + [("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]",)] ), - partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"), # A different user joins the same room partial(send_stanza, ""), connection_sequence("irc.localhost", '{jid_two}/{resource_one}'), - partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']",)), - partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}']",)), + partial(expect_unordered, [ + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']",), + ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}']",) + ] + ), - partial(expect_stanza, - "/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']"), - partial(expect_stanza, - ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']", - "/presence/muc_user:x/muc_user:status[@code='110']") - ), + partial(expect_unordered, [ + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']", + "/presence/muc_user:x/muc_user:status[@code='110']",), + ] + ), partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), # That second user sends a private message to the first one @@ -679,8 +707,6 @@ if __name__ == '__main__': # The first user receives the two messages, on the connected resource, once each partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']"), partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']"), - - ]), Scenario("channel_messages", [ @@ -692,7 +718,7 @@ if __name__ == '__main__': partial(expect_stanza, "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", "/presence/muc_user:x/muc_user:status[@code='110']") ), partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), @@ -702,23 +728,21 @@ if __name__ == '__main__': ""), connection_sequence("irc.localhost", '{jid_two}/{resource_one}'), # Our presence, sent to the other user - partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",)), - # The other user presence - partial(expect_stanza, - "/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']"), - # Our own presence - partial(expect_stanza, - ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']", - "/presence/muc_user:x/muc_user:status[@code='110']") - ), - partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), + partial(expect_unordered, [ + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]",) + ]), # Send a channel message partial(send_stanza, "coucou"), # Receive the message, forwarded to the two users - partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), - partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='coucou']"), + partial(expect_unordered, [ + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='coucou']",) + ]), # Send a private message, to a in-room JID partial(send_stanza, "coucou in private"), @@ -851,34 +875,30 @@ if __name__ == '__main__': partial(send_stanza, ""), connection_sequence("irc.localhost", '{jid_two}/{resource_one}'), - partial(expect_stanza, - "/presence/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']",), - - partial(expect_stanza, - "/presence/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"), - partial(expect_stanza, - "/presence/muc_user:x/muc_user:status[@code='110']"), - partial(expect_stanza, "/message/subject"), + partial(expect_unordered, [ + ("/presence/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']",), + ("/presence/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",), + ("/presence/muc_user:x/muc_user:status[@code='110']",), + ("/message/subject",), + ]), # Moderator kicks participant partial(log_message, "Moderator kicks participant"), partial(send_stanza, "reported"), partial(log_message, "Presence is sent to everyone"), - partial(expect_stanza, - ("/presence[@type='unavailable'][@to='{jid_second}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", + partial(expect_unordered, [ + ("/presence[@type='unavailable'][@to='{jid_two}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", "/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']", "/presence/muc_user:x/muc_user:status[@code='307']", "/presence/muc_user:x/muc_user:status[@code='110']" - )), - partial(expect_stanza, - ("/presence[@type='unavailable']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", + ), + ("/presence[@type='unavailable'][@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", "/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']", "/presence/muc_user:x/muc_user:status[@code='307']", ), - ), - partial(expect_stanza, - "/iq[@id='kick1'][@type='result']"), + ("/iq[@id='kick1'][@type='result']",), + ]), ]), Scenario("multisession_kick", [ @@ -891,18 +911,16 @@ if __name__ == '__main__': partial(expect_stanza, "/presence/muc_user:x/muc_user:status[@code='110']"), partial(expect_stanza, "/message[@type='groupchat']/subject"), - # Second user joins, from two resources + # Second user joins, fprom two resources partial(send_stanza, ""), connection_sequence("irc.localhost", '{jid_two}/{resource_one}'), - partial(expect_stanza, - "/presence/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']",), - - partial(expect_stanza, - "/presence/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"), - partial(expect_stanza, - "/presence/muc_user:x/muc_user:status[@code='110']"), - partial(expect_stanza, "/message/subject"), + partial(expect_unordered, [ + ("/presence/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']",), + ("/presence/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",), + ("/presence/muc_user:x/muc_user:status[@code='110']",), + ("/message/subject",), + ]), partial(send_stanza, ""), @@ -919,26 +937,23 @@ if __name__ == '__main__': partial(send_stanza, "reported"), partial(log_message, "Unavailable presence is sent to the two resources"), - partial(expect_stanza, - ("/presence[@type='unavailable'][@to='{jid_second}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", + partial(expect_unordered, [ + ("/presence[@type='unavailable'][@to='{jid_two}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", "/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']", "/presence/muc_user:x/muc_user:status[@code='307']", "/presence/muc_user:x/muc_user:status[@code='110']" - )), - partial(expect_stanza, - ("/presence[@type='unavailable'][@to='{jid_second}/{resource_two}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", + ), + ("/presence[@type='unavailable'][@to='{jid_two}/{resource_two}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", "/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']", "/presence/muc_user:x/muc_user:status[@code='307']", "/presence/muc_user:x/muc_user:status[@code='110']" - )), - partial(expect_stanza, + ), ("/presence[@type='unavailable']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']", "/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']", "/presence/muc_user:x/muc_user:status[@code='307']", ), - ), - partial(expect_stanza, - "/iq[@id='kick1'][@type='result']"), + ("/iq[@id='kick1'][@type='result']",), + ]), ]), Scenario("self_version", [ @@ -1094,7 +1109,7 @@ if __name__ == '__main__': partial(expect_stanza, "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", "/presence/muc_user:x/muc_user:status[@code='110']") ), partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), @@ -1156,7 +1171,7 @@ if __name__ == '__main__': partial(expect_stanza, "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), partial(expect_stanza, - ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']", + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']", "/presence/muc_user:x/muc_user:status[@code='110']") ), partial(expect_stanza, "/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"), @@ -1496,10 +1511,9 @@ if __name__ == '__main__': handshake_sequence(), partial(send_stanza, - ""), - partial(expect_stanza, "/iq[@type='result']/disco_info:query[@node='{muc_traffic}']"), + ""), + partial(expect_stanza, "/iq[@type='result']/disco_info:query[@node='http://jabber.org/protocol/muc#traffic']"), ]), - ) failures = 0 -- cgit v1.2.3 From 548e4ad473e7be22f971184312cc5ce9b8fe56b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 11 Oct 2016 00:18:48 +0200 Subject: Parse the timezone myself, instead of using the broken strptime See https://lab.louiz.org/louiz/biboumi/issues/3215 https://github.com/andikleen/glibc/blob/master/time/strptime_l.c#L746-L747 for why strptime() sucks We use std::get_time now, to parse the date and time. And we parse the timezone by hand. fix #3215 --- tests/utils.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/utils.cpp b/tests/utils.cpp index a18fc81..48951da 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -124,7 +124,19 @@ TEST_CASE("time_to_string") TEST_CASE("parse_datetime") { - CHECK(utils::parse_datetime("1970-01-01T00:00:00z") == 0); + CHECK(utils::parse_datetime("1970-01-01T00:00:00Z") == 0); + + const int twenty_three_hours = 82800; + CHECK(utils::parse_datetime("1970-01-01T23:00:12Z") == twenty_three_hours + 12); + CHECK(utils::parse_datetime("1970-01-01T23:00:12Z") == utils::parse_datetime("1970-01-01T23:00:12+00:00")); + CHECK(utils::parse_datetime("1970-01-01T23:00:12Z") == utils::parse_datetime("1970-01-01T23:00:12-00:00")); + CHECK(utils::parse_datetime("1970-01-02T00:00:12Z") == utils::parse_datetime("1970-01-01T23:00:12-01:00")); + CHECK(utils::parse_datetime("1970-01-02T00:00:12Z") == utils::parse_datetime("1970-01-02T01:00:12+01:00")); + CHECK(utils::parse_datetime("2016-08-29T14:29:29Z") == 1472480969); + CHECK(utils::parse_datetime("blah") == -1); -} \ No newline at end of file + CHECK(utils::parse_datetime("1970-01-02T00:00:12B") == -1); + CHECK(utils::parse_datetime("1970-01-02T00:00:12*00:00") == -1); + CHECK(utils::parse_datetime("1970-01-02T00:00:12+0000") == -1); +} -- cgit v1.2.3 From c3a7cd36279a123feec6d3665a4ba64b7ac1866b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 12 Oct 2016 20:59:13 +0200 Subject: e2e: the port to use should be an int, not a string --- tests/end_to_end/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index a104ded..1218c89 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -101,7 +101,7 @@ class XMPPComponent(slixmpp.BaseXMPP): @asyncio.coroutine def accept_routine(self): self.accepting_server = yield from self.loop.create_server(lambda: self, - "127.0.0.1", "8811", reuse_address=True) + "127.0.0.1", 8811, reuse_address=True) def check_stanza_against_all_expected_xpaths(self): pass -- cgit v1.2.3 From 44f35a256dd7fc3238ae81f9bd42a42c013dba90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 12 Oct 2016 20:59:37 +0200 Subject: e2e: test the private and no-copy thingy --- tests/end_to_end/__main__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 1218c89..9cad963 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -121,7 +121,9 @@ def match(stanza, xpath): 'delay': 'urn:xmpp:delay', 'forward': 'urn:xmpp:forward:0', 'client': 'jabber:client', - 'rsm': 'http://jabber.org/protocol/rsm'}) + 'rsm': 'http://jabber.org/protocol/rsm', + 'carbon': 'urn:xmpp:carbons:2', + 'hints': 'urn:xmpp:hints'}) return matched @@ -691,7 +693,9 @@ if __name__ == '__main__': # That second user sends a private message to the first one partial(send_stanza, "RELLO"), # Message is received with a server-wide JID, by the two resources behind nick_one - partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='RELLO']"), + partial(expect_stanza, ("/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='RELLO']", + "/message/hints:no-copy", + "/message/carbon:private")), partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='RELLO']"), # One resource leaves the server entirely. -- cgit v1.2.3 From 34bd8b93da7f7dd570a100b125941eef6331410e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 12 Oct 2016 22:18:53 +0200 Subject: Disable the output in the config unit test --- tests/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests') diff --git a/tests/config.cpp b/tests/config.cpp index ddea151..a6fa92a 100644 --- a/tests/config.cpp +++ b/tests/config.cpp @@ -1,9 +1,14 @@ #include "catch.hpp" +#include "io_tester.hpp" + +#include #include TEST_CASE("Config basic") { + // Disable all output for this test + IoTester out(std::cout); // Write a value in the config file Config::read_conf("test.cfg"); Config::set("coucou", "bonjour", true); -- cgit v1.2.3 From 501a6f26614116e70cdbb1c9633aeefd0a7d5399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 14 Oct 2016 23:51:04 +0200 Subject: Add two e2e tests on adhoc commands --- tests/end_to_end/__main__.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 9cad963..5526e19 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -123,7 +123,8 @@ def match(stanza, xpath): 'client': 'jabber:client', 'rsm': 'http://jabber.org/protocol/rsm', 'carbon': 'urn:xmpp:carbons:2', - 'hints': 'urn:xmpp:hints'}) + 'hints': 'urn:xmpp:hints', + 'stanza': 'urn:ietf:params:xml:ns:xmpp-stanzas'}) return matched @@ -647,6 +648,35 @@ if __name__ == '__main__': partial(send_stanza, "COUCOU"), partial(expect_stanza, "/iq[@type='result']/commands:command[@node='hello'][@status='completed']/commands:note[@type='info'][text()='Hello COUCOU!']") ]), + Scenario("execute_forbidden_adhoc_command", + [ + handshake_sequence(), + partial(send_stanza, ""), + partial(expect_stanza, ("/iq[@type='error'][@id='command1']/commands:command[@node='disconnect-user']", + "/iq/commands:command/commands:error[@type='cancel']/stanza:forbidden")), + ]), + Scenario("execute_disconnect_user_adhoc_command", + [ + handshake_sequence(), + + partial(log_message, "Join a channel"), + partial(send_stanza, ""), + connection_sequence("irc.localhost", '{jid_admin}/{resource_one}'), + partial(expect_stanza, "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, ""), + partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='disconnect-user'][@sessionid][@status='executing']", + "/iq/commands:command/commands:actions/commands:next", + ), + after = partial(save_value, "sessionid", partial(extract_attribute, "/iq/commands:command[@node='disconnect-user']", "sessionid")) + ), + partial(send_stanza, "{jid_admin}Disconnected by e2e"), + partial(expect_stanza, "/iq[@type='result']/commands:command[@node='disconnect-user'][@status='completed']/commands:note[@type='info'][text()='1 user has been disconnected.']"), + # Note, charybdis ignores our QUIT message, so we can't test it + partial(expect_stanza, "/presence[@type='unavailable'][@to='{jid_admin}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']"), + ]), Scenario("multisessionnick", [ handshake_sequence(), -- cgit v1.2.3 From 2a0f5f1b6a92540cebb38340683a9713309a8d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 17 Oct 2016 19:48:51 +0200 Subject: Add tests for the nick change, and the nick conflict --- tests/end_to_end/__main__.py | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 5526e19..6942073 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -268,8 +268,6 @@ def expect_unordered(list_of_xpaths, xmpp, biboumi): formatted_xpath = xpath.format_map(common_replacements) formatted_xpaths.append(formatted_xpath) formatted_list_of_xpaths.append(tuple(formatted_xpaths)) - # formatted_list_of_xpaths = [tuple(xpath.format_map(common_replacements) for xpath in xpaths) for xpaths in list_of_xpaths] - expect_unordered_already_formatted(formatted_list_of_xpaths, xmpp, biboumi) def expect_unordered_already_formatted(formatted_list_of_xpaths, xmpp, biboumi): @@ -367,6 +365,7 @@ common_replacements = { 'jid_two': 'second@example.com', 'jid_admin': 'admin@example.com', 'nick_two': 'Bobby', + 'nick_three': 'Bernard', 'lower_nick_one': 'nick', 'lower_nick_two': 'bobby', } @@ -728,16 +727,49 @@ if __name__ == '__main__': "/message/carbon:private")), partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='RELLO']"), + + partial(log_message, "Nickname conflict"), + # First occupant (with the two resources) changes her/his nick + partial(send_stanza, ""), + partial(expect_unordered, [ + ("/message[@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='irc.localhost: Bobby: Nickname is already in use.']",), + ("/message[@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='irc.localhost: Bobby: Nickname is already in use.']",), + ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}'][@type='error']",), + ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}'][@type='error']",), + ]), + + # partial(log_message, "Nickname change"), + # First occupant (with the two resources) changes her/his nick + partial(send_stanza, ""), + partial(expect_unordered, [ + ("/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']", + "/presence/muc_user:x/muc_user:status[@code='303']"), + ("/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_two}/{resource_one}']",), + ("/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']", + "/presence/muc_user:x/muc_user:status[@code='303']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ("/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_one}/{resource_one}']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + + ("/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_two}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']", + "/presence/muc_user:x/muc_user:status[@code='303']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ("/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_one}/{resource_two}']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ]), + # One resource leaves the server entirely. partial(send_stanza, ""), # The leave is forwarded only to us partial(expect_stanza, ("/presence[@type='unavailable']/muc_user:x/muc_user:status[@code='110']", - "/presence/status[text()='Biboumi note: 1 resources are still in this channel.']") + "/presence/status[text()='Biboumi note: 1 resources are still in this channel.']", + ) ), + # The second user sends two new private messages to the first user - partial(send_stanza, "first"), - partial(send_stanza, "second"), + partial(send_stanza, "first"), + partial(send_stanza, "second"), # The first user receives the two messages, on the connected resource, once each partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']"), partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']"), -- cgit v1.2.3 From 6b4d2e8e3ea6a019778624106b7a839d875152cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 17 Oct 2016 19:49:45 +0200 Subject: Use expect_unordered in a few more places --- tests/end_to_end/__main__.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 6942073..d04238e 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -707,16 +707,13 @@ if __name__ == '__main__': partial(expect_unordered, [ ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']",), - ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}']",) + ("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']", + "/presence/muc_user:x/muc_user:status[@code='110']",), + ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']",), ] ), - partial(expect_unordered, [ - ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']",), - ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']", - "/presence/muc_user:x/muc_user:status[@code='110']",), - ] - ), partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), # That second user sends a private message to the first one @@ -771,8 +768,11 @@ if __name__ == '__main__': partial(send_stanza, "first"), partial(send_stanza, "second"), # The first user receives the two messages, on the connected resource, once each - partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']"), - partial(expect_stanza, "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']"), + + partial(expect_unordered, [ + ("/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']",), + ("/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']",), + ]), ]), Scenario("channel_messages", [ -- cgit v1.2.3 From 4388b9c31122f98c4291f8fba5a0d3524902b8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 21 Oct 2016 01:00:52 +0200 Subject: Remove an unused variable in e2e --- tests/end_to_end/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index d04238e..56d7a6d 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -129,7 +129,7 @@ def match(stanza, xpath): def check_xpath(xpaths, xmpp, after, stanza): - for i, xpath in enumerate(xpaths): + for xpath in enumerate(xpaths): matched = match(stanza, xpath) if not matched: raise StanzaError("Received stanza “%s” did not match expected xpath “%s”" % (stanza, xpath)) -- cgit v1.2.3 From a4d67ce041f50e0d25e2b47d04cc25bdad86a048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 21 Oct 2016 01:05:15 +0200 Subject: Use ensure_future instead of async --- tests/end_to_end/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 56d7a6d..4a42820 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -57,7 +57,7 @@ class XMPPComponent(slixmpp.BaseXMPP): self.add_event_handler("session_end", self.on_end_session) - asyncio.async(self.accept_routine()) + asyncio.ensure_future(self.accept_routine()) self.scenario = scenario self.biboumi = biboumi -- cgit v1.2.3 From 82a6fa6d098c82914ff8a6ed44398eb0cf8c4d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 21 Oct 2016 01:05:38 +0200 Subject: e2e: Fix some logic in check_list_of_xpath --- tests/end_to_end/__main__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 4a42820..fedfa6a 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -151,14 +151,13 @@ def check_list_of_xpath(list_of_xpaths, xmpp, stanza): found = None for i, xpaths in enumerate(list_of_xpaths): if all_xpaths_match(stanza, xpaths): - found = i + found = True + list_of_xpaths.pop(i) break - if found is None: + if not found: raise StanzaError("Received stanza “%s” did not match any of the expected xpaths:\n%s" % (stanza, list_of_xpaths)) - list_of_xpaths.pop(i) - if list_of_xpaths: step = partial(expect_unordered_already_formatted, list_of_xpaths) xmpp.scenario.steps.insert(0, step) -- cgit v1.2.3 From ac32d257386fe1c8df2632cf1d6452b1875eb645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 21 Oct 2016 18:50:04 +0200 Subject: Fix the broken commit 4388b9c --- tests/end_to_end/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index fedfa6a..fd515e2 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -129,7 +129,7 @@ def match(stanza, xpath): def check_xpath(xpaths, xmpp, after, stanza): - for xpath in enumerate(xpaths): + for xpath in xpaths: matched = match(stanza, xpath) if not matched: raise StanzaError("Received stanza “%s” did not match expected xpath “%s”" % (stanza, xpath)) -- cgit v1.2.3 From 8b8bbceeb39b32b90f76a9c0beb3f7d30ed6fd7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 21 Oct 2016 19:12:25 +0200 Subject: Revert "Use ensure_future instead of async" This reverts commit a4d67ce041f50e0d25e2b47d04cc25bdad86a048. --- tests/end_to_end/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index fd515e2..747c8f5 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -57,7 +57,7 @@ class XMPPComponent(slixmpp.BaseXMPP): self.add_event_handler("session_end", self.on_end_session) - asyncio.ensure_future(self.accept_routine()) + asyncio.async(self.accept_routine()) self.scenario = scenario self.biboumi = biboumi -- cgit v1.2.3 From 5990a8bf8ae622f075a7e2a12b2f5ac0cab8713b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 24 Oct 2016 00:18:34 +0200 Subject: Correctly handle the nick change inside the virtual channel --- tests/end_to_end/__main__.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 747c8f5..890043f 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -482,7 +482,7 @@ if __name__ == '__main__': ), partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), ]), - Scenario("virtual_channel_join", + Scenario("virtual_channel", [ handshake_sequence(), partial(send_stanza, @@ -494,6 +494,38 @@ if __name__ == '__main__': ), partial(expect_stanza, "/message[@from='%{irc_server_one}'][@type='groupchat']/subject[re:test(text(), '^This is a virtual channel.*$')]"), connection_end_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(send_stanza, ""), + partial(expect_stanza, "/presence[@type='unavailable'][@from='%{irc_server_one}/{nick_one}']"), + partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Closing Link: localhost (Client Quit)']"), + partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Connection closed.']"), + ]), + Scenario("irc_server_disconnection", + [ + handshake_sequence(), + partial(send_stanza, + ""), + connection_begin_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='%{irc_server_one}'][@type='groupchat']/subject[re:test(text(), '^This is a virtual channel.*$')]"), + connection_end_sequence("irc.localhost", '{jid_one}/{resource_one}'), + + partial(send_stanza, ""), + + partial(expect_unordered, [ + ("/presence[@from='%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='{nick_two}']", + "/presence/muc_user:x/muc_user:status[@code='110']", + "/presence/muc_user:x/muc_user:status[@code='303']"), + ("/presence[@from='%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ]), + + partial(send_stanza, ""), + partial(expect_stanza, "/presence[@type='unavailable'][@from='%{irc_server_one}/{nick_two}']"), + partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Closing Link: localhost (Client Quit)']"), + partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Connection closed.']"), ]), Scenario("channel_join_with_two_users", [ -- cgit v1.2.3 From 021f025cb039011ad07158b0d94f1b430a409e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 26 Oct 2016 21:19:53 +0200 Subject: Refactor the sha1 digest into its own function, and do not use sprintf --- tests/xmpp.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/xmpp.cpp b/tests/xmpp.cpp index 6aab8c4..37d2b54 100644 --- a/tests/xmpp.cpp +++ b/tests/xmpp.cpp @@ -1,6 +1,7 @@ #include "catch.hpp" #include +#include TEST_CASE("Test basic XML parsing") { @@ -45,3 +46,9 @@ TEST_CASE("XML escape") const std::string unescaped = "'coucou'/&\"gaga\""; CHECK(xml_escape(unescaped) == "'coucou'<cc>/&"gaga""); } + +TEST_CASE("handshake_digest") +{ + const auto res = get_handshake_digest("id1234", "S4CR3T"); + CHECK(res == "c92901b5d376ad56269914da0cce3aab976847df"); +} -- cgit v1.2.3 From 6d65e9527e90dda7b76168be23690dfead73c847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 27 Oct 2016 01:16:04 +0200 Subject: Remove calls to INFO() in catch, they are useless --- tests/encoding.cpp | 2 -- tests/timed_events.cpp | 1 - 2 files changed, 3 deletions(-) (limited to 'tests') diff --git a/tests/encoding.cpp b/tests/encoding.cpp index 389cf23..b5192ff 100644 --- a/tests/encoding.cpp +++ b/tests/encoding.cpp @@ -11,7 +11,6 @@ TEST_CASE("UTF-8 validation") CHECK_FALSE(utils::is_valid_utf8("\xFE\xFE\xFF\xFF")); std::string in = "Biboumi ╯°□°)╯︵ ┻━┻"; - INFO(in); CHECK(utils::is_valid_utf8(in.data())); } @@ -49,7 +48,6 @@ TEST_CASE("Remove invalid XML chars") { std::string without_ctrl_char("𤭢€¢$"); std::string in = "Biboumi ╯°□°)╯︵ ┻━┻"; - INFO(in); CHECK(utils::remove_invalid_xml_chars(without_ctrl_char) == without_ctrl_char); CHECK(utils::remove_invalid_xml_chars(in) == in); CHECK(utils::remove_invalid_xml_chars("\acouco\u0008u\uFFFEt\uFFFFe\r\n♥") == "coucoute\r\n♥"); diff --git a/tests/timed_events.cpp b/tests/timed_events.cpp index d63abef..fece422 100644 --- a/tests/timed_events.cpp +++ b/tests/timed_events.cpp @@ -38,7 +38,6 @@ TEST_CASE("Test timed event expiration") CHECK(TimedEventsManager::instance().execute_expired_events() == 0); std::chrono::milliseconds timoute = TimedEventsManager::instance().get_timeout(); - INFO("Sleeping for " << timoute.count() << "ms"); std::this_thread::sleep_for(timoute + 1ms); // Event is now expired -- cgit v1.2.3 From 1ff71ca79ef701b0623728ce91c27a0b57a9a85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 31 Oct 2016 00:35:03 +0100 Subject: Test raw messages --- tests/end_to_end/__main__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 890043f..95aa1b6 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1611,6 +1611,18 @@ if __name__ == '__main__': ""), partial(expect_stanza, "/iq[@type='result']/disco_info:query[@node='http://jabber.org/protocol/muc#traffic']"), ]), + Scenario("raw_message", + [ + handshake_sequence(), + partial(send_stanza, ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, "WHOIS {nick_one}"), + partial(expect_stanza, "/message[@from='{irc_server_one}'][@type='chat']/body[text()='irc.localhost: {nick_one} ~{nick_one} localhost * {nick_one}']"), + ]), ) failures = 0 -- cgit v1.2.3 From ec555d05dfff976e5584db7b15768fff0fab448c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 31 Oct 2016 00:40:41 +0100 Subject: e2e: add the possibility to launch a specific list of scenarios only --- tests/end_to_end/__main__.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 95aa1b6..d235c02 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1627,6 +1627,7 @@ if __name__ == '__main__': failures = 0 + scenar_list = sys.argv[1:] irc_output = open("irc_output.txt", "w") irc = IrcServerRunner() print("Starting irc server…") @@ -1643,6 +1644,8 @@ if __name__ == '__main__': print("Running %s checks for biboumi." % (len(scenarios))) for s in scenarios: + if s.name not in scenar_list: + continue test = BiboumiTest(s) if not test.run(): print("You can check the files slixmpp_%s_output.txt and biboumi_%s_output.txt to help you debug." % -- cgit v1.2.3 From 1d6aa89ab9656878689d86bd1aa74140756740fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 31 Oct 2016 01:12:39 +0100 Subject: Test self disco --- tests/end_to_end/__main__.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index d235c02..a591bc9 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1623,6 +1623,19 @@ if __name__ == '__main__': partial(send_stanza, "WHOIS {nick_one}"), partial(expect_stanza, "/message[@from='{irc_server_one}'][@type='chat']/body[text()='irc.localhost: {nick_one} ~{nick_one} localhost * {nick_one}']"), ]), + Scenario("self_disco_info", + [ + handshake_sequence(), + partial(send_stanza, ""), + partial(expect_stanza, + ("/iq[@type='result']/disco_info:query/disco_info:identity[@category='conference'][@type='irc'][@name='Biboumi XMPP-IRC gateway']", + "/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']", + "/iq/disco_info:query/disco_info:feature[@var='http://jabber.org/protocol/commands']", + "/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:ping']", + "/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:mam:1']", + "/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']", + )), + ]), ) failures = 0 -- cgit v1.2.3 From fdf336afa017c24eb483f741e4037226f8a08401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 31 Oct 2016 01:12:50 +0100 Subject: Use ensure_future if available, otherwise use asyncio.async --- tests/end_to_end/__main__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index a591bc9..c98c3a6 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -13,6 +13,8 @@ import os from functools import partial from slixmpp.xmlstream.matcher.base import MatcherBase +if not hasattr(asyncio, "ensure_future"): + asyncio.ensure_future = getattr(asyncio, "async") class MatchAll(MatcherBase): """match everything""" @@ -57,7 +59,7 @@ class XMPPComponent(slixmpp.BaseXMPP): self.add_event_handler("session_end", self.on_end_session) - asyncio.async(self.accept_routine()) + asyncio.ensure_future(self.accept_routine()) self.scenario = scenario self.biboumi = biboumi -- cgit v1.2.3 From db7ac6f13d4cb1f280afcfed7c17533244a1d010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 31 Oct 2016 01:39:04 +0100 Subject: Test successful invite of an other user --- tests/end_to_end/__main__.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index c98c3a6..d618fda 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1638,6 +1638,24 @@ if __name__ == '__main__': "/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']", )), ]), + Scenario("invite_other", + [ + handshake_sequence(), + partial(send_stanza, ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, ""), + connection_sequence("irc.localhost", '{jid_two}/{resource_two}'), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + partial(send_stanza, ""), + partial(expect_stanza, "/message/body[text()='{nick_two} has been invited to #foo']"), + partial(expect_stanza, "/message[@to='{jid_two}/{resource_two}'][@from='#foo%{irc_server_one}']/muc_user:x/muc_user:invite[@from='#foo%{irc_server_one}/{nick_one}']"), + ]), ) failures = 0 -- cgit v1.2.3 From 056bc3da066bbf0345db27ac41bca0433ba4db0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 31 Oct 2016 01:45:09 +0100 Subject: Actually run all the e2e scenario if nothing is specified --- tests/end_to_end/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index d618fda..e2a497d 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1677,7 +1677,7 @@ if __name__ == '__main__': print("Running %s checks for biboumi." % (len(scenarios))) for s in scenarios: - if s.name not in scenar_list: + if scenar_list and s.name not in scenar_list: continue test = BiboumiTest(s) if not test.run(): -- cgit v1.2.3 From c70301e503fdb887387a54fcf5284d593e65d837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 2 Nov 2016 21:25:26 +0100 Subject: Fix the presences sent, when multiple resources join the virtual channel fix #3216 --- tests/end_to_end/__main__.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index e2a497d..26e7b05 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1656,6 +1656,59 @@ if __name__ == '__main__': partial(expect_stanza, "/message/body[text()='{nick_two} has been invited to #foo']"), partial(expect_stanza, "/message[@to='{jid_two}/{resource_two}'][@from='#foo%{irc_server_one}']/muc_user:x/muc_user:invite[@from='#foo%{irc_server_one}/{nick_one}']"), ]), + Scenario("virtual_channel_multisession", + [ + handshake_sequence(), + partial(send_stanza, + ""), + connection_begin_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_one}'][@from='%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@from='%{irc_server_one}'][@type='groupchat']/subject[re:test(text(), '^This is a virtual channel.*$')]"), + connection_end_sequence("irc.localhost", '{jid_one}/{resource_one}'), + + partial(send_stanza, + ""), + + partial(expect_stanza, + ("/presence[@to='{jid_one}/{resource_two}'][@from='%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']", + "/presence/muc_user:x/muc_user:status[@code='110']") + ), + partial(expect_stanza, "/message[@to='{jid_one}/{resource_two}'][@from='%{irc_server_one}'][@type='groupchat']/subject[re:test(text(), '^This is a virtual channel.*$')]"), + + + partial(log_message, "Nick change"), + partial(send_stanza, ""), + + partial(expect_unordered, [ + ("/presence[@from='%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_two}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bobby']", + "/presence/muc_user:x/muc_user:status[@code='303']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ("/presence[@from='%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_two}']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + + ("/presence[@from='%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bobby']", + "/presence/muc_user:x/muc_user:status[@code='303']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ("/presence[@from='%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}']", + "/presence/muc_user:x/muc_user:status[@code='110']"), + ]), + + + partial(log_message, "First resource leaves."), + partial(send_stanza, ""), + partial(expect_stanza, ("/presence[@type='unavailable'][@from='%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:status[@code='110']", + "/presence/status[text()='Biboumi note: 1 resources are still in this channel.']",) + ), + + partial(log_message, "Second resource leaves."), + partial(send_stanza, ""), + partial(expect_stanza, "/presence[@type='unavailable'][@from='%{irc_server_one}/{nick_two}']"), + partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Closing Link: localhost (Client Quit)']"), + partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Connection closed.']"), + ]), ) failures = 0 -- cgit v1.2.3 From 50d7590db426ce821148af769ea18d556e97f393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 3 Nov 2016 22:02:07 +0100 Subject: Test the global and IRC server configure commands --- tests/end_to_end/__main__.py | 90 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 26e7b05..a7a5f69 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1709,8 +1709,98 @@ if __name__ == '__main__': partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Closing Link: localhost (Client Quit)']"), partial(expect_stanza, "/message[@from='{irc_server_one}']/body[text()='ERROR: Connection closed.']"), ]), + Scenario("global_configure", + [ + handshake_sequence(), + partial(send_stanza, ""), + partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']", + "/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']", + "/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='20']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='true']", + "/iq/commands:command/commands:actions/commands:next", + ), + after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid")) + ), + partial(send_stanza, "042"), + partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"), + + partial(send_stanza, ""), + partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']", + "/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']", + "/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='42']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='false']", + "/iq/commands:command/commands:actions/commands:next", + ), + after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid")) + ), + partial(send_stanza, ""), + partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"), + ]), + Scenario("irc_server_configure", + [ + handshake_sequence(), + partial(send_stanza, ""), + partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']", + "/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC server irc.localhost']", + "/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure the settings of the IRC server irc.localhost']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='ports']/dataform:value[text()='6667']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6670']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6697']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='verify_cert']/dataform:value[text()='true']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='after_connect_command']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='ISO-8859-1']", + "/iq/commands:command/commands:actions/commands:next", + ), + after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid")) + ), + partial(send_stanza, "" + "" + "" + "" + "66976698" + "1" + "12:12:12" + "coucou" + "INVALID command" + "username" + "realname" + "UTF-8" + "latin-1" + ""), + partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"), + + partial(send_stanza, ""), + partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']", + "/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC server irc.localhost']", + "/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure the settings of the IRC server irc.localhost']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6697']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6698']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='verify_cert']/dataform:value[text()='true']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']/dataform:value[text()='12:12:12']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']/dataform:value[text()='coucou']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='after_connect_command']/dataform:value[text()='INVALID command']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']/dataform:value[text()='username']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']/dataform:value[text()='realname']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']", + "/iq/commands:command/commands:actions/commands:next", + ), + after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid")) + ), + partial(send_stanza, ""), + partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"), + ]), ) + failures = 0 scenar_list = sys.argv[1:] -- cgit v1.2.3 From 7376831bc8f6dbec8eaf4f4c0a6bba819a0a1e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 7 Nov 2016 14:43:07 +0100 Subject: Add get-irc-connection-info adhoc command fix #3171 --- tests/end_to_end/__main__.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index a7a5f69..239f044 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -631,7 +631,7 @@ if __name__ == '__main__': handshake_sequence(), partial(send_stanza, ""), partial(expect_stanza, ("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']", - "/iq/disco_items:query/disco_items:item[3]")), + "/iq/disco_items:query/disco_items:item[5]")), ], conf='fixed_server'), Scenario("list_admin_adhoc_fixed_server", [ @@ -647,7 +647,7 @@ if __name__ == '__main__': handshake_sequence(), partial(send_stanza, ""), partial(expect_stanza, ("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']", - "/iq/disco_items:query/disco_items:item[1]")), + "/iq/disco_items:query/disco_items:item[2]")), ]), Scenario("list_adhoc_irc_fixed_server", [ @@ -1798,6 +1798,44 @@ if __name__ == '__main__': partial(send_stanza, ""), partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"), ]), + Scenario("get_irc_connection_info", + [ + handshake_sequence(), + + partial(log_message, "Not connected yet"), + partial(send_stanza, ""), + partial(expect_stanza, "/iq/commands:command/commands:note[text()='You are not connected to the IRC server irc.localhost']"), + + partial(log_message, "Join one room"), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, ""), + partial(expect_stanza, r"/iq/commands:command/commands:note[re:test(text(), 'Connected to IRC server irc.localhost on port 6667 since \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d \(\d+ seconds ago\)\.\n#foo from 1 resource: {resource_one}.*')]"), + ]), + Scenario("get_irc_connection_info_fixed", + [ + handshake_sequence(), + + partial(log_message, "Not connected yet"), + partial(send_stanza, ""), + partial(expect_stanza, "/iq/commands:command/commands:note[text()='You are not connected to the IRC server irc.localhost']"), + + partial(log_message, "Join one room"), + partial(send_stanza, + ""), + connection_sequence("irc.localhost", '{jid_one}/{resource_one}'), + partial(expect_stanza, "/message"), + partial(expect_stanza, "/presence"), + partial(expect_stanza, "/message"), + + partial(send_stanza, ""), + partial(expect_stanza, r"/iq/commands:command/commands:note[re:test(text(), 'Connected to IRC server irc.localhost on port 6667 since \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d \(\d+ seconds ago\)\.\n#foo from 1 resource: {resource_one}.*')]"), + ], conf='fixed_server'), ) -- cgit v1.2.3 From f36bccd7bbd685cc34370da4ab4b7d124bcc69a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 7 Nov 2016 21:51:39 +0100 Subject: Test the error on joining invalid room --- tests/end_to_end/__main__.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tests') diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 239f044..7658d92 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -113,6 +113,7 @@ def match(stanza, xpath): tree = lxml.etree.parse(io.StringIO(str(stanza))) matched = tree.xpath(xpath, namespaces={'re': 'http://exslt.org/regular-expressions', 'muc_user': 'http://jabber.org/protocol/muc#user', + 'muc': 'http://jabber.org/protocol/muc', 'disco_info': 'http://jabber.org/protocol/disco#info', 'muc_traffic': 'http://jabber.org/protocol/muc#traffic', 'disco_items': 'http://jabber.org/protocol/disco#items', @@ -1836,6 +1837,22 @@ if __name__ == '__main__': partial(send_stanza, ""), partial(expect_stanza, r"/iq/commands:command/commands:note[re:test(text(), 'Connected to IRC server irc.localhost on port 6667 since \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d \(\d+ seconds ago\)\.\n#foo from 1 resource: {resource_one}.*')]"), ], conf='fixed_server'), + Scenario("invalid_room_jid", + [ + handshake_sequence(), + partial(send_stanza, ""), + partial(expect_stanza, ("/presence[@type='error'][@to='{jid_one}/{resource_one}'][@from='invalid%{irc_server_one}/{nick_one}']/error[@type='cancel']/stanza:item-not-found", + "/presence/muc:x", + "/presence/error/stanza:text")), + ]), + Scenario("invalid_room_jid_fixed", + [ + handshake_sequence(), + partial(send_stanza, ""), + partial(expect_stanza, ("/presence[@type='error'][@to='{jid_one}/{resource_one}'][@from='invalid@{biboumi_host}/{nick_one}']/error[@type='cancel']/stanza:item-not-found", + "/presence/muc:x", + "/presence/error/stanza:text")), + ], conf='fixed_server'), ) -- cgit v1.2.3