File indexing completed on 2024-12-22 04:52:57

0001 /*
0002  * This file is part of the KDE Akonadi Search Project
0003  * SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006  *
0007  */
0008 #include "scheduler.h"
0009 #include "collectionindexingjob.h"
0010 
0011 #include <Akonadi/Collection>
0012 #include <Akonadi/ServerManager>
0013 #include <akonadi/qtest_akonadi.h>
0014 
0015 #include <KConfig>
0016 #include <KConfigGroup>
0017 
0018 #include <QStandardPaths>
0019 #include <QTest>
0020 
0021 class DummyIndexingJob : public CollectionIndexingJob
0022 {
0023     Q_OBJECT
0024 public:
0025     DummyIndexingJob(Index &index, const Akonadi::Collection &col, const QList<Akonadi::Item::Id> &pending, QObject *parent = nullptr)
0026         : CollectionIndexingJob(index, col, pending, parent)
0027     {
0028     }
0029 
0030     void start() override
0031     {
0032         QMetaObject::invokeMethod(this, &DummyIndexingJob::finish, Qt::QueuedConnection);
0033     }
0034 
0035 private Q_SLOTS:
0036     void finish()
0037     {
0038         emitResult();
0039     }
0040 };
0041 
0042 class DummyJobFactory : public JobFactory
0043 {
0044 public:
0045     Akonadi::Collection::List indexedCollections;
0046     Akonadi::Item::List indexedItems;
0047     QList<bool> fullSyncs;
0048 
0049     CollectionIndexingJob *createCollectionIndexingJob(Index &index,
0050                                                        const Akonadi::Collection &col,
0051                                                        const QList<Akonadi::Item::Id> &pending,
0052                                                        bool fullSync,
0053                                                        QObject *parent = nullptr) override
0054     {
0055         for (qint64 id : pending) {
0056             indexedItems << Akonadi::Item(id);
0057         }
0058         indexedCollections << col;
0059         fullSyncs << fullSync;
0060         return new DummyIndexingJob(index, col, pending, parent);
0061     }
0062 };
0063 
0064 class SchedulerTest : public QObject
0065 {
0066     Q_OBJECT
0067 
0068 private Q_SLOTS:
0069     void initTestCase()
0070     {
0071         qRegisterMetaType<Akonadi::Collection::Id>("Akonadi::Collection::Id");
0072         QStandardPaths::setTestModeEnabled(true);
0073     }
0074 
0075     void init()
0076     {
0077         AkonadiTest::checkTestIsIsolated();
0078         AkonadiTest::setAllResourcesOffline();
0079         Akonadi::AgentInstance agent = Akonadi::AgentManager::self()->instance(QStringLiteral("akonadi_knut_resource_0"));
0080         QVERIFY(agent.isValid());
0081         agent.setIsOnline(true);
0082         QTRY_VERIFY(agent.isOnline());
0083     }
0084 
0085     void testInitialIndexing()
0086     {
0087         QSKIP("Broken test");
0088 
0089         auto config = KSharedConfig::openConfig(QStringLiteral("akonadi_indexing_agent"));
0090 
0091         Index index;
0092         QSharedPointer<DummyJobFactory> factory(new DummyJobFactory());
0093         Scheduler scheduler(index, config, factory);
0094         QSignalSpy statusSpy(&scheduler, &Scheduler::status);
0095         scheduler.setBusyTimeout(0);
0096         // Wait for ready signal (indicates that indexing is complete)
0097         QTRY_COMPARE(statusSpy.count(), 1);
0098         QTRY_COMPARE(factory->indexedCollections.size(), 2);
0099         QVERIFY(factory->fullSyncs.at(0));
0100         QVERIFY(factory->fullSyncs.at(1));
0101     }
0102 
0103     void testIndexCollections()
0104     {
0105         auto config = KSharedConfig::openConfig(QStringLiteral("akonadi_indexing_agent"));
0106         KConfigGroup group = config->group(QStringLiteral("General"));
0107         group.writeEntry("initialIndexingComplete", true);
0108 
0109         Index index;
0110         QSharedPointer<DummyJobFactory> factory(new DummyJobFactory());
0111         Scheduler scheduler(index, config, factory);
0112         QSignalSpy statusSpy(&scheduler, &Scheduler::status);
0113         QSignalSpy finishedIndexing(&scheduler, &Scheduler::collectionIndexingFinished);
0114         scheduler.setBusyTimeout(0);
0115 
0116         Akonadi::Collection col1(3);
0117         scheduler.scheduleCollection(col1);
0118         Akonadi::Collection col2(4);
0119         scheduler.scheduleCollection(col2, true);
0120 
0121         // Wait for ready signal (indicates that indexing is complete)
0122         QTRY_COMPARE(statusSpy.count(), 1);
0123         QTRY_COMPARE(factory->indexedCollections.size(), 2);
0124         QCOMPARE(factory->indexedCollections.at(0).id(), col1.id());
0125         QVERIFY(!factory->fullSyncs.at(0));
0126         QCOMPARE(factory->indexedCollections.at(1).id(), col2.id());
0127         QVERIFY(factory->fullSyncs.at(1));
0128         // We index 2 collections.
0129         QCOMPARE(finishedIndexing.count(), 2);
0130     }
0131 
0132     void testIndexItems()
0133     {
0134         auto config = KSharedConfig::openConfig(QStringLiteral("akonadi_indexing_agent"));
0135         KConfigGroup group = config->group(QStringLiteral("General"));
0136         group.writeEntry("initialIndexingComplete", true);
0137 
0138         Index index;
0139         QSharedPointer<DummyJobFactory> factory(new DummyJobFactory());
0140         Scheduler scheduler(index, config, factory);
0141         QSignalSpy statusSpy(&scheduler, &Scheduler::status);
0142         scheduler.setBusyTimeout(0);
0143 
0144         Akonadi::Collection parent1(3);
0145         Akonadi::Item item1(1);
0146         item1.setParentCollection(parent1);
0147         scheduler.addItem(item1);
0148 
0149         Akonadi::Item item2(2);
0150         item2.setParentCollection(parent1);
0151         scheduler.addItem(item2);
0152 
0153         Akonadi::Collection parent2(4);
0154         Akonadi::Item item3(3);
0155         item3.setParentCollection(parent2);
0156         scheduler.addItem(item3);
0157 
0158         // Wait for ready signal (indicates that indexing is complete)
0159         QTRY_COMPARE(statusSpy.count(), 1);
0160         QTRY_COMPARE(factory->indexedCollections.size(), 2);
0161         QCOMPARE(factory->indexedCollections.at(0).id(), parent1.id());
0162         QVERIFY(!factory->fullSyncs.at(0));
0163         QCOMPARE(factory->indexedCollections.at(1).id(), parent2.id());
0164         QVERIFY(!factory->fullSyncs.at(1));
0165         QCOMPARE(factory->indexedItems.size(), 3);
0166         QCOMPARE(factory->indexedItems.at(0).id(), item1.id());
0167         QCOMPARE(factory->indexedItems.at(1).id(), item2.id());
0168         QCOMPARE(factory->indexedItems.at(2).id(), item3.id());
0169     }
0170 
0171     void testDirtyCollections()
0172     {
0173         auto config = KSharedConfig::openConfig(QStringLiteral("akonadi_indexing_agent"));
0174         KConfigGroup group = config->group(QStringLiteral("General"));
0175         group.writeEntry("initialIndexingComplete", true);
0176         Akonadi::Collection col1(1);
0177 
0178         Index index;
0179 
0180         // Populate dirty collections
0181         {
0182             QSharedPointer<DummyJobFactory> factory(new DummyJobFactory());
0183             Scheduler scheduler(index, config, factory);
0184             scheduler.scheduleCollection(col1, true);
0185         }
0186 
0187         QSharedPointer<DummyJobFactory> factory(new DummyJobFactory());
0188         Scheduler scheduler(index, config, factory);
0189         QSignalSpy statusSpy(&scheduler, &Scheduler::status);
0190         QSignalSpy finishedIndexing(&scheduler, &Scheduler::collectionIndexingFinished);
0191 
0192         scheduler.setBusyTimeout(0);
0193 
0194         QTRY_COMPARE(statusSpy.count(), 1);
0195         QCOMPARE(factory->indexedCollections.size(), 1);
0196         QCOMPARE(factory->indexedCollections.at(0).id(), col1.id());
0197         QVERIFY(factory->fullSyncs.at(0));
0198 
0199         QCOMPARE(finishedIndexing.count(), 1);
0200     }
0201 };
0202 
0203 QTEST_MAIN(SchedulerTest)
0204 
0205 #include "schedulertest.moc"