SPDX-FileCopyrightText: 2013 Ivan Cukic <ivan.cukic(at)kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "Process.h"
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QDebug>
#include <QProcess>
#include <QRegularExpression>
#include <QStandardPaths>
#include <QString>
#include <QTemporaryDir>
#include <QTest>
#include <signal.h>
#include <sys/types.h>
#include "common/dbus/common.h"
namespace Process
{
QProcess *Modifier::s_process = nullptr;
QTemporaryDir *Modifier::s_tempDir = nullptr;
QString nulluuid = QStringLiteral("00000000-0000-0000-0000-000000000000");
Modifier::Modifier(Action action)
: Test()
, m_action(action)
{
if (!s_process) {
s_process = new QProcess();
s_tempDir = new QTemporaryDir();
if (!s_tempDir->isValid()) {
qFatal("Can not create a temporary dir");
}
qDebug() << "Running KAMD in " << s_tempDir->path();
s_process->setProcessChannelMode(QProcess::ForwardedChannels);
}
}
void Modifier::initTestCase()
{
const auto state = s_process->state();
if (state != QProcess::NotRunning && m_action == Start) {
qFatal("Already running");
}
switch (m_action) {
case Start: {
qDebug() << "Starting...";
QRegularExpression nonxdg(QStringLiteral("^[^X][^D][^G].*$"));
auto env = QProcessEnvironment::systemEnvironment().toStringList().filter(nonxdg)
<< QStringLiteral("XDG_DATA_HOME=") + s_tempDir->path() + QStringLiteral("/")
<< QStringLiteral("XDG_CONFIG_HOME=") + s_tempDir->path() + QStringLiteral("/")
<< QStringLiteral("XDG_CACHE_HOME=") + s_tempDir->path() + QStringLiteral("/");
s_process->setEnvironment(env);
const QString exec = QStandardPaths::findExecutable(QStringLiteral("kactivitymanagerd"));
QVERIFY(!exec.isEmpty());
s_process->start(exec, QStringList());
s_process->waitForStarted();
break;
}
case Stop:
case Kill:
case Crash: {
qDebug() << "Stopping...";
const auto dbus = QDBusConnection::sessionBus().interface();
const auto kamd = KAMD_DBUS_SERVICE;
if (!dbus->isServiceRegistered(kamd)) {
break;
}
uint pid = dbus->servicePid(kamd);
::kill(pid,
m_action == Stop ? SIGQUIT :
m_action == Kill ? SIGKILL :
SIGSEGV
);
while (Test::isActivityManagerRunning()) {
QCoreApplication::processEvents();
}
if (s_process->state() == QProcess::Running) {
s_process->terminate();
s_process->waitForFinished();
}
break;
}
}
}
void Modifier::testProcess()
{
const auto state = s_process->state();
switch (m_action) {
case Start:
QCOMPARE(state, QProcess::Running);
break;
case Stop:
QCOMPARE(state, QProcess::NotRunning);
break;
case Kill:
QCOMPARE(state, QProcess::NotRunning);
break;
case Crash:
break;
}
}
void Modifier::cleanupTestCase()
{
Q_EMIT testFinished();
}
Modifier *exec(Action action)
{
return new Modifier(action);
}
}
#include "moc_Process.cpp"