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

0001 /*
0002     SPDX-FileCopyrightText: 2019 David Faure <faure@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <QObject>
0008 
0009 #include "fakeakonadiserver.h"
0010 #include "fakeintervalcheck.h"
0011 #include "shared/aktest.h"
0012 
0013 #include <QTest>
0014 
0015 using namespace Akonadi;
0016 using namespace Akonadi::Server;
0017 using TimePoint = CollectionScheduler::TimePoint;
0018 
0019 using namespace std::literals::chrono_literals;
0020 
0021 class CollectionSchedulerTest : public QObject
0022 {
0023     Q_OBJECT
0024 
0025     FakeAkonadiServer mAkonadi;
0026 private Q_SLOTS:
0027     void initTestCase()
0028     {
0029         mAkonadi.init();
0030     }
0031 
0032     void shouldInitializeSyncIntervals()
0033     {
0034         // WHEN
0035         auto sched = AkThread::create<FakeIntervalCheck>(mAkonadi.itemRetrievalManager());
0036         sched->waitForInit();
0037         const TimePoint now(std::chrono::steady_clock::now());
0038         // THEN
0039         // Collections root (1), ColA (2), ColB (3), ColD (5), virtual (6) and virtual2 (7)
0040         // should have a check scheduled in 5 minutes (default value)
0041         for (qint64 collectionId : {1, 2, 3, 5, 6, 7}) {
0042             QVERIFY2(sched->nextScheduledTime(collectionId) > now + 4min, qPrintable(QString::number(collectionId)));
0043             QVERIFY(sched->nextScheduledTime(collectionId) < now + 6min);
0044         }
0045         QCOMPARE(sched->nextScheduledTime(4).time_since_epoch(), TimePoint::duration::zero()); // ColC is skipped because syncPref=false
0046         QCOMPARE(sched->nextScheduledTime(314).time_since_epoch(), TimePoint::duration::zero()); // no such collection
0047         QVERIFY(sched->currentTimerInterval() > 4min);
0048         QVERIFY(sched->currentTimerInterval() < 6min);
0049     }
0050 
0051     // (not that this feature is really used right now, it defaults to 5 and CacheCleaner sets it to 5)
0052     void shouldObeyMinimumInterval()
0053     {
0054         // GIVEN
0055         auto sched = AkThread::create<FakeIntervalCheck>(mAkonadi.itemRetrievalManager());
0056         // WHEN
0057         sched->setMinimumInterval(10);
0058         sched->waitForInit();
0059         // THEN
0060         const TimePoint now(std::chrono::steady_clock::now());
0061         QTRY_VERIFY(sched->nextScheduledTime(2).time_since_epoch() > TimePoint::duration::zero());
0062         QVERIFY(sched->nextScheduledTime(2) > now + 9min);
0063         QVERIFY(sched->nextScheduledTime(2) < now + 11min);
0064         QVERIFY(sched->currentTimerInterval() > 9min);
0065         QVERIFY(sched->currentTimerInterval() < 11min);
0066     }
0067 
0068     void shouldRemoveAndAddCollectionFromSchedule()
0069     {
0070         // GIVEN
0071         auto sched = AkThread::create<FakeIntervalCheck>(mAkonadi.itemRetrievalManager());
0072         sched->waitForInit();
0073         const auto timeForRoot = sched->nextScheduledTime(1);
0074         const auto timeForColB = sched->nextScheduledTime(3);
0075         QVERIFY(sched->nextScheduledTime(2) <= timeForColB);
0076         // WHEN
0077         sched->collectionRemoved(2);
0078         // THEN
0079         QTRY_COMPARE(sched->nextScheduledTime(2).time_since_epoch(), TimePoint::duration::zero());
0080         QCOMPARE(sched->nextScheduledTime(1), timeForRoot); // unchanged
0081         QCOMPARE(sched->nextScheduledTime(3), timeForColB); // unchanged
0082         QVERIFY(sched->currentTimerInterval() > 4min); // unchanged
0083         QVERIFY(sched->currentTimerInterval() < 6min); // unchanged
0084 
0085         // AND WHEN re-adding the collection
0086         QTest::qWait(1000); // we only have precision to the second...
0087         sched->collectionAdded(2);
0088         // THEN
0089         QTRY_VERIFY(sched->nextScheduledTime(2).time_since_epoch() > TimePoint::duration::zero());
0090         // This is unchanged, even though it would normally have been 1s later. See "minor optimization" in scheduler.
0091         QCOMPARE(sched->nextScheduledTime(2), timeForColB);
0092         QCOMPARE(sched->nextScheduledTime(1), timeForRoot); // unchanged
0093         QCOMPARE(sched->nextScheduledTime(3), timeForColB); // unchanged
0094         QVERIFY(sched->currentTimerInterval() > 4min); // unchanged
0095         QVERIFY(sched->currentTimerInterval() < 6min); // unchanged
0096     }
0097 
0098     void shouldHonourIntervalChange()
0099     {
0100         // GIVEN
0101         auto sched = AkThread::create<FakeIntervalCheck>(mAkonadi.itemRetrievalManager());
0102         sched->waitForInit();
0103         const auto timeForColB = sched->nextScheduledTime(3);
0104         Collection colA = Collection::retrieveByName(QStringLiteral("Collection A"));
0105         QCOMPARE(colA.id(), 2);
0106         QVERIFY(sched->nextScheduledTime(2) <= timeForColB);
0107         // WHEN
0108         colA.setCachePolicyInherit(false);
0109         colA.setCachePolicyCheckInterval(20); // in minutes
0110         QVERIFY(colA.update());
0111         sched->collectionChanged(2);
0112         // THEN
0113         // "in 20 minutes" is 15 minutes later than "in 5 minutes"
0114         QTRY_VERIFY(sched->nextScheduledTime(2) >= timeForColB + 14min);
0115         QVERIFY(sched->nextScheduledTime(2) <= timeForColB + 16min);
0116         QVERIFY(sched->currentTimerInterval() > 4min); // unchanged
0117         QVERIFY(sched->currentTimerInterval() < 6min); // unchanged
0118     }
0119 };
0120 
0121 AKTEST_FAKESERVER_MAIN(CollectionSchedulerTest)
0122 
0123 #include "collectionschedulertest.moc"