Telegram-iOS/tools/tgcalls_cli/run-until-crash.sh
Isaac 5962a563e4 feat: tgcalls CLI test tool with group SFU, video, and adaptation
Squashed buildout of the tgcalls testbench:

- CLI test tool with --mode p2p/reflector/group/group-churn,
  cross-version interop (--version, --version2), and quiet/summary output
- Linux toolchain + Docker multi-stage build, AWS Fargate mass test harness,
  local parallel mass test harness with signaling loss simulation
- SCTP writable gate, retransmission timer tuning, role-based handshake
- InstanceV2CompatImpl (PeerConnection backend with V2Impl signaling) and
  SignalingTranslator for v14.0.0 interop
- In-process Go/Pion SFU (ICE+DTLS+SRTP+SCTP per participant) with audio
  RTP forwarding, ActiveAudio/VideoSsrcs data channel broadcast, RTCP
  feedback path, and CGo c-archive integration
- GroupInstanceReferenceImpl (PeerConnection group-call) and mixed-impl
  group mode (--reference-participants), with SDP munging for simulcast
- H264 simulcast group video (FakeVideoTrackSource pattern generator,
  FakeVideoSink frame counting, --video flag, two-pass channel setup,
  reactive video setup from ActiveVideoSsrcs)
- Group churn stress mode (--mode group-churn, --churn-cycles)
- SFU stream-quality adaptation: BandwidthEstimator, LayerSelector
  state machine, RtxRingBuffer, simulcast SSRC rewrite
- Transport-cc feedback generation, NetworkSimulator (delay/jitter/loss/
  token-bucket bandwidth), --network-scenario step-down-up
- CLAUDE.md updates throughout

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:28:43 +02:00

93 lines
2.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# Run parallel tests, stop on first crash (non-zero exit).
set -euo pipefail
BINARY="./bazel-bin/tools/tgcalls_cli/tgcalls_cli"
PARALLEL=250
DURATION=15
VERSION="11.0.0"
DROP_RATE=0.3
DELAY="50-200"
MODE="p2p"
while [[ $# -gt 0 ]]; do
case $1 in
-j) PARALLEL="$2"; shift 2 ;;
-d) DURATION="$2"; shift 2 ;;
--version) VERSION="$2"; shift 2 ;;
--drop-rate) DROP_RATE="$2"; shift 2 ;;
--delay) DELAY="$2"; shift 2 ;;
--mode) MODE="$2"; shift 2 ;;
*) echo "Usage: $0 [-j PARALLEL] [-d DURATION] [--version VER] [--drop-rate R] [--delay D] [--mode M]"; exit 1 ;;
esac
done
if [ ! -x "$BINARY" ]; then
echo "Binary not found: $BINARY"
exit 1
fi
TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT
echo "Running waves of $PARALLEL until first crash (${DURATION}s, drop=${DROP_RATE}, delay=${DELAY}, version=${VERSION})"
wave=0
total=0
while true; do
wave=$((wave + 1))
pids=()
for i in $(seq 1 $PARALLEL); do
id=$((total + i))
(
set +e
"$BINARY" --mode "$MODE" --duration "$DURATION" \
--drop-rate "$DROP_RATE" --delay "$DELAY" --version "$VERSION" --quiet \
> "$TMPDIR/${id}.out" 2>"$TMPDIR/${id}.err"
echo $? > "$TMPDIR/${id}.rc"
) &
pids+=($!)
done
for pid in "${pids[@]}"; do
wait "$pid" 2>/dev/null || true
done
total=$((total + PARALLEL))
# Check for crashes
crashes=0
for i in $(seq $((total - PARALLEL + 1)) $total); do
rc_file="$TMPDIR/${i}.rc"
if [ ! -f "$rc_file" ]; then
crashes=$((crashes + 1))
echo ""
echo "=== CRASH in run $i (no rc file) ==="
echo "--- stderr ---"
cat "$TMPDIR/${i}.err" 2>/dev/null || echo "(empty)"
else
rc=$(cat "$rc_file")
if [ "$rc" -gt 128 ] 2>/dev/null; then
crashes=$((crashes + 1))
echo ""
echo "=== CRASH in run $i (exit $rc) ==="
echo "--- stderr ---"
cat "$TMPDIR/${i}.err" 2>/dev/null || echo "(empty)"
echo "--- stdout ---"
cat "$TMPDIR/${i}.out" 2>/dev/null || echo "(empty)"
# Only show first crash in detail
if [ $crashes -eq 1 ]; then
echo "=== END CRASH ==="
fi
fi
fi
done
if [ $crashes -gt 0 ]; then
echo ""
echo "Wave $wave: $crashes crashes in $PARALLEL runs (total $total runs)"
exit 1
fi
echo " Wave $wave: $PARALLEL/$PARALLEL passed (total $total)"
done