Codex: Stabilize proxy E2E stream isolation.

Randomize proxy E2E stream names to avoid stale shared state between runs, and make the WHIP HLS check skip the first possibly incomplete segment before requiring audio/video playback.

Verified with the full srs-develop proxy script set: proxy unit coverage and all proxy E2E scripts passed.

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
This commit is contained in:
winlin 2026-05-10 20:20:27 -04:00
parent 6c2bff53a4
commit de69339785
5 changed files with 72 additions and 9 deletions

View File

@ -38,7 +38,12 @@ PYTHON_BIN="${PYTHON_BIN:-python3}"
SOURCE_FLV="$WORKSPACE/trunk/doc/source.flv"
SRS_BINARY="$WORKSPACE/trunk/objs/srs"
TEST_STREAM_URL="__defaultVhost__/live/livestream"
# Randomize per run so each invocation uses unique Redis keys and never shares
# state with sibling E2E tests or a developer's local proxy that publishes to
# "live/livestream".
STREAM_NAME="redis$(date +%s)"
STREAM_PATH="live/$STREAM_NAME"
TEST_STREAM_URL="__defaultVhost__/$STREAM_PATH"
# PIDs to clean up on exit.
PROXY_A_PID=""
@ -279,7 +284,7 @@ echo "SRS origin started and registered in Redis."
# --- Step 6: Publish RTMP stream to proxy A ---
echo "=== Step 6: Publishing RTMP stream to proxy A ==="
ffmpeg -stream_loop -1 -re -i "$SOURCE_FLV" -c copy -f flv \
"rtmp://localhost:$PROXY_A_RTMP_PORT/live/livestream" >/tmp/srs-ffmpeg-redis-e2e.log 2>&1 &
"rtmp://localhost:$PROXY_A_RTMP_PORT/$STREAM_PATH" >/tmp/srs-ffmpeg-redis-e2e.log 2>&1 &
FFMPEG_PID=$!
echo "FFmpeg publisher PID: $FFMPEG_PID"
@ -296,7 +301,7 @@ echo "Stream publishing through proxy A."
# --- Step 7: Verify RTMP playback through proxy B ---
echo "=== Step 7: Verifying RTMP playback through proxy B ==="
PROBE_OUTPUT=$(ffprobe -v error -show_streams \
"rtmp://localhost:$PROXY_B_RTMP_PORT/live/livestream" 2>&1 || true)
"rtmp://localhost:$PROXY_B_RTMP_PORT/$STREAM_PATH" 2>&1 || true)
if echo "$PROBE_OUTPUT" | grep -q "codec_type=video"; then
echo "PASS: Video stream detected through proxy B."

View File

@ -35,7 +35,10 @@ ORIGIN_SRT_PORT=10081
SOURCE_FLV="$WORKSPACE/trunk/doc/source.flv"
SRS_BINARY="$WORKSPACE/trunk/objs/srs"
STREAM_URL="live/livestream"
# Randomize per run so each invocation starts from clean origin state (HLS
# segments, RTMP source, proxy stream registry) and never shares state with
# sibling E2E tests that publish to "live/livestream".
STREAM_URL="live/srt$(date +%s)"
# SRT streamid format used by SRS: "#!::r=<app>/<stream>,m=publish|request".
# @see trunk/3rdparty/srs-docs/doc/srt.md and internal/proxy/srt.go.

View File

@ -24,6 +24,10 @@ PROXY_SYSTEM_API_PORT=12025
SOURCE_FLV="$WORKSPACE/trunk/doc/source.flv"
SRS_BINARY="$WORKSPACE/trunk/objs/srs"
ORIGIN_CONF="$WORKSPACE/trunk/conf/origin1-for-proxy.conf"
# Randomize per run so each invocation starts from clean origin state (HLS
# segments, RTMP source, proxy stream registry) and never shares state with
# sibling E2E tests that publish to "live/livestream".
STREAM_URL="live/rtmp$(date +%s)"
# PIDs to clean up on exit.
PROXY_PID=""
@ -143,7 +147,7 @@ echo "SRS origin started and registered."
# --- Step 5: Publish RTMP stream ---
echo "=== Step 5: Publishing RTMP stream to proxy ==="
ffmpeg -stream_loop -1 -re -i "$SOURCE_FLV" -c copy -f flv \
"rtmp://localhost:$PROXY_RTMP_PORT/live/livestream" >/tmp/srs-ffmpeg-e2e.log 2>&1 &
"rtmp://localhost:$PROXY_RTMP_PORT/$STREAM_URL" >/tmp/srs-ffmpeg-e2e.log 2>&1 &
FFMPEG_PID=$!
echo "FFmpeg publisher PID: $FFMPEG_PID"
@ -160,7 +164,7 @@ echo "Stream publishing."
# --- Step 6: Verify RTMP playback ---
echo "=== Step 6: Verifying RTMP playback via proxy ==="
PROBE_OUTPUT=$(ffprobe -v error -show_streams \
"rtmp://localhost:$PROXY_RTMP_PORT/live/livestream" 2>&1 || true)
"rtmp://localhost:$PROXY_RTMP_PORT/$STREAM_URL" 2>&1 || true)
if echo "$PROBE_OUTPUT" | grep -q "codec_type=video"; then
echo "PASS: Video stream detected."

