Files
eco_os/isotest/run-test.sh

266 lines
8.2 KiB
Bash
Raw Permalink Normal View History

2026-01-08 18:33:14 +00:00
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
2026-01-10 08:42:37 +00:00
# Parse arguments
AUTO_MODE=false
for arg in "$@"; do
case $arg in
--auto)
AUTO_MODE=true
shift
;;
esac
done
2026-01-08 18:33:14 +00:00
PROJECT_ROOT="$SCRIPT_DIR/.."
VM_DIR="$PROJECT_ROOT/.nogit/vm"
ISO_PATH="$PROJECT_ROOT/.nogit/iso/ecoos.iso"
DISK_PATH="$VM_DIR/test-disk.qcow2"
MONITOR_SOCK="$VM_DIR/qemu-monitor.sock"
SERIAL_SOCK="$VM_DIR/serial.sock"
SERIAL_LOG="$VM_DIR/serial.log"
PID_FILE="$VM_DIR/qemu.pid"
# Create VM directory if not exists
mkdir -p "$VM_DIR"
# Check if ISO exists
if [ ! -f "$ISO_PATH" ]; then
echo "ERROR: ISO not found at $ISO_PATH"
echo "Run 'pnpm run build' first to create the ISO"
exit 1
fi
# Create test disk if not exists
if [ ! -f "$DISK_PATH" ]; then
echo "Creating test disk (20GB)..."
qemu-img create -f qcow2 "$DISK_PATH" 20G
fi
# Check if already running
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
echo "QEMU already running (PID: $PID)"
echo "Run 'pnpm run test:stop' to stop it first"
exit 1
fi
fi
echo "Starting QEMU with EcoOS ISO..."
# Check if KVM is available
KVM_OPTS=""
if [ -e /dev/kvm ] && [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
KVM_OPTS="-enable-kvm -cpu host"
echo "Using KVM acceleration"
else
echo "KVM not available, using software emulation (slower)"
fi
2026-01-09 19:39:14 +00:00
# Cleanup function
cleanup() {
echo ""
echo "Shutting down..."
if [ -n "$SCREENSHOT_LOOP_PID" ] && kill -0 "$SCREENSHOT_LOOP_PID" 2>/dev/null; then
kill "$SCREENSHOT_LOOP_PID" 2>/dev/null || true
fi
if [ -n "$ENABLE_PID" ] && kill -0 "$ENABLE_PID" 2>/dev/null; then
kill "$ENABLE_PID" 2>/dev/null || true
fi
2026-01-09 19:39:14 +00:00
if [ -n "$VIEWER_PID" ] && kill -0 "$VIEWER_PID" 2>/dev/null; then
kill "$VIEWER_PID" 2>/dev/null || true
fi
2026-01-09 23:28:33 +00:00
if [ -n "$TWM_PID" ] && kill -0 "$TWM_PID" 2>/dev/null; then
kill "$TWM_PID" 2>/dev/null || true
fi
2026-01-09 19:45:25 +00:00
if [ -n "$XORG_PID" ] && kill -0 "$XORG_PID" 2>/dev/null; then
kill "$XORG_PID" 2>/dev/null || true
fi
2026-01-09 19:39:14 +00:00
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
kill "$PID" 2>/dev/null || true
fi
rm -f "$PID_FILE"
fi
echo "Done"
}
trap cleanup EXIT INT TERM
# Start QEMU with virtio-gpu multi-head (3 outputs)
2026-01-08 18:33:14 +00:00
> "$SERIAL_LOG" # Clear old log
qemu-system-x86_64 \
$KVM_OPTS \
-m 4G \
2026-01-09 09:41:47 +00:00
-smp 4 \
2026-01-08 18:33:14 +00:00
-bios /usr/share/qemu/OVMF.fd \
-drive file="$ISO_PATH",media=cdrom \
-drive file="$DISK_PATH",format=qcow2,if=virtio \
2026-01-09 23:28:33 +00:00
-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=64 \
-device qxl,id=video1,ram_size=67108864,vram_size=67108864,vgamem_mb=64 \
-device qxl,id=video2,ram_size=67108864,vram_size=67108864,vgamem_mb=64 \
2026-01-08 18:33:14 +00:00
-display none \
2026-01-09 09:41:47 +00:00
-spice port=5930,disable-ticketing=on \
2026-01-09 19:39:14 +00:00
-device virtio-serial-pci \
-chardev spicevmc,id=vdagent,name=vdagent \
-device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \
2026-01-08 18:33:14 +00:00
-serial unix:"$SERIAL_SOCK",server,nowait \
-monitor unix:"$MONITOR_SOCK",server,nowait \
-nic user,model=virtio-net-pci,hostfwd=tcp::3006-:3006,hostfwd=tcp::2222-:22 \
2026-01-09 09:41:47 +00:00
-pidfile "$PID_FILE" &
2026-01-08 18:33:14 +00:00
2026-01-09 19:39:14 +00:00
QEMU_PID=$!
2026-01-08 18:33:14 +00:00
echo ""
echo "=== EcoOS Test VM Started ==="
2026-01-09 19:39:14 +00:00
echo "QEMU PID: $QEMU_PID"
2026-01-08 18:33:14 +00:00
echo "Management UI: http://localhost:3006"
echo ""
2026-01-09 19:39:14 +00:00
# Wait for QEMU to start and SPICE to be ready
echo "Waiting for SPICE server..."
sleep 3
# Check if remote-viewer is available
if ! command -v remote-viewer &> /dev/null; then
echo "WARNING: remote-viewer not installed"
echo "Install with: sudo apt install virt-viewer"
echo ""
echo "Running without display viewer. Press Ctrl-C to stop."
wait $QEMU_PID
exit 0
fi
# Set up virt-viewer settings for multi-display
VIRT_VIEWER_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/virt-viewer"
mkdir -p "$VIRT_VIEWER_CONFIG_DIR"
if [ -f "$SCRIPT_DIR/virt-viewer-settings" ]; then
cp "$SCRIPT_DIR/virt-viewer-settings" "$VIRT_VIEWER_CONFIG_DIR/settings"
echo "Configured virt-viewer for 3 displays"
fi
2026-01-09 19:39:14 +00:00
# Detect DISPLAY if not set
if [ -z "$DISPLAY" ]; then
# Try to find an active X display
if [ -S /tmp/.X11-unix/X0 ]; then
export DISPLAY=:0
elif [ -S /tmp/.X11-unix/X1 ]; then
export DISPLAY=:1
fi
fi
# Detect WAYLAND_DISPLAY if not set
if [ -z "$WAYLAND_DISPLAY" ] && [ -z "$DISPLAY" ]; then
# Try common Wayland sockets
if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
export WAYLAND_DISPLAY=wayland-0
elif [ -S "/run/user/$(id -u)/wayland-0" ]; then
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
export WAYLAND_DISPLAY=wayland-0
fi
fi
2026-01-09 19:45:25 +00:00
# Launch remote-viewer - use dummy X server with 3 monitors if no display available
2026-01-09 19:39:14 +00:00
if [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ]; then
2026-01-09 19:45:25 +00:00
echo "No display found, starting headless X server with 3 virtual monitors..."
# Find an available display number
XDISPLAY=99
while [ -S "/tmp/.X11-unix/X$XDISPLAY" ]; do
XDISPLAY=$((XDISPLAY + 1))
done
# Start Xorg with dummy driver config for 3 monitors
XORG_CONFIG="$SCRIPT_DIR/xorg-dummy.conf"
Xorg :$XDISPLAY -config "$XORG_CONFIG" -noreset +extension GLX +extension RANDR +extension RENDER &
XORG_PID=$!
sleep 2
export DISPLAY=:$XDISPLAY
# Configure 3 virtual monitors using xrandr
# Add mode to disconnected DUMMY outputs and position them
xrandr --newmode "1920x1080" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync 2>/dev/null || true
# Add mode to DUMMY1 and DUMMY2, then enable them
xrandr --addmode DUMMY1 "1920x1080" 2>/dev/null || true
xrandr --addmode DUMMY2 "1920x1080" 2>/dev/null || true
# Position the outputs side by side
xrandr --output DUMMY0 --mode 1920x1080 --pos 0x0 --primary
xrandr --output DUMMY1 --mode 1920x1080 --pos 1920x0 2>/dev/null || true
xrandr --output DUMMY2 --mode 1920x1080 --pos 3840x0 2>/dev/null || true
2026-01-09 23:28:33 +00:00
echo "Headless X server started on :$XDISPLAY"
2026-01-09 19:45:25 +00:00
2026-01-09 23:28:33 +00:00
# Launch remote-viewer in fullscreen to request all monitors
2026-01-09 19:45:25 +00:00
remote-viewer --full-screen spice://localhost:5930 &
2026-01-09 19:39:14 +00:00
VIEWER_PID=$!
2026-01-09 19:45:25 +00:00
echo "remote-viewer running headlessly (PID: $VIEWER_PID)"
2026-01-09 19:39:14 +00:00
else
echo "Launching remote-viewer with fullscreen for multi-display (DISPLAY=$DISPLAY, WAYLAND_DISPLAY=$WAYLAND_DISPLAY)..."
remote-viewer --full-screen spice://localhost:5930 &
2026-01-09 19:39:14 +00:00
VIEWER_PID=$!
fi
echo ""
echo "=== Press Ctrl-C to stop ==="
echo ""
2026-01-10 08:42:37 +00:00
# Enable all 3 displays via SPICE protocol (waits for agent automatically)
# Using 300s timeout since ISO boot can take several minutes
if [ -f "$SCRIPT_DIR/enable-displays.py" ]; then
2026-01-10 08:42:37 +00:00
echo "Enabling displays (waiting for SPICE agent, up to 5 minutes)..."
python3 "$SCRIPT_DIR/enable-displays.py" --timeout 300 2>&1 &
ENABLE_PID=$!
fi
2026-01-09 19:39:14 +00:00
echo "Tips:"
echo " - http://localhost:3006 - Management UI"
echo " - socat - UNIX-CONNECT:.nogit/vm/serial.sock - Serial console (login: ecouser/ecouser)"
2026-01-09 19:39:14 +00:00
echo ""
# Start screenshot loop in background (takes screenshots every 5 seconds)
echo "Starting screenshot loop..."
(while true; do "$SCRIPT_DIR/screenshot.sh" 2>/dev/null; sleep 5; done) &
SCREENSHOT_LOOP_PID=$!
2026-01-10 08:42:37 +00:00
if [ "$AUTO_MODE" = true ]; then
echo "=== Auto mode: waiting for display setup ==="
# Wait for enable-displays.py to complete
if [ -n "$ENABLE_PID" ]; then
wait $ENABLE_PID
ENABLE_EXIT=$?
if [ $ENABLE_EXIT -ne 0 ]; then
echo "FAIL: Could not enable displays (exit code: $ENABLE_EXIT)"
exit 1
fi
fi
# Take screenshot
echo "Taking screenshot..."
"$SCRIPT_DIR/screenshot.sh"
# Verify screenshot dimensions (should be 5760x1080 for 3 displays)
SCREENSHOT="$PROJECT_ROOT/.nogit/screenshots/latest.png"
if [ -f "$SCREENSHOT" ]; then
WIDTH=$(identify -format "%w" "$SCREENSHOT" 2>/dev/null || echo "0")
if [ "$WIDTH" -ge 5760 ]; then
echo "SUCCESS: Multi-display test passed (width: ${WIDTH}px)"
exit 0
else
echo "FAIL: Screenshot width is ${WIDTH}px, expected >= 5760px"
exit 1
fi
else
echo "FAIL: Screenshot not found"
exit 1
fi
else
# Interactive mode - wait for QEMU to exit
wait $QEMU_PID 2>/dev/null || true
fi