#!/usr/bin/env python3 """Test public window behavior on isolated display servers.""" import os from pathlib import Path import subprocess import sys import tempfile import time def wait_for(process, ready): deadline = time.monotonic() + 10 while time.monotonic() < deadline: if process.poll() is not None: raise RuntimeError("The display server stopped.") if ready(): return time.sleep(0.02) raise TimeoutError("The display server did not start.") def main(): weston, xwayland, test, timers = sys.argv[1:] servers = [] with tempfile.TemporaryDirectory(prefix="yasl-backends-") as directory: root = Path(directory) env = os.environ.copy() env.pop("WAYLAND_SOCKET", None) env.update(XDG_RUNTIME_DIR=directory, WAYLAND_DISPLAY="yasl-test", XDG_SESSION_TYPE="wayland") with (root / "weston.log").open("w+") as wl_log, \ (root / "xwayland.log").open("w+") as x_log: try: wl = subprocess.Popen([ weston, "--backend=headless", "--renderer=pixman", "--socket=yasl-test", "--idle-time=0", "--no-config", ], env=env, stdout=wl_log, stderr=wl_log) servers.append(wl) wait_for(wl, lambda: (root / "yasl-test").is_socket()) display_file = root / "display" with display_file.open("w") as display_fd: x = subprocess.Popen([ xwayland, "-displayfd", str(display_fd.fileno()), "-shm", "-noreset", "-nolisten", "tcp", ], env=env, pass_fds=(display_fd.fileno(),), stdout=x_log, stderr=x_log) servers.append(x) wait_for(x, lambda: bool(display_file.read_text().strip())) env["DISPLAY"] = ":" + display_file.read_text().strip() def run(mode, request=None, expected=None, **changes): case_env = env.copy() for key, value in changes.items(): if value is None: case_env.pop(key, None) else: case_env[key] = value args = [test, mode] if request is not None: args.append(str(request)) if expected is not None: args.append(str(expected)) print("Test:", mode, request, expected, changes, flush=True) subprocess.run(args, env=case_env, check=True, timeout=8) run("open", 1, 1) run("open", 2, 2) run("open", 0, 1) run("null", 0, 1) run("open", 0, 2, WAYLAND_DISPLAY=None, XDG_SESSION_TYPE="x11") run("open", 0, 2, WAYLAND_DISPLAY="missing-socket") run("failure", 1, WAYLAND_DISPLAY="missing-socket") run("failure", 2, DISPLAY=":59999") run("failure", 0, WAYLAND_DISPLAY="missing-socket", DISPLAY=":59999") run("mixed") print("Test: Wayland surface timers", flush=True) subprocess.run([timers], env=env, check=True, timeout=8) x_env = env.copy() x_env.pop("WAYLAND_DISPLAY", None) x_env["XDG_SESSION_TYPE"] = "x11" print("Test: X11 surface timers", flush=True) subprocess.run([timers], env=x_env, check=True, timeout=8) except BaseException: for log in (wl_log, x_log): log.flush() log.seek(0) print(log.read(), file=sys.stderr) raise finally: for server in reversed(servers): server.terminate() try: server.wait(timeout=5) except subprocess.TimeoutExpired: server.kill() server.wait() if __name__ == "__main__": main()