File indexing completed on 2024-09-15 07:20:36
0001 /* This file is part of the KDE project 0002 0003 Copyright (C) 2009 Dario Massarin <nekkar@libero.it> 0004 Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 */ 0011 0012 #include "testtransfers.h" 0013 #include "core/kget.h" 0014 #include "core/transfergrouphandler.h" 0015 #include "core/transferhandler.h" 0016 0017 #include "kget_debug.h" 0018 #include "kget_interface.h" 0019 #include "transfer_interface.h" 0020 #include "verifier_interface.h" 0021 0022 #include <KDialogJobUiDelegate> 0023 #include <KIO/CommandLauncherJob> 0024 0025 #include <QDBusConnection> 0026 #include <QDBusConnectionInterface> 0027 #include <QDBusPendingReply> 0028 #include <QList> 0029 0030 #include <QTest> 0031 0032 // FIXME not working fine if files or transfers are existing already 0033 QHash<QString, int> Commands::s_stringCommands; 0034 QHash<QString, int> Commands::s_transferChangeEvents; 0035 0036 Commands::Commands(const QString &source, QObject *parent) 0037 : QObject(parent) 0038 , m_timerId(-1) 0039 , m_source(source) 0040 , m_transfer(nullptr) 0041 , m_verifier(nullptr) 0042 { 0043 static int instance = 0; 0044 if (!instance++) { 0045 s_stringCommands["start"] = Start; 0046 s_stringCommands["stop"] = Stop; 0047 s_stringCommands["addchecksum"] = AddChecksum; 0048 s_stringCommands["addpartialchecksums"] = AddPartialChecksums; 0049 s_stringCommands["isverifyable"] = IsVerifyable; 0050 s_stringCommands["verify"] = Verify; 0051 s_stringCommands["findbrokenpieces"] = FindBrokenPieces; 0052 s_stringCommands["repair"] = Repair; 0053 s_stringCommands["setdirectory"] = SetDirectory; 0054 s_stringCommands["wait"] = Wait; 0055 s_stringCommands["randomaction"] = RandomAction; 0056 s_stringCommands["verified"] = Verified; 0057 s_stringCommands["changedevent"] = ChangedEvent; 0058 s_stringCommands["brokenpieces"] = BrokenPieces; 0059 0060 s_transferChangeEvents["tc_filename"] = Transfer::Tc_FileName; 0061 s_transferChangeEvents["tc_status"] = Transfer::Tc_Status; 0062 s_transferChangeEvents["tc_totalsize"] = Transfer::Tc_TotalSize; 0063 s_transferChangeEvents["tc_percent"] = Transfer::Tc_Percent; 0064 s_transferChangeEvents["tc_downloadspeed"] = Transfer::Tc_DownloadSpeed; 0065 s_transferChangeEvents["tc_remainingtime"] = Transfer::Tc_RemainingTime; 0066 s_transferChangeEvents["tc_uploadspeed"] = Transfer::Tc_UploadSpeed; 0067 s_transferChangeEvents["tc_uploadlimit"] = Transfer::Tc_UploadLimit; 0068 s_transferChangeEvents["tc_downloadlimit"] = Transfer::Tc_DownloadLimit; 0069 s_transferChangeEvents["tc_canresume"] = Transfer::Tc_CanResume; 0070 s_transferChangeEvents["tc_downloadedsize"] = Transfer::Tc_DownloadedSize; 0071 s_transferChangeEvents["tc_uploadedsize"] = Transfer::Tc_UploadedSize; 0072 s_transferChangeEvents["tc_log"] = Transfer::Tc_Log; 0073 s_transferChangeEvents["tc_group"] = Transfer::Tc_Group; 0074 s_transferChangeEvents["tc_selection"] = Transfer::Tc_Selection; 0075 } 0076 } 0077 0078 QList<QPair<int, QVariant>> Commands::parseCommands(const QDomElement &e, TestTransfers *transfer) 0079 { 0080 QList<QPair<int, QVariant>> commands; 0081 0082 for (QDomElement elem = e.firstChildElement("command"); !elem.isNull(); elem = elem.nextSiblingElement("command")) { 0083 const QString typeString = elem.attribute("type").toLower(); 0084 0085 if (!s_stringCommands.contains(typeString)) { 0086 qCDebug(KGET_DEBUG) << "Error while parsing, type" << typeString << "not supported."; 0087 QWARN("Problem while parsing."); 0088 return commands; 0089 } 0090 const int type = s_stringCommands[typeString]; 0091 0092 QVariant data; 0093 QStringList args; 0094 for (QDomElement arg = elem.firstChildElement("arg"); !arg.isNull(); arg = arg.nextSiblingElement("arg")) { 0095 args << arg.text(); 0096 } 0097 0098 switch (type) { 0099 case Verify: 0100 case FindBrokenPieces: 0101 case Start: 0102 case Stop: 0103 commands.append(QPair<int, QVariant>(type, data)); 0104 break; 0105 case IsVerifyable: 0106 case Verified: 0107 case Repair: 0108 if (args.count() == 1) { 0109 data = args.first(); 0110 if (data.canConvert(QVariant::Bool)) { 0111 commands.append(QPair<int, QVariant>(type, data)); 0112 break; 0113 } 0114 } 0115 qCDebug(KGET_DEBUG) << "Parsing IsVerifyable/Verified/Repair failed."; 0116 QWARN("Problem while parsing."); 0117 break; 0118 case AddChecksum: 0119 if (args.count() == 2) { 0120 data = args; 0121 commands.append(QPair<int, QVariant>(type, data)); 0122 } else { 0123 qCDebug(KGET_DEBUG) << "Parsing setHash failed."; 0124 QWARN("Problem while parsing."); 0125 } 0126 break; 0127 case AddPartialChecksums: { 0128 if (args.count() >= 3) { 0129 bool worked; 0130 QList<QVariant> list; 0131 list << args[0]; // Type 0132 const qulonglong length = args[1].toULongLong(&worked); 0133 if (worked) { 0134 list << length; 0135 for (int i = 2; i < args.count(); ++i) { 0136 list << args[i]; 0137 } 0138 data = list; 0139 commands.append(QPair<int, QVariant>(type, data)); 0140 break; 0141 } 0142 } 0143 qCDebug(KGET_DEBUG) << "Parsing AddPartialChecksums failed."; 0144 QWARN("Problem while parsing."); 0145 break; 0146 } 0147 case BrokenPieces: { 0148 QList<QVariant> list; 0149 bool worked = true; 0150 foreach (const QString &arg, args) { 0151 const int value = arg.toInt(&worked); 0152 if (!worked) { 0153 break; 0154 } 0155 list << value; 0156 } 0157 if (worked) { 0158 data = list; 0159 commands.append(QPair<int, QVariant>(type, data)); 0160 break; 0161 } 0162 qCDebug(KGET_DEBUG) << "Parsing BrokenPieces failed."; 0163 QWARN("Problem while parsing."); 0164 break; 0165 } 0166 case RandomAction: { 0167 QList<QVariant> list; 0168 if (args.count() == 1) { 0169 data = args.takeFirst(); 0170 if (data.canConvert(QVariant::Bool) && !data.toBool()) { 0171 list << data.toBool(); 0172 data = list; 0173 commands.append(QPair<int, QVariant>(type, data)); 0174 break; 0175 } 0176 } else if (args.count() == 2) { 0177 data = args.takeFirst(); 0178 if (data.canConvert(QVariant::Bool) && data.toBool()) { 0179 list << data.toBool(); 0180 bool worked; 0181 list << args.takeFirst().toInt(&worked); 0182 if (worked) { 0183 data = list; 0184 commands.append(QPair<int, QVariant>(type, data)); 0185 break; 0186 } 0187 } 0188 } 0189 qCDebug(KGET_DEBUG) << "Parsing RandomAction failed."; 0190 QWARN("Problem while parsing."); 0191 break; 0192 } 0193 case SetDirectory: 0194 if (args.count() == 2) { 0195 data = args.last(); 0196 QString newDirectory = args.first(); 0197 if (transfer) { 0198 newDirectory.replace("${DIR}/", transfer->tempDir()); 0199 } 0200 if (!newDirectory.isEmpty() && data.canConvert(QVariant::Bool)) { 0201 const bool shouldWork = data.toBool(); 0202 QList<QVariant> list; 0203 list << newDirectory << shouldWork; 0204 data = list; 0205 commands.append(QPair<int, QVariant>(type, data)); 0206 break; 0207 } 0208 } 0209 qCDebug(KGET_DEBUG) << "Parsing SetDirectory failed."; 0210 QWARN("Problem while parsing."); 0211 break; 0212 case Wait: 0213 if (args.count() == 1) { 0214 bool worked; 0215 data = args.first().toInt(&worked); 0216 if (worked) { 0217 commands.append(QPair<int, QVariant>(type, data)); 0218 break; 0219 } 0220 } 0221 qCDebug(KGET_DEBUG) << "Parsing Wait failed."; 0222 QWARN("Problem while parsing."); 0223 break; 0224 case ChangedEvent: 0225 if (!args.isEmpty() && (args.count() <= 2)) { 0226 QList<QVariant> list; 0227 const QString typeString = args.first().toLower(); 0228 if (s_transferChangeEvents.contains(typeString)) { 0229 int value = s_transferChangeEvents[typeString]; 0230 list << value; 0231 if (args.count() == 2) { 0232 bool worked; 0233 value = args.last().toInt(&worked); 0234 if (worked) { 0235 list << value; 0236 data = list; 0237 commands.append(QPair<int, QVariant>(type, data)); 0238 break; 0239 } 0240 } else { 0241 data = list; 0242 commands.append(QPair<int, QVariant>(type, data)); 0243 break; 0244 } 0245 } 0246 } 0247 qCDebug(KGET_DEBUG) << "Parsing ChangedEvent failed" << args; 0248 QWARN("Problem while parsing."); 0249 break; 0250 default: 0251 QWARN("Default should never happen."); 0252 break; 0253 } 0254 } 0255 0256 return commands; 0257 } 0258 0259 QString Commands::source() const 0260 { 0261 return m_source; 0262 } 0263 0264 void Commands::associateTransfer(OrgKdeKgetTransferInterface *transfer) 0265 { 0266 if (m_transfer) { 0267 disconnect(m_transfer, nullptr, this, nullptr); 0268 } 0269 if (m_verifier) { 0270 disconnect(m_verifier, nullptr, this, nullptr); 0271 delete m_verifier; 0272 } 0273 0274 m_transfer = transfer; 0275 qCDebug(KGET_DEBUG) << this << "associated with" << m_transfer << m_source; 0276 0277 QDBusPendingReply<QString> reply = m_transfer->dest(); 0278 const QString dest = reply.value(); 0279 0280 reply = m_transfer->verifier(dest); 0281 m_verifier = new OrgKdeKgetVerifierInterface("org.kde.kget", reply.value(), QDBusConnection::sessionBus(), this); 0282 0283 connect(m_verifier, &OrgKdeKgetVerifierInterface::verified, this, &Commands::slotVerified); 0284 connect(m_verifier, SIGNAL(brokenPieces(QStringList, qulonglong)), this, SLOT(slotBrokenPieces(QStringList, qulonglong))); 0285 connect(m_transfer, &OrgKdeKgetTransferInterface::transferChangedEvent, this, &Commands::slotChangedEvent); 0286 } 0287 0288 bool Commands::hasCommands() const 0289 { 0290 return !m_commands.isEmpty(); 0291 } 0292 0293 void Commands::setCommands(const QList<QPair<int, QVariant>> &commands) 0294 { 0295 m_commands = commands; 0296 } 0297 0298 void Commands::timerEvent(QTimerEvent *event) 0299 { 0300 Q_UNUSED(event) 0301 0302 const int value = QRandomGenerator::global()->bounded(10); 0303 // 70% of the cases start, in 30% stop 0304 if (value > 2) { 0305 qCDebug(KGET_DEBUG) << this << "is randomly started."; 0306 m_transfer->start(); 0307 } else { 0308 qCDebug(KGET_DEBUG) << this << "is randomly stopped"; 0309 m_transfer->stop(); 0310 } 0311 } 0312 0313 void Commands::slotWaitEvent() 0314 { 0315 // wait is over so continue with executing commands 0316 if (!m_commands.isEmpty()) { 0317 m_commands.takeFirst(); 0318 executeCommands(); 0319 } 0320 } 0321 0322 void Commands::executeCommands() 0323 { 0324 if (!m_transfer) { 0325 QFAIL("Calling executeCommands when no transfer is set."); 0326 } 0327 0328 // NOTE no checks are being done if the commands are correct, this is to ensure that KGet crashes 0329 // on faulty commands making sure that those are found 0330 while (!m_commands.isEmpty()) { 0331 const QPair<int, QVariant> operation = m_commands.first(); 0332 const int type = operation.first; 0333 0334 if (type >= CustomEvent) { 0335 return; 0336 } 0337 const QVariant command = operation.second; 0338 0339 switch (type) { 0340 case Start: 0341 m_transfer->start(); 0342 qCDebug(KGET_DEBUG) << this << "is started."; 0343 break; 0344 case Stop: 0345 m_transfer->stop(); 0346 qCDebug(KGET_DEBUG) << this << "is stopped."; 0347 break; 0348 case AddChecksum: { 0349 QStringList hash = command.toStringList(); 0350 qCDebug(KGET_DEBUG) << this << "adding hash" << hash; 0351 QDBusPendingReply<void> reply = m_verifier->addChecksum(hash.takeFirst(), hash.takeLast()); 0352 break; 0353 } 0354 case AddPartialChecksums: { 0355 QList<QVariant> list = command.toList(); 0356 qCDebug(KGET_DEBUG) << this << "adding partial hash" << list; 0357 const QString type = list.takeFirst().toString(); 0358 const qulonglong length = list.takeFirst().toULongLong(); 0359 QStringList checksums; 0360 foreach (const QVariant &value, list) { 0361 checksums << value.toString(); 0362 } 0363 m_verifier->addPartialChecksums(type, length, checksums); 0364 break; 0365 } 0366 case IsVerifyable: { 0367 const bool shouldWork = command.toBool(); 0368 QDBusPendingReply<bool> reply = m_verifier->isVerifyable(); 0369 qCDebug(KGET_DEBUG) << this << "isVerifyable" << reply.value(); 0370 QVERIFY(reply.value() == shouldWork); 0371 break; 0372 } 0373 case Verify: { 0374 qCDebug(KGET_DEBUG) << this << "verification started."; 0375 m_verifier->verify(); 0376 break; 0377 } 0378 case FindBrokenPieces: 0379 qCDebug(KGET_DEBUG) << this << "find broken pieces."; 0380 m_verifier->brokenPieces(); 0381 break; 0382 case Repair: { 0383 const bool shouldWork = command.toBool(); 0384 QDBusPendingReply<QString> dest = m_transfer->dest(); 0385 QDBusPendingReply<bool> reply = m_transfer->repair(dest.value()); 0386 0387 const bool isRepairable = reply.value(); 0388 qCDebug(KGET_DEBUG) << this << "repair started" << isRepairable; 0389 QVERIFY(isRepairable == shouldWork); 0390 break; 0391 } 0392 case SetDirectory: { 0393 QList<QVariant> commands = command.toList(); 0394 const QString newDirectory = commands.takeFirst().toString(); 0395 const bool shouldWork = commands.takeFirst().toBool(); 0396 QDBusPendingReply<bool> reply = m_transfer->setDirectory(newDirectory); 0397 0398 const bool moveStarted = reply.value(); 0399 qCDebug(KGET_DEBUG) << this << "set changing directory started" << moveStarted; 0400 QVERIFY(moveStarted == shouldWork); 0401 break; 0402 } 0403 case Wait: { 0404 const int time = command.toInt(); 0405 qCDebug(KGET_DEBUG) << this << "waiting for" << time << "msecs" << m_transfer; 0406 QTimer::singleShot(time, this, &Commands::slotWaitEvent); 0407 return; 0408 break; 0409 } 0410 case RandomAction: { 0411 QList<QVariant> commands = command.toList(); 0412 const bool turnOn = commands.takeFirst().toBool(); 0413 if (m_timerId == -1) { 0414 if (turnOn) { 0415 qCDebug(KGET_DEBUG) << this << "starting random timer."; 0416 m_timerId = startTimer(commands.takeFirst().toInt()); 0417 } 0418 } else { 0419 qCDebug(KGET_DEBUG) << this << "killing random timer."; 0420 killTimer(m_timerId); 0421 m_timerId = -1; 0422 if (turnOn) { 0423 qCDebug(KGET_DEBUG) << this << "starting random timer."; 0424 m_timerId = startTimer(commands.takeFirst().toInt()); 0425 } 0426 } 0427 break; 0428 } 0429 } 0430 0431 m_commands.takeFirst(); 0432 } 0433 } 0434 void Commands::slotChangedEvent(int event) 0435 { 0436 if (!m_transfer || m_commands.isEmpty()) { 0437 return; 0438 } 0439 0440 const QPair<int, QVariant> operation = m_commands.first(); 0441 const int type = operation.first; 0442 0443 if (type != ChangedEvent) { 0444 return; 0445 } 0446 0447 const QList<QVariant> commands = operation.second.toList(); 0448 0449 // at least one and maximum two commands allowed; 0450 if (commands.isEmpty() || commands.count() > 2) { 0451 return; 0452 } 0453 0454 bool worked; 0455 const int eventType = commands.first().toInt(&worked); 0456 if (!worked || !(eventType & event)) { 0457 return; 0458 } 0459 0460 if (commands.count() == 2) { 0461 const int compareValue = commands.last().toInt(&worked); 0462 if (!worked) { 0463 return; 0464 } 0465 0466 switch (eventType) { 0467 case Transfer::Tc_Status: { 0468 QDBusPendingReply<int> reply = m_transfer->status(); 0469 if (reply.value() == compareValue) { 0470 m_commands.takeFirst(); 0471 executeCommands(); 0472 } 0473 break; 0474 } 0475 case Transfer::Tc_Percent: { 0476 QDBusPendingReply<int> reply = m_transfer->percent(); 0477 if (reply.value() >= compareValue) { 0478 qCDebug(KGET_DEBUG) << this << "ChangedEvent percent."; 0479 m_commands.takeFirst(); 0480 executeCommands(); 0481 } 0482 break; 0483 } 0484 default: 0485 break; 0486 } 0487 } else { 0488 m_commands.takeFirst(); 0489 executeCommands(); 0490 } 0491 } 0492 0493 void Commands::slotVerified(bool verified) 0494 { 0495 if (!m_commands.isEmpty()) { 0496 const QPair<int, QVariant> operation = m_commands.first(); 0497 const int type = operation.first; 0498 0499 if (type == Verified) { 0500 const QVariant command = operation.second; 0501 m_commands.takeFirst(); 0502 if (command.canConvert(QVariant::Bool)) { 0503 const bool shouldWork = command.toBool(); 0504 qCDebug(KGET_DEBUG) << this << "is verified" << verified; 0505 QVERIFY(verified == shouldWork); 0506 } 0507 0508 executeCommands(); 0509 return; 0510 } 0511 } 0512 0513 qCDebug(KGET_DEBUG) << this << "is verified" << verified; 0514 QVERIFY(verified); 0515 } 0516 0517 void Commands::slotBrokenPieces(const QStringList &offsets, qulonglong length) 0518 { 0519 if (m_commands.isEmpty()) { 0520 return; 0521 } 0522 0523 const QPair<int, QVariant> operation = m_commands.first(); 0524 const int type = operation.first; 0525 if (type != BrokenPieces) { 0526 return; 0527 } 0528 0529 // QList<QVariant> list = brokenPieces.variant().toList();//FIXME 0530 QList<QVariant> compareList = operation.second.toList(); 0531 if (offsets.count() != compareList.count()) { 0532 QFAIL("Emitted brokenPieces list does not match."); 0533 } 0534 for (int i = 0; i < offsets.count(); ++i) { 0535 QVERIFY(static_cast<int>(offsets[i].toULongLong() / length) == compareList[i].toInt()); 0536 } 0537 0538 m_commands.takeFirst(); 0539 executeCommands(); 0540 } 0541 0542 TestTransfers::TestTransfers() 0543 { 0544 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) { 0545 const QString command = QStringLiteral("kget --showDropTarget --hideMainWindow"); 0546 auto *job = new KIO::CommandLauncherJob(command); 0547 job->setDesktopName(QStringLiteral("org.kde.kget")); 0548 job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, nullptr)); 0549 job->start(); 0550 } 0551 0552 m_dir.reset(new QTemporaryDir()); 0553 qCDebug(KGET_DEBUG) << "Using temp dir:" << tempDir(); 0554 0555 // TODO add a signal to check if the move worked!! 0556 0557 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdeedu-4.3.1.tar.bz2" 0558 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdegames-4.3.1.tar.bz2" 0559 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdegraphics-4.3.1.tar.bz2" 0560 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdelibs-4.3.1.tar.bz2" 0561 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdelibs-experimental-4.3.1.tar.bz2" 0562 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdemultimedia-4.3.1.tar.bz2" 0563 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdenetwork-4.3.1.tar.bz2" 0564 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdepim-4.3.1.tar.bz2" 0565 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdepim-runtime-4.3.1.tar.bz2" 0566 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdepimlibs-4.3.1.tar.bz2" 0567 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdeplasma-addons-4.3.1.tar.bz2" 0568 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdesdk-4.3.1.tar.bz2" 0569 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdetoys-4.3.1.tar.bz2" 0570 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdewebdev-4.3.1.tar.bz2" 0571 // << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/oxygen-icons-4.3.1.tar.bz2"; 0572 0573 // << "6326cff7779dfadc1b18a3a6bbe7b0750fb7ceaf" 0574 // << "576255ce66a0c089e0840bd90ea89d5705872bc8" 0575 // << "d57d9007b95607c0ee925cc963d7e14798fc69f9" 0576 // << "511532852caca9302c643fded4013ef1f57d5433" 0577 // << "7d560817a186c4b7099d321ee4a58705962a59d3" 0578 // << "ef50f869f1a6cdf91fe7808f095fccbd9463a7dd" 0579 // << "57194b5f89b37329e562951c491fa18029c0b431" 0580 // << "6fd0309dbd911e2667ec1c08d1f10f2626a54534" 0581 // << "c39b0fc1d3721fb8c6074ba6a174ad8716c6c604" 0582 // << "f4b04b21a6aa3accc530bc6c32cf0d820c611265" 0583 // << "83421181dd3a80c4ac0ff5bab111b7f71f6a1192" 0584 // << "ded236a12002b824f97856ce5dc882161ed437d2" 0585 // << "31a60deafef34a02fb7de5339eed1c750a456d3b" 0586 // << "28580c6f283fa7a6405f6a4415ebe9a4167f0992" 0587 // << "75a82d2e80d946333f63e32db56767c3ed17ba33"; 0588 } 0589 0590 QString TestTransfers::tempDir() const 0591 { 0592 return m_dir->path(); 0593 } 0594 0595 void TestTransfers::parseFile() 0596 { 0597 const QString xmlFile = QFINDTESTDATA("kget-test.xml"); 0598 QVERIFY(!xmlFile.isEmpty()); 0599 QFile file(xmlFile); 0600 QVERIFY(file.open(QIODevice::ReadOnly)); 0601 0602 QDomDocument doc; 0603 if (!doc.setContent(&file)) { 0604 QFAIL("Not able to set content."); 0605 } 0606 0607 for (QDomElement elem = doc.firstChildElement("tests").firstChildElement("transfer"); !elem.isNull(); elem = elem.nextSiblingElement("transfer")) { 0608 const QString source = elem.attribute("source"); 0609 if (source.isEmpty()) { 0610 QFAIL("One transfer does not have an source attribute."); 0611 return; 0612 } 0613 auto *transfer = new Commands(source, this); 0614 transfer->setCommands(Commands::parseCommands(elem, this)); 0615 m_commands.append(transfer); 0616 } 0617 } 0618 0619 void TestTransfers::createTransfer() 0620 { 0621 if (m_commands.isEmpty()) { 0622 QFAIL("No commands set."); 0623 } 0624 0625 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) { 0626 qCDebug(KGET_DEBUG) << "Service not registered yet, retrying."; 0627 QTimer::singleShot(500, this, &TestTransfers::createTransfer); 0628 return; 0629 } 0630 QVERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")); 0631 0632 OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); 0633 0634 foreach (Commands *command, m_commands) { 0635 QDBusPendingReply<QStringList> reply = 0636 kgetInterface.addTransfer(command->source(), tempDir() + QUrl::fromLocalFile(command->source()).fileName(), false); 0637 reply.waitForFinished(); 0638 0639 if (reply.value().size()) { 0640 qCDebug(KGET_DEBUG) << "TestTransfers::createTransfer -> transfer = " << reply.value(); 0641 auto *transfer = new OrgKdeKgetTransferInterface("org.kde.kget", reply.value().first(), QDBusConnection::sessionBus(), this); 0642 0643 command->associateTransfer(transfer); 0644 command->executeCommands(); 0645 } else { 0646 QFAIL("Reply NOT VALID!!!"); 0647 } 0648 } 0649 } 0650 0651 void TestTransfers::simpleTest() 0652 { 0653 parseFile(); 0654 createTransfer(); 0655 0656 // execute as long as there are still commands left 0657 forever { 0658 bool abort = true; 0659 foreach (Commands *commands, m_commands) { 0660 if (commands->hasCommands()) { 0661 abort = false; 0662 break; 0663 } 0664 } 0665 0666 if (abort) { 0667 break; 0668 } 0669 QTest::qWait(3000); 0670 } 0671 } 0672 0673 QTEST_MAIN(TestTransfers) 0674 0675 #include "moc_testtransfers.cpp"