File indexing completed on 2024-11-10 04:40:13
0001 /* 0002 SPDX-FileCopyrightText: 2012 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "qtest_akonadi.h" 0008 0009 #include "fakesession.h" 0010 #include "job.h" 0011 0012 Q_DECLARE_METATYPE(KJob *) 0013 Q_DECLARE_METATYPE(Akonadi::Job *) 0014 0015 using namespace Akonadi; 0016 0017 class FakeJob : public Job 0018 { 0019 Q_OBJECT 0020 public: 0021 explicit FakeJob(QObject *parent = nullptr) 0022 : Job(parent) 0023 { 0024 } 0025 void done() 0026 { 0027 emitResult(); 0028 } 0029 0030 protected: 0031 void doStart() override 0032 { 0033 emitWriteFinished(); 0034 } 0035 }; 0036 0037 class JobTest : public QObject 0038 { 0039 Q_OBJECT 0040 private Q_SLOTS: 0041 void initTestCase() 0042 { 0043 qRegisterMetaType<KJob *>(); 0044 qRegisterMetaType<Akonadi::Job *>(); 0045 } 0046 0047 void testTopLevelJobExecution() 0048 { 0049 FakeSession session("fakeSession", FakeSession::EndJobsManually); 0050 0051 QSignalSpy sessionQueueSpy(&session, &FakeSession::jobAdded); 0052 QVERIFY(sessionQueueSpy.isValid()); 0053 0054 auto job1 = new FakeJob(&session); 0055 QSignalSpy job1DoneSpy(job1, &KJob::result); 0056 QVERIFY(job1DoneSpy.isValid()); 0057 0058 auto job2 = new FakeJob(&session); 0059 QSignalSpy job2DoneSpy(job2, &KJob::result); 0060 QVERIFY(job2DoneSpy.isValid()); 0061 0062 QCOMPARE(sessionQueueSpy.size(), 2); 0063 QCOMPARE(job1DoneSpy.size(), 0); 0064 0065 QSignalSpy job1AboutToStartSpy(job1, &Job::aboutToStart); 0066 QVERIFY(job1AboutToStartSpy.wait()); 0067 0068 QCOMPARE(job1DoneSpy.size(), 0); 0069 0070 job1->done(); 0071 QCOMPARE(job1DoneSpy.size(), 1); 0072 0073 QSignalSpy job2AboutToStartSpy(job2, &Job::aboutToStart); 0074 QVERIFY(job2AboutToStartSpy.wait()); 0075 QCOMPARE(job2DoneSpy.size(), 0); 0076 job2->done(); 0077 0078 QCOMPARE(job1DoneSpy.size(), 1); 0079 QCOMPARE(job2DoneSpy.size(), 1); 0080 } 0081 0082 void testKillSession() 0083 { 0084 FakeSession session("fakeSession", FakeSession::EndJobsManually); 0085 0086 QSignalSpy sessionQueueSpy(&session, &FakeSession::jobAdded); 0087 QVERIFY(sessionQueueSpy.isValid()); 0088 QSignalSpy sessionReconnectSpy(&session, &Session::reconnected); 0089 QVERIFY(sessionReconnectSpy.isValid()); 0090 0091 auto job1 = new FakeJob(&session); 0092 QSignalSpy job1DoneSpy(job1, &KJob::result); 0093 QVERIFY(job1DoneSpy.isValid()); 0094 0095 auto job2 = new FakeJob(&session); 0096 QSignalSpy job2DoneSpy(job2, &KJob::result); 0097 QVERIFY(job2DoneSpy.isValid()); 0098 0099 auto job3 = new FakeJob(&session); 0100 QSignalSpy job3DoneSpy(job3, &KJob::result); 0101 QVERIFY(job3DoneSpy.isValid()); 0102 0103 auto job4 = new FakeJob(&session); 0104 QSignalSpy job4DoneSpy(job4, &KJob::result); 0105 QVERIFY(job4DoneSpy.isValid()); 0106 0107 QCOMPARE(sessionQueueSpy.size(), 4); 0108 QSignalSpy job1AboutToStartSpy(job1, &Job::aboutToStart); 0109 QVERIFY(job1AboutToStartSpy.wait()); 0110 0111 // one job running, 3 queued, now kill the session 0112 session.clear(); 0113 QVERIFY(sessionReconnectSpy.wait()); 0114 0115 QCOMPARE(job1DoneSpy.size(), 1); 0116 QCOMPARE(job2DoneSpy.size(), 1); 0117 QCOMPARE(job3DoneSpy.size(), 1); 0118 QCOMPARE(job4DoneSpy.size(), 1); 0119 QCOMPARE(sessionReconnectSpy.size(), 2); 0120 } 0121 0122 void testKillQueuedJob() 0123 { 0124 FakeSession session("fakeSession", FakeSession::EndJobsManually); 0125 0126 QSignalSpy sessionQueueSpy(&session, &FakeSession::jobAdded); 0127 QVERIFY(sessionQueueSpy.isValid()); 0128 QSignalSpy sessionReconnectSpy(&session, &Session::reconnected); 0129 QVERIFY(sessionReconnectSpy.isValid()); 0130 0131 auto job1 = new FakeJob(&session); 0132 QSignalSpy job1DoneSpy(job1, &KJob::result); 0133 QVERIFY(job1DoneSpy.isValid()); 0134 0135 auto job2 = new FakeJob(&session); 0136 QSignalSpy job2DoneSpy(job2, &KJob::result); 0137 QVERIFY(job2DoneSpy.isValid()); 0138 0139 QCOMPARE(sessionQueueSpy.size(), 2); 0140 QSignalSpy job1AboutToStartSpy(job1, &Job::aboutToStart); 0141 QVERIFY(job1AboutToStartSpy.wait()); 0142 0143 // one job running, one queued, now kill the waiting job 0144 QVERIFY(job2->kill(KJob::EmitResult)); 0145 0146 QCOMPARE(job1DoneSpy.size(), 0); 0147 QCOMPARE(job2DoneSpy.size(), 1); 0148 0149 job1->done(); 0150 QCOMPARE(job1DoneSpy.size(), 1); 0151 QCOMPARE(job2DoneSpy.size(), 1); 0152 QCOMPARE(sessionReconnectSpy.size(), 1); 0153 } 0154 0155 void testKillRunningJob() 0156 { 0157 FakeSession session("fakeSession", FakeSession::EndJobsManually); 0158 0159 QSignalSpy sessionQueueSpy(&session, &FakeSession::jobAdded); 0160 QVERIFY(sessionQueueSpy.isValid()); 0161 QSignalSpy sessionReconnectSpy(&session, &Session::reconnected); 0162 QVERIFY(sessionReconnectSpy.isValid()); 0163 0164 auto job1 = new FakeJob(&session); 0165 QSignalSpy job1DoneSpy(job1, &KJob::result); 0166 QVERIFY(job1DoneSpy.isValid()); 0167 0168 auto job2 = new FakeJob(&session); 0169 QSignalSpy job2DoneSpy(job2, &KJob::result); 0170 QVERIFY(job2DoneSpy.isValid()); 0171 0172 QCOMPARE(sessionQueueSpy.size(), 2); 0173 QSignalSpy job1AboutToStartSpy(job1, &Job::aboutToStart); 0174 QVERIFY(job1AboutToStartSpy.wait()); 0175 0176 // one job running, one queued, now kill the running one 0177 QVERIFY(job1->kill(KJob::EmitResult)); 0178 0179 QCOMPARE(job1DoneSpy.size(), 1); 0180 QCOMPARE(job2DoneSpy.size(), 0); 0181 0182 // session needs to reconnect, then execute the next job 0183 QSignalSpy job2AboutToStartSpy(job2, &Job::aboutToStart); 0184 QVERIFY(job2AboutToStartSpy.wait()); 0185 QCOMPARE(sessionReconnectSpy.size(), 2); 0186 job2->done(); 0187 0188 QCOMPARE(job1DoneSpy.size(), 1); 0189 QCOMPARE(job2DoneSpy.size(), 1); 0190 QCOMPARE(sessionReconnectSpy.size(), 2); 0191 } 0192 0193 void testKillRunningSubjob() 0194 { 0195 FakeSession session("fakeSession", FakeSession::EndJobsManually); 0196 0197 QSignalSpy sessionQueueSpy(&session, &FakeSession::jobAdded); 0198 QSignalSpy sessionReconnectSpy(&session, &Session::reconnected); 0199 0200 auto parentJob = new FakeJob(&session); 0201 parentJob->setObjectName(QLatin1StringView("parentJob")); 0202 QSignalSpy parentJobDoneSpy(parentJob, &KJob::result); 0203 0204 auto subjob = new FakeJob(parentJob); 0205 subjob->setObjectName(QLatin1StringView("subjob")); 0206 QSignalSpy subjobDoneSpy(subjob, &KJob::result); 0207 0208 auto subjob2 = new FakeJob(parentJob); 0209 subjob2->setObjectName(QLatin1StringView("subjob2")); 0210 QSignalSpy subjob2DoneSpy(subjob2, &KJob::result); 0211 0212 auto nextJob = new FakeJob(&session); 0213 nextJob->setObjectName(QLatin1StringView("nextJob")); 0214 QSignalSpy nextJobDoneSpy(nextJob, &KJob::result); 0215 0216 QCOMPARE(sessionQueueSpy.size(), 2); 0217 QSignalSpy parentJobAboutToStart(parentJob, &Job::aboutToStart); 0218 QVERIFY(parentJobAboutToStart.wait()); 0219 0220 QSignalSpy subjobAboutToStart(subjob, &Job::aboutToStart); 0221 QVERIFY(subjobAboutToStart.wait()); 0222 0223 // one parent job, one subjob running (another one waiting), now kill the running subjob 0224 QVERIFY(subjob->kill(KJob::EmitResult)); 0225 0226 QCOMPARE(subjobDoneSpy.size(), 1); 0227 QCOMPARE(subjob2DoneSpy.size(), 0); 0228 0229 // Note that killing a subjob aborts the whole parent job 0230 // Since the session only knows about the parent 0231 QCOMPARE(parentJobDoneSpy.size(), 1); 0232 0233 // session needs to reconnect, then execute the next job 0234 QSignalSpy nextJobAboutToStartSpy(nextJob, &Job::aboutToStart); 0235 QVERIFY(nextJobAboutToStartSpy.wait()); 0236 QCOMPARE(sessionReconnectSpy.size(), 2); 0237 nextJob->done(); 0238 0239 QCOMPARE(subjob2DoneSpy.size(), 0); 0240 QCOMPARE(nextJobDoneSpy.size(), 1); 0241 } 0242 }; 0243 0244 QTEST_AKONADIMAIN(JobTest) 0245 0246 #include "jobtest.moc"