View File

@ -32,7 +32,10 @@ ORIGIN_SRT_PORT=10081
SOURCE_FLV="$WORKSPACE/trunk/doc/source.flv"
SRS_BINARY="$WORKSPACE/trunk/objs/srs"
STREAM_URL="live/livestream"
# Randomize per run so each invocation starts from clean origin state (HLS
# segments, RTMP source, proxy stream registry) and never shares state with
# sibling E2E tests that publish to "live/livestream".
STREAM_URL="live/transmux$(date +%s)"
# PIDs to clean up on exit.
PROXY_PID=""

View File

@ -35,12 +35,16 @@ ORIGIN_SRT_PORT=10081
SOURCE_FLV="$WORKSPACE/trunk/doc/source.flv"
SRS_BINARY="$WORKSPACE/trunk/objs/srs"
STREAM_URL="live/livestream"
# Randomize the stream name per run so each test starts from a clean origin
# state (HLS segments, RTMP source, proxy stream registry) and never shares
# state with sibling E2E tests that publish to "live/livestream".
STREAM_NAME="whip$(date +%s)"
STREAM_URL="live/$STREAM_NAME"
# WHIP endpoint exposed by the proxy. The proxy parses ?app=&stream= via
# utils.ConvertURLToStreamURL, then forwards the SDP exchange to the backend
# SRS origin. @see internal/proxy/api.go and internal/proxy/rtc.go.
WHIP_PUBLISH_URL="http://localhost:$PROXY_HTTP_API_PORT/rtc/v1/whip/?app=live&stream=livestream"
WHIP_PUBLISH_URL="http://localhost:$PROXY_HTTP_API_PORT/rtc/v1/whip/?app=live&stream=$STREAM_NAME"
# Make the SRS origin advertise a host candidate that loops back through the
# proxy. The proxy rewrites only the port in the SDP answer (origin RTC port
@ -117,6 +121,49 @@ wait_for_hls_playlist() {
exit 1
}
first_hls_segment() {
local url="$1"
curl -fsS "$url" 2>/dev/null | awk '
/^[[:space:]]*$/ { next }
/^#/ { next }
{ print; exit }
'
}
wait_for_hls_to_skip_first_segment() {
local url="$1"
local deadline=60
local first_segment current_segment output
first_segment="$(first_hls_segment "$url")"
if [[ -z "$first_segment" ]]; then
echo "FAIL: HLS playlist has no media segment: $url" >&2
curl -fsS "$url" 2>&1 || true
exit 1
fi
echo "Waiting for HLS to skip the first possibly incomplete segment (up to ${deadline}s): $first_segment"
for ((i = 1; i <= deadline; i++)); do
current_segment="$(first_hls_segment "$url")"
if [[ -n "$current_segment" && "$current_segment" != "$first_segment" ]]; then
output=$("$FFPROBE_BIN" -v error -show_streams "$url" 2>&1 || true)
if echo "$output" | grep -q "codec_type=video" && echo "$output" | grep -q "codec_type=audio"; then
echo "HLS first segment advanced and audio/video is ready: $current_segment"
return
fi
fi
sleep 1
done
echo "FAIL: HLS did not skip the first segment and expose audio/video in ${deadline}s." >&2
echo "Last HLS response:" >&2
curl -fsS "$url" 2>&1 || true
echo "Last ffprobe output:" >&2
echo "$output" >&2
exit 1
}
echo "=== E2E WHIP Proxy Test ==="
echo "Workspace: $WORKSPACE"
echo "Stream: $STREAM_URL"
@ -285,6 +332,7 @@ probe_has_audio_video "HTTP-FLV" "http://localhost:$PROXY_HTTP_SERVER_PORT/$STRE
echo "=== Step 8: Verifying HLS playback via proxy ==="
HLS_URL="http://localhost:$PROXY_HTTP_SERVER_PORT/$STREAM_URL.m3u8"
wait_for_hls_playlist "$HLS_URL"
wait_for_hls_to_skip_first_segment "$HLS_URL"
probe_has_audio_video "HLS" "$HLS_URL"
# --- Step 9: WebRTC WHEP playback (placeholder) ---