diff --git a/resources/maildir/autotests/synctest.cpp b/resources/maildir/autotests/synctest.cpp index 568a445d1..68d98788e 100644 --- a/resources/maildir/autotests/synctest.cpp +++ b/resources/maildir/autotests/synctest.cpp @@ -1,78 +1,83 @@ /* Copyright 2009 Constantin Berzan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "synctest.h" #include "maildirsettings.h" // generated #include #include #include #include #include #include #include #include #include #define TIMES 100 // How many times to sync. #define TIMEOUT 10 // How many seconds to wait before declaring the resource dead. using namespace Akonadi; void SyncTest::initTestCase() { AkonadiTest::checkTestIsIsolated(); AgentType maildirType = AgentManager::self()->type(QStringLiteral("akonadi_maildir_resource")); AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(maildirType); QVERIFY(agentCreateJob->exec()); mMaildirIdentifier = agentCreateJob->instance().identifier(); - OrgKdeAkonadiMaildirSettingsInterface interface(QStringLiteral("org.freedesktop.Akonadi.Resource.%1").arg(mMaildirIdentifier), QStringLiteral("/"), QDBusConnection::sessionBus()); + QString service = QStringLiteral("org.freedesktop.Akonadi.Resource.") + mMaildirIdentifier; + if (Akonadi::ServerManager::hasInstanceIdentifier()) { + service += QLatin1Char('.') + Akonadi::ServerManager::instanceIdentifier(); + } + + OrgKdeAkonadiMaildirSettingsInterface interface(service, QStringLiteral("/"), QDBusConnection::sessionBus()); QVERIFY(interface.isValid()); const QString mailPath = QFINDTESTDATA("maildir"); QVERIFY(!mailPath.isEmpty()); QVERIFY(QFile::exists(mailPath)); interface.setPath(mailPath); } void SyncTest::testSync() { AgentInstance instance = AgentManager::self()->instance(mMaildirIdentifier); QVERIFY(instance.isValid()); for (int i = 0; i < TIMES; ++i) { QDBusInterface interface( Akonadi::ServerManager::agentServiceName(Akonadi::ServerManager::Resource, mMaildirIdentifier), QStringLiteral("/"), QStringLiteral("org.freedesktop.Akonadi.Resource"), QDBusConnection::sessionBus(), this); QVERIFY(interface.isValid()); QElapsedTimer t; t.start(); instance.synchronize(); QSignalSpy spy(&interface, SIGNAL(synchronized())); QVERIFY(spy.isValid()); QVERIFY(spy.wait(TIMEOUT * 1000)); qDebug() << "Sync attempt" << i << "in" << t.elapsed() << "ms."; } } QTEST_AKONADIMAIN(SyncTest) diff --git a/resources/pop3/autotests/pop3test.cpp b/resources/pop3/autotests/pop3test.cpp index a5593ea3d..efdfb97d5 100644 --- a/resources/pop3/autotests/pop3test.cpp +++ b/resources/pop3/autotests/pop3test.cpp @@ -1,918 +1,924 @@ /* Copyright 2009 Thomas McGuire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "pop3test.h" #include #include #include #include #include #include #include #include #include #include #include #include QTEST_AKONADIMAIN(Pop3Test) using namespace Akonadi; void Pop3Test::initTestCase() { AkonadiTest::checkTestIsIsolated(); QVERIFY(Akonadi::Control::start()); // switch all resources offline to reduce interference from them foreach (Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances()) { agent.setIsOnline(false); } /* qDebug() << "==========================================================="; qDebug() << "============ Stopping for debugging ======================="; qDebug() << "==========================================================="; kill( qApp->applicationPid(), SIGSTOP ); */ // // Create the maildir and pop3 resources // AgentType maildirType = AgentManager::self()->type(QStringLiteral("akonadi_maildir_resource")); AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(maildirType); QVERIFY(agentCreateJob->exec()); mMaildirIdentifier = agentCreateJob->instance().identifier(); AgentType popType = AgentManager::self()->type(QStringLiteral("akonadi_pop3_resource")); agentCreateJob = new AgentInstanceCreateJob(popType); QVERIFY(agentCreateJob->exec()); mPop3Identifier = agentCreateJob->instance().identifier(); // // Configure the maildir resource // QString maildirRootPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QLatin1String("tester"); mMaildirPath = maildirRootPath + QLatin1String("/new"); + + QString service = QLatin1String("org.freedesktop.Akonadi.Resource.") + mMaildirIdentifier; + if (Akonadi::ServerManager::hasInstanceIdentifier()) { + service += QLatin1Char('.') + Akonadi::ServerManager::instanceIdentifier(); + } + mMaildirSettingsInterface = new OrgKdeAkonadiMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + mMaildirIdentifier, + service, QStringLiteral("/Settings"), QDBusConnection::sessionBus(), this); QDBusReply setPathReply = mMaildirSettingsInterface->setPath(maildirRootPath); QVERIFY(setPathReply.isValid()); AgentManager::self()->instance(mMaildirIdentifier).reconfigure(); QDBusReply getPathReply = mMaildirSettingsInterface->path(); QCOMPARE(getPathReply.value(), maildirRootPath); AgentManager::self()->instance(mMaildirIdentifier).synchronize(); // // Find the root maildir collection // bool found = false; QTime time; time.start(); while (!found) { CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); QVERIFY(job->exec()); Collection::List collections = job->collections(); foreach (const Collection &col, collections) { if (col.resource() == AgentManager::self()->instance(mMaildirIdentifier).identifier()) { mMaildirCollection = col; found = true; break; } } QVERIFY(time.elapsed() < 10 * 1000); // maildir should not need more than 10 secs to sync } // // Start the fake POP3 server // mFakeServerThread = new FakeServerThread(this); mFakeServerThread->start(); QTest::qWait(100); QVERIFY(mFakeServerThread->server() != nullptr); // // Configure the pop3 resource // mPOP3SettingsInterface = new OrgKdeAkonadiPOP3SettingsInterface( Akonadi::ServerManager::agentServiceName(Akonadi::ServerManager::Resource, mPop3Identifier), QStringLiteral("/Settings"), QDBusConnection::sessionBus(), this); QDBusReply reply0 = mPOP3SettingsInterface->port(); QVERIFY(reply0.isValid()); QCOMPARE(reply0.value(), 110u); mPOP3SettingsInterface->setPort(5989); AgentManager::self()->instance(mPop3Identifier).reconfigure(); QDBusReply reply = mPOP3SettingsInterface->port(); QVERIFY(reply.isValid()); QCOMPARE(reply.value(), 5989u); mPOP3SettingsInterface->setHost(QStringLiteral("localhost")); AgentManager::self()->instance(mPop3Identifier).reconfigure(); QDBusReply reply2 = mPOP3SettingsInterface->host(); QVERIFY(reply2.isValid()); QCOMPARE(reply2.value(), QLatin1String("localhost")); mPOP3SettingsInterface->setLogin(QStringLiteral("HansWurst")); AgentManager::self()->instance(mPop3Identifier).reconfigure(); QDBusReply reply3 = mPOP3SettingsInterface->login(); QVERIFY(reply3.isValid()); QCOMPARE(reply3.value(), QLatin1String("HansWurst")); mPOP3SettingsInterface->setUnitTestPassword(QStringLiteral("Geheim")); AgentManager::self()->instance(mPop3Identifier).reconfigure(); QDBusReply reply4 = mPOP3SettingsInterface->unitTestPassword(); QVERIFY(reply4.isValid()); QCOMPARE(reply4.value(), QLatin1String("Geheim")); mPOP3SettingsInterface->setTargetCollection(mMaildirCollection.id()); AgentManager::self()->instance(mPop3Identifier).reconfigure(); QDBusReply reply5 = mPOP3SettingsInterface->targetCollection(); QVERIFY(reply5.isValid()); QCOMPARE(reply5.value(), mMaildirCollection.id()); } void Pop3Test::cleanupTestCase() { // Post the "quit" event to the thread's event loop, then wait until the thread // is finished (it finishes when the event loop finishes) QMetaObject::invokeMethod(mFakeServerThread, "quit", Qt::QueuedConnection); if (!mFakeServerThread->wait(10000)) { qWarning() << "The fake server thread has not yet finished, what is wrong!?"; } } static const QByteArray simpleMail1 = "From: \"Bill Lumbergh\" \r\n" "To: \"Peter Gibbons\" \r\n" "Subject: TPS Reports - New Cover Sheets\r\n" "MIME-Version: 1.0\r\n" "Content-Type: text/plain\r\n" "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" "\r\n" "Hi, Peter. What's happening? We need to talk about your TPS reports.\r\n"; static const QByteArray simpleMail2 = "From: \"Amy McCorkell\" \r\n" "To: gov.palin@yaho.com\r\n" "Subject: HI SARAH\r\n" "MIME-Version: 1.0\r\n" "Content-Type: text/plain\r\n" "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" "\r\n" "Hey Sarah,\r\n" "bla bla bla bla bla\r\n"; static const QByteArray simpleMail3 = "From: chunkylover53@aol.com\r\n" "To: tylerdurden@paperstreetsoapcompany.com\r\n" "Subject: ILOVEYOU\r\n" "MIME-Version: 1.0\r\n" "Content-Type: text/plain\r\n" "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" "\r\n" "kindly check the attached LOVELETTER coming from me.\r\n"; static const QByteArray simpleMail4 = "From: karl@aol.com\r\n" "To: lenny@aol.com\r\n" "Subject: Who took the donuts?\r\n" "\r\n" "Hi Lenny, do you know who took all the donuts?\r\n"; static const QByteArray simpleMail5 = "From: foo@bar.com\r\n" "To: bar@foo.com\r\n" "Subject: Hello\r\n" "\r\n" "Hello World!!\r\n"; void Pop3Test::cleanupMaildir(Akonadi::Item::List items) { // Delete all mails so the maildir is clean for the next test if (!items.isEmpty()) { ItemDeleteJob *job = new ItemDeleteJob(items); QVERIFY(job->exec()); } QTime time; time.start(); int lastCount = -1; forever { qApp->processEvents(); QTest::qWait(500); QDir maildir(mMaildirPath); maildir.refresh(); int curCount = maildir.entryList(QDir::Files | QDir::NoDotAndDotDot).count(); // Restart the timer when a mail arrives, as it shows that the maildir resource is // still alive and kicking. if (curCount != lastCount) { time.restart(); lastCount = curCount; } if (curCount == 0) { break; } QVERIFY(time.elapsed() < 60000 || time.elapsed() > 80000000); } } void Pop3Test::checkMailsInMaildir(const QList &mails) { // Now, test that all mails actually ended up in the maildir. Since the maildir resource // might be slower, give it a timeout so it can write the files to disk QTime time; time.start(); int lastCount = -1; forever { qApp->processEvents(); QTest::qWait(500); QDir maildir(mMaildirPath); maildir.refresh(); int curCount = static_cast(maildir.entryList(QDir::Files | QDir::NoDotAndDotDot).count()); // Restart the timer when a mail arrives, as it shows that the maildir resource is // still alive and kicking. if (curCount != lastCount) { time.start(); lastCount = curCount; } if (curCount == mails.count()) { break; } QVERIFY(static_cast(maildir.entryList(QDir::NoDotAndDotDot).count()) <= mails.count()); QVERIFY(time.elapsed() < 60000 || time.elapsed() > 80000000); } // TODO: check file contents as well or is this overkill? } Akonadi::Item::List Pop3Test::checkMailsOnAkonadiServer(const QList &mails) { // The fake server got disconnected, which means the pop3 resource has entered the QUIT // stage. That means all messages should be on the server now, so test that. ItemFetchJob *job = new ItemFetchJob(mMaildirCollection); job->fetchScope().fetchFullPayload(); Q_ASSERT(job->exec()); Item::List items = job->items(); Q_ASSERT(mails.size() == items.size()); QSet ourMailBodies; QSet itemMailBodies; foreach (const Item &item, items) { KMime::Message::Ptr itemMail = item.payload(); QByteArray itemMailBody = itemMail->body(); // For some reason, the body in the maildir has one additional newline. // Get rid of this so we can compare them. // FIXME: is this a bug? Find out where the newline comes from! itemMailBody.chop(1); itemMailBodies.insert(itemMailBody); } foreach (const QByteArray &mail, mails) { KMime::Message::Ptr ourMail(new KMime::Message()); ourMail->setContent(KMime::CRLFtoLF(mail)); ourMail->parse(); QByteArray ourMailBody = ourMail->body(); ourMailBodies.insert(ourMailBody); } Q_ASSERT(ourMailBodies == itemMailBodies); return items; } void Pop3Test::syncAndWaitForFinish() { AgentManager::self()->instance(mPop3Identifier).synchronize(); // The pop3 resource, ioslave and the fakeserver are all in different processes or threads. // We simply wait until the FakeServer got disconnected or until a timeout. // Since POP3 fetching can take longer, we reset the timeout timer when the FakeServer // does some processing. QTime time; time.start(); int lastProgress = -1; forever { qApp->processEvents(); // Finish correctly when the connection got closed if (mFakeServerThread->server()->gotDisconnected()) { break; } // Reset the timeout when the server is working const int newProgress = mFakeServerThread->server()->progress(); if (newProgress != lastProgress) { time.restart(); lastProgress = newProgress; } // Assert when nothing happens for a certain timeout, that indicates something went // wrong and is stuck somewhere if (time.elapsed() >= 60000) { Q_ASSERT_X(false, "poptest", "FakeServer timed out."); break; } } } QString Pop3Test::loginSequence() const { return QStringLiteral("C: USER HansWurst\r\n" "S: +OK May I have your password, please?\r\n" "C: PASS Geheim\r\n" "S: +OK Mailbox locked and ready\r\n"); } QString Pop3Test::retrieveSequence(const QList &mails, const QList &exceptions) const { QString result; for (int i = 1; i <= mails.size(); i++) { if (!exceptions.contains(i)) { result += QLatin1String( "C: RETR %RETR%\r\n" "S: +OK Here is your spam\r\n" "%MAIL%\r\n" ".\r\n"); } } return result; } QString Pop3Test::deleteSequence(int numToDelete) const { QString result; for (int i = 0; i < numToDelete; i++) { result += QLatin1String("C: DELE %DELE%\r\n" "S: +OK message sent to /dev/null\r\n"); } return result; } QString Pop3Test::quitSequence() const { return QStringLiteral("C: QUIT\r\n" "S: +OK Have a nice day.\r\n"); } QString Pop3Test::listSequence(const QList &mails) const { QString result = QStringLiteral("C: LIST\r\n" "S: +OK You got new spam\r\n"); for (int i = 1; i <= mails.size(); i++) { result += QStringLiteral("%1 %MAILSIZE%\r\n").arg(i); } result += QLatin1String(".\r\n"); return result; } QString Pop3Test::uidSequence(const QStringList &uids) const { QString result = QStringLiteral("C: UIDL\r\n" "S: +OK\r\n"); for (int i = 1; i <= uids.size(); i++) { result += QStringLiteral("%1 %2\r\n").arg(i).arg(uids[i - 1]); } result += QLatin1String(".\r\n"); return result; } static bool sortedEqual(const QStringList &list1, const QStringList &list2) { QStringList sorted1 = list1; sorted1.sort(); QStringList sorted2 = list2; sorted2.sort(); return std::equal(sorted1.begin(), sorted1.end(), sorted2.begin()); } void Pop3Test::lowerTimeOfSeenMail(const QString &uidOfMail, int secondsToLower) { const int index = mPOP3SettingsInterface->seenUidList().value().indexOf(uidOfMail); QList seenTimeList = mPOP3SettingsInterface->seenUidTimeList().value(); int msgTime = seenTimeList.at(index); msgTime -= secondsToLower; seenTimeList.replace(index, msgTime); mPOP3SettingsInterface->setSeenUidTimeList(seenTimeList); } void Pop3Test::testSimpleDownload() { QList mails; mails << simpleMail1 << simpleMail2 << simpleMail3; QStringList uids; uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); mFakeServerThread->server()->setAllowedDeletions(QStringLiteral("1,2,3")); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("1,2,3")); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + deleteSequence(mails.size()) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); cleanupMaildir(items); } void Pop3Test::testBigFetch() { QList mails; QStringList uids; QString allowedRetrs; for (int i = 0; i < 1000; i++) { QByteArray newMail = simpleMail1; newMail.append(QString::number(i + 1).toLatin1()); mails << newMail; uids << QStringLiteral("UID%1").arg(i + 1); allowedRetrs += QString::number(i + 1) + QLatin1Char(','); } allowedRetrs.chop(1); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(allowedRetrs); mFakeServerThread->server()->setAllowedDeletions(allowedRetrs); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + deleteSequence(mails.size()) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); cleanupMaildir(items); } void Pop3Test::testSeenUIDCleanup() { // // First, fetch 3 normal mails, but leave them on the server. // mPOP3SettingsInterface->setLeaveOnServer(true); QList mails; mails << simpleMail1 << simpleMail2 << simpleMail3; QStringList uids; uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); mFakeServerThread->server()->setAllowedDeletions(QString()); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("1,2,3")); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); cleanupMaildir(items); QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); // // Now, pretend that the messages were removed from the server in the meantime // by having no mails on the fake server. // mFakeServerThread->server()->setMails(QList()); mFakeServerThread->server()->setAllowedRetrieves(QString()); mFakeServerThread->server()->setAllowedDeletions(QString()); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(QList()) + uidSequence(QStringList()) + quitSequence() ); syncAndWaitForFinish(); items = checkMailsOnAkonadiServer(QList()); checkMailsInMaildir(QList()); cleanupMaildir(items); QVERIFY(mPOP3SettingsInterface->seenUidList().value().isEmpty()); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); mPOP3SettingsInterface->setLeaveOnServer(false); } void Pop3Test::testSimpleLeaveOnServer() { mPOP3SettingsInterface->setLeaveOnServer(true); QList mails; mails << simpleMail1 << simpleMail2 << simpleMail3; QStringList uids; uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("1,2,3")); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); // The resource should have saved the UIDs of the seen messages QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); foreach (int seenTime, mPOP3SettingsInterface->seenUidTimeList().value()) { // Those message were just downloaded from the fake server, so they are at maximum // 10 minutes old (for slooooow running tests) QVERIFY(seenTime >= time(nullptr) - 10 * 60); } // // OK, next mail check: We have to check that the old seen messages are not downloaded again, // only new mails. // QList newMails(mails); newMails << simpleMail4; QStringList newUids(uids); newUids << QStringLiteral("newUID"); QList idsToNotDownload; idsToNotDownload << 1 << 2 << 3; mFakeServerThread->server()->setMails(newMails); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("4")); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(newMails) + uidSequence(newUids) + retrieveSequence(newMails, idsToNotDownload) + quitSequence(), idsToNotDownload ); syncAndWaitForFinish(); items = checkMailsOnAkonadiServer(newMails); checkMailsInMaildir(newMails); QVERIFY(sortedEqual(newUids, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); // // Ok, next test: When turning off leaving on the server, all mails should be deleted, but // none downloaded. // mPOP3SettingsInterface->setLeaveOnServer(false); mFakeServerThread->server()->setAllowedDeletions(QStringLiteral("1,2,3,4")); mFakeServerThread->server()->setAllowedRetrieves(QString()); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(newMails) + uidSequence(newUids) + deleteSequence(newMails.size()) + quitSequence() ); syncAndWaitForFinish(); items = checkMailsOnAkonadiServer(newMails); checkMailsInMaildir(newMails); cleanupMaildir(items); QVERIFY(mPOP3SettingsInterface->seenUidList().value().isEmpty()); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); } void Pop3Test::testTimeBasedLeaveRule() { mPOP3SettingsInterface->setLeaveOnServer(true); mPOP3SettingsInterface->setLeaveOnServerDays(2); // // First download 3 mails and leave them on the server // QList mails; mails << simpleMail1 << simpleMail2 << simpleMail3; QStringList uids; uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("1,2,3")); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); // // Now, modify the seenUidTimeList on the server for UID2 to pretend it // was downloaded 3 days ago, which means it should be deleted. // lowerTimeOfSeenMail(QStringLiteral("UID2"), 60 * 60 * 24 * 3); QList idsToNotDownload; idsToNotDownload << 1 << 3; mFakeServerThread->server()->setAllowedDeletions(QStringLiteral("2")); mFakeServerThread->server()->setAllowedRetrieves(QString()); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + deleteSequence(1) + quitSequence(), idsToNotDownload ); syncAndWaitForFinish(); items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); cleanupMaildir(items); uids.removeAll(QStringLiteral("UID2")); QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); foreach (int seenTime, mPOP3SettingsInterface->seenUidTimeList().value()) { QVERIFY(seenTime >= time(nullptr) - 10 * 60); } mPOP3SettingsInterface->setLeaveOnServer(false); mPOP3SettingsInterface->setLeaveOnServerDays(0); mPOP3SettingsInterface->setSeenUidTimeList(QList()); mPOP3SettingsInterface->setSeenUidList(QStringList()); } void Pop3Test::testCountBasedLeaveRule() { mPOP3SettingsInterface->setLeaveOnServer(true); mPOP3SettingsInterface->setLeaveOnServerCount(3); // // First download 3 mails and leave them on the server // QList mails; mails << simpleMail1 << simpleMail2 << simpleMail3; QStringList uids; uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("1,2,3")); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + quitSequence() ); syncAndWaitForFinish(); checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); // Make the 3 just downloaded mails appear older than they are lowerTimeOfSeenMail(QStringLiteral("UID1"), 60 * 60 * 24 * 2); lowerTimeOfSeenMail(QStringLiteral("UID2"), 60 * 60 * 24 * 1); lowerTimeOfSeenMail(QStringLiteral("UID3"), 60 * 60 * 24 * 3); // // Now, download 2 more mails. Since only 3 mails are allowed to be left // on the server, the oldest ones, UID1 and UID3, should be deleted // QList moreMails; moreMails << simpleMail4 << simpleMail5; QStringList moreUids; moreUids << QStringLiteral("UID4") << QStringLiteral("UID5"); mFakeServerThread->server()->setMails(mails + moreMails); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("4,5")); mFakeServerThread->server()->setAllowedDeletions(QStringLiteral("1,3")); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails + moreMails) + uidSequence(uids + moreUids) + retrieveSequence(moreMails) + deleteSequence(2) + quitSequence(), QList() << 1 << 2 << 3 ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails + moreMails); checkMailsInMaildir(mails + moreMails); cleanupMaildir(items); QStringList uidsLeft; uidsLeft << QStringLiteral("UID2") << QStringLiteral("UID4") << QStringLiteral("UID5"); QVERIFY(sortedEqual(uidsLeft, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); mPOP3SettingsInterface->setLeaveOnServer(false); mPOP3SettingsInterface->setLeaveOnServerCount(0); mPOP3SettingsInterface->setSeenUidTimeList(QList()); mPOP3SettingsInterface->setSeenUidList(QStringList()); } void Pop3Test::testSizeBasedLeaveRule() { mPOP3SettingsInterface->setLeaveOnServer(true); mPOP3SettingsInterface->setLeaveOnServerSize(10); // 10 MB // // First download 3 mails and leave them on the server. // QList mails; mails << simpleMail1 << simpleMail2 << simpleMail3; QStringList uids; uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(QStringLiteral("1,2,3")); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + quitSequence() ); syncAndWaitForFinish(); checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); // Make the 3 just downloaded mails appear older than they are lowerTimeOfSeenMail(QStringLiteral("UID1"), 60 * 60 * 24 * 2); lowerTimeOfSeenMail(QStringLiteral("UID2"), 60 * 60 * 24 * 1); lowerTimeOfSeenMail(QStringLiteral("UID3"), 60 * 60 * 24 * 3); // Now, do another mail check, but with no new mails on the server. // Instead we let the server pretend that the mails have a fake size, // each 7 MB. That means the two oldest get deleted, because the total // mail size is over 10 MB with them. mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(QString()); mFakeServerThread->server()->setAllowedDeletions(QStringLiteral("1,3")); mFakeServerThread->server()->setNextConversation( loginSequence() + QLatin1String("C: LIST\r\n" "S: +OK You got new spam\r\n" "1 7340032\r\n" "2 7340032\r\n" "3 7340032\r\n" ".\r\n") + uidSequence(uids) + deleteSequence(2) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); cleanupMaildir(items); QStringList uidsLeft; uidsLeft << QStringLiteral("UID2"); QVERIFY(sortedEqual(uidsLeft, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); mPOP3SettingsInterface->setLeaveOnServer(false); mPOP3SettingsInterface->setLeaveOnServerCount(0); mPOP3SettingsInterface->setLeaveOnServerSize(0); mPOP3SettingsInterface->setSeenUidTimeList(QList()); mPOP3SettingsInterface->setSeenUidList(QStringList()); } void Pop3Test::testMixedLeaveRules() { mPOP3SettingsInterface->setLeaveOnServer(true); // // Generate 10 mails // QList mails; QStringList uids; QString allowedRetrs; for (int i = 0; i < 10; i++) { QByteArray newMail = simpleMail1; newMail.append(QString::number(i + 1).toLatin1()); mails << newMail; uids << QStringLiteral("UID%1").arg(i + 1); allowedRetrs += QString::number(i + 1) + QLatin1Char(','); } allowedRetrs.chop(1); // // Now, download these 10 mails // mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(allowedRetrs); mFakeServerThread->server()->setNextConversation( loginSequence() + listSequence(mails) + uidSequence(uids) + retrieveSequence(mails) + quitSequence() ); syncAndWaitForFinish(); checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); // Fake the time of the messages, UID1 is one day old, UID2 is two days old, etc for (int i = 1; i <= 10; i++) { lowerTimeOfSeenMail(QStringLiteral("UID%1").arg(i), 60 * 60 * 24 * i); } mPOP3SettingsInterface->setLeaveOnServer(true); mPOP3SettingsInterface->setLeaveOnServerSize(25); // UID 4, 5 oldest here mPOP3SettingsInterface->setLeaveOnServerCount(5); // UID 6, 7 oldest here mPOP3SettingsInterface->setLeaveOnServerDays(7); // UID 8, 9 and 10 too old // Ok, now we do another mail check that only deletes stuff from the server. // Above are the UIDs that should be deleted. mFakeServerThread->server()->setMails(mails); mFakeServerThread->server()->setAllowedRetrieves(QString()); mFakeServerThread->server()->setAllowedDeletions(QStringLiteral("4,5,6,7,8,9,10")); mFakeServerThread->server()->setNextConversation( loginSequence() + QLatin1String("C: LIST\r\n" "S: +OK You got new spam\r\n" "1 7340032\r\n" "2 7340032\r\n" "3 7340032\r\n" "4 7340032\r\n" "5 7340032\r\n" "6 7340032\r\n" "7 7340032\r\n" "8 7340032\r\n" "9 7340032\r\n" "10 7340032\r\n" ".\r\n") + uidSequence(uids) + deleteSequence(7) + quitSequence() ); syncAndWaitForFinish(); Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); checkMailsInMaildir(mails); cleanupMaildir(items); QStringList uidsLeft; uidsLeft << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); QVERIFY(sortedEqual(uidsLeft, mPOP3SettingsInterface->seenUidList().value())); QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == mPOP3SettingsInterface->seenUidList().value().size()); mPOP3SettingsInterface->setLeaveOnServer(false); mPOP3SettingsInterface->setLeaveOnServerCount(0); mPOP3SettingsInterface->setLeaveOnServerSize(0); mPOP3SettingsInterface->setSeenUidTimeList(QList()); mPOP3SettingsInterface->setSeenUidList(QStringList()); }