69 lines
2.4 KiB
Go
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)
|
|
}
|
|
}
|