Files
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

69 lines
2.4 KiB
Go

package player
import (
"errors"
"testing"
"time"
)
func TestWaitCause(t *testing.T) {
ytdlErr := errors.New("yt-dlp: Sign in to confirm you're not a bot")
ffmpegErr := errors.New("ffmpeg: Invalid data found when processing input")
tests := []struct {
name string
d time.Duration
ytdl error // value sent on ytdlErr, gated by send
send bool // whether to send ytdl at all
ff error
ffSnd bool
want error
}{
// Blocking (grace) path.
{name: "ytdl error preferred over ffmpeg", d: 50 * time.Millisecond, ytdl: ytdlErr, send: true, ff: ffmpegErr, ffSnd: true, want: ytdlErr},
{name: "ffmpeg error when ytdl exits clean", d: 50 * time.Millisecond, ytdl: nil, send: true, ff: ffmpegErr, ffSnd: true, want: ffmpegErr},
{name: "both clean exit", d: 50 * time.Millisecond, ytdl: nil, send: true, ff: nil, ffSnd: true, want: nil},
{name: "ytdl error without ffmpeg report", d: 50 * time.Millisecond, ytdl: ytdlErr, send: true, ff: nil, ffSnd: false, want: ytdlErr},
{name: "neither reports before deadline", d: 50 * time.Millisecond, send: false, ffSnd: false, want: nil},
// Non-blocking poll (d <= 0).
{name: "poll ytdl error", d: 0, ytdl: ytdlErr, send: true, want: ytdlErr},
{name: "poll ffmpeg fallback after clean ytdl", d: 0, ytdl: nil, send: true, ff: ffmpegErr, ffSnd: true, want: ffmpegErr},
{name: "poll nothing pending", d: 0, send: false, ffSnd: false, want: nil},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ytdlCh := make(chan error, 1)
ffmpegCh := make(chan error, 1)
if tt.send {
ytdlCh <- tt.ytdl
}
if tt.ffSnd {
ffmpegCh <- tt.ff
}
y := &ytdlPipeStreamer{ytdlErr: ytdlCh, ffmpegErr: ffmpegCh}
got := y.waitCause(tt.d)
if !errors.Is(got, tt.want) {
t.Fatalf("waitCause = %v, want %v", got, tt.want)
}
})
}
}
// TestWaitCauseReturnsBeforeDeadline verifies that a present yt-dlp error is
// returned promptly rather than blocking for the full grace period waiting on
// a silent ffmpeg.
func TestWaitCauseReturnsBeforeDeadline(t *testing.T) {
ytdlCh := make(chan error, 1)
ytdlCh <- errors.New("boom")
y := &ytdlPipeStreamer{ytdlErr: ytdlCh, ffmpegErr: make(chan error, 1)}
start := time.Now()
if err := y.waitCause(2 * time.Second); err == nil {
t.Fatal("expected error, got nil")
}
if elapsed := time.Since(start); elapsed > 500*time.Millisecond {
t.Fatalf("waitCause blocked %v waiting for ffmpeg; should return on yt-dlp error", elapsed)
}
}