Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
173
tools/check-desktop.py
Normal file
173
tools/check-desktop.py
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Run desktop integration and restart checks on a private X11 display."""
|
||||
|
||||
import argparse
|
||||
import importlib.util
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from marionette_client import Client
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--candidate", action="store_true")
|
||||
parser.add_argument(
|
||||
"--phase",
|
||||
action="append",
|
||||
choices=["first", "feedback", "apps", "platform", "languages", "restart"],
|
||||
help="Run only the selected phase(s)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
for command in ["Xvfb", "xdotool", "import"]:
|
||||
if not shutil.which(command):
|
||||
sys.exit("Dépendance de test absente : " + command)
|
||||
extra = ["--candidate"] if args.candidate else []
|
||||
for port in [2857, 8765]:
|
||||
with socket.socket() as probe:
|
||||
probe.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
try:
|
||||
probe.bind(("127.0.0.1", port))
|
||||
except OSError:
|
||||
sys.exit(f"Port {port} occupé : fermer le laboratoire actuel avant les tests.")
|
||||
(ROOT / "logs").mkdir(exist_ok=True)
|
||||
with tempfile.TemporaryFile() as display_file, (ROOT / "logs/xvfb.log").open("w") as log:
|
||||
xserver = subprocess.Popen(
|
||||
[
|
||||
"Xvfb",
|
||||
"-displayfd",
|
||||
str(display_file.fileno()),
|
||||
"-screen",
|
||||
"0",
|
||||
"800x1000x24",
|
||||
"-nolisten",
|
||||
"tcp",
|
||||
],
|
||||
pass_fds=(display_file.fileno(),),
|
||||
stdout=log,
|
||||
stderr=log,
|
||||
)
|
||||
try:
|
||||
import time
|
||||
|
||||
for _ in range(100):
|
||||
display_file.seek(0)
|
||||
display = display_file.read().decode().strip()
|
||||
if display:
|
||||
break
|
||||
if xserver.poll() is not None:
|
||||
sys.exit("Xvfb a échoué : logs/xvfb.log")
|
||||
time.sleep(0.05)
|
||||
else:
|
||||
sys.exit("Xvfb ne répond pas")
|
||||
env = os.environ.copy()
|
||||
env.update(DISPLAY=":" + display, GDK_BACKEND="x11", MOZ_ENABLE_WAYLAND="0")
|
||||
for phase in args.phase or [
|
||||
"first",
|
||||
"feedback",
|
||||
"apps",
|
||||
"platform",
|
||||
"languages",
|
||||
"restart",
|
||||
]:
|
||||
with (ROOT / "logs" / ("desktop-" + phase + ".log")).open("w") as output:
|
||||
host = subprocess.Popen(
|
||||
[sys.executable, str(ROOT / "tools/run-host.py"), "--test", *extra],
|
||||
env=env,
|
||||
stdout=output,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
connected = False
|
||||
try:
|
||||
# Wait for Marionette initialization before opening the suite.
|
||||
with Client(2857) as client:
|
||||
spec = importlib.util.spec_from_file_location("probe", ROOT / "tools/probe-desktop.py")
|
||||
probe = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(probe)
|
||||
probe.register(client)
|
||||
for _ in range(200):
|
||||
ready = probe.evaluate(client, "system", "return document.body?.getAttribute('ready-state')==='fullyLoaded';")
|
||||
if ready.get("value"):
|
||||
break
|
||||
time.sleep(.1)
|
||||
else:
|
||||
raise RuntimeError("Gaia did not finish loading")
|
||||
# Wake before unlocking: waking can activate the lockscreen.
|
||||
probe.evaluate(client, "system", "ScreenManager.turnScreenOn(true);return true;")
|
||||
time.sleep(.5)
|
||||
probe.evaluate(client, "system", "lockScreen.unlock(true);return true;")
|
||||
time.sleep(.5)
|
||||
connected = True
|
||||
# The ownership test deliberately removes Gaia's iframe.
|
||||
# Start the UI regressions in a fresh process, preserving data.
|
||||
if phase in ["first", "restart"]:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "tools/test-host.py"),
|
||||
*extra,
|
||||
*(["--restart-check"] if phase == "restart" else []),
|
||||
],
|
||||
env=env,
|
||||
check=True,
|
||||
)
|
||||
if phase in ["feedback", "restart"]:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "tools/test-feedback.py"),
|
||||
*(["--restart-check"] if phase == "restart" else []),
|
||||
],
|
||||
env=env,
|
||||
check=True,
|
||||
)
|
||||
if phase in ["apps", "restart"]:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "tools/test-apps.py"),
|
||||
*(["--restart-check"] if phase == "restart" else []),
|
||||
],
|
||||
env=env,
|
||||
check=True,
|
||||
)
|
||||
if phase == "platform":
|
||||
subprocess.run(
|
||||
[sys.executable, str(ROOT / "tools/test-camera.py")],
|
||||
env=env,
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(
|
||||
[sys.executable, str(ROOT / "tools/test-platform.py")],
|
||||
env=env,
|
||||
check=True,
|
||||
)
|
||||
if phase in ["languages", "restart"]:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "tools/test-languages.py"),
|
||||
*(["--restart-check"] if phase == "restart" else []),
|
||||
],
|
||||
env=env,
|
||||
check=True,
|
||||
)
|
||||
finally:
|
||||
try:
|
||||
if connected:
|
||||
with Client(2857) as client:
|
||||
client.call("Marionette:Quit", {"flags": ["eAttemptQuit"]})
|
||||
finally:
|
||||
try:
|
||||
host.wait(timeout=15)
|
||||
except subprocess.TimeoutExpired:
|
||||
host.terminate()
|
||||
host.wait(timeout=10)
|
||||
if host.returncode:
|
||||
sys.exit("Le lanceur a échoué, consulter logs/desktop-" + phase + ".log")
|
||||
finally:
|
||||
xserver.terminate()
|
||||
xserver.wait(timeout=10)
|
||||
Loading…
Reference in a new issue