From 3d6476c9021519995239ec93bbb11f0dce6c60a0 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Thu, 26 Jun 2025 19:43:39 +0200 Subject: Core: Add a test suite (#9297) Adds a test suite for testing hyprland's features with a runtime tester --------- Co-authored-by: Mihai Fufezan --- hyprtester/src/tests/shared.cpp | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 hyprtester/src/tests/shared.cpp (limited to 'hyprtester/src/tests/shared.cpp') diff --git a/hyprtester/src/tests/shared.cpp b/hyprtester/src/tests/shared.cpp new file mode 100644 index 00000000..b7aa325c --- /dev/null +++ b/hyprtester/src/tests/shared.cpp @@ -0,0 +1,92 @@ +#include "shared.hpp" +#include +#include +#include +#include +#include "../shared.hpp" +#include "../hyprctlCompat.hpp" + +using namespace Hyprutils::OS; +using namespace Hyprutils::Memory; + +CUniquePointer Tests::spawnKitty(const std::string& class_) { + const auto COUNT_BEFORE = windowCount(); + + CUniquePointer kitty = makeUnique("kitty", class_.empty() ? std::vector{} : std::vector{"--class", class_}); + kitty->addEnv("WAYLAND_DISPLAY", WLDISPLAY); + kitty->runAsync(); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + // wait while kitty spawns + int counter = 0; + while (processAlive(kitty->pid()) && windowCount() == COUNT_BEFORE) { + counter++; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + if (counter > 50) + return nullptr; + } + + if (!processAlive(kitty->pid())) + return nullptr; + + return kitty; +} + +bool Tests::processAlive(pid_t pid) { + errno = 0; + int ret = kill(pid, 0); + return ret != -1 || errno != ESRCH; +} + +int Tests::windowCount() { + return countOccurrences(getFromSocket("/clients"), "focusHistoryID: "); +} + +int Tests::countOccurrences(const std::string& in, const std::string& what) { + int cnt = 0; + auto pos = in.find(what); + while (pos != std::string::npos) { + cnt++; + pos = in.find(what, pos + what.length() - 1); + } + + return cnt; +} + +bool Tests::killAllWindows() { + auto str = getFromSocket("/clients"); + auto pos = str.find("Window "); + while (pos != std::string::npos) { + auto pos2 = str.find(" -> ", pos); + getFromSocket("/dispatch killwindow address:0x" + str.substr(pos + 7, pos2 - pos - 7)); + pos = str.find("Window ", pos + 5); + } + + int counter = 0; + while (Tests::windowCount() != 0) { + counter++; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + if (counter > 50) { + std::println("{}Timed out waiting for windows to close", Colors::RED); + return false; + } + } + + return true; +} + +void Tests::waitUntilWindowsN(int n) { + int counter = 0; + while (Tests::windowCount() != n) { + counter++; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + if (counter > 50) { + std::println("{}Timed out waiting for windows", Colors::RED); + return; + } + } +} -- cgit v1.2.3