60170933b0
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
239 lines
6.8 KiB
Bash
Executable File
239 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# test-dbus-qemu.sh — Validate D-Bus system bus and redbear-sessiond inside a QEMU guest
|
|
#
|
|
# Usage:
|
|
# ./local/scripts/test-dbus-qemu.sh [--check] [--config CONFIG]
|
|
#
|
|
# Options:
|
|
# --check Run non-interactively, exit 0 on pass, 1 on fail
|
|
# --config CONFIG Build config to test (default: redbear-kde)
|
|
#
|
|
# --check mode boots the image, waits for the login prompt, then sends D-Bus
|
|
# validation commands via the serial console. Output is captured and parsed.
|
|
#
|
|
# Checks performed inside the guest:
|
|
# 1. dbus-daemon is running (system bus socket exists)
|
|
# 2. org.freedesktop.login1 is registered on the system bus
|
|
# 3. redbear-sessiond process is running
|
|
# 4. login1.Manager.ListSessions returns session c1
|
|
# 5. login1.Manager.IdleHint property is false
|
|
# 6. login1.Session.Active property is true
|
|
# 7. login1.Seat.CanGraphical property is true
|
|
#
|
|
# Exit codes:
|
|
# 0 All checks passed
|
|
# 1 One or more checks failed
|
|
# 2 Build or QEMU launch failed
|
|
|
|
set -euo pipefail
|
|
|
|
CHECK_MODE=0
|
|
CONFIG_NAME="redbear-kde"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--check)
|
|
CHECK_MODE=1
|
|
shift
|
|
;;
|
|
--config)
|
|
CONFIG_NAME="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [--check] [--config CONFIG]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
IMAGE="${REPO_ROOT}/build/${CONFIG_NAME}/x86_64/harddrive.img"
|
|
|
|
if [[ ! -f "$IMAGE" ]]; then
|
|
echo "test-dbus-qemu: image not found at ${IMAGE}" >&2
|
|
echo " Run: make all CONFIG_NAME=${CONFIG_NAME}" >&2
|
|
exit 2
|
|
fi
|
|
|
|
GUEST_SCRIPT='/tmp/dbus-check.sh'
|
|
OUTPUT_FILE='/tmp/dbus-qemu-output.txt'
|
|
|
|
# Build the guest-side check script as a standalone file.
|
|
# Uses org.freedesktop.DBus.Properties.Get for property access (checks 5-7).
|
|
cat > "$GUEST_SCRIPT" <<'GUEST_EOF'
|
|
#!/bin/sh
|
|
echo "=== D-Bus System Bus Validation ==="
|
|
|
|
# Check 1: dbus-daemon running
|
|
if [ -S /run/dbus/system_bus_socket ]; then
|
|
echo "PASS: system bus socket exists at /run/dbus/system_bus_socket"
|
|
else
|
|
echo "FAIL: system bus socket not found at /run/dbus/system_bus_socket"
|
|
fi
|
|
|
|
# Check 2: org.freedesktop.login1 registered
|
|
if command -v dbus-send >/dev/null 2>&1; then
|
|
RESULT=$(dbus-send --system --dest=org.freedesktop.DBus \
|
|
--type=method_call --print-reply \
|
|
/org/freedesktop/DBus \
|
|
org.freedesktop.DBus.ListNames 2>&1)
|
|
if echo "$RESULT" | grep -q "org.freedesktop.login1"; then
|
|
echo "PASS: org.freedesktop.login1 is registered on the system bus"
|
|
else
|
|
echo "FAIL: org.freedesktop.login1 not found on the system bus"
|
|
echo " Available names: $(echo "$RESULT" | grep string || echo none)"
|
|
fi
|
|
else
|
|
echo "SKIP: dbus-send not available (install dbus package)"
|
|
fi
|
|
|
|
# Check 3: redbear-sessiond process
|
|
if ps | grep -q '[r]edbear-sessiond'; then
|
|
echo "PASS: redbear-sessiond process is running"
|
|
else
|
|
echo "FAIL: redbear-sessiond process not found"
|
|
fi
|
|
|
|
# Check 4: login1.Manager.ListSessions
|
|
if command -v dbus-send >/dev/null 2>&1; then
|
|
SESSIONS=$(dbus-send --system --dest=org.freedesktop.login1 \
|
|
--type=method_call --print-reply \
|
|
/org/freedesktop/login1 \
|
|
org.freedesktop.login1.Manager.ListSessions 2>&1)
|
|
if echo "$SESSIONS" | grep -q "c1"; then
|
|
echo "PASS: ListSessions returns session c1"
|
|
else
|
|
echo "FAIL: ListSessions did not return session c1"
|
|
fi
|
|
fi
|
|
|
|
# Check 5: login1.Manager.IdleHint (property, not method)
|
|
if command -v dbus-send >/dev/null 2>&1; then
|
|
IDLE=$(dbus-send --system --dest=org.freedesktop.login1 \
|
|
--type=method_call --print-reply \
|
|
/org/freedesktop/login1 \
|
|
org.freedesktop.DBus.Properties.Get \
|
|
string:'org.freedesktop.login1.Manager' \
|
|
string:'IdleHint' 2>&1)
|
|
if echo "$IDLE" | grep -q "false"; then
|
|
echo "PASS: Manager.IdleHint = false"
|
|
else
|
|
echo "FAIL: Manager.IdleHint not false (got: $IDLE)"
|
|
fi
|
|
fi
|
|
|
|
# Check 6: login1.Session.Active (property, not method)
|
|
if command -v dbus-send >/dev/null 2>&1; then
|
|
ACTIVE=$(dbus-send --system --dest=org.freedesktop.login1 \
|
|
--type=method_call --print-reply \
|
|
/org/freedesktop/login1/session/c1 \
|
|
org.freedesktop.DBus.Properties.Get \
|
|
string:'org.freedesktop.login1.Session' \
|
|
string:'Active' 2>&1)
|
|
if echo "$ACTIVE" | grep -q "true"; then
|
|
echo "PASS: Session.Active = true"
|
|
else
|
|
echo "FAIL: Session.Active not true (got: $ACTIVE)"
|
|
fi
|
|
fi
|
|
|
|
# Check 7: login1.Seat.CanGraphical (property, not method)
|
|
if command -v dbus-send >/dev/null 2>&1; then
|
|
GRAPH=$(dbus-send --system --dest=org.freedesktop.login1 \
|
|
--type=method_call --print-reply \
|
|
/org/freedesktop/login1/seat/seat0 \
|
|
org.freedesktop.DBus.Properties.Get \
|
|
string:'org.freedesktop.login1.Seat' \
|
|
string:'CanGraphical' 2>&1)
|
|
if echo "$GRAPH" | grep -q "true"; then
|
|
echo "PASS: Seat.CanGraphical = true"
|
|
else
|
|
echo "FAIL: Seat.CanGraphical not true (got: $GRAPH)"
|
|
fi
|
|
fi
|
|
|
|
echo "=== D-Bus Validation Complete ==="
|
|
GUEST_EOF
|
|
chmod +x "$GUEST_SCRIPT"
|
|
|
|
if [[ "$CHECK_MODE" -eq 1 ]]; then
|
|
if ! command -v expect >/dev/null 2>&1; then
|
|
echo "test-dbus-qemu: --check mode requires 'expect' (install tcllib/expect)" >&2
|
|
exit 2
|
|
fi
|
|
|
|
echo "test-dbus-qemu: launching QEMU with D-Bus checks (non-interactive)"
|
|
|
|
# Use expect to boot the guest, wait for login, run checks, capture output
|
|
expect <<'EXPECT_EOF' > "$OUTPUT_FILE" 2>&1
|
|
set timeout 120
|
|
spawn qemu-system-x86_64 \
|
|
-drive file="$::env(IMAGE)" \
|
|
-m 2G \
|
|
-smp 2 \
|
|
-nographic \
|
|
-no-reboot
|
|
|
|
expect {
|
|
"login:" { }
|
|
timeout { puts "FAIL: timed out waiting for login prompt"; exit 1 }
|
|
}
|
|
|
|
sleep 2
|
|
send "root\r"
|
|
|
|
expect {
|
|
"#" { }
|
|
timeout { puts "FAIL: timed out waiting for shell prompt"; exit 1 }
|
|
}
|
|
|
|
sleep 1
|
|
|
|
# Read and send the check script line by line
|
|
set fp [open "/tmp/dbus-check.sh" r]
|
|
while {[gets $fp line] >= 0} {
|
|
send "$line\r"
|
|
expect {
|
|
"#" { }
|
|
timeout { puts "FAIL: timed out during check execution"; exit 1 }
|
|
}
|
|
}
|
|
close $fp
|
|
|
|
sleep 2
|
|
send "poweroff\r"
|
|
|
|
expect {
|
|
"Power down" { }
|
|
timeout { }
|
|
}
|
|
|
|
exit 0
|
|
EXPECT_EOF
|
|
|
|
FAILED=$(grep -c "FAIL" "$OUTPUT_FILE" 2>/dev/null || true)
|
|
PASSED=$(grep -c "PASS" "$OUTPUT_FILE" 2>/dev/null || true)
|
|
|
|
grep -E "PASS|FAIL|=== D-Bus" "$OUTPUT_FILE" || true
|
|
echo ""
|
|
echo "Results: ${PASSED} passed, ${FAILED} failed"
|
|
|
|
rm -f "$GUEST_SCRIPT"
|
|
if [[ "$FAILED" -gt 0 ]]; then
|
|
exit 1
|
|
fi
|
|
exit 0
|
|
else
|
|
echo "test-dbus-qemu: launching QEMU (interactive mode)"
|
|
echo " Guest check script written to /tmp/dbus-check.sh"
|
|
echo " After login, run: sh /tmp/dbus-check.sh"
|
|
echo ""
|
|
|
|
qemu-system-x86_64 \
|
|
-drive file="$IMAGE",format=raw \
|
|
-m 2G \
|
|
-smp 2 \
|
|
-serial mon:stdio
|
|
fi
|