File indexing completed on 2025-01-26 04:57:20
0001 /* 0002 SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "createdatabasefilejobtest.h" 0008 #include "../createdatabasefilejob.h" 0009 #include "../createphishingurldatabasejob.h" 0010 #include "../localdatabasefile.h" 0011 #include <QStandardPaths> 0012 0013 #include <QDebug> 0014 #include <QSignalSpy> 0015 #include <QTest> 0016 Q_DECLARE_METATYPE(QList<WebEngineViewer::Addition>) 0017 QByteArray readJsonFile(const QString &jsonFile) 0018 { 0019 QFile file(QLatin1StringView(CHECKPHISHINGURL_DATA_DIR) + QLatin1Char('/') + jsonFile); 0020 file.open(QIODevice::ReadOnly); 0021 Q_ASSERT(file.isOpen()); 0022 const QByteArray data = file.readAll(); 0023 Q_ASSERT(!data.isEmpty()); 0024 return data; 0025 } 0026 0027 CreateDatabaseFileJobTest::CreateDatabaseFileJobTest(QObject *parent) 0028 : QObject(parent) 0029 { 0030 QStandardPaths::setTestModeEnabled(true); 0031 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/phishingurl")); 0032 } 0033 0034 CreateDatabaseFileJobTest::~CreateDatabaseFileJobTest() = default; 0035 0036 void CreateDatabaseFileJobTest::initTestCase() 0037 { 0038 qRegisterMetaType<WebEngineViewer::CreatePhishingUrlDataBaseJob::DataBaseDownloadResult>(); 0039 qRegisterMetaType<WebEngineViewer::CreatePhishingUrlDataBaseJob::ContraintsCompressionType>(); 0040 qRegisterMetaType<WebEngineViewer::UpdateDataBaseInfo>(); 0041 } 0042 0043 void CreateDatabaseFileJobTest::shouldHaveDefaultValue() 0044 { 0045 WebEngineViewer::CreateDatabaseFileJob job; 0046 QVERIFY(!job.canStart()); 0047 } 0048 0049 void CreateDatabaseFileJobTest::shouldCreateFile_data() 0050 { 0051 QTest::addColumn<QString>("filename"); 0052 QTest::addColumn<quint64>("numberOfElement"); 0053 QTest::addColumn<bool>("success"); 0054 QTest::newRow("correctdatabase") << QStringLiteral("current.json") << static_cast<quint64>(580600) << true; 0055 QTest::newRow("correctdatabase2") << QStringLiteral("newdatabase2.json") << static_cast<quint64>(579416) << true; 0056 QTest::newRow("incorrectdatabase") << QStringLiteral("incorrectdatabase2.json") << static_cast<quint64>(0) << false; 0057 } 0058 0059 void CreateDatabaseFileJobTest::shouldCreateFile() 0060 { 0061 QFETCH(QString, filename); 0062 QFETCH(quint64, numberOfElement); 0063 QFETCH(bool, success); 0064 0065 const QByteArray ba = readJsonFile(filename); 0066 WebEngineViewer::CreatePhishingUrlDataBaseJob job; 0067 QSignalSpy spy1(&job, &WebEngineViewer::CreatePhishingUrlDataBaseJob::finished); 0068 job.parseResult(ba); 0069 QCOMPARE(spy1.count(), 1); 0070 const auto info = spy1.at(0).at(0).value<WebEngineViewer::UpdateDataBaseInfo>(); 0071 WebEngineViewer::CreateDatabaseFileJob databasejob; 0072 const QString createDataBaseName = 0073 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/phishingurl") + QLatin1StringView("/test.db"); 0074 qDebug() << " new filename " << createDataBaseName; 0075 databasejob.setFileName(createDataBaseName); 0076 databasejob.setUpdateDataBaseInfo(info); 0077 0078 QSignalSpy spy2(&databasejob, &WebEngineViewer::CreateDatabaseFileJob::finished); 0079 databasejob.start(); 0080 QCOMPARE(spy2.count(), 1); 0081 bool successCreateDataBase = spy2.at(0).at(0).toBool(); 0082 QCOMPARE(successCreateDataBase, success); 0083 0084 WebEngineViewer::LocalDataBaseFile newFile(createDataBaseName); 0085 QVERIFY(newFile.isValid()); 0086 QCOMPARE(newFile.getUint16(0), static_cast<quint16>(1)); 0087 QCOMPARE(newFile.getUint16(2), static_cast<quint16>(0)); 0088 if (success) { 0089 QCOMPARE(newFile.getUint64(4), numberOfElement); 0090 } 0091 } 0092 0093 void CreateDatabaseFileJobTest::shouldRemoveElementInDataBase_data() 0094 { 0095 QTest::addColumn<QList<quint32>>("listElementToRemove"); 0096 QTest::addColumn<QList<WebEngineViewer::Addition>>("listElementToAdd"); 0097 QTest::addColumn<QByteArray>("newssha"); 0098 QTest::addColumn<bool>("success"); 0099 QList<WebEngineViewer::Addition> lstAdditions; 0100 QList<quint32> r = {2, 3, 4}; 0101 QTest::newRow("correctdatabase") << r << lstAdditions << QByteArrayLiteral("yTnyjAgIFeS6Cv+b4IJHngYbdvp5uz1bx9V4el5CyeE=") << true; 0102 r = {3, 2, 4}; 0103 QTest::newRow("correctdatabaseotherorder") << r << lstAdditions << QByteArrayLiteral("yTnyjAgIFeS6Cv+b4IJHngYbdvp5uz1bx9V4el5CyeE=") << true; 0104 0105 r = {4, 2, 3}; 0106 QTest::newRow("correctdatabaseotherorder2") << r << lstAdditions << QByteArrayLiteral("yTnyjAgIFeS6Cv+b4IJHngYbdvp5uz1bx9V4el5CyeE=") << true; 0107 0108 // >>> import hashlib 0109 // >>> m = hashlib.sha256() 0110 // >>> m.update("111154321abcdabcdebbbbbcdef") 0111 // >>> m.digest() 0112 // '\x81\xdd9\xe3\xae\x94s\xfd\x16o\\\xcea \xb7\xbc\x1b+R\nN\x05o\xfe\xeeWY\x7f\x8a\xcb\xbeN' 0113 // >>> import base64 0114 // >>> encoded = base64.b64encode(m.digest()) 0115 // >>> encoded 0116 // 'gd05466Uc/0Wb1zOYSC3vBsrUgpOBW/+7ldZf4rLvk4=' 0117 // >>> 0118 0119 r = {0, 2, 8}; 0120 QTest::newRow("correctdatabaseotherorder3") << r << lstAdditions << QByteArrayLiteral("gd05466Uc/0Wb1zOYSC3vBsrUgpOBW/+7ldZf4rLvk4=") << true; 0121 0122 r = {0, 2, 8}; 0123 0124 WebEngineViewer::Addition c; 0125 c.hashString = QByteArray("mnopqrst"); 0126 c.prefixSize = 4; 0127 c.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0128 0129 WebEngineViewer::Addition b; 0130 b.hashString = QByteArray("uvwx"); 0131 b.prefixSize = 4; 0132 b.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0133 0134 lstAdditions << c << b; 0135 0136 // >>> import hashlib 0137 // >>> m = hashlib.sha256() 0138 // >>> m.update("111154321abcdabcdebbbbbcdefmnopqrstuvwx") 0139 // >>> m.digest() 0140 // '\n\xae\xe2\xe0!\x8f\xa4\x05N\x89,\xdcJ*\xbe\x85\xa1Q\xc3\x9c\xc8}j\x83*s\xd5L&\xbe\xfbh' 0141 // >>> import base64 0142 // >>> encoded = base64.b64encode(m.digest()) 0143 // >>> encoded 0144 // 'Cq7i4CGPpAVOiSzcSiq+haFRw5zIfWqDKnPVTCa++2g=' 0145 0146 // m.update("111154321abcdabcdebbbbbcdefmnopqrstuvwx"); 0147 0148 QTest::newRow("correctdatabaseotherorderwithadditions") << r << lstAdditions << QByteArrayLiteral("Cq7i4CGPpAVOiSzcSiq+haFRw5zIfWqDKnPVTCa++2g=") << true; 0149 } 0150 0151 void CreateDatabaseFileJobTest::shouldRemoveElementInDataBase() 0152 { 0153 QFETCH(QList<quint32>, listElementToRemove); 0154 QFETCH(QList<WebEngineViewer::Addition>, listElementToAdd); 0155 QFETCH(QByteArray, newssha); 0156 QFETCH(bool, success); 0157 0158 // Proof of checksum validity using python: 0159 // >>> import hashlib 0160 // >>> m = hashlib.sha256() 0161 // >>> m.update("----11112222254321abcdabcdebbbbbcdefefgh") 0162 // >>> m.digest() 0163 // "\xbc\xb3\xedk\xe3x\xd1(\xa9\xedz7]" 0164 // "x\x18\xbdn]\xa5\xa8R\xf7\xab\xcf\xc1\xa3\xa3\xc5Z,\xa6o" 0165 0166 WebEngineViewer::CreateDatabaseFileJob databasejob; 0167 const QString createDataBaseName = 0168 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/phishingurl") + QLatin1StringView("/correctBinary.db"); 0169 qDebug() << " new filename " << createDataBaseName; 0170 databasejob.setFileName(createDataBaseName); 0171 0172 WebEngineViewer::UpdateDataBaseInfo info; 0173 0174 WebEngineViewer::Addition a; 0175 a.hashString = QByteArray("----1111bbbb"); 0176 a.prefixSize = 4; 0177 a.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0178 0179 WebEngineViewer::Addition b; 0180 b.hashString = QByteArray("abcdefgh"); 0181 b.prefixSize = 4; 0182 b.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0183 0184 WebEngineViewer::Addition c; 0185 c.hashString = QByteArray("54321abcde"); 0186 c.prefixSize = 5; 0187 c.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0188 0189 WebEngineViewer::Addition d; 0190 d.hashString = QByteArray("22222bcdef"); 0191 d.prefixSize = 5; 0192 d.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0193 0194 QList<WebEngineViewer::Addition> lst; 0195 lst << a << b << c << d; 0196 info.additionList = lst; 0197 info.minimumWaitDuration = QStringLiteral("593.440s"); 0198 info.threatType = QStringLiteral("MALWARE"); 0199 info.threatEntryType = QStringLiteral("URL"); 0200 info.responseType = WebEngineViewer::UpdateDataBaseInfo::FullUpdate; 0201 info.platformType = QStringLiteral("WINDOWS"); 0202 info.newClientState = QStringLiteral("ChAIBRADGAEiAzAwMSiAEDABEAFGpqhd"); 0203 info.sha256 = QByteArrayLiteral("vLPta+N40Sip7Xo3XXgYvW5dpahS96vPwaOjxVospm8="); 0204 0205 databasejob.setUpdateDataBaseInfo(info); 0206 0207 QSignalSpy spy2(&databasejob, &WebEngineViewer::CreateDatabaseFileJob::finished); 0208 databasejob.start(); 0209 QCOMPARE(spy2.count(), 1); 0210 bool successCreateDataBase = spy2.at(0).at(0).toBool(); 0211 QVERIFY(successCreateDataBase); 0212 0213 WebEngineViewer::LocalDataBaseFile newFile(createDataBaseName); 0214 QVERIFY(newFile.isValid()); 0215 QCOMPARE(newFile.getUint16(0), static_cast<quint16>(1)); 0216 QCOMPARE(newFile.getUint16(2), static_cast<quint16>(0)); 0217 QCOMPARE(newFile.getUint64(4), static_cast<quint64>(9)); 0218 int index = 4 + sizeof(quint64); 0219 QList<QByteArray> storageData; 0220 storageData << QByteArrayLiteral("----"); 0221 storageData << QByteArrayLiteral("1111"); 0222 storageData << QByteArrayLiteral("22222"); 0223 storageData << QByteArrayLiteral("54321"); 0224 storageData << QByteArrayLiteral("abcd"); 0225 storageData << QByteArrayLiteral("abcde"); 0226 storageData << QByteArrayLiteral("bbbb"); 0227 storageData << QByteArrayLiteral("bcdef"); 0228 storageData << QByteArrayLiteral("efgh"); 0229 0230 for (int i = 0; i < 9; ++i) { 0231 quint64 value = newFile.getUint64(index); 0232 // qDebug() << "char "<< newFile.getCharStar(value); 0233 QCOMPARE(storageData.at(i), QByteArray(newFile.getCharStar(value))); 0234 index += sizeof(quint64); 0235 } 0236 const QList<WebEngineViewer::Addition> lstInfo = newFile.extractAllInfo(); 0237 QCOMPARE(lstInfo.count(), 9); 0238 for (int i = 0; i < 9; i++) { 0239 QCOMPARE(lstInfo.at(i).hashString, storageData.at(i)); 0240 QCOMPARE(lstInfo.at(i).prefixSize, lstInfo.at(i).hashString.size()); 0241 } 0242 0243 // Before 0244 // storageData << QByteArrayLiteral("----"); 0245 // storageData << QByteArrayLiteral("1111"); 0246 // storageData << QByteArrayLiteral("22222"); 0247 // storageData << QByteArrayLiteral("54321"); 0248 // storageData << QByteArrayLiteral("abcd"); 0249 // storageData << QByteArrayLiteral("abcde"); 0250 // storageData << QByteArrayLiteral("bbbb"); 0251 // storageData << QByteArrayLiteral("bcdef"); 0252 // storageData << QByteArrayLiteral("efgh"); 0253 0254 // TODO remove items. 0255 WebEngineViewer::UpdateDataBaseInfo updateinfo; 0256 0257 // we will remove QByteArrayLiteral("22222"); QByteArrayLiteral("54321"); QByteArrayLiteral("abcd"); 0258 WebEngineViewer::Removal r; 0259 r.indexes = listElementToRemove; 0260 r.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0261 0262 // Proof of checksum validity using python: 0263 // >>> import hashlib 0264 // >>> m = hashlib.sha256() 0265 // >>> m.update("----1111abcdebbbbbcdefefgh") 0266 // >>> m.digest() 0267 // '\xc99\xf2\x8c\x08\x08\x15\xe4\xba\n\xff\x9b\xe0\x82G\x9e\x06\x1bv\xfay\xbb=[\xc7\xd5xz^B\xc9\xe1' 0268 // >>> import base64 0269 // >>> encoded = base64.b64encode(m.digest()) 0270 // >>> encoded 0271 // 'yTnyjAgIFeS6Cv+b4IJHngYbdvp5uz1bx9V4el5CyeE=' 0272 0273 QList<WebEngineViewer::Removal> lstRemovals; 0274 lstRemovals << r; 0275 updateinfo.additionList = listElementToAdd; 0276 updateinfo.removalList = lstRemovals; 0277 updateinfo.minimumWaitDuration = QStringLiteral("593.440s"); 0278 updateinfo.threatType = QStringLiteral("MALWARE"); 0279 updateinfo.threatEntryType = QStringLiteral("URL"); 0280 updateinfo.responseType = WebEngineViewer::UpdateDataBaseInfo::PartialUpdate; 0281 updateinfo.platformType = QStringLiteral("WINDOWS"); 0282 updateinfo.newClientState = QStringLiteral("ChAIBRADGAEiAzAwMSiAEDABEAFGpqhd"); 0283 updateinfo.sha256 = /*QByteArrayLiteral("yTnyjAgIFeS6Cv+b4IJHngYbdvp5uz1bx9V4el5CyeE=")*/ newssha; 0284 0285 WebEngineViewer::CreateDatabaseFileJob updateDatabasejob; 0286 qDebug() << " new filename " << createDataBaseName; 0287 updateDatabasejob.setFileName(createDataBaseName); 0288 0289 updateDatabasejob.setUpdateDataBaseInfo(updateinfo); 0290 0291 QSignalSpy spy3(&updateDatabasejob, &WebEngineViewer::CreateDatabaseFileJob::finished); 0292 updateDatabasejob.start(); 0293 QCOMPARE(spy3.count(), 1); 0294 successCreateDataBase = spy3.at(0).at(0).toBool(); 0295 QCOMPARE(successCreateDataBase, success); 0296 } 0297 0298 void CreateDatabaseFileJobTest::shouldCreateCorrectBinaryFile() 0299 { 0300 WebEngineViewer::CreateDatabaseFileJob databasejob; 0301 const QString createDataBaseName = 0302 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/phishingurl") + QLatin1StringView("/correctBinary.db"); 0303 qDebug() << " new filename " << createDataBaseName; 0304 databasejob.setFileName(createDataBaseName); 0305 0306 WebEngineViewer::UpdateDataBaseInfo info; 0307 0308 WebEngineViewer::Addition a; 0309 a.hashString = QByteArray("----1111bbbb"); 0310 a.prefixSize = 4; 0311 a.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0312 0313 WebEngineViewer::Addition b; 0314 b.hashString = QByteArray("abcdefgh"); 0315 b.prefixSize = 4; 0316 b.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0317 0318 WebEngineViewer::Addition c; 0319 c.hashString = QByteArray("54321abcde"); 0320 c.prefixSize = 5; 0321 c.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0322 0323 WebEngineViewer::Addition d; 0324 d.hashString = QByteArray("22222bcdef"); 0325 d.prefixSize = 5; 0326 d.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression; 0327 0328 QList<WebEngineViewer::Addition> lst; 0329 lst << a << b << c << d; 0330 info.additionList = lst; 0331 info.minimumWaitDuration = QStringLiteral("593.440s"); 0332 info.threatType = QStringLiteral("MALWARE"); 0333 info.threatEntryType = QStringLiteral("URL"); 0334 info.responseType = WebEngineViewer::UpdateDataBaseInfo::FullUpdate; 0335 info.platformType = QStringLiteral("WINDOWS"); 0336 info.newClientState = QStringLiteral("ChAIBRADGAEiAzAwMSiAEDABEAFGpqhd"); 0337 info.sha256 = QByteArrayLiteral("vLPta+N40Sip7Xo3XXgYvW5dpahS96vPwaOjxVospm8="); 0338 0339 databasejob.setUpdateDataBaseInfo(info); 0340 0341 QSignalSpy spy2(&databasejob, &WebEngineViewer::CreateDatabaseFileJob::finished); 0342 databasejob.start(); 0343 QCOMPARE(spy2.count(), 1); 0344 bool successCreateDataBase = spy2.at(0).at(0).toBool(); 0345 QVERIFY(successCreateDataBase); 0346 0347 WebEngineViewer::LocalDataBaseFile newFile(createDataBaseName); 0348 QVERIFY(newFile.isValid()); 0349 QCOMPARE(newFile.getUint16(0), static_cast<quint16>(1)); 0350 QCOMPARE(newFile.getUint16(2), static_cast<quint16>(0)); 0351 QCOMPARE(newFile.getUint64(4), static_cast<quint64>(9)); 0352 int index = 4 + sizeof(quint64); 0353 QList<QByteArray> storageData; 0354 storageData << QByteArrayLiteral("----"); 0355 storageData << QByteArrayLiteral("1111"); 0356 storageData << QByteArrayLiteral("22222"); 0357 storageData << QByteArrayLiteral("54321"); 0358 storageData << QByteArrayLiteral("abcd"); 0359 storageData << QByteArrayLiteral("abcde"); 0360 storageData << QByteArrayLiteral("bbbb"); 0361 storageData << QByteArrayLiteral("bcdef"); 0362 storageData << QByteArrayLiteral("efgh"); 0363 0364 for (int i = 0; i < 9; ++i) { 0365 quint64 value = newFile.getUint64(index); 0366 // qDebug() << "char "<< newFile.getCharStar(value); 0367 QCOMPARE(storageData.at(i), QByteArray(newFile.getCharStar(value))); 0368 index += sizeof(quint64); 0369 } 0370 const QList<WebEngineViewer::Addition> lstInfo = newFile.extractAllInfo(); 0371 QCOMPARE(lstInfo.count(), 9); 0372 for (int i = 0; i < 9; i++) { 0373 QCOMPARE(lstInfo.at(i).hashString, storageData.at(i)); 0374 QCOMPARE(lstInfo.at(i).prefixSize, lstInfo.at(i).hashString.size()); 0375 } 0376 } 0377 0378 void CreateDatabaseFileJobTest::shouldUpdateDataBase() 0379 { 0380 QString firstFilename = QStringLiteral("newdatabase2.json"); 0381 const QByteArray ba = readJsonFile(firstFilename); 0382 WebEngineViewer::CreatePhishingUrlDataBaseJob job; 0383 QSignalSpy spy1(&job, &WebEngineViewer::CreatePhishingUrlDataBaseJob::finished); 0384 job.parseResult(ba); 0385 QCOMPARE(spy1.count(), 1); 0386 const auto info = spy1.at(0).at(0).value<WebEngineViewer::UpdateDataBaseInfo>(); 0387 WebEngineViewer::CreateDatabaseFileJob databasejob; 0388 const QString createDataBaseName = 0389 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/phishingurl") + QLatin1StringView("/update.db"); 0390 // qDebug() << " new filename " << createDataBaseName; 0391 databasejob.setFileName(createDataBaseName); 0392 databasejob.setUpdateDataBaseInfo(info); 0393 0394 QSignalSpy spy2(&databasejob, &WebEngineViewer::CreateDatabaseFileJob::finished); 0395 databasejob.start(); 0396 QCOMPARE(spy2.count(), 1); 0397 bool successCreateDataBase = spy2.at(0).at(0).toBool(); 0398 QVERIFY(successCreateDataBase); 0399 0400 WebEngineViewer::LocalDataBaseFile newFile(createDataBaseName); 0401 QVERIFY(newFile.isValid()); 0402 QCOMPARE(newFile.getUint16(0), static_cast<quint16>(1)); 0403 QCOMPARE(newFile.getUint16(2), static_cast<quint16>(0)); 0404 QCOMPARE(newFile.getUint64(4), static_cast<quint64>(579416)); 0405 newFile.close(); 0406 0407 QString updateFilename = QStringLiteral("partial_download3.json"); 0408 const QByteArray baUpdate = readJsonFile(updateFilename); 0409 0410 WebEngineViewer::CreatePhishingUrlDataBaseJob jobUpdate; 0411 QSignalSpy spy3(&jobUpdate, &WebEngineViewer::CreatePhishingUrlDataBaseJob::finished); 0412 jobUpdate.parseResult(baUpdate); 0413 QCOMPARE(spy3.count(), 1); 0414 0415 const auto infoUpdate = spy3.at(0).at(0).value<WebEngineViewer::UpdateDataBaseInfo>(); 0416 QCOMPARE(infoUpdate.responseType, WebEngineViewer::UpdateDataBaseInfo::PartialUpdate); 0417 0418 WebEngineViewer::CreateDatabaseFileJob databasejob2; 0419 databasejob2.setFileName(createDataBaseName); 0420 databasejob2.setUpdateDataBaseInfo(infoUpdate); 0421 0422 QSignalSpy spy4(&databasejob2, &WebEngineViewer::CreateDatabaseFileJob::finished); 0423 databasejob2.start(); 0424 QCOMPARE(spy4.count(), 1); 0425 successCreateDataBase = spy4.at(0).at(0).toBool(); 0426 QEXPECT_FAIL("", "Expected a success but not", Continue); 0427 QVERIFY(successCreateDataBase); 0428 } 0429 0430 QTEST_MAIN(CreateDatabaseFileJobTest) 0431 0432 #include "moc_createdatabasefilejobtest.cpp"