diff --git a/test/integration/framework/base.h b/test/integration/framework/base.h index 71098fd7..1663f121 100644 --- a/test/integration/framework/base.h +++ b/test/integration/framework/base.h @@ -20,12 +20,11 @@ #include #include -#include #include +#include +#include #include -#include - namespace znc_inttest { template @@ -35,6 +34,7 @@ class IO { : m_device(device), m_verbose(verbose) {} virtual ~IO() {} void ReadUntil(QByteArray pattern); + void ReadUntilRe(QString pattern); /* * Reads from Device until pattern is matched and returns this pattern * up to and excluding the first newline. Pattern itself can contain a newline. @@ -116,7 +116,36 @@ void IO::ReadUntil(QByteArray pattern) { } const int timeout_ms = QDateTime::currentDateTime().msecsTo(deadline); - ASSERT_GT(timeout_ms, 0) << "Wanted:" << pattern.toStdString(); + ASSERT_GT(timeout_ms, 0) << "Wanted: " << pattern.toStdString(); + ASSERT_TRUE(m_device->waitForReadyRead(timeout_ms)) + << "Wanted: " << pattern.toStdString(); + QByteArray chunk = m_device->readAll(); + if (m_verbose) { + std::cout << chunk.toStdString() << std::flush; + } + m_readed += chunk; + } +} + +template +void IO::ReadUntilRe(QString pattern) { + QRegularExpression expr(pattern); + auto deadline = QDateTime::currentDateTime().addSecs(60); + while (true) { + QRegularExpressionMatch match = + expr.match(QString::fromUtf8(m_readed), 0, + QRegularExpression::PartialPreferCompleteMatch); + if (match.hasMatch()) { + m_readed.remove(0, match.capturedEnd()); + return; + } + if (!match.hasPartialMatch()) { + m_readed.clear(); + } + const int timeout_ms = + QDateTime::currentDateTime().msecsTo(deadline); + ASSERT_GT(timeout_ms, 0) + << "Wanted: " << pattern.toStdString(); ASSERT_TRUE(m_device->waitForReadyRead(timeout_ms)) << "Wanted: " << pattern.toStdString(); QByteArray chunk = m_device->readAll(); @@ -158,7 +187,7 @@ void IO::ReadUntilAndGet(QByteArray pattern, QByteArray& match) { } const int timeout_ms = QDateTime::currentDateTime().msecsTo(deadline); - ASSERT_GT(timeout_ms, 0) << "Wanted:" << pattern.toStdString(); + ASSERT_GT(timeout_ms, 0) << "Wanted: " << pattern.toStdString(); ASSERT_TRUE(m_device->waitForReadyRead(timeout_ms)) << "Wanted: " << pattern.toStdString(); QByteArray chunk = m_device->readAll(); diff --git a/test/integration/tests/modules.cpp b/test/integration/tests/modules.cpp index 5815c088..652fccb4 100644 --- a/test/integration/tests/modules.cpp +++ b/test/integration/tests/modules.cpp @@ -39,23 +39,23 @@ TEST_F(ZNCTest, NotifyConnectModule) { client2.Write("PASS :hunter2"); client2.Write("NICK nick"); client2.Write("USER user/test x x :x"); - client.ReadUntil("NOTICE nick :*** user attached from localhost"); + client.ReadUntil("NOTICE nick :*** user attached from "); auto client3 = ConnectClient(); client3.Write("PASS :hunter2"); client3.Write("NICK nick"); client3.Write("USER user@identifier/test x x :x"); client.ReadUntil( - "NOTICE nick :*** user@identifier attached from localhost"); + "NOTICE nick :*** user@identifier attached from "); client2.ReadUntil( - "NOTICE nick :*** user@identifier attached from localhost"); + "NOTICE nick :*** user@identifier attached from "); client2.Write("QUIT"); - client.ReadUntil("NOTICE nick :*** user detached from localhost"); + client.ReadUntil("NOTICE nick :*** user detached from "); client3.Close(); client.ReadUntil( - "NOTICE nick :*** user@identifier detached from localhost"); + "NOTICE nick :*** user@identifier detached from "); } TEST_F(ZNCTest, ClientNotifyModule) { @@ -65,41 +65,46 @@ TEST_F(ZNCTest, ClientNotifyModule) { client.Write("znc loadmod clientnotify"); client.ReadUntil("Loaded module"); - auto check_not_sent = [](Socket& client, std::string wrongAnswer){ - auto result = QString{client.ReadRemainder()}.toStdString(); - EXPECT_THAT(result, Not(HasSubstr((wrongAnswer)))) << "Got an answer from the ClientNotifyModule even though we didnt want one with the given configuration"; + auto check_not_sent = [](Socket& client, QString wrongAnswer) { + QString result = QString::fromUtf8(client.ReadRemainder()); + QRegularExpression expr(wrongAnswer); + QRegularExpressionMatch match = expr.match(result); + EXPECT_FALSE(match.hasMatch()) + << "Got an answer from the ClientNotifyModule even though we didnt " + "want one with the given configuration: " + << wrongAnswer.toStdString() << result.toStdString(); }; auto client2 = LoginClient(); - client.ReadUntil(":Another client (localhost) authenticated as your user. Use the 'ListClients' command to see all 2 clients."); + client.ReadUntilRe(R"(:Another client \((localhost)?\) authenticated as your user. Use the 'ListClients' command to see all 2 clients.)"); auto client3 = LoginClient(); - client.ReadUntil(":Another client (localhost) authenticated as your user. Use the 'ListClients' command to see all 3 clients."); + client.ReadUntilRe(R"(:Another client \((localhost)?\) authenticated as your user. Use the 'ListClients' command to see all 3 clients.)"); // disable notifications for every message client.Write("PRIVMSG *clientnotify :NewOnly on"); // check that we do not ge a notification after connecting from a know ip auto client4 = LoginClient(); - check_not_sent(client, ":Another client (localhost) authenticated as your user. Use the 'ListClients' command to see all 4 clients."); + check_not_sent(client, ":Another client (.*) authenticated as your user. Use the 'ListClients' command to see all 4 clients."); // choose to notify only on new client ids client.Write("PRIVMSG *clientnotify :NotifyOnNewID on"); auto client5 = LoginClient("identifier123"); - client.ReadUntil(":Another client (localhost / identifier123) authenticated as your user. Use the 'ListClients' command to see all 5 clients."); + client.ReadUntilRe(R"(:Another client \((localhost)? / identifier123\) authenticated as your user. Use the 'ListClients' command to see all 5 clients.)"); auto client6 = LoginClient("identifier123"); - check_not_sent(client, ":Another client (localhost / identifier123) authenticated as your user. Use the 'ListClients' command to see all 6 clients."); + check_not_sent(client, ":Another client (.* / identifier123) authenticated as your user. Use the 'ListClients' command to see all 6 clients."); auto client7 = LoginClient("not_identifier123"); - client.ReadUntil(":Another client (localhost / not_identifier123) authenticated as your user. Use the 'ListClients' command to see all 7 clients."); + client.ReadUntilRe(R"(:Another client \((localhost)? / not_identifier123\) authenticated as your user. Use the 'ListClients' command to see all 7 clients.)"); // choose to notify from both clientids and new IPs client.Write("PRIVMSG *clientnotify :NotifyOnNewIP on"); auto client8 = LoginClient(); - check_not_sent(client, ":Another client (localhost / identifier123) authenticated as your user. Use the 'ListClients' command to see all 8 clients."); + check_not_sent(client, ":Another client (.* / identifier123) authenticated as your user. Use the 'ListClients' command to see all 8 clients."); auto client9 = LoginClient("definitely_not_identifier123"); - client.ReadUntil(":Another client (localhost / definitely_not_identifier123) authenticated as your user. Use the 'ListClients' command to see all 9 clients."); + client.ReadUntilRe(R"(:Another client \((localhost)? / definitely_not_identifier123\) authenticated as your user. Use the 'ListClients' command to see all 9 clients.)"); } TEST_F(ZNCTest, ShellModule) { diff --git a/test/integration/tests/scripting.cpp b/test/integration/tests/scripting.cpp index fbba2f3d..afeeaeb7 100644 --- a/test/integration/tests/scripting.cpp +++ b/test/integration/tests/scripting.cpp @@ -490,9 +490,9 @@ TEST_F(ZNCTest, ModpythonSaslAuth) { client2.Write("AUTHENTICATE FOO"); client2.ReadUntil("AUTHENTICATE " + QByteArrayLiteral("Welcome").toBase64()); client2.Write("AUTHENTICATE +"); - client2.ReadUntil( - ":irc.znc.in 900 nick nick!user@localhost user :You are now logged in " - "as user"); + client2.ReadUntilRe( + ":irc.znc.in 900 nick nick!user@(localhost)? user :You are now logged " + "in as user"); } TEST_F(ZNCTest, ModperlSaslAuth) { @@ -547,9 +547,9 @@ TEST_F(ZNCTest, ModperlSaslAuth) { client2.Write("AUTHENTICATE FOO"); client2.ReadUntil("AUTHENTICATE " + QByteArrayLiteral("Welcome").toBase64()); client2.Write("AUTHENTICATE +"); - client2.ReadUntil( - ":irc.znc.in 900 nick nick!user@localhost user :You are now logged in " - "as user"); + client2.ReadUntilRe( + ":irc.znc.in 900 nick nick!user@(localhost)? user :You are now logged " + "in as user"); } } // namespace