mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-03-26 17:03:08 +00:00
tests: recover sessions after gamecenter restart
This commit is contained in:
parent
57d1e6e130
commit
8891e85dbc
1 changed files with 96 additions and 0 deletions
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-FileCopyrightText: 2026 A-La-Karte Contributors
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusInterface>
|
||||
|
|
@ -53,6 +54,27 @@ static bool waitForService(QDBusConnection &bus, const QString &service, int tim
|
|||
return false;
|
||||
}
|
||||
|
||||
static QVariant unwrapDbusVariant(QVariant v)
|
||||
{
|
||||
if (v.canConvert<QDBusVariant>()) {
|
||||
v = v.value<QDBusVariant>().variant();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static QVariantMap unwrapVariantMap(QVariant v)
|
||||
{
|
||||
v = unwrapDbusVariant(v);
|
||||
if (v.canConvert<QDBusArgument>()) {
|
||||
const QDBusArgument arg = v.value<QDBusArgument>();
|
||||
return qdbus_cast<QVariantMap>(arg);
|
||||
}
|
||||
if (v.canConvert<QVariantMap>()) {
|
||||
return v.toMap();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static QByteArray readProcFile(const QString &path, qint64 maxSize = 65536)
|
||||
{
|
||||
QFile f(path);
|
||||
|
|
@ -226,6 +248,8 @@ private Q_SLOTS:
|
|||
void stopDirectLaunch();
|
||||
void stopByGameIdDirectLaunch();
|
||||
|
||||
void recoverSessionsAfterDaemonRestart();
|
||||
|
||||
private:
|
||||
QString m_gamecenterPath;
|
||||
QProcess m_gamecenter;
|
||||
|
|
@ -351,6 +375,78 @@ void StopLaunchingRegressionTest::cleanupTestCase()
|
|||
}
|
||||
}
|
||||
|
||||
void StopLaunchingRegressionTest::recoverSessionsAfterDaemonRestart()
|
||||
{
|
||||
QDBusConnection bus = QDBusConnection::sessionBus();
|
||||
if (!bus.isConnected()) {
|
||||
QSKIP("session bus not available");
|
||||
}
|
||||
|
||||
QDBusInterface iface(QStringLiteral("org.kde.GameCenter1"), QStringLiteral("/org/kde/ALaKarte/GameCenter1"), QStringLiteral("org.kde.GameCenter1"), bus);
|
||||
QVERIFY2(iface.isValid(), "GameCenter1 DBus interface not valid");
|
||||
|
||||
const QByteArray markerNeedle = (QStringLiteral("ALAKARTE_TEST_MARKER=") + m_markerValue).toUtf8();
|
||||
killPids(pidsWithEnvironEntry(markerNeedle));
|
||||
|
||||
const QString envExe = QStandardPaths::findExecutable(QStringLiteral("env"));
|
||||
if (envExe.isEmpty()) {
|
||||
QSKIP("env executable not found");
|
||||
}
|
||||
|
||||
const QString gameId = QStringLiteral("test-reattach-%1").arg(QUuid::createUuid().toString(QUuid::WithoutBraces));
|
||||
|
||||
QVariantMap spec;
|
||||
spec.insert(QStringLiteral("provider"), QStringLiteral("manual"));
|
||||
spec.insert(QStringLiteral("program"), envExe);
|
||||
spec.insert(QStringLiteral("args"),
|
||||
QStringList{QStringLiteral("ALAKARTE_TEST_MARKER=%1").arg(m_markerValue), QStringLiteral("/bin/sleep"), QStringLiteral("60")});
|
||||
spec.insert(QStringLiteral("gameId"), gameId);
|
||||
|
||||
const QDBusReply<QString> launchReply = iface.call(QStringLiteral("Launch"), spec);
|
||||
QVERIFY2(launchReply.isValid(), qPrintable(launchReply.error().message()));
|
||||
const QString sessionId = launchReply.value();
|
||||
QVERIFY2(!sessionId.isEmpty(), "Launch returned empty sessionId");
|
||||
const QString unitName = QStringLiteral("alakarte-game-%1.scope").arg(sessionId);
|
||||
|
||||
QVERIFY2(waitForAnyEnvironEntry(markerNeedle, 5000), "direct launch marker process did not appear");
|
||||
|
||||
m_gamecenter.kill();
|
||||
QVERIFY(m_gamecenter.waitForFinished(5000));
|
||||
QVERIFY2(waitForNoEnvironEntry(markerNeedle, 1000) == false, "marker process unexpectedly disappeared after daemon kill");
|
||||
|
||||
m_gamecenter.start();
|
||||
QVERIFY(m_gamecenter.waitForStarted(5000));
|
||||
QVERIFY2(waitForService(bus, QStringLiteral("org.kde.GameCenter1"), 5000), "GameCenter1 service did not re-appear after restart");
|
||||
|
||||
QDBusInterface iface2(QStringLiteral("org.kde.GameCenter1"), QStringLiteral("/org/kde/ALaKarte/GameCenter1"), QStringLiteral("org.kde.GameCenter1"), bus);
|
||||
QVERIFY2(iface2.isValid(), "GameCenter1 DBus interface not valid after restart");
|
||||
|
||||
const QDBusReply<QVariantList> listReply = iface2.call(QStringLiteral("ListSessions"));
|
||||
QVERIFY2(listReply.isValid(), qPrintable(listReply.error().message()));
|
||||
|
||||
bool found = false;
|
||||
for (const QVariant &v : listReply.value()) {
|
||||
const QVariantMap m = unwrapVariantMap(v);
|
||||
if (m.value(QStringLiteral("sessionId")).toString() == sessionId) {
|
||||
found = true;
|
||||
QCOMPARE(m.value(QStringLiteral("gameId")).toString(), gameId);
|
||||
QCOMPARE(m.value(QStringLiteral("state")).toString(), QStringLiteral("Running"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY2(found, "expected recovered session not found in ListSessions() after restart");
|
||||
|
||||
const QDBusReply<void> stopReply = iface2.call(QStringLiteral("Stop"), sessionId);
|
||||
QVERIFY2(stopReply.isValid(), qPrintable(stopReply.error().message()));
|
||||
|
||||
const bool cleaned = waitForNoEnvironEntry(markerNeedle, 15000);
|
||||
if (!cleaned) {
|
||||
killPids(pidsWithEnvironEntry(markerNeedle));
|
||||
}
|
||||
QVERIFY2(cleaned, "marker process still alive after Stop() on recovered session");
|
||||
QVERIFY2(waitForUnitNotActive(unitName, 15000), "systemd unit still active after Stop() on recovered session");
|
||||
}
|
||||
|
||||
void StopLaunchingRegressionTest::stopWhileLaunchingSteam()
|
||||
{
|
||||
QDBusConnection bus = QDBusConnection::sessionBus();
|
||||
|
|
|
|||
Loading…
Reference in a new issue