joeylib2/scripts/verify-sdl3-serial.sh

95 lines
3.5 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-sdl3-serial.sh - both-directions RS-232 gate for the SDL3 port, and
# the close's promise to put the line back.
#
# Runs SERTEST (examples/sertest: banner, then echo) with JOEYLIB_SERIAL
# naming the guest end of a pseudo-terminal pair the host peer
# (scripts/lib/serialLoopPeer.py) makes: 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) -> termios -> the pty -> the host. Before the run the
# guest end is set to 4800 baud with HUPCL on; SERTEST opens it at 9600. The
# peer then has SERTEST close the port (its DTR check, which closes it twice
# and leaves it closed; a pseudo-terminal has no modem lines, so DTR itself
# is not judged here), and once SERTEST no longer holds the pty the line
# must read 4800 again, with HUPCL off: the close puts back the speed the
# port had and leaves DTR as it was.
#
# Usage: scripts/verify-sdl3-serial.sh
# Requires: python3, stty; build/sdl3/bin/SERTEST (make sdl3).
set -uo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
source "$repo/scripts/lib/joeyEnv.sh"
label=verify-sdl3-serial
program=$(joeyExampleProgram sertest sdl3)
[ -x "$program" ] || { echo "$label: build SERTEST first (make sdl3)" >&2; exit 2; }
wall=40
ptyWaitTries=40
closeWaitTries=40
speedBefore=4800
work=$(mktemp -d -t joeylib-sdl3-serial.XXXXXX)
peerPid=""
programPid=""
cleanup() {
touch "$work/release"
joeyStop "$programPid" "$peerPid"
rm -rf "$work"
}
trap cleanup EXIT
python3 "$repo/scripts/lib/serialLoopPeer.py" pty "$work/pty.path" "$wall" --close-hold "$work/release" > "$work/peer.log" 2>&1 &
peerPid=$!
for ((tries = 0; tries < ptyWaitTries; tries++)); do
[ -s "$work/pty.path" ] && break
sleep 0.25
done
[ -s "$work/pty.path" ] || { echo "$label: FAIL - the peer made no pty" >&2; exit 1; }
pty=$(cat "$work/pty.path")
stty -F "$pty" "$speedBefore" hupcl
JOEYLIB_SERIAL="$pty" "$program" > "$work/program.log" 2>&1 &
programPid=$!
for ((tries = 0; tries < wall * 4; tries++)); do
grep -q "^CLOSE \|^LOOP FAIL" "$work/peer.log" && break
joeyAlive "$peerPid" || break
sleep 0.25
done
# The close is done when SERTEST no longer has the pty open.
for ((tries = 0; tries < closeWaitTries; tries++)); do
stillOpen=no
for fd in /proc/"$programPid"/fd/*; do
[ "$(readlink "$fd" 2> /dev/null)" = "$pty" ] && stillOpen=yes
done
[ "$stillOpen" = no ] && break
sleep 0.25
done
settings=$(stty -F "$pty" -a 2>&1)
touch "$work/release"
wait "$peerPid"
peerPid=""
cat "$work/peer.log"
if ! grep -q "^LOOP PASS" "$work/peer.log"; then
echo "$label: FAIL - the probe was not echoed" >&2
exit 1
fi
if ! grep -q "^CLOSE PASS" "$work/peer.log" || [ "$stillOpen" = yes ]; then
echo "$label: FAIL - SERTEST did not close the port" >&2
exit 1
fi
speedAfter=$(printf '%s\n' "$settings" | sed -n 's/.*speed \([0-9]*\) baud.*/\1/p')
if [ "$speedAfter" != "$speedBefore" ]; then
echo "$label: FAIL - after the close the line runs at ${speedAfter:-?} baud, not the $speedBefore it had" >&2
exit 1
fi
if ! printf '%s\n' "$settings" | grep -qw -- "-hupcl"; then
echo "$label: FAIL - the close left HUPCL on, so the last close would drop DTR" >&2
exit 1
fi
echo "$label: PASS (banner out, probe echoed through the pty; the close put back $speedBefore baud and left HUPCL off)"