diff --git a/tests/manual/wasm/eventloop/CMakeLists.txt b/tests/manual/wasm/eventloop/CMakeLists.txt index 132fd15dbbc..c6f14eb8325 100644 --- a/tests/manual/wasm/eventloop/CMakeLists.txt +++ b/tests/manual/wasm/eventloop/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(asyncify_exec) add_subdirectory(eventloop_auto) +add_subdirectory(suspendresumecontrol_auto) add_subdirectory(main_exec) add_subdirectory(main_noexec) add_subdirectory(thread_exec) diff --git a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/CMakeLists.txt b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/CMakeLists.txt new file mode 100644 index 00000000000..97aa7ed8e2f --- /dev/null +++ b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause +include_directories(../../qtwasmtestlib/) + +qt_internal_add_manual_test(suspendresumecontrol_auto + SOURCES + main.cpp + ../../qtwasmtestlib/qtwasmtestlib.cpp + LIBRARIES + Qt::Core + Qt::CorePrivate +) + +add_custom_command( + TARGET suspendresumecontrol_auto POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/suspendresumecontrol_auto.html + ${CMAKE_CURRENT_BINARY_DIR}/suspendresumecontrol_auto.html) + +add_custom_command( + TARGET suspendresumecontrol_auto POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/../../qtwasmtestlib/qtwasmtestlib.js + ${CMAKE_CURRENT_BINARY_DIR}/qtwasmtestlib.js) diff --git a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp new file mode 100644 index 00000000000..59f1f00cc59 --- /dev/null +++ b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp @@ -0,0 +1,148 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include +#include +#include + +using namespace emscripten; + +const int timerTimeout = 10; + +// Test QWasmSuspendResumeControl suspend/resume and event processing, +// via QWasmTimer native timer events. +class WasmSuspendResumeControlTest: public QObject +{ + Q_OBJECT +private slots: + void timer(); + void multipleTimers(); + void reuseTimer(); + void cancelTimer(); + void deleteTimer(); +}; + +// Verify that a single timer fires +void WasmSuspendResumeControlTest::timer() +{ + QWasmSuspendResumeControl suspendResume; + bool timerFired = false; + + QWasmTimer timer(&suspendResume, [&timerFired](){ + timerFired = true; + }); + timer.setTimeout(timerTimeout); + + while (!timerFired) { + suspendResume.suspend(); + suspendResume.sendPendingEvents(); + } + + QWASMSUCCESS(); +} + +// Verify that multiple parallel timers fire +void WasmSuspendResumeControlTest::multipleTimers() +{ + QWasmSuspendResumeControl suspendResume; + const int expectedTimers = 10; + int compledtedTimers = 0; + + std::unique_ptr timers[expectedTimers]; + for (int i = 0; i < expectedTimers; ++i) { + timers[i] = std::make_unique(&suspendResume, [&compledtedTimers](){ + ++compledtedTimers; + }); + timers[i]->setTimeout(timerTimeout * i); + } + + while (compledtedTimers < expectedTimers) { + suspendResume.suspend(); + suspendResume.sendPendingEvents(); + } + + QWASMSUCCESS(); +} + +// Verify that a reused timer fires again +void WasmSuspendResumeControlTest::reuseTimer() +{ + QWasmSuspendResumeControl suspendResume; + const int expectedTimers = 10; + int compledtedTimers = 0; + + QWasmTimer timer(&suspendResume, [&compledtedTimers](){ + ++compledtedTimers; + }); + + while (compledtedTimers < expectedTimers) { + timer.setTimeout(timerTimeout); + suspendResume.suspend(); + suspendResume.sendPendingEvents(); + } + + QWASMSUCCESS(); +} + +// Verify that a cancelled timer does not fire +void WasmSuspendResumeControlTest::cancelTimer() +{ + QWasmSuspendResumeControl suspendResume; + + // controlTimer checks that the cancelled testTimer didn't fire + bool controlFired = false; + QWasmTimer controlTimer(&suspendResume, [&controlFired](){ + controlFired = true; + }); + + QWasmTimer testTimer(&suspendResume, [](){ + QWASMFAIL("Cancelled timer did fire"); + }); + + controlTimer.setTimeout(timerTimeout * 4); + testTimer.setTimeout(timerTimeout); + testTimer.clearTimeout(); + + while (!controlFired) { + suspendResume.suspend(); + suspendResume.sendPendingEvents(); + } + + QWASMSUCCESS(); +} + +// Verify that a deleted timer does not fire +void WasmSuspendResumeControlTest::deleteTimer() +{ + QWasmSuspendResumeControl suspendResume; + + // controlTimer checks that the deleted testTimer didn't fire + bool controlFired = false; + QWasmTimer controlTimer(&suspendResume, [&controlFired](){ + controlFired = true; + }); + controlTimer.setTimeout(timerTimeout * 4); + + { + QWasmTimer testTimer(&suspendResume, [](){ + QWASMFAIL("Deleted timer did fire"); + }); + testTimer.setTimeout(timerTimeout); + } + + while (!controlFired) { + suspendResume.suspend(); + suspendResume.sendPendingEvents(); + } + + QWASMSUCCESS(); +} + +int main(int argc, char **argv) +{ + auto testObject = std::make_shared(); + QtWasmTest::initTestCase(argc, argv, testObject); + return 0; +} + +#include "main.moc" diff --git a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/suspendresumecontrol_auto.html b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/suspendresumecontrol_auto.html new file mode 100644 index 00000000000..4ebba6af7ce --- /dev/null +++ b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/suspendresumecontrol_auto.html @@ -0,0 +1,10 @@ + + + + +

Running event dispatcher auto test.

+