File indexing completed on 2024-04-28 15:20:31

0001 /*
0002     This file is part of libkdbus
0003 
0004     SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org>
0005     SPDX-FileCopyrightText: 2011 David Faure <faure@kde.org>
0006     SPDX-FileCopyrightText: 2011 Kevin Ottens <ervin@kde.org>
0007 
0008     SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #include <QCoreApplication>
0012 #include <QDebug>
0013 #include <QDir>
0014 #include <QFile>
0015 #include <QMetaObject>
0016 #include <QProcess>
0017 #include <QTimer>
0018 
0019 #include <kdbusservice.h>
0020 
0021 #include <stdio.h>
0022 
0023 class TestObject : public QObject
0024 {
0025     Q_OBJECT
0026 public:
0027     TestObject(KDBusService *service)
0028         : m_proc(nullptr)
0029         , m_callCount(0)
0030         , m_service(service)
0031     {
0032     }
0033 
0034     ~TestObject() override
0035     {
0036         if (m_proc) {
0037             m_proc->waitForFinished();
0038         }
0039     }
0040 
0041     int callCount() const
0042     {
0043         return m_callCount;
0044     }
0045 
0046     void slotActivateRequested(const QStringList &args, const QString &workingDirectory)
0047     {
0048         Q_UNUSED(workingDirectory);
0049         qDebug() << "Application executed with args" << args;
0050 
0051         ++m_callCount;
0052 
0053         if (m_callCount == 1) {
0054             Q_ASSERT(args.count() == 1);
0055             Q_ASSERT(args.at(0) == QLatin1String("dummy call"));
0056         } else if (m_callCount == 2) {
0057             Q_ASSERT(args.count() == 2);
0058             Q_ASSERT(args.at(1) == QLatin1String("bad call"));
0059             m_service->setExitValue(4);
0060         } else if (m_callCount == 3) {
0061             Q_ASSERT(args.count() == 3);
0062             Q_ASSERT(args.at(1) == QLatin1String("real call"));
0063             Q_ASSERT(args.at(2) == QLatin1String("second arg"));
0064             // OK, all done, quit
0065             QCoreApplication::instance()->quit();
0066         }
0067     }
0068 
0069 public Q_SLOTS:
0070     void firstCall()
0071     {
0072         QStringList args;
0073         args << QStringLiteral("bad call");
0074         executeNewChild(args);
0075     }
0076 
0077 private Q_SLOTS:
0078     void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
0079     {
0080         Q_UNUSED(exitStatus)
0081         qDebug() << "Process exited with code" << exitCode;
0082         m_proc = nullptr;
0083         if (m_callCount == 2) {
0084             Q_ASSERT(exitCode == 4);
0085             secondCall();
0086         }
0087     }
0088 
0089     void secondCall()
0090     {
0091         QStringList args;
0092         args << QStringLiteral("real call") << QStringLiteral("second arg");
0093         executeNewChild(args);
0094     }
0095 
0096 private:
0097     void executeNewChild(const QStringList &args)
0098     {
0099         // Duplicated from kglobalsettingstest.cpp - make a shared helper method?
0100         m_proc = new QProcess(this);
0101         connect(m_proc, &QProcess::finished, this, &TestObject::slotProcessFinished);
0102         QString appName = QStringLiteral("kdbusservicetest");
0103 #ifdef Q_OS_WIN
0104         appName += ".exe";
0105 #else
0106         if (QFile::exists(appName + ".shell")) {
0107             appName = "./" + appName + ".shell";
0108         } else {
0109             Q_ASSERT(QFile::exists(appName));
0110             appName = "./" + appName;
0111         }
0112 #endif
0113         qDebug() << "about to run" << appName << args;
0114         m_proc->start(appName, args);
0115     }
0116 
0117     QProcess *m_proc;
0118     int m_callCount;
0119     KDBusService *m_service;
0120 };
0121 
0122 int main(int argc, char *argv[])
0123 {
0124     QCoreApplication a(argc, argv);
0125 
0126     QCoreApplication::setApplicationName(QStringLiteral("kdbusservicetest"));
0127     QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
0128 
0129     QDir::setCurrent(QCoreApplication::applicationDirPath());
0130 
0131     KDBusService service(KDBusService::Unique);
0132     TestObject testObject(&service);
0133     QObject::connect(&service, &KDBusService::activateRequested, &testObject, &TestObject::slotActivateRequested);
0134 
0135     // Testcase for the problem coming from the old fork-on-startup solution:
0136     // the "Activate" D-Bus call would time out if the app took too much time
0137     // to be ready.
0138     // printf("Sleeping.\n");
0139     // sleep(200);
0140     QStringList args;
0141     args << QStringLiteral("dummy call");
0142 
0143     auto activateSignal = [&service, &args]() {
0144         service.activateRequested(args, QDir::currentPath());
0145     };
0146     QMetaObject::invokeMethod(&service, activateSignal, Qt::QueuedConnection);
0147     QTimer::singleShot(400, &testObject, &TestObject::firstCall);
0148     qDebug() << "Running.";
0149     a.exec();
0150     qDebug() << "Terminating.";
0151 
0152     Q_ASSERT(testObject.callCount() == 3);
0153     const bool ok = testObject.callCount() == 3;
0154 
0155     return ok ? 0 : 1;
0156 }
0157 
0158 #include "kdbusservicetest.moc"