vdi-cloud/terminal/kiosk-shell/tests/test_moonlight_session.cpp

168 lines
6.2 KiB
C++

#include <QtTest>
#include "moonlight_session.h"
using namespace vdi;
class MoonlightSessionTest : public QObject {
Q_OBJECT
private slots:
void parsesSplitReadyMarkers();
void requiresBothReadyMarkers();
void acceptsSeparateHardwareTestDecoder();
void rejectsSecondStart();
void buildsConsistentStreamArguments();
void selectsProfileWithoutLosingStats();
void rejectsInvalidDecoderOverride();
};
void MoonlightSessionTest::parsesSplitReadyMarkers() {
MoonlightOutputParser parser;
parser.append("Test decode succ");
QVERIFY(!parser.isReady());
parser.append("essful\nRenderer 'SDL' with 'DRM' backend ");
QVERIFY(parser.hasTestDecode());
QVERIFY(!parser.hasRenderer());
parser.append("chosen\n");
QVERIFY(parser.isReady());
}
void MoonlightSessionTest::requiresBothReadyMarkers() {
MoonlightOutputParser parser;
parser.append("Test decode successful\n");
QVERIFY(!parser.isReady());
parser.reset();
parser.append("Renderer 'SDL' chosen\n");
QVERIFY(!parser.isReady());
parser.append("Connection terminated: -1\n");
QVERIFY(parser.hasTerminalError());
QVERIFY(!parser.isReady());
}
void MoonlightSessionTest::acceptsSeparateHardwareTestDecoder() {
MoonlightOutputParser parser;
parser.append("Using custom H.264 decoder (H264_DECODER_HINT): h264_rkmpp\n");
QVERIFY(!parser.isReady());
parser.append("Not reusing test decoder for h264_rkmpp\n");
QVERIFY(parser.hasTestDecode());
QVERIFY(!parser.isReady());
parser.append("Renderer 'EGL' with 'DRM' backend chosen\n");
QVERIFY(parser.isReady());
parser.append("Connection terminated: -1\n");
QVERIFY(!parser.isReady());
}
void MoonlightSessionTest::rejectsSecondStart() {
QTemporaryDir tempDir;
QVERIFY(tempDir.isValid());
const QString executable = tempDir.filePath(QStringLiteral("moonlight-qt"));
QFile script(executable);
QVERIFY(script.open(QIODevice::WriteOnly | QIODevice::Text));
script.write("#!/bin/sh\n"
"printf 'Test decode successful\\n'\n"
"printf \"Renderer 'SDL' with 'DRM' backend chosen\\n\"\n"
"sleep 5\n");
script.close();
QVERIFY(script.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner |
QFileDevice::ExeOwner | QFileDevice::ReadGroup |
QFileDevice::ExeGroup | QFileDevice::ReadOther |
QFileDevice::ExeOther));
const QByteArray oldPath = qgetenv("PATH");
qputenv("PATH", tempDir.path().toUtf8() + ':' + oldPath);
ConnectionTicket ticket;
ticket.endpoint = QStringLiteral("127.0.0.1");
ticket.app = QStringLiteral("Desktop");
MoonlightSession session;
int started = 0;
int ready = 0;
int terminal = 0;
const auto callback = [&](const MoonlightSession::Event& event) {
if (event.type == MoonlightSession::EventType::kStarted) {
++started;
} else if (event.type == MoonlightSession::EventType::kStreamReady) {
++ready;
} else if (event.type == MoonlightSession::EventType::kFailed ||
event.type == MoonlightSession::EventType::kFinished) {
++terminal;
}
};
QVERIFY(session.start(ticket, callback));
QTRY_COMPARE_WITH_TIMEOUT(started, 1, 2000);
QVERIFY(!session.start(ticket, callback));
QTRY_COMPARE_WITH_TIMEOUT(ready, 1, 3000);
session.stop();
QTRY_COMPARE_WITH_TIMEOUT(terminal, 1, 4000);
QCOMPARE(ready, 1);
QCOMPARE(terminal, 1);
qputenv("PATH", oldPath);
}
void MoonlightSessionTest::buildsConsistentStreamArguments() {
ConnectionTicket ticket;
ticket.endpoint = QStringLiteral("192.168.1.70");
ticket.app = QStringLiteral("Desktop");
ticket.width = 2560;
ticket.height = 1440;
ticket.fps = 30;
MoonlightSession::Options options;
options.profile = QStringLiteral("low-latency");
options.decoder = QStringLiteral("software");
options.videoCodec = QStringLiteral("H.264");
options.vsync = false;
options.framePacing = false;
options.performanceOverlay = true;
const QStringList args = MoonlightSession::buildStreamArguments(ticket, options);
QVERIFY(args.contains(QStringLiteral("--resolution")));
QVERIFY(args.contains(QStringLiteral("2560x1440")));
QVERIFY(args.contains(QStringLiteral("--fps")));
QVERIFY(args.contains(QStringLiteral("30")));
QVERIFY(args.contains(QStringLiteral("--bitrate")));
QVERIFY(args.contains(QStringLiteral("30000")));
QVERIFY(args.contains(QStringLiteral("--no-vsync")));
QVERIFY(args.contains(QStringLiteral("--no-frame-pacing")));
QVERIFY(args.contains(QStringLiteral("--performance-overlay")));
QVERIFY(args.contains(QStringLiteral("--absolute-mouse")));
}
void MoonlightSessionTest::selectsProfileWithoutLosingStats() {
QProcessEnvironment environment;
environment.insert(QStringLiteral("VDI_STREAM_PROFILE"), QStringLiteral("low-latency"));
environment.insert(QStringLiteral("VDI_STREAM_STATS"), QStringLiteral("1"));
auto options = MoonlightSession::optionsFromEnvironment(environment);
QVERIFY(!options.vsync);
QVERIFY(!options.framePacing);
QVERIFY(options.performanceOverlay);
environment.insert(QStringLiteral("VDI_STREAM_PROFILE"), QStringLiteral("smooth"));
options = MoonlightSession::optionsFromEnvironment(environment);
QVERIFY(options.vsync);
QVERIFY(options.framePacing);
QVERIFY(options.performanceOverlay);
}
void MoonlightSessionTest::rejectsInvalidDecoderOverride() {
QProcessEnvironment environment;
environment.insert(QStringLiteral("VDI_MOONLIGHT_DECODER"), QStringLiteral("h264_rkmpp"));
environment.insert(QStringLiteral("VDI_STREAM_PROFILE"), QStringLiteral("invalid"));
auto options = MoonlightSession::optionsFromEnvironment(environment);
QCOMPARE(options.decoder, QStringLiteral("software"));
QCOMPARE(options.profile, QStringLiteral("smooth"));
environment.insert(QStringLiteral("VDI_MOONLIGHT_DECODER"), QStringLiteral("hardware"));
options = MoonlightSession::optionsFromEnvironment(environment);
QCOMPARE(options.decoder, QStringLiteral("hardware"));
}
QTEST_GUILESS_MAIN(MoonlightSessionTest)
#include "test_moonlight_session.moc"