File indexing completed on 2024-11-10 04:40:15

0001 /*
0002     SPDX-FileCopyrightText: 2009 Thomas McGuire <mcguire@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #include "resourceschedulertest.h"
0007 
0008 #include "../src/agentbase/resourcescheduler_p.h"
0009 
0010 #include <QSignalSpy>
0011 #include <QTest>
0012 
0013 using namespace Akonadi;
0014 
0015 QTEST_MAIN(ResourceSchedulerTest)
0016 
0017 Q_DECLARE_METATYPE(QSet<QByteArray>)
0018 
0019 ResourceSchedulerTest::ResourceSchedulerTest(QObject *parent)
0020     : QObject(parent)
0021 {
0022     qRegisterMetaType<QSet<QByteArray>>();
0023 }
0024 
0025 void ResourceSchedulerTest::testTaskComparison()
0026 {
0027     ResourceScheduler::Task t1;
0028     t1.type = ResourceScheduler::ChangeReplay;
0029     ResourceScheduler::Task t2;
0030     t2.type = ResourceScheduler::ChangeReplay;
0031     QCOMPARE(t1, t2);
0032     QList<ResourceScheduler::Task> taskList;
0033     taskList.append(t1);
0034     QVERIFY(taskList.contains(t2));
0035 
0036     ResourceScheduler::Task t3;
0037     t3.type = ResourceScheduler::DeleteResourceCollection;
0038     QVERIFY(!(t2 == t3));
0039     QVERIFY(!taskList.contains(t3));
0040 
0041     ResourceScheduler::Task t4;
0042     t4.type = ResourceScheduler::Custom;
0043     t4.receiver = this;
0044     t4.methodName = "customTask";
0045     t4.argument = QStringLiteral("call1");
0046 
0047     ResourceScheduler::Task t5(t4);
0048     QVERIFY(t4 == t5);
0049 
0050     t5.argument = QStringLiteral("call2");
0051     QVERIFY(!(t4 == t5));
0052 }
0053 
0054 void ResourceSchedulerTest::testChangeReplaySchedule()
0055 {
0056     ResourceScheduler scheduler;
0057     scheduler.setOnline(true);
0058     qRegisterMetaType<Akonadi::Collection>("Akonadi::Collection");
0059     QSignalSpy changeReplaySpy(&scheduler, SIGNAL(executeChangeReplay()));
0060     QSignalSpy collectionTreeSyncSpy(&scheduler, SIGNAL(executeCollectionTreeSync()));
0061     QSignalSpy syncSpy(&scheduler, SIGNAL(executeCollectionSync(Akonadi::Collection)));
0062     QVERIFY(changeReplaySpy.isValid());
0063     QVERIFY(collectionTreeSyncSpy.isValid());
0064     QVERIFY(syncSpy.isValid());
0065 
0066     // Schedule a change replay, it should be executed first thing when we enter the
0067     // event loop, but not before
0068     QVERIFY(scheduler.isEmpty());
0069     scheduler.scheduleChangeReplay();
0070     QVERIFY(!scheduler.isEmpty());
0071     QVERIFY(changeReplaySpy.isEmpty());
0072     QTest::qWait(1);
0073     QCOMPARE(changeReplaySpy.count(), 1);
0074     scheduler.taskDone();
0075     QTest::qWait(1);
0076     QCOMPARE(changeReplaySpy.count(), 1);
0077 
0078     // Schedule two change replays. The duplicate one should not be executed.
0079     changeReplaySpy.clear();
0080     scheduler.scheduleChangeReplay();
0081     scheduler.scheduleChangeReplay();
0082     QVERIFY(changeReplaySpy.isEmpty());
0083     QTest::qWait(1);
0084     QCOMPARE(changeReplaySpy.count(), 1);
0085     scheduler.taskDone();
0086     QTest::qWait(1);
0087     QCOMPARE(changeReplaySpy.count(), 1);
0088 
0089     // Schedule a second change replay while one is in progress, should give as two signal emissions
0090     changeReplaySpy.clear();
0091     scheduler.scheduleChangeReplay();
0092     QVERIFY(changeReplaySpy.isEmpty());
0093     QTest::qWait(1);
0094     QCOMPARE(changeReplaySpy.count(), 1);
0095     scheduler.scheduleChangeReplay();
0096     scheduler.taskDone();
0097     QTest::qWait(1);
0098     QCOMPARE(changeReplaySpy.count(), 2);
0099     scheduler.taskDone();
0100 
0101     //
0102     // Schedule various stuff.
0103     //
0104     Collection collection(42);
0105     changeReplaySpy.clear();
0106     scheduler.scheduleCollectionTreeSync();
0107     scheduler.scheduleChangeReplay();
0108     scheduler.scheduleSync(collection);
0109     scheduler.scheduleChangeReplay();
0110 
0111     QTest::qWait(1);
0112     QCOMPARE(collectionTreeSyncSpy.count(), 0);
0113     QCOMPARE(changeReplaySpy.count(), 1);
0114     QCOMPARE(syncSpy.count(), 0);
0115 
0116     scheduler.taskDone();
0117     QTest::qWait(1);
0118     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0119     QCOMPARE(changeReplaySpy.count(), 1);
0120     QCOMPARE(syncSpy.count(), 0);
0121 
0122     // Omit a taskDone() here, there shouldn't be a new signal
0123     QTest::qWait(1);
0124     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0125     QCOMPARE(changeReplaySpy.count(), 1);
0126     QCOMPARE(syncSpy.count(), 0);
0127 
0128     scheduler.taskDone();
0129     QTest::qWait(1);
0130     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0131     QCOMPARE(changeReplaySpy.count(), 1);
0132     QCOMPARE(syncSpy.count(), 1);
0133 
0134     // At this point, we're done, check that nothing else is emitted
0135     scheduler.taskDone();
0136     QVERIFY(scheduler.isEmpty());
0137     QTest::qWait(1);
0138     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0139     QCOMPARE(changeReplaySpy.count(), 1);
0140     QCOMPARE(syncSpy.count(), 1);
0141 }
0142 
0143 void ResourceSchedulerTest::customTaskNoArg()
0144 {
0145     ++mCustomCallCount;
0146 }
0147 
0148 void ResourceSchedulerTest::customTask(const QVariant &argument)
0149 {
0150     ++mCustomCallCount;
0151     mLastArgument = argument;
0152 }
0153 
0154 void ResourceSchedulerTest::testCustomTask()
0155 {
0156     ResourceScheduler scheduler;
0157     scheduler.setOnline(true);
0158     mCustomCallCount = 0;
0159 
0160     scheduler.scheduleCustomTask(this, "customTask", QStringLiteral("call1"));
0161     scheduler.scheduleCustomTask(this, "customTask", QStringLiteral("call1"));
0162     scheduler.scheduleCustomTask(this, "customTask", QStringLiteral("call2"));
0163     scheduler.scheduleCustomTask(this, "customTaskNoArg", QVariant());
0164 
0165     QCOMPARE(mCustomCallCount, 0);
0166 
0167     QTest::qWait(1);
0168     QCOMPARE(mCustomCallCount, 1);
0169     QCOMPARE(mLastArgument.toString(), QStringLiteral("call1"));
0170 
0171     scheduler.taskDone();
0172     QVERIFY(!scheduler.isEmpty());
0173     QTest::qWait(1);
0174     QCOMPARE(mCustomCallCount, 2);
0175     QCOMPARE(mLastArgument.toString(), QStringLiteral("call2"));
0176 
0177     scheduler.taskDone();
0178     QVERIFY(!scheduler.isEmpty());
0179     QTest::qWait(1);
0180     QCOMPARE(mCustomCallCount, 3);
0181 
0182     scheduler.taskDone();
0183     QVERIFY(scheduler.isEmpty());
0184 }
0185 
0186 void ResourceSchedulerTest::testCompression()
0187 {
0188     ResourceScheduler scheduler;
0189     scheduler.setOnline(true);
0190     qRegisterMetaType<Akonadi::Collection>("Akonadi::Collection");
0191     qRegisterMetaType<Akonadi::Item>("Akonadi::Item");
0192     QSignalSpy fullSyncSpy(&scheduler, SIGNAL(executeFullSync()));
0193     QSignalSpy collectionTreeSyncSpy(&scheduler, SIGNAL(executeCollectionTreeSync()));
0194     QSignalSpy syncSpy(&scheduler, SIGNAL(executeCollectionSync(Akonadi::Collection)));
0195     QSignalSpy fetchSpy(&scheduler, SIGNAL(executeItemFetch(Akonadi::Item, QSet<QByteArray>)));
0196     QVERIFY(fullSyncSpy.isValid());
0197     QVERIFY(collectionTreeSyncSpy.isValid());
0198     QVERIFY(syncSpy.isValid());
0199     QVERIFY(fetchSpy.isValid());
0200 
0201     // full sync
0202     QVERIFY(scheduler.isEmpty());
0203     scheduler.scheduleFullSync();
0204     scheduler.scheduleFullSync();
0205     QTest::qWait(1); // start execution
0206     QCOMPARE(fullSyncSpy.count(), 1);
0207     scheduler.scheduleCollectionTreeSync();
0208     scheduler.taskDone();
0209     QTest::qWait(1);
0210     QCOMPARE(fullSyncSpy.count(), 1);
0211     QVERIFY(scheduler.isEmpty());
0212 
0213     // collection tree sync
0214     QVERIFY(scheduler.isEmpty());
0215     scheduler.scheduleCollectionTreeSync();
0216     scheduler.scheduleCollectionTreeSync();
0217     QTest::qWait(1); // start execution
0218     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0219     scheduler.scheduleCollectionTreeSync();
0220     scheduler.taskDone();
0221     QTest::qWait(1);
0222     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0223     QVERIFY(scheduler.isEmpty());
0224 
0225     // sync collection
0226     scheduler.scheduleSync(Akonadi::Collection(42));
0227     scheduler.scheduleSync(Akonadi::Collection(42));
0228     QTest::qWait(1); // start execution
0229     QCOMPARE(syncSpy.count(), 1);
0230     scheduler.scheduleSync(Akonadi::Collection(43));
0231     scheduler.scheduleSync(Akonadi::Collection(42));
0232     scheduler.taskDone();
0233     QTest::qWait(1);
0234     QCOMPARE(syncSpy.count(), 2);
0235     scheduler.taskDone();
0236     QTest::qWait(2);
0237     QVERIFY(scheduler.isEmpty());
0238 
0239     // sync collection
0240     scheduler.scheduleItemFetch(Akonadi::Item(42), QSet<QByteArray>(), QDBusMessage());
0241     scheduler.scheduleItemFetch(Akonadi::Item(42), QSet<QByteArray>(), QDBusMessage());
0242     QTest::qWait(1); // start execution
0243     QCOMPARE(fetchSpy.count(), 1);
0244     scheduler.scheduleItemFetch(Akonadi::Item(43), QSet<QByteArray>(), QDBusMessage());
0245     scheduler.scheduleItemFetch(Akonadi::Item(42), QSet<QByteArray>(), QDBusMessage());
0246     scheduler.taskDone();
0247     QTest::qWait(1);
0248     QCOMPARE(fetchSpy.count(), 2);
0249     scheduler.taskDone();
0250     QTest::qWait(2);
0251     QVERIFY(scheduler.isEmpty());
0252 }
0253 
0254 void ResourceSchedulerTest::testSyncCompletion()
0255 {
0256     ResourceScheduler scheduler;
0257     scheduler.setOnline(true);
0258     QSignalSpy completionSpy(&scheduler, SIGNAL(fullSyncComplete()));
0259     QVERIFY(completionSpy.isValid());
0260 
0261     // sync completion does not do compression
0262     QVERIFY(scheduler.isEmpty());
0263     scheduler.scheduleFullSyncCompletion();
0264     scheduler.scheduleFullSyncCompletion();
0265     QTest::qWait(1); // start execution
0266     QCOMPARE(completionSpy.count(), 1);
0267     scheduler.scheduleFullSyncCompletion();
0268     scheduler.taskDone();
0269     QTest::qWait(1);
0270     QCOMPARE(completionSpy.count(), 2);
0271     scheduler.taskDone();
0272     QTest::qWait(1);
0273     QCOMPARE(completionSpy.count(), 3);
0274     scheduler.taskDone();
0275     QVERIFY(scheduler.isEmpty());
0276 }
0277 
0278 void ResourceSchedulerTest::testPriorities()
0279 {
0280     ResourceScheduler scheduler;
0281     scheduler.setOnline(true);
0282     qRegisterMetaType<Akonadi::Collection>("Akonadi::Collection");
0283     qRegisterMetaType<Akonadi::Item>("Akonadi::Item");
0284     QSignalSpy changeReplaySpy(&scheduler, SIGNAL(executeChangeReplay()));
0285     QSignalSpy fullSyncSpy(&scheduler, SIGNAL(executeFullSync()));
0286     QSignalSpy collectionTreeSyncSpy(&scheduler, SIGNAL(executeCollectionTreeSync()));
0287     QSignalSpy syncSpy(&scheduler, SIGNAL(executeCollectionSync(Akonadi::Collection)));
0288     QSignalSpy fetchSpy(&scheduler, SIGNAL(executeItemFetch(Akonadi::Item, QSet<QByteArray>)));
0289     QSignalSpy attributesSyncSpy(&scheduler, SIGNAL(executeCollectionAttributesSync(Akonadi::Collection)));
0290     QVERIFY(changeReplaySpy.isValid());
0291     QVERIFY(fullSyncSpy.isValid());
0292     QVERIFY(collectionTreeSyncSpy.isValid());
0293     QVERIFY(syncSpy.isValid());
0294     QVERIFY(fetchSpy.isValid());
0295     QVERIFY(attributesSyncSpy.isValid());
0296 
0297     scheduler.scheduleCollectionTreeSync();
0298     scheduler.scheduleChangeReplay();
0299     scheduler.scheduleSync(Akonadi::Collection(42));
0300     scheduler.scheduleItemFetch(Akonadi::Item(42), QSet<QByteArray>(), QDBusMessage());
0301     scheduler.scheduleAttributesSync(Akonadi::Collection(42));
0302     scheduler.scheduleFullSync();
0303 
0304     QTest::qWait(1);
0305     QCOMPARE(collectionTreeSyncSpy.count(), 0);
0306     QCOMPARE(changeReplaySpy.count(), 1);
0307     QCOMPARE(syncSpy.count(), 0);
0308     QCOMPARE(fullSyncSpy.count(), 0);
0309     QCOMPARE(fetchSpy.count(), 0);
0310     QCOMPARE(attributesSyncSpy.count(), 0);
0311     scheduler.taskDone();
0312 
0313     QTest::qWait(1);
0314     QCOMPARE(collectionTreeSyncSpy.count(), 0);
0315     QCOMPARE(changeReplaySpy.count(), 1);
0316     QCOMPARE(syncSpy.count(), 0);
0317     QCOMPARE(fullSyncSpy.count(), 0);
0318     QCOMPARE(fetchSpy.count(), 1);
0319     QCOMPARE(attributesSyncSpy.count(), 0);
0320     scheduler.taskDone();
0321 
0322     QTest::qWait(1);
0323     QCOMPARE(collectionTreeSyncSpy.count(), 0);
0324     QCOMPARE(changeReplaySpy.count(), 1);
0325     QCOMPARE(syncSpy.count(), 0);
0326     QCOMPARE(fullSyncSpy.count(), 0);
0327     QCOMPARE(fetchSpy.count(), 1);
0328     QCOMPARE(attributesSyncSpy.count(), 1);
0329     scheduler.taskDone();
0330 
0331     QTest::qWait(1);
0332     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0333     QCOMPARE(changeReplaySpy.count(), 1);
0334     QCOMPARE(syncSpy.count(), 0);
0335     QCOMPARE(fullSyncSpy.count(), 0);
0336     QCOMPARE(fetchSpy.count(), 1);
0337     QCOMPARE(attributesSyncSpy.count(), 1);
0338     scheduler.taskDone();
0339 
0340     QTest::qWait(1);
0341     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0342     QCOMPARE(changeReplaySpy.count(), 1);
0343     QCOMPARE(syncSpy.count(), 1);
0344     QCOMPARE(fullSyncSpy.count(), 0);
0345     QCOMPARE(fetchSpy.count(), 1);
0346     QCOMPARE(attributesSyncSpy.count(), 1);
0347     scheduler.taskDone();
0348 
0349     QTest::qWait(1);
0350     QCOMPARE(collectionTreeSyncSpy.count(), 1);
0351     QCOMPARE(changeReplaySpy.count(), 1);
0352     QCOMPARE(syncSpy.count(), 1);
0353     QCOMPARE(fullSyncSpy.count(), 1);
0354     QCOMPARE(fetchSpy.count(), 1);
0355     QCOMPARE(attributesSyncSpy.count(), 1);
0356     scheduler.taskDone();
0357 
0358     QVERIFY(scheduler.isEmpty());
0359 }
0360 
0361 #include "moc_resourceschedulertest.cpp"