Fix config upgrade failures, save races, lock confirmation and release validation (#23)

* Coordinate config writes and gate releases on desktop validation

* Use toolkit rc.2 with painting and session lock fixes

* Ignore retired desktop widget settings in existing configs
This commit is contained in:
Samuel Onoja authored and GitHub committed 2026-10-11 12:15:28 +01:00
1 parent a447136b01
commit 91e2f227d2
18 files changed
+536 -155

No files matched your search

+47 -22
View File
@@ -1,4 +1,4 @@
"""Run native regressions against a private, headless Weston instance."""
"""Run native regressions on a private software-rendered Weston host."""
import argparse
import os
from pathlib import Path
@@ -9,22 +9,34 @@ import tempfile
import time
def stop(process):
if process.poll() is None:
os.killpg(process.pid, signal.SIGINT)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait(timeout=5)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--log-dir", type=Path, required=True)
parser.add_argument("--suite", choices=("panel-xwayland", "desktop"), default="panel-xwayland")
args = parser.parse_args()
logs = args.log_dir.resolve()
logs.mkdir(parents=True, exist_ok=True)
repo = Path(__file__).resolve().parents[2]
# No inherited session endpoints or activation settings reach the test host.
env = {key: value for key, value in os.environ.items()
if not key.startswith("FERESE_") or key.startswith("FERESE_TEST_")}
for key in ("DISPLAY", "WAYLAND_DISPLAY", "WAYLAND_SOCKET", "XAUTHORITY",
"DBUS_SESSION_BUS_ADDRESS", "DBUS_SESSION_BUS_PID", "EGL_PLATFORM"):
env.pop(key, None)
env.update(LIBGL_ALWAYS_SOFTWARE="1", FERESE_TEST_LOG_DIR=str(logs))
for key, value in {"FERESE_TEST_BINARY": "target/debug/ferese",
"FERESE_TEST_CTL": "target/debug/feresectl",
"FERESE_TEST_SHELL": "target/debug/ferese-shell"}.items():
env.setdefault(key, value)
with tempfile.TemporaryDirectory(prefix="ferese-native-host-") as temporary:
root = Path(temporary)
runtime = root / "runtime"
@@ -34,9 +46,10 @@ def main():
XDG_CACHE_HOME=str(root / "cache"))
with (logs / "weston.log").open("w") as log:
host = subprocess.Popen([
env.get("FERESE_TEST_WESTON", "weston"), "--backend=headless-backend.so",
"--renderer=pixman", "--width=1600", "--height=1000",
"--socket=ferese-test-host", "--idle-time=0", "--no-config",
env.get("FERESE_TEST_WESTON", "weston"),
"--backend=headless-backend.so", "--renderer=pixman",
"--width=1600", "--height=1000", "--socket=ferese-test-host",
"--idle-time=0", "--no-config",
], env=env, stdout=log, stderr=log, start_new_session=True)
try:
deadline = time.monotonic() + 15
@@ -44,22 +57,34 @@ def main():
if host.poll() is not None or time.monotonic() >= deadline:
raise RuntimeError((logs / "weston.log").read_text())
time.sleep(.05)
for layout in ("continuous", "islands"):
subprocess.run([
sys.executable, "scripts/tests/test_shell_motion_isolated.py", "-v",
], cwd=repo, env=dict(env, FERESE_TEST_SHELL_MOTION="1",
FERESE_TEST_BAR_LAYOUT=layout), check=True)
subprocess.run([
sys.executable, "scripts/tests/test_xwayland_isolated.py", "-v",
], cwd=repo, env=dict(env, FERESE_TEST_XWAYLAND="1"), check=True)
cases = [
("shell-continuous", "shell_motion", {"FERESE_TEST_SHELL_MOTION": "1", "FERESE_TEST_BAR_LAYOUT": "continuous"}),
("shell-islands", "shell_motion", {"FERESE_TEST_SHELL_MOTION": "1", "FERESE_TEST_BAR_LAYOUT": "islands"}),
]
if args.suite == "desktop":
cases.insert(0, ("lock", "lock", {"FERESE_TEST_LOCK": "1", "FERESE_TEST_BIN_DIR": "target/debug"}))
cases.extend([
("presentation", "presentation", {"FERESE_TEST_PRESENTATION": "1"}),
("resize", "resize_dependencies", {"FERESE_TEST_RESIZE": "1"}),
])
else:
cases.append(("xwayland", "xwayland", {"FERESE_TEST_XWAYLAND": "1"}))
for name, script, options in cases:
print(f"Running {name}", flush=True)
with (logs / f"{name}-test.log").open("w") as output:
test = subprocess.Popen([
sys.executable, f"scripts/tests/test_{script}_isolated.py", "-v",
], cwd=repo, env=dict(env, **options), stdout=output, stderr=output,
start_new_session=True)
try:
status = test.wait(timeout=180)
if status:
raise RuntimeError((logs / f"{name}-test.log").read_text())
finally:
stop(test)
print(f"Passed {name}", flush=True)
finally:
if host.poll() is None:
os.killpg(host.pid, signal.SIGTERM)
try:
host.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(host.pid, signal.SIGKILL)
host.wait(timeout=5)
stop(host)
if __name__ == "__main__":