Running pytest against a stale build/ binary silently proved nothing: test.sh and test-headless.sh now run build.sh first, and build.sh skips meson setup/compile when both binaries are newer than their sources (tracked per program: kick.c feeds kick, tests/wltest.c feeds wltest, meson.build and subprojects feed both).
106 lines
No EOL
3.3 KiB
Bash
Executable file
106 lines
No EOL
3.3 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
# Run the pytest suite with no window appearing on the desktop.
|
|
#
|
|
# The nested tests open the compositor's single host window on the ambient
|
|
# Wayland session. This wrapper re-hosts that window inside an invisible
|
|
# headless compositor: a second, standalone instance of the same binary
|
|
# (KICK_MODE=standalone WLR_BACKENDS=headless) whose output is shown
|
|
# nowhere. WAYLAND_DISPLAY is pointed at that headless host for the pytest
|
|
# run, so every nested session maps its window inside the headless scene
|
|
# instead of flashing on the real desktop.
|
|
#
|
|
# The headless host exposes wlr-data-control and wl_data_device, so the
|
|
# clipboard tests exercise the (preferred) data-control bridge rather than
|
|
# the focus-based one; the focus bridge is keyed to your real compositor
|
|
# granting the window focus, which no headless host does.
|
|
|
|
set -e
|
|
|
|
cd "$(dirname "$0")"
|
|
|
|
./build.sh
|
|
|
|
BIN=build/kick
|
|
WL=build/wltest
|
|
HOST_LOG=/tmp/kick-headless-host.log
|
|
|
|
for p in "$BIN" "$WL"; do
|
|
if [ ! -x "$p" ]; then
|
|
echo "test-headless.sh: build first: $p" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
rm -f "$HOST_LOG"
|
|
|
|
# One invisible tab so the host never exits on its own; the quotes make it a
|
|
# single CLI tab ("wltest '#112233'"), not a bare command plus a stray arg.
|
|
host_tab="$WL '#112233'"
|
|
|
|
# A real font, mirroring _pick_font() in tests/test_smoke.py.
|
|
font="${KICK_FONT:-}"
|
|
if [ -z "$font" ]; then
|
|
for f in \
|
|
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf \
|
|
/usr/share/fonts/dejavu/DejaVuSans.ttf \
|
|
/usr/share/fonts/TTF/DejaVuSans.ttf \
|
|
/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf \
|
|
/usr/share/fonts/liberation/LiberationSans-Regular.ttf \
|
|
/usr/share/fonts/noto/NotoSans-Regular.ttf; do
|
|
if [ -f "$f" ]; then
|
|
font="$f"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# env -i so the host never sees the desktop WAYLAND_DISPLAY: inheriting it
|
|
# would make the "standalone" host go nested instead and open its own visible
|
|
# window. This mirrors the standalone_session fixture's environment. The
|
|
# subshell keeps "$@" (the pytest args) untouched.
|
|
(
|
|
export PATH="$PATH" \
|
|
HOME="${HOME:-/}" \
|
|
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp}" \
|
|
XDG_DATA_HOME="${XDG_DATA_HOME:-}" \
|
|
XDG_DATA_DIRS="${XDG_DATA_DIRS:-}" \
|
|
KICK_LOG=2 \
|
|
KICK_MODE=standalone \
|
|
WLR_BACKENDS=headless \
|
|
KICK_FONT="$font" \
|
|
XCURSOR_THEME=Adwaita
|
|
unset WAYLAND_DISPLAY
|
|
exec stdbuf -oL "$BIN" "$host_tab"
|
|
) >"$HOST_LOG" 2>&1 &
|
|
host_pid=$!
|
|
|
|
cleanup() {
|
|
kill -TERM "$host_pid" 2>/dev/null || true
|
|
wait "$host_pid" 2>/dev/null || true
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
socket=
|
|
deadline=$(( $(date +%s) + 60 ))
|
|
while [ -z "$socket" ]; do
|
|
if ! kill -0 "$host_pid" 2>/dev/null; then
|
|
echo "test-headless.sh: headless host died:" >&2
|
|
cat "$HOST_LOG" >&2
|
|
exit 1
|
|
fi
|
|
socket=$(sed -n 's/.*Wayland socket: \(kick-[0-9][0-9]*\).*/\1/p' \
|
|
"$HOST_LOG" | tail -n 1)
|
|
if [ -z "$socket" ] && [ "$(date +%s)" -ge "$deadline" ]; then
|
|
echo "test-headless.sh: timed out waiting for the headless host socket:" >&2
|
|
cat "$HOST_LOG" >&2
|
|
exit 1
|
|
fi
|
|
[ -z "$socket" ] && sleep 0.2
|
|
done
|
|
|
|
export WAYLAND_DISPLAY="$socket"
|
|
|
|
pytest -v "$@"
|
|
status=$?
|
|
exit $status |