Files
feresaria/scripts/tests/test_blurred_popup_isolated.py

87 lines
4.5 KiB
Python

"""Open, update and close blurred popups on a private nested compositor.
FERESE_TEST_BLURRED_POPUP=1 FERESE_TEST_BINARY=target/release/ferese \\
FERESE_TEST_CTL=target/release/feresectl python3 scripts/tests/test_blurred_popup_isolated.py
Requires a Wayland host, wayland-scanner and a C compiler.
"""
import os
from pathlib import Path
from session_socket import ipc_environment, ipc_socket
import subprocess
import tempfile
import time
import unittest
@unittest.skipUnless(os.environ.get("FERESE_TEST_BLURRED_POPUP") == "1", "opt-in nested blur test")
class BlurredPopupTest(unittest.TestCase):
def test_popup_lifecycle_keeps_presenting_frames(self):
repo = Path(__file__).resolve().parents[2]
with tempfile.TemporaryDirectory(prefix="ferese-blurred-popup-") as temporary:
root = Path(temporary)
protocols = Path(subprocess.check_output(
["pkg-config", "--variable=pkgdatadir", "wayland-protocols"], text=True
).strip())
generated = []
for name, xml in [
("xdg-shell", protocols / "stable/xdg-shell/xdg-shell.xml"),
("ferese-effects", repo / "protocols/ferese-effects-v1.xml"),
]:
source = root / f"{name}.c"
subprocess.run(["wayland-scanner", "client-header", str(xml),
str(root / f"{name}-client-protocol.h")], check=True)
subprocess.run(["wayland-scanner", "private-code", str(xml), str(source)], check=True)
generated.append(str(source))
flags = subprocess.check_output(
["pkg-config", "--cflags", "--libs", "wayland-client"], text=True
).split()
client = root / "client"
subprocess.run(["cc", "-Wall", "-Wextra", "-Werror", "-I", str(root),
str(repo / "scripts/tests/fixtures/blurred-popup.c"),
*generated, "-o", str(client), *flags], check=True)
runtime = root / "runtime"
runtime.mkdir(mode=0o700)
config = root / "config/ferese"
config.mkdir(parents=True)
(config / "config.kdl").write_text('theme { material { style "translucent"; } }\n')
host = Path(os.environ["WAYLAND_DISPLAY"])
if not host.is_absolute():
host = Path(os.environ["XDG_RUNTIME_DIR"]) / host
env = dict(os.environ, WAYLAND_DISPLAY=str(host), XDG_RUNTIME_DIR=str(runtime),
XDG_CONFIG_HOME=str(root / "config"), XDG_STATE_HOME=str(root / "state"),
XDG_CACHE_HOME=str(root / "cache"), RUST_LOG="ferese=info")
env.pop("WAYLAND_SOCKET", None)
env.pop("FERESE_SHELL_CONTROL_SOCKET", None)
binary = repo / os.environ.get("FERESE_TEST_BINARY", "target/debug/ferese")
log_path = root / "compositor.log"
with log_path.open("w") as log:
compositor = subprocess.Popen(
[str(binary), "--backend", "nested", "--grant-effects", "--", str(client)],
env=ipc_environment(env), stdout=log, stderr=log,
)
try:
deadline = time.monotonic() + 30
while log_path.read_text().splitlines().count("close") < 3:
self.assertIsNone(compositor.poll(), log_path.read_text())
if time.monotonic() >= deadline:
self.fail("Blurred popup stopped presenting frames:\n" + log_path.read_text())
time.sleep(.025)
control = repo / os.environ.get("FERESE_TEST_CTL", "target/debug/feresectl")
subprocess.run([str(control), "-j", "outputs"], env=ipc_environment(env), check=True,
stdout=subprocess.DEVNULL, timeout=5)
phases = log_path.read_text().splitlines()
for name, count in [("parent", 1), ("open", 3), ("update", 9), ("close", 3)]:
self.assertEqual(phases.count(name), count, log_path.read_text())
finally:
if compositor.poll() is None:
compositor.terminate()
try:
compositor.wait(timeout=5)
except subprocess.TimeoutExpired:
compositor.kill()
compositor.wait()
if __name__ == "__main__":
unittest.main()