mirror of
https://github.com/aaddrick/claude-desktop-debian.git
synced 2026-05-17 00:26:21 +03:00
test: add headless launch + --doctor smoke tests for AppImage artifact (#592)
The AppImage artifact test only validated package structure (extraction, AppDir layout, asar contents) — runtime regressions like frame-fix-wrapper syntax errors, bad asar patches, or Electron startup crashes silently passed CI. The .deb path already ran `--doctor` as a smoke check; the AppImage path now has parity plus a 10s headless launch under Xvfb. `setsid` + `kill -- -PGID` is load-bearing: xvfb-run's EXIT trap leaks Xvfb on signal kill, so running the whole stack in its own process group lets the teardown reap xvfb-run, Xvfb, dbus, AppRun, electron, and zygote children together. `procps` (for pkill), `dbus-x11`, and `xvfb` added to the CI apt line. The headless probe catches main-process startup failures only — GPU / renderer-process crashes like #583 leave the main process alive and pass this check; that scope disclaimer is inlined at test-artifact-appimage.sh lines 114-117 so future contributors don't try to claim #583 coverage by switching Xvfb off. Co-authored-by: Sum Abiut <sabiut@users.noreply.github.com>
This commit is contained in:
3
.github/workflows/test-artifacts.yml
vendored
3
.github/workflows/test-artifacts.yml
vendored
@@ -44,7 +44,8 @@ jobs:
|
||||
if: matrix.format != 'rpm'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y file libfuse2 nodejs npm
|
||||
sudo apt-get install -y file libfuse2 nodejs npm \
|
||||
xvfb dbus-x11 procps
|
||||
|
||||
- name: Run artifact tests
|
||||
run: |
|
||||
|
||||
85
tests/test-artifact-appimage.sh
Normal file → Executable file
85
tests/test-artifact-appimage.sh
Normal file → Executable file
@@ -96,6 +96,91 @@ assert_contains "$appdir/AppRun" 'build_electron_args' \
|
||||
resources_dir="$appdir/usr/lib/node_modules/electron/dist/resources"
|
||||
validate_app_contents "$resources_dir" "${component_id}.desktop"
|
||||
|
||||
# --- Doctor smoke test ---
|
||||
# Some --doctor checks fail in CI (no display, etc.); we only care that
|
||||
# the script itself didn't crash via signal or exec failure (>=127).
|
||||
doctor_exit=0
|
||||
"$appimage_file" --doctor >/dev/null 2>&1 || doctor_exit=$?
|
||||
if [[ $doctor_exit -lt 127 ]]; then
|
||||
pass "--doctor runs without crashing (exit: $doctor_exit)"
|
||||
else
|
||||
fail "--doctor crashed (exit: $doctor_exit)"
|
||||
fi
|
||||
|
||||
# --- Headless launch smoke test ---
|
||||
# Catches startup-only regressions (asar/frame-fix-wrapper syntax errors)
|
||||
# that pure structure checks miss.
|
||||
#
|
||||
# Scope: main-process startup failures only. GPU/renderer-process
|
||||
# crashes (e.g. #583-class) leave the main process alive and pass
|
||||
# this check — Xvfb has no GPU, so Electron falls back to SwiftShader
|
||||
# and the GPU-crash path isn't exercised here.
|
||||
if command -v xvfb-run &>/dev/null \
|
||||
&& command -v dbus-run-session &>/dev/null \
|
||||
&& command -v setsid &>/dev/null; then
|
||||
|
||||
# XDG_CACHE_HOME redirect so the test owns the launcher log.
|
||||
cache_root=$(mktemp -d)
|
||||
export XDG_CACHE_HOME="$cache_root"
|
||||
launcher_log="$cache_root/claude-desktop-debian/launcher.log"
|
||||
|
||||
# setsid puts xvfb-run + Xvfb + dbus + AppRun + electron in a fresh
|
||||
# process group; xvfb-run's EXIT trap alone leaves Xvfb behind on
|
||||
# TERM, so we need kill -- -PGID below.
|
||||
# AppRun redirects electron's stdout/stderr into launcher_log;
|
||||
# xvfb_log captures xvfb-run's own stderr.
|
||||
xvfb_log=$(mktemp)
|
||||
setsid xvfb-run -a -s '-screen 0 1280x720x24' \
|
||||
dbus-run-session -- "$appimage_file" \
|
||||
>"$xvfb_log" 2>&1 &
|
||||
launch_pid=$!
|
||||
|
||||
# Safety net: covers Ctrl-C, CI timeout, or any earlier `exit` so we
|
||||
# never leak Xvfb/electron between launch and the explicit kill below.
|
||||
trap '
|
||||
kill -KILL -- "-$launch_pid" 2>/dev/null
|
||||
pkill -KILL -f "$appimage_file" 2>/dev/null
|
||||
rm -rf "$cache_root" "$xvfb_log"
|
||||
' EXIT INT TERM
|
||||
|
||||
# CI is slow; 10s is the floor for Electron startup.
|
||||
sleep 10
|
||||
|
||||
if kill -0 "$launch_pid" 2>/dev/null; then
|
||||
pass "AppImage stays alive under Xvfb for 10s"
|
||||
else
|
||||
wait "$launch_pid" 2>/dev/null
|
||||
exit_code=$?
|
||||
fail "AppImage exited within 10s (exit: $exit_code)"
|
||||
if [[ -f $launcher_log ]]; then
|
||||
echo '--- launcher.log (last 40 lines) ---' >&2
|
||||
tail -40 "$launcher_log" >&2
|
||||
echo '------------------------------------' >&2
|
||||
fi
|
||||
if [[ -s $xvfb_log ]]; then
|
||||
echo '--- xvfb-run stderr (last 20 lines) ---' >&2
|
||||
tail -20 "$xvfb_log" >&2
|
||||
echo '---------------------------------------' >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Negative PID targets the process group.
|
||||
kill -TERM -- "-$launch_pid" 2>/dev/null || true
|
||||
sleep 1
|
||||
kill -KILL -- "-$launch_pid" 2>/dev/null || true
|
||||
wait "$launch_pid" 2>/dev/null || true
|
||||
# Sweep any electron child that escaped the group (e.g. zygote).
|
||||
pkill -KILL -f "$appimage_file" 2>/dev/null || true
|
||||
|
||||
rm -rf "$cache_root" "$xvfb_log"
|
||||
unset XDG_CACHE_HOME
|
||||
else
|
||||
# Match the codebase convention (test-artifact-common.sh
|
||||
# validate_app_contents): tool absence is a skip, not a failure.
|
||||
# Loud failure on missing tools belongs at the workflow layer.
|
||||
pass "Skipping launch smoke test (xvfb-run/dbus-run-session/setsid missing)"
|
||||
fi
|
||||
|
||||
# --- Cleanup ---
|
||||
rm -rf "$extract_dir"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user