1 /* This file is part of the KDE project
2 
3    Copyright (C) 2009 Dario Massarin <nekkar@libero.it>
4    Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net>
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10 */
11 
12 #include "testtransfers.h"
13 #include "core/transfergrouphandler.h"
14 #include "core/transferhandler.h"
15 #include "core/kget.h"
16 
17 #include "kget_debug.h"
18 #include "kget_interface.h"
19 #include "transfer_interface.h"
20 #include "verifier_interface.h"
21 
22 #include <KIO/CommandLauncherJob>
23 #include <KDialogJobUiDelegate>
24 
25 #include <QDBusConnection>
26 #include <QDBusConnectionInterface>
27 #include <QDBusPendingReply>
28 #include <QList>
29 
30 #include <QTemporaryDir>
31 #include <QTest>
32 
33 //FIXME not working fine if files or transfers are existing already
34 QHash<QString, int> Commands::s_stringCommands;
35 QHash<QString, int> Commands::s_transferChangeEvents;
36 
Commands(const QString & source,QObject * parent)37 Commands::Commands(const QString &source, QObject *parent)
38   : QObject(parent),
39     m_timerId(-1),
40     m_source(source),
41     m_transfer(nullptr),
42     m_verifier(nullptr)
43 {
44     static int instance = 0;
45     if (!instance++) {
46         s_stringCommands["start"] = Start;
47         s_stringCommands["stop"] = Stop;
48         s_stringCommands["addchecksum"] = AddChecksum;
49         s_stringCommands["addpartialchecksums"] = AddPartialChecksums;
50         s_stringCommands["isverifyable"] = IsVerifyable;
51         s_stringCommands["verify"] = Verify;
52         s_stringCommands["findbrokenpieces"] = FindBrokenPieces;
53         s_stringCommands["repair"] = Repair;
54         s_stringCommands["setdirectory"] = SetDirectory;
55         s_stringCommands["wait"] = Wait;
56         s_stringCommands["randomaction"] = RandomAction;
57         s_stringCommands["verified"] = Verified;
58         s_stringCommands["changedevent"] = ChangedEvent;
59         s_stringCommands["brokenpieces"] = BrokenPieces;
60 
61         s_transferChangeEvents["tc_filename"] = Transfer::Tc_FileName;
62         s_transferChangeEvents["tc_status"] = Transfer::Tc_Status;
63         s_transferChangeEvents["tc_totalsize"] = Transfer::Tc_TotalSize;
64         s_transferChangeEvents["tc_percent"] = Transfer::Tc_Percent;
65         s_transferChangeEvents["tc_downloadspeed"] = Transfer::Tc_DownloadSpeed;
66         s_transferChangeEvents["tc_remainingtime"] = Transfer::Tc_RemainingTime;
67         s_transferChangeEvents["tc_uploadspeed"] = Transfer::Tc_UploadSpeed;
68         s_transferChangeEvents["tc_uploadlimit"] = Transfer::Tc_UploadLimit;
69         s_transferChangeEvents["tc_downloadlimit"] = Transfer::Tc_DownloadLimit;
70         s_transferChangeEvents["tc_canresume"] = Transfer::Tc_CanResume;
71         s_transferChangeEvents["tc_downloadedsize"] = Transfer::Tc_DownloadedSize;
72         s_transferChangeEvents["tc_uploadedsize"] = Transfer::Tc_UploadedSize;
73         s_transferChangeEvents["tc_log"] = Transfer::Tc_Log;
74         s_transferChangeEvents["tc_group"] = Transfer::Tc_Group;
75         s_transferChangeEvents["tc_selection"] = Transfer::Tc_Selection;
76     }
77 }
78 
parseCommands(const QDomElement & e,TestTransfers * transfer)79 QList<QPair<int, QVariant> > Commands::parseCommands(const QDomElement& e, TestTransfers *transfer)
80 {
81     QList<QPair<int, QVariant> > commands;
82 
83     for (QDomElement elem = e.firstChildElement("command"); !elem.isNull(); elem = elem.nextSiblingElement("command")) {
84         const QString typeString = elem.attribute("type").toLower();
85 
86         if (!s_stringCommands.contains(typeString)) {
87             qCDebug(KGET_DEBUG) << "Error while parsing, type" << typeString << "not supported.";
88             QWARN("Problem while parsing.");
89             return commands;
90         }
91         const int type = s_stringCommands[typeString];
92 
93         QVariant data;
94         QStringList args;
95         for (QDomElement arg = elem.firstChildElement("arg"); !arg.isNull(); arg = arg.nextSiblingElement("arg")) {
96             args << arg.text();
97         }
98 
99         switch (type) {
100             case Verify:
101             case FindBrokenPieces:
102             case Start:
103             case Stop:
104                 commands.append(QPair<int, QVariant>(type, data));
105                 break;
106             case IsVerifyable:
107             case Verified:
108             case Repair:
109                 if (args.count() == 1) {
110                     data = args.first();
111                     if (data.canConvert(QVariant::Bool)) {
112                         commands.append(QPair<int, QVariant>(type, data));
113                         break;
114                     }
115                 }
116                 qCDebug(KGET_DEBUG) << "Parsing IsVerifyable/Verified/Repair failed.";
117                 QWARN("Problem while parsing.");
118                 break;
119             case AddChecksum:
120                 if (args.count() == 2) {
121                     data = args;
122                     commands.append(QPair<int, QVariant>(type, data));
123                 } else {
124                     qCDebug(KGET_DEBUG) << "Parsing setHash failed.";
125                     QWARN("Problem while parsing.");
126                 }
127                 break;
128             case AddPartialChecksums: {
129                 if (args.count() >= 3) {
130                     bool worked;
131                     QList<QVariant> list;
132                     list << args[0];//Type
133                     const qulonglong length = args[1].toULongLong(&worked);
134                     if (worked) {
135                         list << length;
136                         for (int i = 2; i < args.count(); ++i) {
137                             list << args[i];
138                         }
139                         data = list;
140                         commands.append(QPair<int, QVariant>(type, data));
141                         break;
142                     }
143                 }
144                 qCDebug(KGET_DEBUG) << "Parsing AddPartialChecksums failed.";
145                 QWARN("Problem while parsing.");
146                 break;
147             }
148             case BrokenPieces: {
149                 QList<QVariant> list;
150                 bool worked = true;
151                 foreach (const QString &arg, args) {
152                     const int value = arg.toInt(&worked);
153                     if (!worked) {
154                         break;
155                     }
156                     list << value;
157                 }
158                 if (worked) {
159                     data = list;
160                     commands.append(QPair<int, QVariant>(type, data));
161                     break;
162                 }
163                 qCDebug(KGET_DEBUG) << "Parsing BrokenPieces failed.";
164                 QWARN("Problem while parsing.");
165                 break;
166             }
167             case RandomAction: {
168                 QList<QVariant> list;
169                 if (args.count() == 1) {
170                     data = args.takeFirst();
171                     if (data.canConvert(QVariant::Bool) && !data.toBool()) {
172                         list << data.toBool();
173                         data = list;
174                         commands.append(QPair<int, QVariant>(type, data));
175                         break;
176                     }
177                 } else if (args.count() == 2) {
178                     data = args.takeFirst();
179                     if (data.canConvert(QVariant::Bool) && data.toBool()) {
180                         list << data.toBool();
181                         bool worked;
182                         list << args.takeFirst().toInt(&worked);
183                         if (worked) {
184                             data = list;
185                             commands.append(QPair<int, QVariant>(type, data));
186                             break;
187                         }
188                     }
189                 }
190                 qCDebug(KGET_DEBUG) << "Parsing RandomAction failed.";
191                 QWARN("Problem while parsing.");
192                 break;
193             }
194             case SetDirectory:
195                 if (args.count() == 2) {
196                     data = args.last();
197                     QString newDirectory = args.first();
198                     if (transfer) {
199                         newDirectory.replace("${DIR}/", transfer->tempDir());
200                     }
201                     if (!newDirectory.isEmpty() && data.canConvert(QVariant::Bool)) {
202                         const bool shouldWork = data.toBool();
203                         QList<QVariant> list;
204                         list << newDirectory << shouldWork;
205                         data = list;
206                         commands.append(QPair<int, QVariant>(type, data));
207                         break;
208                     }
209                 }
210                 qCDebug(KGET_DEBUG) << "Parsing SetDirectory failed.";
211                 QWARN("Problem while parsing.");
212                 break;
213             case Wait:
214                 if (args.count() == 1) {
215                     bool worked;
216                     data = args.first().toInt(&worked);
217                     if (worked) {
218                         commands.append(QPair<int, QVariant>(type, data));
219                         break;
220                     }
221                 }
222                 qCDebug(KGET_DEBUG) << "Parsing Wait failed.";
223                 QWARN("Problem while parsing.");
224                 break;
225             case ChangedEvent:
226                 if (!args.isEmpty() && (args.count() <= 2)) {
227                     QList<QVariant> list;
228                     const QString typeString = args.first().toLower();
229                     if (s_transferChangeEvents.contains(typeString)) {
230                         int value = s_transferChangeEvents[typeString];
231                         list << value;
232                         if (args.count() == 2) {
233                             bool worked;
234                             value = args.last().toInt(&worked);
235                             if (worked) {
236                                 list << value;
237                                 data = list;
238                                 commands.append(QPair<int, QVariant>(type, data));
239                                 break;
240                             }
241                         } else {
242                             data = list;
243                             commands.append(QPair<int, QVariant>(type, data));
244                             break;
245                         }
246                     }
247                 }
248                 qCDebug(KGET_DEBUG) << "Parsing ChangedEvent failed" << args;
249                 QWARN("Problem while parsing.");
250                 break;
251             default:
252                 QWARN("Default should never happen.");
253                 break;
254         }
255     }
256 
257     return commands;
258 }
259 
source() const260 QString Commands::source() const
261 {
262     return m_source;
263 }
264 
associateTransfer(OrgKdeKgetTransferInterface * transfer)265 void Commands::associateTransfer(OrgKdeKgetTransferInterface *transfer)
266 {
267     if (m_transfer) {
268         disconnect(m_transfer, nullptr, this, nullptr);
269     }
270     if (m_verifier) {
271         disconnect(m_verifier, nullptr, this, nullptr);
272         delete m_verifier;
273     }
274 
275     m_transfer = transfer;
276     qCDebug(KGET_DEBUG) << this << "associated with" << m_transfer << m_source;
277 
278     QDBusPendingReply<QString> reply = m_transfer->dest();
279     const QString dest = reply.value();
280 
281     reply = m_transfer->verifier(dest);
282     m_verifier = new OrgKdeKgetVerifierInterface("org.kde.kget", reply.value(), QDBusConnection::sessionBus(), this);
283 
284     connect(m_verifier, &OrgKdeKgetVerifierInterface::verified, this, &Commands::slotVerified);
285     connect(m_verifier, SIGNAL(brokenPieces(QStringList,qulonglong)), this, SLOT(slotBrokenPieces(QStringList,qulonglong)));
286     connect(m_transfer, &OrgKdeKgetTransferInterface::transferChangedEvent, this, &Commands::slotChangedEvent);
287 }
288 
hasCommands() const289 bool Commands::hasCommands() const
290 {
291     return !m_commands.isEmpty();
292 }
293 
setCommands(const QList<QPair<int,QVariant>> & commands)294 void Commands::setCommands(const QList<QPair<int, QVariant> > &commands)
295 {
296     m_commands = commands;
297 }
298 
timerEvent(QTimerEvent * event)299 void Commands::timerEvent(QTimerEvent *event)
300 {
301     Q_UNUSED(event)
302 
303     const int value = qrand() % 10;
304     //70% of the cases start, in 30% stop
305     if (value > 2) {
306         qCDebug(KGET_DEBUG) << this << "is randomly started.";
307         m_transfer->start();
308     } else {
309         qCDebug(KGET_DEBUG) << this << "is randomly stopped";
310         m_transfer->stop();
311     }
312 }
313 
slotWaitEvent()314 void Commands::slotWaitEvent()
315 {
316     //wait is over so continue with executing commands
317     if (!m_commands.isEmpty()) {
318         m_commands.takeFirst();
319         executeCommands();
320     }
321 }
322 
executeCommands()323 void Commands::executeCommands()
324 {
325     if (!m_transfer) {
326         QFAIL("Calling executeCommands when no transfer is set.");
327     }
328 
329     //NOTE no checks are being done if the commands are correct, this is to ensure that KGet crashes
330     //on faulty commands making sure that those are found
331     while (!m_commands.isEmpty()) {
332         const QPair<int, QVariant> operation = m_commands.first();
333         const int type = operation.first;
334 
335         if (type >= CustomEvent) {
336             return;
337         }
338         const QVariant command = operation.second;
339 
340         switch (type) {
341             case Start:
342                 m_transfer->start();
343                 qCDebug(KGET_DEBUG) << this << "is started.";
344                 break;
345             case Stop:
346                 m_transfer->stop();
347                 qCDebug(KGET_DEBUG) << this << "is stopped.";
348                 break;
349             case AddChecksum: {
350                 QStringList hash = command.toStringList();
351                 qCDebug(KGET_DEBUG) << this << "adding hash" << hash;
352                 QDBusPendingReply<void> reply = m_verifier->addChecksum(hash.takeFirst(), hash.takeLast());
353                 break;
354             }
355             case AddPartialChecksums: {
356                 QList<QVariant> list = command.toList();
357                 qCDebug(KGET_DEBUG) << this << "adding partial hash" << list;
358                 const QString type = list.takeFirst().toString();
359                 const qulonglong length = list.takeFirst().toULongLong();
360                 QStringList checksums;
361                 foreach (const QVariant &value, list) {
362                     checksums << value.toString();
363                 }
364                 m_verifier->addPartialChecksums(type, length, checksums);
365                 break;
366             }
367             case IsVerifyable: {
368                 const bool shouldWork = command.toBool();
369                 QDBusPendingReply<bool> reply = m_verifier->isVerifyable();
370                 qCDebug(KGET_DEBUG) << this << "isVerifyable" << reply.value();
371                 QVERIFY(reply.value() == shouldWork);
372                 break;
373             }
374             case Verify: {
375                 qCDebug(KGET_DEBUG) << this << "verification started.";
376                 m_verifier->verify();
377                 break;
378             }
379             case FindBrokenPieces:
380                 qCDebug(KGET_DEBUG) << this << "find broken pieces.";
381                 m_verifier->brokenPieces();
382                 break;
383             case Repair: {
384                 const bool shouldWork = command.toBool();
385                 QDBusPendingReply<QString> dest = m_transfer->dest();
386                 QDBusPendingReply<bool> reply = m_transfer->repair(dest.value());
387 
388                 const bool isRepairable = reply.value();
389                 qCDebug(KGET_DEBUG) << this << "repair started" << isRepairable;
390                 QVERIFY(isRepairable == shouldWork);
391                 break;
392             }
393             case SetDirectory: {
394                 QList<QVariant> commands = command.toList();
395                 const QString newDirectory = commands.takeFirst().toString();
396                 const bool shouldWork = commands.takeFirst().toBool();
397                 QDBusPendingReply<bool> reply = m_transfer->setDirectory(newDirectory);
398 
399                 const bool moveStarted = reply.value();
400                 qCDebug(KGET_DEBUG) << this << "set changing directory started" << moveStarted;
401                 QVERIFY(moveStarted == shouldWork);
402                 break;
403             }
404             case Wait: {
405                 const int time = command.toInt();
406                 qCDebug(KGET_DEBUG) << this << "waiting for" << time << "msecs" << m_transfer;
407                 QTimer::singleShot(time, this, &Commands::slotWaitEvent);
408                 return;
409                 break;
410             }
411             case RandomAction: {
412                 QList<QVariant> commands = command.toList();
413                 const bool turnOn = commands.takeFirst().toBool();
414                 if (m_timerId == -1) {
415                     if (turnOn) {
416                         qCDebug(KGET_DEBUG) << this << "starting random timer.";
417                         m_timerId = startTimer(commands.takeFirst().toInt());
418                     }
419                 } else {
420                     qCDebug(KGET_DEBUG) << this << "killing random timer.";
421                     killTimer(m_timerId);
422                     m_timerId = -1;
423                     if (turnOn) {
424                         qCDebug(KGET_DEBUG) << this << "starting random timer.";
425                         m_timerId = startTimer(commands.takeFirst().toInt());
426                     }
427                 }
428                 break;
429             }
430         }
431 
432         m_commands.takeFirst();
433     }
434 }
slotChangedEvent(int event)435 void Commands::slotChangedEvent(int event)
436 {
437     if (!m_transfer || m_commands.isEmpty()) {
438         return;
439     }
440 
441     const QPair<int, QVariant> operation = m_commands.first();
442     const int type = operation.first;
443 
444     if (type != ChangedEvent) {
445         return;
446     }
447 
448     const QList<QVariant> commands = operation.second.toList();
449 
450     //at least one and maximum two commands allowed;
451     if (commands.isEmpty() || commands.count() > 2) {
452         return;
453     }
454 
455     bool worked;
456     const int eventType = commands.first().toInt(&worked);
457     if (!worked || !(eventType & event)) {
458         return;
459     }
460 
461     if (commands.count() == 2) {
462         const int compareValue = commands.last().toInt(&worked);
463         if (!worked) {
464             return;
465         }
466 
467         switch (eventType) {
468             case Transfer::Tc_Status: {
469                 QDBusPendingReply<int> reply = m_transfer->status();
470                 if (reply.value() == compareValue) {
471                     m_commands.takeFirst();
472                     executeCommands();
473                 }
474                 break;
475             }
476             case Transfer::Tc_Percent: {
477                 QDBusPendingReply<int> reply = m_transfer->percent();
478                 if (reply.value() >= compareValue) {
479                     qCDebug(KGET_DEBUG) << this << "ChangedEvent percent.";
480                     m_commands.takeFirst();
481                     executeCommands();
482                 }
483                 break;
484             }
485             default:
486                 break;
487         }
488     } else {
489         m_commands.takeFirst();
490         executeCommands();
491     }
492 }
493 
slotVerified(bool verified)494 void Commands::slotVerified(bool verified)
495 {
496     if (!m_commands.isEmpty()) {
497         const QPair<int, QVariant> operation = m_commands.first();
498         const int type = operation.first;
499 
500         if (type == Verified) {
501             const QVariant command = operation.second;
502             m_commands.takeFirst();
503             if (command.canConvert(QVariant::Bool)) {
504                 const bool shouldWork = command.toBool();
505                 qCDebug(KGET_DEBUG) << this << "is verified" << verified;
506                 QVERIFY(verified == shouldWork);
507             }
508 
509             executeCommands();
510             return;
511         }
512     }
513 
514     qCDebug(KGET_DEBUG) << this << "is verified" << verified;
515     QVERIFY(verified);
516 }
517 
slotBrokenPieces(const QStringList & offsets,qulonglong length)518 void Commands::slotBrokenPieces(const QStringList &offsets, qulonglong length)
519 {
520     if (m_commands.isEmpty()) {
521         return;
522     }
523 
524     const QPair<int, QVariant> operation = m_commands.first();
525     const int type = operation.first;
526     if (type != BrokenPieces) {
527         return;
528     }
529 
530 //     QList<QVariant> list = brokenPieces.variant().toList();//FIXME
531     QList<QVariant> compareList = operation.second.toList();
532     if (offsets.count() != compareList.count()) {
533         QFAIL("Emitted brokenPieces list does not match.");
534     }
535     for (int i = 0; i < offsets.count(); ++i) {
536         QVERIFY(static_cast<int>(offsets[i].toULongLong() / length) == compareList[i].toInt());
537     }
538 
539     m_commands.takeFirst();
540     executeCommands();
541 }
542 
TestTransfers()543 TestTransfers::TestTransfers()
544 {
545     if(!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) {
546         const QString command = QStringLiteral("kget --showDropTarget --hideMainWindow");
547         auto *job = new KIO::CommandLauncherJob(command);
548         job->setDesktopName(QStringLiteral("org.kde.kget"));
549         job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, nullptr));
550         job->start();
551     }
552 
553     m_dir.reset(new QTemporaryDir());
554     qCDebug(KGET_DEBUG) << "Using temp dir:" << tempDir();
555 
556 //TODO add a signal to check if the move worked!!
557 
558 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdeedu-4.3.1.tar.bz2"
559 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdegames-4.3.1.tar.bz2"
560 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdegraphics-4.3.1.tar.bz2"
561 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdelibs-4.3.1.tar.bz2"
562 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdelibs-experimental-4.3.1.tar.bz2"
563 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdemultimedia-4.3.1.tar.bz2"
564 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdenetwork-4.3.1.tar.bz2"
565 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdepim-4.3.1.tar.bz2"
566 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdepim-runtime-4.3.1.tar.bz2"
567 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdepimlibs-4.3.1.tar.bz2"
568 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdeplasma-addons-4.3.1.tar.bz2"
569 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdesdk-4.3.1.tar.bz2"
570 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdetoys-4.3.1.tar.bz2"
571 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/kdewebdev-4.3.1.tar.bz2"
572 //                << "http://mirrors.isc.org/pub/kde/stable/4.3.1/src/oxygen-icons-4.3.1.tar.bz2";
573 
574 //                << "6326cff7779dfadc1b18a3a6bbe7b0750fb7ceaf"
575 //                << "576255ce66a0c089e0840bd90ea89d5705872bc8"
576 //                << "d57d9007b95607c0ee925cc963d7e14798fc69f9"
577 //                << "511532852caca9302c643fded4013ef1f57d5433"
578 //                << "7d560817a186c4b7099d321ee4a58705962a59d3"
579 //                << "ef50f869f1a6cdf91fe7808f095fccbd9463a7dd"
580 //                << "57194b5f89b37329e562951c491fa18029c0b431"
581 //                << "6fd0309dbd911e2667ec1c08d1f10f2626a54534"
582 //                << "c39b0fc1d3721fb8c6074ba6a174ad8716c6c604"
583 //                << "f4b04b21a6aa3accc530bc6c32cf0d820c611265"
584 //                << "83421181dd3a80c4ac0ff5bab111b7f71f6a1192"
585 //                << "ded236a12002b824f97856ce5dc882161ed437d2"
586 //                << "31a60deafef34a02fb7de5339eed1c750a456d3b"
587 //                << "28580c6f283fa7a6405f6a4415ebe9a4167f0992"
588 //                << "75a82d2e80d946333f63e32db56767c3ed17ba33";
589 }
590 
tempDir() const591 QString TestTransfers::tempDir() const
592 {
593     return m_dir->path();
594 }
595 
parseFile()596 void TestTransfers::parseFile()
597 {
598     const QString xmlFile = QFINDTESTDATA("kget-test.xml");
599     QVERIFY(!xmlFile.isEmpty());
600     QFile file(xmlFile);
601     QVERIFY(file.open(QIODevice::ReadOnly));
602 
603     QDomDocument doc;
604     if (!doc.setContent(&file)) {
605         QFAIL("Not able to set content.");
606     }
607 
608     for (QDomElement elem = doc.firstChildElement("tests").firstChildElement("transfer"); !elem.isNull(); elem = elem.nextSiblingElement("transfer")) {
609         const QString source = elem.attribute("source");
610         if (source.isEmpty()) {
611             QFAIL("One transfer does not have an source attribute.");
612             return;
613         }
614         auto *transfer = new Commands(source, this);
615         transfer->setCommands(Commands::parseCommands(elem, this));
616         m_commands.append(transfer);
617     }
618 }
619 
createTransfer()620 void TestTransfers::createTransfer()
621 {
622     if (m_commands.isEmpty()) {
623         QFAIL("No commands set.");
624     }
625 
626 
627     if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) {
628         qCDebug(KGET_DEBUG) << "Service not registered yet, retrying.";
629         QTimer::singleShot(500, this, &TestTransfers::createTransfer);
630         return;
631     }
632     QVERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"));
633 
634     OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus());
635 
636     foreach (Commands *command, m_commands) {
637         QDBusPendingReply<QStringList> reply = kgetInterface.addTransfer(command->source(), tempDir() + QUrl::fromLocalFile(command->source()).fileName(), false);
638         reply.waitForFinished();
639 
640         if (reply.value().size()) {
641             qCDebug(KGET_DEBUG) << "TestTransfers::createTransfer -> transfer = " << reply.value();
642             auto *transfer = new OrgKdeKgetTransferInterface("org.kde.kget", reply.value().first(), QDBusConnection::sessionBus(), this);
643 
644             command->associateTransfer(transfer);
645             command->executeCommands();
646         } else {
647             QFAIL("Reply NOT VALID!!!");
648         }
649     }
650 }
651 
simpleTest()652 void TestTransfers::simpleTest()
653 {
654     parseFile();
655     createTransfer();
656 
657     //execute as long as there are still commands left
658     forever {
659         bool abort = true;
660         foreach (Commands *commands, m_commands) {
661             if (commands->hasCommands()) {
662                 abort = false;
663                 break;
664             }
665         }
666 
667         if (abort) {
668             break;
669         }
670         QTest::qWait(3000);
671     }
672 }
673 
674 QTEST_MAIN(TestTransfers)
675 
676