From 05e1b1e037b5dcee2db1845fcd835a4a91a9fb6c Mon Sep 17 00:00:00 2001 From: evgeny Date: Sun, 1 Nov 2026 20:25:14 +0100 Subject: [PATCH] Verify rollback continuity and enumerate test windows through capture IPC --- tools/chatgui/tests/test_stream_publish.cpp | 27 +++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/chatgui/tests/test_stream_publish.cpp b/tools/chatgui/tests/test_stream_publish.cpp index 7e028cd02..6ebae3296 100644 --- a/tools/chatgui/tests/test_stream_publish.cpp +++ b/tools/chatgui/tests/test_stream_publish.cpp @@ -60,6 +60,7 @@ extern "C" { #include "../src/stream_screen_cursor.h" #include #include +#include #undef None #undef Status #endif @@ -1236,6 +1237,24 @@ private slots: auto* sound = SoundManager::instance(); QVERIFY(sound->init()); QLabel pattern("Desktop capture test"); pattern.setWindowTitle("UTUN capture fixture"); pattern.resize(320, 180); pattern.setStyleSheet("background: #c04020; color: white; font-size: 20px;"); pattern.show(); QTest::qWait(100); +#ifdef UTUN_STREAM_X11_CURSOR + // Xvfb без WM: объявляем окно fixture через штатный EWMH-каталог, который читает Qt в дочернем процессе. + auto* native = qGuiApp->nativeInterface(); QVERIFY(native); + Display* display = native->display(); const Window root = XDefaultRootWindow(display); + const Atom clients = XInternAtom(display, "_NET_CLIENT_LIST", False); + Atom oldType = 0; int oldFormat = 0; unsigned long oldCount = 0, remaining = 0; unsigned char* oldClients = nullptr; + QCOMPARE(XGetWindowProperty(display, root, clients, 0, 65536, False, AnyPropertyType, + &oldType, &oldFormat, &oldCount, &remaining, &oldClients), Success); + const Window fixtureWindow = pattern.winId(); + XChangeProperty(display, root, clients, XA_WINDOW, 32, PropModeReplace, + reinterpret_cast(&fixtureWindow), 1); XSync(display, False); + auto restoreClients = qScopeGuard([&] { + if (oldType) XChangeProperty(display, root, clients, oldType, oldFormat, PropModeReplace, oldClients, int(oldCount)); + else XDeleteProperty(display, root, clients); + if (oldClients) XFree(oldClients); + XSync(display, False); + }); +#endif StreamPublishEngine engine; if (StreamPublishEngine::supported()) QTRY_VERIFY_WITH_TIMEOUT(!engine.sources().isEmpty(), 5000); QTRY_VERIFY_WITH_TIMEOUT(!engine.codecs().isEmpty(), 15000); connect(&engine, &StreamPublishEngine::softwareEncodingRequested, &engine, @@ -1324,13 +1343,16 @@ private slots: QVERIFY(record(202, StreamRecordKind::Audio, out)); QVERIFY(out.pts > first + 1000000); stream_member_state member{}; QCOMPARE(stream_member_load(inst, group, inst->node_id, &member, nullptr), STREAM_OK); QCOMPARE(member.source.source_epoch, epoch); + const auto workingRevision = out.format.revision; const auto rollbackPts = out.pts; auto invalid = next; invalid.video.fps = 61; QVERIFY(engine.reconfigure(invalid)); QTRY_COMPARE_WITH_TIMEOUT(engine.config().video.fps, 15, 5000); QTRY_COMPARE(errors.size(), 1); errors.clear(); + QTRY_VERIFY_WITH_TIMEOUT(engine.previewFrame().isValid(), 5000); bool restored = false; elapsed.restart(); while (!restored && elapsed.elapsed() < 5000) { - if (gui_stream_pull(202, out, 0, true, 60000000) && out.kind == StreamRecordKind::Video && out.format.revision >= 3) restored = true; + if (gui_stream_pull(202, out, 0, true, 60000000) && out.kind == StreamRecordKind::Video + && out.format.revision == workingRevision && out.pts > rollbackPts) restored = true; QTest::qWait(1); } QVERIFY(restored); @@ -1344,7 +1366,8 @@ private slots: })(), 5000); QVERIFY(engine.reconfigure(next)); bool window = false; elapsed.restart(); while (!window && elapsed.elapsed() < 5000) { - if (gui_stream_pull(202, out, 0, true, 60000000) && out.kind == StreamRecordKind::Video && out.format.revision >= 4) window = true; + if (gui_stream_pull(202, out, 0, true, 60000000) && out.kind == StreamRecordKind::Video + && out.format.revision > workingRevision) window = true; QTest::qWait(1); } QVERIFY(window);