summaryrefslogtreecommitdiffstats
path: root/scripts/test-msg.sh
blob: 95b7af3007bef55eddfcf36b46377e3f85614ded (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env bash
#
# scripts/test-msg.sh — automated scheduler message-queue round trip.
#
# Tests all message types (user, timer, key, mouse), real-input routing,
# and queue-full boundary.
#
# Env: OVMF, QEMU, SYSTEM_IMG
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$PROJECT_DIR"

OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}"
QEMU="${QEMU:-qemu-system-x86_64}"
SYSTEM_IMG="${SYSTEM_IMG:-/tmp/system.img}"
QPID=/tmp/rsdos-msg-qpid
SOCK=/tmp/rsdos-msg-qmon.sock
LOG=/tmp/rsdos-msg-serial.log
QLOG=/tmp/rsdos-msg-qemu.log

trap 'kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true' EXIT

fail() {
	echo "FAIL: $1"
	[ -f "$LOG" ] && tail -40 "$LOG"
	exit 1
}

wait_log() {
	local i=0
	while [ "$i" -lt $((${3:-60} * 10)) ]; do
		grep -q "$2" "$1" 2>/dev/null && return 0
		sleep 0.1
		i=$((i + 1))
	done
	return 1
}

qemu_hmp() {
	python3 - "$SOCK" "$1" <<'EOF'
import socket, sys, time
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(sys.argv[1])
s.sendall((sys.argv[2] + "\n").encode())
time.sleep(0.4)
EOF
}

wait_qemu_exit() {
	local i=0
	while [ "$i" -lt $((${1:-30} * 10)) ]; do
		kill -0 "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || return 0
		sleep 0.1
		i=$((i + 1))
	done
	return 1
}

echo "==> 1/5 build kernel (debug)"
cargo build --package rsdos --target x86_64-unknown-uefi

echo "==> 2/5 stage system image"
"$SCRIPT_DIR/mksystem.sh" --force "$SYSTEM_IMG"

echo "==> 3/5 boot QEMU (headless)"
kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true
sleep 1
rm -f "$SOCK" "$LOG"
"$QEMU" -bios "$OVMF" \
	-drive file="$SYSTEM_IMG",format=raw,if=none,id=disk \
	-device ide-hd,drive=disk,bus=ide.0 \
	-serial file:"$LOG" \
	-monitor unix:"$SOCK",server,nowait \
	-m 256M -machine q35 -cpu qemu64 -no-reboot -display none \
	>"$QLOG" 2>&1 &
echo $! >"$QPID"

wait_log "$LOG" "boot: entering shell" 90 || fail "kernel never reached the shell"

echo "==> 4/5 drive the shell (msgrecv / send / mouse routing / queue-full)"
python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" \
	"msgrecv" \
	"send 3 user 42" \
	"send 3 timer" \
	"send 3 key enter" \
	"send 3 key ctrl-c" \
	"send 3 key f3" \
	"send 3 mouse 5 -3 3" \
	"sleep 800" \
	"jobs"

python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" "mouse 3"
qemu_hmp "mouse_move 20 7"
qemu_hmp "mouse_button 1"
qemu_hmp "mouse_move -5 -3"
qemu_hmp "mouse_button 0"
qemu_hmp "sendkey ctrl-c"

python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" \
	"send 0 user 1" \
	"send 0 user 2" \
	"send 0 user 3" \
	"send 0 user 4" \
	"send 0 user 5" \
	"send 0 user 6" \
	"send 0 user 7" \
	"send 0 user 8" \
	"send 0 user 9" \
	"send 0 user 10" \
	"send 0 user 11" \
	"send 0 user 12" \
	"send 0 user 13" \
	"send 0 user 14" \
	"send 0 user 15" \
	"send 0 user 16" \
	"send 0 user 17" \
	"sleep 800" \
	"jobs" \
	"poweroff"

echo "==> 5/5 wait for shutdown + verify"
wait_qemu_exit 30 || fail "QEMU did not exit after poweroff"

grep -aq "msgrecv: task 3 listening" "$LOG" || fail "msgrecv did not spawn"
grep -aq "msgrecv\[3\]: User(42)" "$LOG" || fail "user message missing"
grep -aq "msgrecv\[3\]: Timer" "$LOG" || fail "timer message missing"
grep -aq "msgrecv\[3\]: Key(Enter)" "$LOG" || fail "key enter missing"
grep -aq "msgrecv\[3\]: Key(Ctrl-c)" "$LOG" || fail "key ctrl-c missing"
grep -aq "msgrecv\[3\]: Key(F3)" "$LOG" || fail "key f3 missing"
grep -aq "msgrecv\[3\]: Mouse(+5,-3 L R)" "$LOG" || fail "synthesized mouse message missing"
grep -aq "msgrecv\[3\]: Mouse(+20,+7" "$LOG" || fail "real mouse move 20,7 not routed to queue"
grep -aq "msgrecv\[3\]: Mouse(-5,-3 L" "$LOG" || fail "held-button routed move missing"
grep -aq "queue full" "$LOG" || fail "17th send did not report queue full"
grep -aq "send: unknown type" "$LOG" && fail "a bad send slipped through (expected none)"

echo ""
echo "PASS — message queues OK"