diff --git a/src/autotests/DBusTest.cpp b/src/autotests/DBusTest.cpp index c8a0440a..fb634ae5 100644 --- a/src/autotests/DBusTest.cpp +++ b/src/autotests/DBusTest.cpp @@ -1,373 +1,373 @@ /* Copyright 2010 by Kurt Hindenburg This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Own #include "DBusTest.h" #include "../Session.h" #include "../Profile.h" #include "../ProfileWriter.h" // Qt #include #include #include #include using namespace Konsole; /* Exec a new Konsole and grab its dbus */ void DBusTest::initTestCase() { qRegisterMetaType(); const QString interfaceName = QStringLiteral("org.kde.konsole"); QDBusConnectionInterface *bus = nullptr; QStringList konsoleServices; if (!QDBusConnection::sessionBus().isConnected() || ((bus = QDBusConnection::sessionBus().interface()) == nullptr)) { QFAIL("Session bus not found"); } QDBusReply serviceReply = bus->registeredServiceNames(); QVERIFY2(serviceReply.isValid(), "SessionBus interfaces not available"); // Find all current Konsoles' services running QStringList allServices = serviceReply; for (QStringList::const_iterator it = allServices.constBegin(), end = allServices.constEnd(); it != end; ++it) { const QString service = *it; if (service.startsWith(interfaceName)) { konsoleServices << service; } } // Create test profile auto profile = Profile::Ptr(new Profile()); auto profileWriter = new ProfileWriter(); do { _testProfileName = QStringLiteral("konsole-dbus-test-profile-%1") .arg(QRandomGenerator::global()->generate()); profile->setProperty(Profile::UntranslatedName, _testProfileName); profile->setProperty(Profile::Name, _testProfileName); _testProfilePath = profileWriter->getPath(profile); } while (QFile::exists(_testProfilePath)); _testProfileEnv = QStringLiteral("TEST_PROFILE=%1").arg(_testProfileName); profile->setProperty(Profile::Environment, QStringList(_testProfileEnv)); // %D = Current Directory (Long) - hacky way to check current directory profile->setProperty(Profile::LocalTabTitleFormat, QStringLiteral("%D")); profileWriter->writeProfile(_testProfilePath, profile); // Create a new Konsole with a separate process id _process = new QProcess; _process->setProcessChannelMode(QProcess::ForwardedChannels); _process->start(QStringLiteral("konsole"), QStringList(QStringLiteral("--separate"))); if (!_process->waitForStarted()) { QFAIL(QStringLiteral("Unable to exec a new Konsole").toLatin1().data()); } // Wait for above Konsole to finish starting QThread::sleep(5); serviceReply = bus->registeredServiceNames(); QVERIFY2(serviceReply.isValid(), "SessionBus interfaces not available"); // Find dbus service of above Konsole allServices = serviceReply; for (QStringList::const_iterator it = allServices.constBegin(), end = allServices.constEnd(); it != end; ++it) { const QString service = *it; if (service.startsWith(interfaceName)) { if (!konsoleServices.contains(service)) { _interfaceName = service; } } } QVERIFY2(!_interfaceName.isEmpty(), "This test will only work in a Konsole window with a new PID. A new Konsole PID can't be found."); QDBusInterface iface(_interfaceName, QStringLiteral("/Windows/1"), QStringLiteral("org.kde.konsole.Konsole")); QVERIFY(iface.isValid()); } /* Close the Konsole window that was opened to test the DBus interface */ void DBusTest::cleanupTestCase() { // Remove test profile QFile::remove(_testProfilePath); // Need to take care of when user has CloseAllTabs=False otherwise // they will get a popup dialog when we try to close this. QSignalSpy quitSpy(_process, SIGNAL(finished(int,QProcess::ExitStatus))); // Do not use QWidget::close(), as it shows question popup when // CloseAllTabs is set to false (default). QDBusInterface iface(_interfaceName, QStringLiteral("/MainApplication"), QStringLiteral("org.qtproject.Qt.QCoreApplication")); QVERIFY2(iface.isValid(), "Unable to get a dbus interface to Konsole!"); QDBusReply instanceReply = iface.call(QStringLiteral("quit")); if (!instanceReply.isValid()) { QFAIL(QStringLiteral("Unable to close Konsole: %1").arg(instanceReply.error().message()).toLatin1().data()); } quitSpy.wait(); _process->kill(); _process->deleteLater(); } void DBusTest::testSessions() { QDBusReply voidReply; QDBusReply boolReply; QDBusReply arrayReply; QDBusReply stringReply; QDBusReply listReply; QDBusInterface iface(_interfaceName, QStringLiteral("/Sessions/1"), QStringLiteral("org.kde.konsole.Session")); QVERIFY(iface.isValid()); //****************** Test is/set MonitorActivity voidReply = iface.call(QStringLiteral("setMonitorActivity"), false); QVERIFY(voidReply.isValid()); boolReply = iface.call(QStringLiteral("isMonitorActivity")); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), false); voidReply = iface.call(QStringLiteral("setMonitorActivity"), true); QVERIFY(voidReply.isValid()); boolReply = iface.call(QStringLiteral("isMonitorActivity")); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), true); //****************** Test is/set MonitorSilence voidReply = iface.call(QStringLiteral("setMonitorSilence"), false); QVERIFY(voidReply.isValid()); boolReply = iface.call(QStringLiteral("isMonitorSilence")); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), false); voidReply = iface.call(QStringLiteral("setMonitorSilence"), true); QVERIFY(voidReply.isValid()); boolReply = iface.call(QStringLiteral("isMonitorSilence")); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), true); //****************** Test codec and setCodec arrayReply = iface.call(QStringLiteral("codec")); QVERIFY(arrayReply.isValid()); // Obtain a list of system's Codecs QList availableCodecs = QTextCodec::availableCodecs(); for (int i = 0; i < availableCodecs.count(); ++i) { boolReply = iface.call(QStringLiteral("setCodec"), availableCodecs[i]); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), true); arrayReply = iface.call(QStringLiteral("codec")); QVERIFY(arrayReply.isValid()); // Compare result with name due to aliases issue // Better way to do this? QCOMPARE((QTextCodec::codecForName(arrayReply.value()))->name(), (QTextCodec::codecForName(availableCodecs[i]))->name()); } //****************** Test is/set flowControlEnabled voidReply = iface.call(QStringLiteral("setFlowControlEnabled"), true); QVERIFY(voidReply.isValid()); boolReply = iface.call(QStringLiteral("flowControlEnabled")); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), true); voidReply = iface.call(QStringLiteral("setFlowControlEnabled"), false); QVERIFY(voidReply.isValid()); boolReply = iface.call(QStringLiteral("flowControlEnabled")); QVERIFY(boolReply.isValid()); QCOMPARE(boolReply.value(), false); //****************** Test is/set environment listReply = iface.call(QStringLiteral("environment")); QVERIFY(listReply.isValid()); QStringList prevEnv = listReply.value(); //for (int i = 0; i < prevEnv.size(); ++i) // qDebug()<< prevEnv.at(i).toLocal8Bit().constData() << endl; voidReply = iface.call(QStringLiteral("setEnvironment"), QStringList()); QVERIFY(voidReply.isValid()); listReply = iface.call(QStringLiteral("environment")); QVERIFY(listReply.isValid()); QCOMPARE(listReply.value(), QStringList()); voidReply = iface.call(QStringLiteral("setEnvironment"), prevEnv); QVERIFY(voidReply.isValid()); listReply = iface.call(QStringLiteral("environment")); QVERIFY(listReply.isValid()); QCOMPARE(listReply.value(), prevEnv); //****************** Test is/set title // TODO: Consider checking what is in Profile stringReply = iface.call(QStringLiteral("title"), Session::NameRole); QVERIFY(stringReply.isValid()); // set title to, what title should be QMap titleMap; titleMap[QStringLiteral("Shell")] = QStringLiteral("Shell"); // BUG: It appears that Session::LocalTabTitle is set to Shell and // doesn't change. While RemoteTabTitle is actually the LocalTabTitle // TODO: Figure out what's going on... QMapIterator i(titleMap); while (i.hasNext()) { i.next(); voidReply = iface.call(QStringLiteral("setTitle"), Session::NameRole, i.key()); QVERIFY(voidReply.isValid()); stringReply = iface.call(QStringLiteral("title"), Session::NameRole); QVERIFY(stringReply.isValid()); QCOMPARE(stringReply.value(), i.value()); } } void DBusTest::testWindows() { // Tested functions: // [+] int sessionCount(); // [+] QStringList sessionList(); // [+] int currentSession(); // [+] void setCurrentSession(int sessionId); // [+] int newSession(); // [+] int newSession(const QString &profile); // [+] int newSession(const QString &profile, const QString &directory); // [ ] QString defaultProfile(); // [ ] QStringList profileList(); // [ ] void nextSession(); // [ ] void prevSession(); // [ ] void moveSessionLeft(); // [ ] void moveSessionRight(); // [ ] void setTabWidthToText(bool); QDBusReply intReply; QDBusReply listReply; QDBusReply voidReply; QDBusReply stringReply; int sessionCount = -1; int initialSessionId = -1; QDBusInterface iface(_interfaceName, QStringLiteral("/Windows/1"), QStringLiteral("org.kde.konsole.Window")); QVERIFY(iface.isValid()); intReply = iface.call(QStringLiteral("sessionCount")); QVERIFY(intReply.isValid()); sessionCount = intReply.value(); QVERIFY(sessionCount > 0); intReply = iface.call(QStringLiteral("currentSession")); QVERIFY(intReply.isValid()); initialSessionId = intReply.value(); intReply = iface.call(QStringLiteral("newSession")); QVERIFY(intReply.isValid()); ++sessionCount; int newSessionId = intReply.value(); QVERIFY(newSessionId != initialSessionId); listReply = iface.call(QStringLiteral("sessionList")); QVERIFY(listReply.isValid()); QStringList sessions = listReply.value(); QVERIFY(sessions.contains(QString::number(initialSessionId))); QVERIFY(sessions.contains(QString::number(newSessionId))); QVERIFY(sessions.size() == sessionCount); intReply = iface.call(QStringLiteral("newSession"), _testProfileName); QVERIFY(intReply.isValid()); ++sessionCount; newSessionId = intReply.value(); QVERIFY(newSessionId != initialSessionId); { QDBusInterface sessionIface(_interfaceName, QStringLiteral("/Sessions/%1").arg(newSessionId), QStringLiteral("org.kde.konsole.Session")); QVERIFY(iface.isValid()); listReply = sessionIface.call(QStringLiteral("environment")); QVERIFY(listReply.isValid()); QStringList env = listReply.value(); QVERIFY(env.contains(_testProfileEnv)); } const auto tempDirectories = QStandardPaths::standardLocations(QStandardPaths::TempLocation); - const QString sessionDirectory = tempDirectories.size() > 0 ? tempDirectories.constFirst() : QStringLiteral("/"); + const QString sessionDirectory = tempDirectories.empty() ? QStringLiteral("/") : tempDirectories.constFirst(); intReply = iface.call(QStringLiteral("newSession"), _testProfileName, sessionDirectory); QVERIFY(intReply.isValid()); ++sessionCount; newSessionId = intReply.value(); QVERIFY(newSessionId != initialSessionId); { QDBusInterface sessionIface(_interfaceName, QStringLiteral("/Sessions/%1").arg(newSessionId), QStringLiteral("org.kde.konsole.Session")); QVERIFY(iface.isValid()); listReply = sessionIface.call(QStringLiteral("environment")); QVERIFY(listReply.isValid()); QStringList env = listReply.value(); QVERIFY(env.contains(_testProfileEnv)); // Apparently there's no function for checking CWD. // The profile uses "%D" as title format, so check the title stringReply = sessionIface.call(QStringLiteral("title"), Session::DisplayedTitleRole); QVERIFY(stringReply.isValid()); QVERIFY(QDir(stringReply.value()) == QDir(sessionDirectory)); } voidReply = iface.call(QStringLiteral("setCurrentSession"), initialSessionId); QVERIFY(voidReply.isValid()); intReply = iface.call(QStringLiteral("currentSession")); QVERIFY(intReply.isValid()); QVERIFY(intReply.value() == initialSessionId); intReply = iface.call(QStringLiteral("sessionCount")); QVERIFY(intReply.isValid()); QVERIFY(intReply.value() == sessionCount); } QTEST_MAIN(DBusTest)