File indexing completed on 2024-12-22 04:56:51
0001 /* 0002 * SPDX-FileCopyrightText: 2013 Christian Mollekopf <mollekopf@kolabsys.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 * 0006 */ 0007 0008 #include <KJobTrackerInterface> 0009 #include <QDebug> 0010 #include <QSignalSpy> 0011 #include <QTest> 0012 0013 #include "../migrationscheduler.h" 0014 #include "migration/migratorbase.h" 0015 0016 Q_DECLARE_METATYPE(QModelIndex) 0017 0018 class Testmigrator : public MigratorBase 0019 { 0020 Q_OBJECT 0021 public: 0022 explicit Testmigrator(const QString &identifier, QObject *parent = nullptr) 0023 : MigratorBase(QLatin1StringView("testmigrator") + identifier, QString(), QString(), parent) 0024 , mAutostart(false) 0025 { 0026 } 0027 0028 [[nodiscard]] QString displayName() const override 0029 { 0030 return QStringLiteral("name"); 0031 } 0032 0033 void startWork() override 0034 { 0035 } 0036 0037 void abort() override 0038 { 0039 setMigrationState(Aborted); 0040 } 0041 0042 virtual void complete() 0043 { 0044 setMigrationState(Complete); 0045 } 0046 0047 [[nodiscard]] bool shouldAutostart() const override 0048 { 0049 return mAutostart; 0050 } 0051 0052 void pause() override 0053 { 0054 setMigrationState(Paused); 0055 } 0056 0057 void resume() override 0058 { 0059 setMigrationState(InProgress); 0060 } 0061 0062 bool mAutostart; 0063 }; 0064 0065 class TestJobTracker : public KJobTrackerInterface 0066 { 0067 public: 0068 TestJobTracker() 0069 : mPercent(0) 0070 { 0071 } 0072 0073 void registerJob(KJob *job) override 0074 { 0075 KJobTrackerInterface::registerJob(job); 0076 mJobs << job; 0077 } 0078 0079 void unregisterJob(KJob *job) override 0080 { 0081 mJobs.removeAll(job); 0082 } 0083 0084 void finished(KJob *job) override 0085 { 0086 mJobs.removeAll(job); 0087 } 0088 0089 void percent(KJob *job, long unsigned int percent) override 0090 { 0091 Q_UNUSED(job) 0092 mPercent = percent; 0093 } 0094 0095 QList<KJob *> mJobs; 0096 int mPercent; 0097 }; 0098 0099 class SchedulerTest : public QObject 0100 { 0101 Q_OBJECT 0102 private Q_SLOTS: 0103 0104 void initTestcase() 0105 { 0106 qRegisterMetaType<QModelIndex>(); 0107 } 0108 0109 void testInsertRow() 0110 { 0111 MigrationScheduler scheduler; 0112 QAbstractItemModel &model(scheduler.model()); 0113 0114 QCOMPARE(model.rowCount(), 0); 0115 0116 QSignalSpy rowsInsertedSpy(&model, &QAbstractItemModel::rowsInserted); 0117 QVERIFY(rowsInsertedSpy.isValid()); 0118 0119 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id")))); 0120 QCOMPARE(model.rowCount(), 1); 0121 QCOMPARE(rowsInsertedSpy.count(), 1); 0122 0123 QVERIFY(model.index(0, 0).isValid()); 0124 QVERIFY(!model.index(1, 0).isValid()); 0125 0126 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id2")))); 0127 QCOMPARE(model.rowCount(), 2); 0128 QCOMPARE(rowsInsertedSpy.count(), 2); 0129 } 0130 0131 void testDisplayName() 0132 { 0133 MigrationScheduler scheduler; 0134 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id")))); 0135 QAbstractItemModel &model(scheduler.model()); 0136 QCOMPARE(model.data(model.index(0, 0)).toString(), QStringLiteral("name")); 0137 } 0138 0139 void testStartStop() 0140 { 0141 MigrationScheduler scheduler; 0142 QSharedPointer<Testmigrator> migrator(new Testmigrator(QStringLiteral("id"))); 0143 scheduler.addMigrator(migrator); 0144 0145 scheduler.start(migrator->identifier()); 0146 QCOMPARE(migrator->migrationState(), MigratorBase::InProgress); 0147 0148 scheduler.abort(migrator->identifier()); 0149 QCOMPARE(migrator->migrationState(), MigratorBase::Aborted); 0150 } 0151 0152 void testNoDuplicates() 0153 { 0154 MigrationScheduler scheduler; 0155 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id")))); 0156 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id")))); 0157 QAbstractItemModel &model(scheduler.model()); 0158 QCOMPARE(model.rowCount(), 1); 0159 } 0160 0161 void testMigrationStateChanged() 0162 { 0163 MigrationScheduler scheduler; 0164 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id1")))); 0165 QSharedPointer<Testmigrator> migrator(new Testmigrator(QStringLiteral("id2"))); 0166 scheduler.addMigrator(migrator); 0167 scheduler.addMigrator(QSharedPointer<Testmigrator>(new Testmigrator(QStringLiteral("id3")))); 0168 QAbstractItemModel &model(scheduler.model()); 0169 0170 QSignalSpy spy(&model, &QAbstractItemModel::dataChanged); 0171 QVERIFY(spy.isValid()); 0172 migrator->start(); 0173 0174 QCOMPARE(spy.count(), 1); 0175 const QVariantList args = spy.takeFirst(); 0176 QCOMPARE(args.at(0).value<QModelIndex>().row(), 1); 0177 QCOMPARE(args.at(1).value<QModelIndex>().row(), 1); 0178 } 0179 0180 void testRunMultiple() 0181 { 0182 MigrationScheduler scheduler; 0183 0184 QSharedPointer<Testmigrator> m1(new Testmigrator(QStringLiteral("id1"))); 0185 scheduler.addMigrator(m1); 0186 0187 QSharedPointer<Testmigrator> m2(new Testmigrator(QStringLiteral("id2"))); 0188 scheduler.addMigrator(m2); 0189 0190 scheduler.start(m1->identifier()); 0191 scheduler.start(m2->identifier()); 0192 0193 QCOMPARE(m1->migrationState(), MigratorBase::InProgress); 0194 QCOMPARE(m2->migrationState(), MigratorBase::InProgress); 0195 } 0196 0197 void testRunAutostart() 0198 { 0199 MigrationScheduler scheduler; 0200 0201 QSharedPointer<Testmigrator> m1(new Testmigrator(QStringLiteral("id1"))); 0202 m1->mAutostart = true; 0203 scheduler.addMigrator(m1); 0204 0205 QSharedPointer<Testmigrator> m2(new Testmigrator(QStringLiteral("id2"))); 0206 m2->mAutostart = true; 0207 scheduler.addMigrator(m2); 0208 0209 QCOMPARE(m1->migrationState(), MigratorBase::InProgress); 0210 qDebug() << m2->migrationState(); 0211 QCOMPARE(m2->migrationState(), MigratorBase::None); 0212 m1->complete(); 0213 QCOMPARE(m2->migrationState(), MigratorBase::InProgress); 0214 } 0215 0216 void testJobTracker() 0217 { 0218 TestJobTracker jobTracker; 0219 MigrationScheduler scheduler(&jobTracker); 0220 QSharedPointer<Testmigrator> m1(new Testmigrator(QStringLiteral("id1"))); 0221 m1->mAutostart = true; 0222 scheduler.addMigrator(m1); 0223 0224 QCOMPARE(jobTracker.mJobs.size(), 1); 0225 0226 m1->complete(); 0227 0228 // Give the job some time to delete itself 0229 QTest::qWait(500); 0230 0231 QCOMPARE(jobTracker.mJobs.size(), 0); 0232 } 0233 0234 void testSuspend() 0235 { 0236 TestJobTracker jobTracker; 0237 MigrationScheduler scheduler(&jobTracker); 0238 QSharedPointer<Testmigrator> m1(new Testmigrator(QStringLiteral("id1"))); 0239 m1->mAutostart = true; 0240 scheduler.addMigrator(m1); 0241 jobTracker.mJobs.first()->suspend(); 0242 QCOMPARE(m1->migrationState(), MigratorBase::Paused); 0243 jobTracker.mJobs.first()->resume(); 0244 QCOMPARE(m1->migrationState(), MigratorBase::InProgress); 0245 } 0246 0247 /* 0248 * Even if the migrator doesn't implement suspend, the executor suspends after completing the current job and waits with starting the second job. 0249 */ 0250 void testJobFinishesDuringSuspend() 0251 { 0252 TestJobTracker jobTracker; 0253 MigrationScheduler scheduler(&jobTracker); 0254 QSharedPointer<Testmigrator> m1(new Testmigrator(QStringLiteral("id1"))); 0255 m1->mAutostart = true; 0256 scheduler.addMigrator(m1); 0257 QSharedPointer<Testmigrator> m2(new Testmigrator(QStringLiteral("id2"))); 0258 m2->mAutostart = true; 0259 scheduler.addMigrator(m2); 0260 jobTracker.mJobs.first()->suspend(); 0261 m1->complete(); 0262 QCOMPARE(m2->migrationState(), MigratorBase::None); 0263 jobTracker.mJobs.first()->resume(); 0264 QCOMPARE(m2->migrationState(), MigratorBase::InProgress); 0265 } 0266 0267 void testProgressReporting() 0268 { 0269 TestJobTracker jobTracker; 0270 MigrationScheduler scheduler(&jobTracker); 0271 QSharedPointer<Testmigrator> m1(new Testmigrator(QStringLiteral("id1"))); 0272 m1->mAutostart = true; 0273 scheduler.addMigrator(m1); 0274 QCOMPARE(jobTracker.mPercent, 0); 0275 m1->complete(); 0276 QCOMPARE(jobTracker.mPercent, 100); 0277 } 0278 }; 0279 0280 QTEST_MAIN(SchedulerTest) 0281 0282 #include "schedulertest.moc"