diff --git a/autotests/server/partstreamertest.cpp b/autotests/server/partstreamertest.cpp index bc111c008..5e51c00c4 100644 --- a/autotests/server/partstreamertest.cpp +++ b/autotests/server/partstreamertest.cpp @@ -1,282 +1,283 @@ /* * Copyright (C) 2014 Daniel Vrátil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "fakeakonadiserver.h" #include "fakeconnection.h" #include "aktest.h" #include "entities.h" #include #include #include "storage/partstreamer.h" #include #include #include #include #include using namespace Akonadi; using namespace Akonadi::Server; Q_DECLARE_METATYPE(Akonadi::Server::PimItem) Q_DECLARE_METATYPE(Akonadi::Server::Part::Storage) class PartStreamerTest : public QObject { Q_OBJECT public: PartStreamerTest() { // Set a very small treshold for easier testing const QString serverConfigFile = StandardDirs::serverConfigFile(StandardDirs::ReadWrite); QSettings settings(serverConfigFile, QSettings::IniFormat); settings.setValue(QStringLiteral("General/SizeThreshold"), 5); try { FakeAkonadiServer::instance()->init(); } catch (const FakeAkonadiServerException &e) { qWarning() << "Server exception: " << e.what(); qFatal("Fake Akonadi Server failed to start up, aborting test"); } } ~PartStreamerTest() { FakeAkonadiServer::instance()->quit(); } Protocol::ModifyItemsCommandPtr createCommand(const PimItem &item) { auto cmd = Protocol::ModifyItemsCommandPtr::create(item.id()); cmd->setParts({ "PLD:DATA" }); return cmd; } private Q_SLOTS: void testStreamer_data() { QTest::addColumn("scenarios"); QTest::addColumn("expectedPartName"); QTest::addColumn("expectedPartData"); QTest::addColumn("expectedFileData"); QTest::addColumn("expectedPartSize"); QTest::addColumn("expectedChanged"); QTest::addColumn("storage"); QTest::addColumn("pimItem"); PimItem item; item.setCollectionId(Collection::retrieveByName(QStringLiteral("Col A")).id()); item.setMimeType(MimeType::retrieveByName(QStringLiteral("application/octet-stream"))); item.setSize(1); // this will not match reality during the test, but that does not matter, as // that's not the subject of this test QVERIFY(item.insert()); qint64 partId = -1; Part::List parts = Part::retrieveAll(); if (parts.isEmpty()) { partId = 0; } else { partId = parts.last().id() + 1; } // Order of these tests matters! { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 3))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", "123")) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item.id(), 1)); QTest::newRow("item 1, internal") << scenarios << QByteArray("PLD:DATA") << QByteArray("123") << QByteArray() << 3ll << true << Part::Internal << item; } { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 9))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data, QStringLiteral("%1_r0").arg(partId))) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA")) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item.id(), 2)); QTest::newRow("item 1, change to external") << scenarios << QByteArray("PLD:DATA") << QByteArray("15_r0") << QByteArray("123456789") << 9ll << true << Part::External << item; } { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 9))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data, QStringLiteral("%1_r1").arg(partId))) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA")) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item.id(), 3)); QTest::newRow("item 1, update external") << scenarios << QByteArray("PLD:DATA") << QByteArray("15_r1") << QByteArray("987654321") << 9ll << true << Part::External << item; } { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 9))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data, QStringLiteral("%1_r2").arg(partId))) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA")) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item.id(), 4)); QTest::newRow("item 1, external, no change") << scenarios << QByteArray("PLD:DATA") << QByteArray("15_r2") << QByteArray("987654321") << 9ll << false << Part::External << item; } { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 4))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", "1234")) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item.id(), 5)); QTest::newRow("item 1, change to internal") << scenarios << QByteArray("PLD:DATA") << QByteArray("1234") << QByteArray() << 4ll << true << Part::Internal << item; } { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 4))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", "1234")) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item.id(), 6)); QTest::newRow("item 1, internal, no change") << scenarios << QByteArray("PLD:DATA") << QByteArray("1234") << QByteArray() << 4ll << false << Part::Internal << item; } // Insert new item PimItem item2 = item; QVERIFY(item2.insert()); const QString foreignPath = FakeAkonadiServer::basePath() + QStringLiteral("/tmp/foreignPayloadFile"); { TestScenario::List scenarios; scenarios << FakeAkonadiServer::loginScenario() << TestScenario::create(5, TestScenario::ClientCmd, createCommand(item2)) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::MetaData)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", Protocol::PartMetaData("PLD:DATA", 3, 0, Protocol::PartMetaData::Foreign))) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::StreamPayloadCommandPtr::create("PLD:DATA", Protocol::StreamPayloadCommand::Data)) << TestScenario::create(5, TestScenario::ClientCmd, Protocol::StreamPayloadResponsePtr::create("PLD:DATA", foreignPath.toUtf8())) << TestScenario::create(5, TestScenario::ServerCmd, Protocol::ModifyItemsResponsePtr::create(item2.id(), 1)); QTest::newRow("item 2, new foreign part") << scenarios << QByteArray("PLD:DATA") << foreignPath.toUtf8() << QByteArray("123") << 3ll << false << Part::Foreign << item2; } } void testStreamer() { QFETCH(TestScenario::List, scenarios); QFETCH(QByteArray, expectedPartName); QFETCH(QByteArray, expectedPartData); QFETCH(QByteArray, expectedFileData); QFETCH(qint64, expectedPartSize); QFETCH(Part::Storage, storage); QFETCH(PimItem, pimItem); if (storage == Part::External) { // Create the payload file now, since don't have means to react // directly to the streaming command QFile file(ExternalPartStorage::resolveAbsolutePath(expectedPartData)); file.open(QIODevice::WriteOnly); file.write(expectedFileData); file.close(); } else if (storage == Part::Foreign) { // Create the foreign payload file QDir().mkpath(FakeAkonadiServer::basePath() + QStringLiteral("/tmp")); QFile file(QString::fromUtf8(expectedPartData)); file.open(QIODevice::WriteOnly); file.write(expectedFileData); file.close(); } FakeAkonadiServer::instance()->setScenarios(scenarios); FakeAkonadiServer::instance()->runTest(); PimItem item = PimItem::retrieveById(pimItem.id()); const QVector parts = item.parts(); QVERIFY(parts.count() == 1); const Part part = parts[0]; QCOMPARE(part.datasize(), expectedPartSize); QCOMPARE(part.storage(), storage); const QByteArray data = part.data(); if (storage == Part::External) { QCOMPARE(data, expectedPartData); QFile file(ExternalPartStorage::resolveAbsolutePath(data)); QVERIFY(file.exists()); QCOMPARE(file.size(), expectedPartSize); QVERIFY(file.open(QIODevice::ReadOnly)); const QByteArray fileData = file.readAll(); QCOMPARE(fileData, expectedFileData); // Make sure no previous versions are left behind in file_db_data const int revision = data.mid(data.indexOf("_r") + 2).toInt(); for (int i = 0; i < revision; ++i) { const QByteArray fileName = QByteArray::number(part.id()) + "_r" + QByteArray::number(i); const QString filePath = ExternalPartStorage::resolveAbsolutePath(fileName); - QVERIFY2(!QFile::exists(filePath), qPrintable(filePath)); + // TRY because the deletion happens in another thread + QTRY_VERIFY2(!QFile::exists(filePath), qPrintable(filePath)); } } else if (storage == Part::Foreign) { QCOMPARE(data, expectedPartData); QFile file(QString::fromUtf8(data)); QVERIFY(file.exists()); QCOMPARE(file.size(), expectedPartSize); QVERIFY(file.open(QIODevice::ReadOnly)); const QByteArray fileData = file.readAll(); QCOMPARE(fileData, expectedFileData); } else { QCOMPARE(data, expectedPartData); // Make sure nothing is left behind in file_db_data // TODO: we have no way of knowing what is the last revision for (int i = 0; i <= 100; ++i) { const QByteArray fileName = QByteArray::number(part.id()) + "_r" + QByteArray::number(i); const QString filePath = ExternalPartStorage::resolveAbsolutePath(fileName); - QVERIFY2(!QFile::exists(filePath), qPrintable(filePath)); + QTRY_VERIFY2(!QFile::exists(filePath), qPrintable(filePath)); } } } }; AKTEST_FAKESERVER_MAIN(PartStreamerTest) #include "partstreamertest.moc"