|
- package icecast
-
- import (
- "bytes"
- "context"
- "errors"
- "io"
- "testing"
-
- "github.com/jan/fm-rds-tx/internal/ingest"
- "github.com/jan/fm-rds-tx/internal/ingest/decoder"
- )
-
- type testDecoder struct {
- name string
- err error
- called int
- }
-
- func (d *testDecoder) Name() string { return d.name }
-
- func (d *testDecoder) DecodeStream(_ context.Context, _ io.Reader, _ decoder.StreamMeta, _ func(ingest.PCMChunk) error) error {
- d.called++
- return d.err
- }
-
- func TestDecodeWithPreferenceAutoFallsBackFromNativeUnsupported(t *testing.T) {
- native := &testDecoder{name: "native", err: decoder.ErrUnsupported}
- fallback := &testDecoder{name: "ffmpeg"}
-
- reg := decoder.NewRegistry()
- reg.Register("mp3", func() decoder.Decoder { return native })
- reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
-
- src := New("ice-test", "http://example", nil, ReconnectConfig{},
- WithDecoderRegistry(reg),
- WithDecoderPreference("auto"),
- )
-
- err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
- ContentType: "audio/mpeg",
- SourceID: "ice-test",
- })
- if err != nil {
- t.Fatalf("decode: %v", err)
- }
- if native.called != 1 {
- t.Fatalf("native called %d times", native.called)
- }
- if fallback.called != 1 {
- t.Fatalf("fallback called %d times", fallback.called)
- }
- }
-
- func TestDecodeWithPreferenceNativeDoesNotFallback(t *testing.T) {
- nativeErr := errors.New("decode failed")
- native := &testDecoder{name: "native", err: nativeErr}
- fallback := &testDecoder{name: "ffmpeg"}
-
- reg := decoder.NewRegistry()
- reg.Register("mp3", func() decoder.Decoder { return native })
- reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
-
- src := New("ice-test", "http://example", nil, ReconnectConfig{},
- WithDecoderRegistry(reg),
- WithDecoderPreference("native"),
- )
-
- err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
- ContentType: "audio/mpeg",
- SourceID: "ice-test",
- })
- if !errors.Is(err, nativeErr) {
- t.Fatalf("expected native error, got %v", err)
- }
- if fallback.called != 0 {
- t.Fatalf("fallback should not be called, got %d", fallback.called)
- }
- }
-
- func TestDecodeWithPreferenceFFmpegOnly(t *testing.T) {
- native := &testDecoder{name: "native"}
- fallback := &testDecoder{name: "ffmpeg"}
-
- reg := decoder.NewRegistry()
- reg.Register("mp3", func() decoder.Decoder { return native })
- reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
-
- src := New("ice-test", "http://example", nil, ReconnectConfig{},
- WithDecoderRegistry(reg),
- WithDecoderPreference("ffmpeg"),
- )
-
- err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
- ContentType: "audio/mpeg",
- SourceID: "ice-test",
- })
- if err != nil {
- t.Fatalf("decode: %v", err)
- }
- if native.called != 0 {
- t.Fatalf("native should not be called in ffmpeg mode, got %d", native.called)
- }
- if fallback.called != 1 {
- t.Fatalf("fallback called %d times", fallback.called)
- }
- }
-
- func TestDecodeWithPreferenceAutoUnsupportedContentTypeFallsBack(t *testing.T) {
- fallback := &testDecoder{name: "ffmpeg"}
- reg := decoder.NewRegistry()
- reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
-
- src := New("ice-test", "http://example", nil, ReconnectConfig{},
- WithDecoderRegistry(reg),
- WithDecoderPreference("auto"),
- )
-
- err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
- ContentType: "application/octet-stream",
- SourceID: "ice-test",
- })
- if err != nil {
- t.Fatalf("decode: %v", err)
- }
- if fallback.called != 1 {
- t.Fatalf("fallback called %d times", fallback.called)
- }
- }
-
- func TestDecodeWithPreferenceAutoUsesOggNativeForOggContentType(t *testing.T) {
- ogg := &testDecoder{name: "oggvorbis"}
- fallback := &testDecoder{name: "ffmpeg"}
-
- reg := decoder.NewRegistry()
- reg.Register("oggvorbis", func() decoder.Decoder { return ogg })
- reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
-
- src := New("ice-test", "http://example", nil, ReconnectConfig{},
- WithDecoderRegistry(reg),
- WithDecoderPreference("auto"),
- )
-
- err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
- ContentType: "audio/ogg",
- SourceID: "ice-test",
- })
- if err != nil {
- t.Fatalf("decode: %v", err)
- }
- if ogg.called != 1 {
- t.Fatalf("ogg decoder called %d times", ogg.called)
- }
- if fallback.called != 0 {
- t.Fatalf("fallback should not be called, got %d", fallback.called)
- }
- }
-
- func TestWithDecoderPreferenceFallbackAliasNormalizesToFFmpeg(t *testing.T) {
- src := New("ice-test", "http://example", nil, ReconnectConfig{}, WithDecoderPreference("fallback"))
- if got := src.Descriptor().Codec; got != "ffmpeg" {
- t.Fatalf("codec=%s want ffmpeg", got)
- }
- }
|