joeylib2/scripts/verify-be-serial.sh

85 lines
3.2 KiB
Bash
Executable file

#!/usr/bin/env bash
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# verify-be-serial.sh - both-directions RS-232 gate for the Be API ports.
#
# Runs SERTEST (examples/sertest: banner, then echo) in the port's VM
# (scripts/lib/beGate.sh) with the machine's second serial port joined to
# the host peer (scripts/lib/serialLoopPeer.py) over TCP: the peer listens,
# QEMU's COM2 connects to it, and JOEYLIB_SERIAL names COM2's device to the
# program (Haiku's /dev/ports/pc_serial1; COM1 is the VM's console). The
# peer waits for the banner, sends a probe and expects it echoed, so the
# chain is JoeyLib's POSIX serial HAL (src/hosted/posix) -> the system's
# termios -> its serial driver -> QEMU -> the host. QEMU's TCP serial carries no modem lines: DTR and the close's
# settings are gated on SDL3 (verify-sdl3-serial.sh).
#
# BeOS R5 SKIPs: its serial driver finds the ports through the ISA plug and
# play bus, which the VM goes without (installer/lib/beos.sh: it crashes R5
# in the fail-safe video mode), so the machine has none.
#
# Usage: scripts/verify-be-serial.sh [haiku|haiku32|beos]
# Requires: the port's VM (component haikuVm, haikuVm32 or beosVm), python3;
# build/PORT/bin/SERTEST (make PORT).
set -uo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
source "$repo/scripts/lib/joeyEnv.sh"
source "$repo/scripts/lib/beGate.sh"
port=${1:-haiku}
label="verify-be-serial ($port)"
if [ "$port" = beos ]; then
echo "$label: SKIP (the BeOS R5 VM has no serial ports: R5 finds them through the ISA plug and play bus, which the VM goes without)"
exit 2
fi
beNeed "$port"
program=$(joeyExampleProgram sertest "$port")
[ -x "$program" ] || { echo "$label: build SERTEST first (make $port)" >&2; exit 2; }
bootSeconds=150
runSeconds=60 # SERTEST echoes until the job ends it
peerPortMin=40000
peerPortSpan=20000
device=/dev/ports/pc_serial1
work=$(mktemp -d -t joeylib-be-serial.XXXXXX)
peerPid=""
cleanup() {
beStop
joeyStop "$peerPid"
rm -rf "$work"
}
trap cleanup EXIT
mkdir -p "$work/job/SERTEST"
cp "$program" "$work/job/SERTEST/SERTEST"
{
printf 'ls /dev/ports > ports.txt\n'
printf '(\n'
beJobScript SERTEST SERTEST "" "$runSeconds" JOEYLIB_SERIAL="$device"
printf ')\n'
} > "$work/job/job.sh"
beJobDisk "$work/job.img" "$work/job"
peerPort=$((peerPortMin + RANDOM % peerPortSpan))
python3 "$repo/scripts/lib/serialLoopPeer.py" tcp-server "$peerPort" "$((bootSeconds + runSeconds))" > "$work/peer.log" 2>&1 &
peerPid=$!
sleep 1
beStart "$work" "$work/job.img" -serial "tcp:127.0.0.1:$peerPort"
if ! beWaitJob "$work" "$bootSeconds"; then
echo "$label: FAIL - the VM did not start the job within ${bootSeconds} s" >&2
exit 1
fi
wait "$peerPid"
peerStatus=$?
peerPid=""
beWaitExit "$work" "$((runSeconds + 60))" || true
beJobGet "$work/job.img" ports.txt "$work/ports.txt" || true
cat "$work/peer.log"
if [ "$peerStatus" -eq 0 ]; then
echo "$label: PASS (banner out, probe echoed through $device)"
else
echo "$label: FAIL - the probe did not come back through $device; the machine's ports: $(tr '\n' ' ' < "$work/ports.txt" 2> /dev/null)" >&2
exit 1
fi