open-standards/joule-code/joule-code-rs/crates/joule-moq-interop/scripts/clients.sh
Transaction Science d3840db88b joule-moq-relay: a publisher's last streams and PUBLISH_DONE survive its leaving
Two races met when an interop test client finishes publishing: it sends
PUBLISH_DONE and its last data streams, then closes its control stream (an -18
§3.3 protocol violation) and its session. The relay closed the session on the
control stream's FIN at once, cutting streams still arriving, and its session
clean-up ended the publisher's tracks with GOING_AWAY, racing the PUBLISH_DONE
that had just come in, so subscribers saw GOING_AWAY and a reset stream.

Now a closed control stream closes the session once nothing of the peer's
publishing is left (every track it published ended, every data stream of its
read), or after PUBLISH_DONE_STREAM_WAIT. Session clean-up leaves each track to
its own request stream, which ends it with the PUBLISH_DONE status it read, or
GOING_AWAY; and a PUBLISH_DONE waiting on streams stops waiting once the
publisher's session is gone. Tested at -18 with a session written from -18's
messages, and over -22, -18 and -16 with a close after PUBLISH_DONE.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 12:40:25 -04:00

37 lines
1.7 KiB
Shell
Executable file

#!/bin/bash
# Other implementations' interop test clients against joule-moq-relay on this host.
# scripts/clients.sh <target-dir> <out-dir> <label>=<client binary> ...
# Each client speaks the interop runner's test-client interface (--relay, --test,
# --tls-disable-verify; TAP 14 on stdout). Every client runs its whole suite over raw
# QUIC and over WebTransport against a relay on loopback with a development
# certificate; each run's TAP and log go to <out-dir> (VERBOSE=1 asks the clients for
# their debug logs). No network beyond loopback.
set -u
T=$1
OUT=$2
shift 2
mkdir -p "$OUT"
JOULE_MOQ_RELAY_LOG=debug "$T/debug/joule-moq-relay" --dev > "$OUT/relay.log" 2>&1 &
R=$!
# The relay is gone before this script is: a next run binds the same port.
trap 'kill $R 2>/dev/null; wait $R 2>/dev/null' EXIT
sleep 1
if ! kill -0 $R 2>/dev/null; then
echo "the relay did not start:"; tail -3 "$OUT/relay.log"; exit 1
fi
# A run that hangs is ended after five minutes (no coreutils timeout on every host).
limit() { perl -e 'alarm shift; exec @ARGV or die "$ARGV[0]: $!"' "$@"; }
rc=0
for spec in "$@"; do
label=${spec%%=*}
bin=${spec#*=}
for url in moqt://127.0.0.1:4443/moq https://127.0.0.1:4443/moq; do
case $url in moqt:*) tr=quic ;; *) tr=webtransport ;; esac
limit 300 "$bin" --relay "$url" --tls-disable-verify ${VERBOSE:+--verbose} > "$OUT/${label}_${tr}.tap" 2> "$OUT/${label}_${tr}.log"
code=$?
[ $code -eq 0 ] || rc=1
summary=$(grep -E '^(ok|not ok) ' "$OUT/${label}_${tr}.tap" | sed -E 's/^(ok|not ok) [0-9]+ - ([^ ]+)( # SKIP.*)?$/\2=\1\3/' | sed -E 's/=not ok/=FAIL/; s/# SKIP.*/skip/' | tr '\n' ' ')
echo "${label} ${tr}: exit ${code} ${summary}"
done
done
exit $rc