Files
trycua--cua/scripts/ci/linux/run-rust-e2e-wayland.sh
wehub-resource-sync 91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:19 +08:00

220 lines
7.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Start one native, headless Sway session and run the complete Rust E2E matrix.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
RUNTIME_DIR="$(mktemp -d)"
SWAY_CONFIG="$(mktemp)"
SESSION_KIND="${CUA_E2E_WAYLAND_SESSION:-sway}"
COMPOSITOR_LOG="${REPO_ROOT}/artifacts/cua-driver/linux/${SESSION_KIND}.log"
ATSPI_LOG="${REPO_ROOT}/artifacts/cua-driver/linux/at-spi-bus.log"
COMPOSITOR_PID=""
DBUS_PID=""
ATSPI_PID=""
cleanup() {
if [[ -n "${COMPOSITOR_PID}" ]]; then
kill "${COMPOSITOR_PID}" 2>/dev/null || true
wait "${COMPOSITOR_PID}" 2>/dev/null || true
fi
if [[ -n "${DBUS_PID}" ]]; then
kill "${DBUS_PID}" 2>/dev/null || true
fi
if [[ -n "${ATSPI_PID}" ]]; then
kill "${ATSPI_PID}" 2>/dev/null || true
wait "${ATSPI_PID}" 2>/dev/null || true
fi
rm -f "${SWAY_CONFIG}"
}
trap cleanup EXIT
mkdir -p "$(dirname "${COMPOSITOR_LOG}")"
chmod 700 "${RUNTIME_DIR}"
cat > "${SWAY_CONFIG}" <<'EOF'
xwayland disable
output HEADLESS-1 mode 1920x1080
seat seat0 fallback true
focus_follows_mouse no
default_border none
default_floating_border none
for_window [title="^CuaTestHarness"] floating enable, resize set 940 780, move position 0 0
for_window [title="CuaTestHarness Sentinel"] fullscreen enable
EOF
unset DISPLAY
unset WAYLAND_DISPLAY
export XDG_RUNTIME_DIR="${RUNTIME_DIR}"
export XDG_SESSION_TYPE=wayland
export XDG_CURRENT_DESKTOP=sway
export XDG_SESSION_DESKTOP=sway
export WLR_BACKENDS=headless
export WLR_RENDERER=pixman
export WLR_RENDERER_ALLOW_SOFTWARE=1
export WLR_LIBINPUT_NO_DEVICES=1
export WLR_HEADLESS_OUTPUTS=1
export CUA_DRIVER_RS_ENABLE_WAYLAND=1
if [[ "${SESSION_KIND}" == cua-compositor ]]; then
export CUA_E2E_COMPOSITOR=cua-compositor-nested
export CUA_E2E_INPUT_BACKENDS=atspi,cua-compositor-inject
export CUA_E2E_HARNESS_FILTER=electron
export CUA_INJECT_SOCKET="${XDG_RUNTIME_DIR}/cua-inject.sock"
else
export CUA_E2E_COMPOSITOR=sway
export CUA_E2E_INPUT_BACKENDS=atspi,wlr-virtual-pointer
fi
export CUA_WAYLAND_RECORDING_OUTPUT=HEADLESS-1
export ELECTRON_OZONE_PLATFORM_HINT=wayland
export GDK_BACKEND=wayland
export QT_QPA_PLATFORM=wayland
# WebKitGTK's accelerated compositor requires a DRM render node. The canonical
# hosted lane has none, so keep its best-effort software settings explicit;
# native-Wayland WebKit coverage runs on the representative GNOME/KDE VMs.
export WEBKIT_DISABLE_COMPOSITING_MODE=1
export WEBKIT_DISABLE_DMABUF_RENDERER=1
# This isolated CI session uses a private runtime directory and no user home
# namespaces. Modern WebKitGTK ignores WEBKIT_FORCE_SANDBOX; use its explicit
# test-only escape hatch so the WebProcess can publish its AT-SPI subtree.
export WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1
export NO_AT_BRIDGE=0
export ACCESSIBILITY_ENABLED=1
if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
dbus_daemon="$(command -v dbus-daemon)"
dbus_prefix="$(dirname "$(dirname "$(readlink -f "${dbus_daemon}")")")"
dbus_config="${dbus_prefix}/share/dbus-1/session.conf"
if [[ ! -f "${dbus_config}" ]]; then
echo "DBus session config is missing: ${dbus_config}" >&2
exit 1
fi
dbus_info="$(dbus-daemon --config-file="${dbus_config}" --fork --print-address=1 --print-pid=1)"
export DBUS_SESSION_BUS_ADDRESS="$(sed -n '1p' <<< "${dbus_info}")"
DBUS_PID="$(sed -n '2p' <<< "${dbus_info}")"
fi
# A private session bus does not activate the desktop accessibility stack by
# itself. Start the repo-pinned AT-SPI launcher, then require org.a11y.Bus to
# answer before any fixture or driver process inherits this session.
ATSPI_LAUNCHER="${CUA_AT_SPI_BUS_LAUNCHER:-$(command -v at-spi-bus-launcher || true)}"
if [[ ! -x "${ATSPI_LAUNCHER}" ]]; then
echo "AT-SPI bus launcher is unavailable: ${ATSPI_LAUNCHER:-<not found>}" >&2
exit 1
fi
"${ATSPI_LAUNCHER}" --launch-immediately > "${ATSPI_LOG}" 2>&1 &
ATSPI_PID=$!
deadline=$((SECONDS + 15))
while ((SECONDS < deadline)); do
if ! kill -0 "${ATSPI_PID}" 2>/dev/null; then
echo "AT-SPI bus launcher exited before org.a11y.Bus became ready" >&2
cat "${ATSPI_LOG}" >&2
exit 1
fi
if gdbus call --session \
--dest org.a11y.Bus \
--object-path /org/a11y/bus \
--method org.a11y.Bus.GetAddress >/dev/null 2>&1; then
break
fi
sleep 0.2
done
if ! gdbus call --session \
--dest org.a11y.Bus \
--object-path /org/a11y/bus \
--method org.a11y.Bus.GetAddress >/dev/null 2>&1; then
echo "org.a11y.Bus did not become ready within 15 seconds" >&2
cat "${ATSPI_LOG}" >&2
exit 1
fi
# The bus launcher and the registry daemon are separate services. Resolve the
# private accessibility bus and require the registry to activate on it before
# any toolkit inherits this session.
a11y_address="$(
gdbus call --session \
--dest org.a11y.Bus \
--object-path /org/a11y/bus \
--method org.a11y.Bus.GetAddress \
| sed -e "s/^('//" -e "s/',)$//"
)"
export AT_SPI_BUS_ADDRESS="${a11y_address}"
if [[ -z "${a11y_address}" ]] || ! gdbus call \
--address "${a11y_address}" \
--dest org.a11y.atspi.Registry \
--object-path /org/a11y/atspi/accessible/root \
--method org.freedesktop.DBus.Properties.Get \
org.a11y.atspi.Accessible ChildCount >/dev/null 2>&1; then
echo "AT-SPI registry did not activate on the accessibility bus" >&2
cat "${ATSPI_LOG}" >&2
exit 1
fi
if ! gdbus call --session \
--dest org.a11y.Bus \
--object-path /org/a11y/bus \
--method org.freedesktop.DBus.Properties.Set \
org.a11y.Status IsEnabled '<true>' >/dev/null 2>&1; then
echo "Could not enable accessibility on org.a11y.Bus" >&2
cat "${ATSPI_LOG}" >&2
exit 1
fi
if [[ "${SESSION_KIND}" == cua-compositor ]]; then
command -v cua-compositor >/dev/null || {
echo "cua-compositor is required for the nested injection lane" >&2
exit 1
}
cua-compositor > "${COMPOSITOR_LOG}" 2>&1 &
else
sway --unsupported-gpu --config "${SWAY_CONFIG}" > "${COMPOSITOR_LOG}" 2>&1 &
fi
COMPOSITOR_PID=$!
deadline=$((SECONDS + 20))
while ((SECONDS < deadline)); do
if ! kill -0 "${COMPOSITOR_PID}" 2>/dev/null; then
echo "${SESSION_KIND} exited before its Wayland socket became ready" >&2
cat "${COMPOSITOR_LOG}" >&2
exit 1
fi
socket="$(find "${XDG_RUNTIME_DIR}" -maxdepth 1 -type s -name 'wayland-*' -print -quit)"
if [[ -n "${socket}" ]]; then
export WAYLAND_DISPLAY="$(basename "${socket}")"
break
fi
sleep 0.2
done
if [[ -z "${WAYLAND_DISPLAY:-}" ]]; then
echo "${SESSION_KIND} did not create a Wayland socket within 20 seconds" >&2
cat "${COMPOSITOR_LOG}" >&2
exit 1
fi
if [[ "${SESSION_KIND}" == cua-compositor ]]; then
deadline=$((SECONDS + 10))
while [[ ! -S "${CUA_INJECT_SOCKET}" ]] && ((SECONDS < deadline)); do
sleep 0.2
done
if [[ ! -S "${CUA_INJECT_SOCKET}" ]]; then
echo "cua-compositor did not expose its injection socket" >&2
cat "${COMPOSITOR_LOG}" >&2
exit 1
fi
else
export SWAYSOCK="$(find "${XDG_RUNTIME_DIR}" -maxdepth 1 -type s -name 'sway-ipc.*.sock' -print -quit)"
if [[ -z "${SWAYSOCK}" ]]; then
echo "Sway did not expose its IPC socket" >&2
cat "${COMPOSITOR_LOG}" >&2
exit 1
fi
fi
echo "Native Wayland E2E session: ${SESSION_KIND} on ${WAYLAND_DISPLAY}"
set +e
"${SCRIPT_DIR}/run-rust-e2e.sh" "$@"
status=$?
set -e
if [[ "${status}" != 0 && "${SESSION_KIND}" == sway ]]; then
swaymsg -t get_tree > "${REPO_ROOT}/artifacts/cua-driver/linux/sway-tree.json" 2>/dev/null || true
fi
exit "${status}"