quintodrome/server/e2e
Deluan Quintão 27209ed26a
fix(transcoding): clamp target channels to codec limit (#5336) (#5345)
* fix(transcoding): clamp target channels to codec limit (#5336)

When transcoding a multi-channel source (e.g. 6-channel FLAC) to MP3, the
decider passed the source channel count through to ffmpeg unchanged. The
default MP3 command path then emitted `-ac 6`, and the template path injected
`-ac 6` after the template's own `-ac 2`, causing ffmpeg to honor the last
occurrence and fail with exit code 234 since libmp3lame only supports up to
2 channels.

Introduce `codecMaxChannels()` in core/stream/codec.go (mp3→2, opus→8),
mirroring the existing `codecMaxSampleRate` pattern, and apply the clamp in
`computeTranscodedStream` right after the sample-rate clamps. Also fix a
pre-existing ordering bug where the profile's MaxAudioChannels check compared
against src.Channels rather than ts.Channels, which would have let a looser
profile setting raise the codec-clamped value back up. Comparing against the
already-clamped ts.Channels makes profile limits strictly narrowing, which
matches how the sample-rate block already behaves.

The ffmpeg buildTemplateArgs comment is refreshed to point at the new upstream
clamp, since the flags it injects are now always codec-safe.

Adds unit tests for codecMaxChannels and four decider scenarios covering the
literal issue repro (6-ch FLAC→MP3 clamps to 2), a stricter profile limit
winning over the codec clamp, a looser profile limit leaving the codec clamp
intact, and a codec with no hard limit (AAC) passing 6 channels through.

* test(e2e): pin codec channel clamp at the Subsonic API surface (#5336)

Add a 6-channel FLAC fixture to the e2e test suite and use it to assert the
codec channel clamp end-to-end on both Subsonic streaming endpoints:

- getTranscodeDecision (mp3OnlyClient, no MaxAudioChannels in profile):
  expects TranscodeStream.AudioChannels == 2 for the 6-channel source. This
  exercises the new codecMaxChannels() helper through the OpenSubsonic
  decision endpoint, with no profile-level channel limit masking the bug.

- /rest/stream (legacy): requests format=mp3 against the multichannel
  fixture and asserts streamerSpy.LastRequest.Channels == 2, confirming
  the clamp propagates through ResolveRequest into the stream.Request that
  the streamer receives.

The fixture is metadata-only (channels: 6 plumbed via the existing
storagetest.File helper) — no real audio bytes required, since the e2e
suite uses a spy streamer rather than invoking ffmpeg. Bumps the empty-query
search3 song count expectation from 13 to 14 to account for the new fixture.

* test(decider): clarify codec-clamp comment terminology

Distinguish "transcoding profile MaxAudioChannels" (Profile.MaxAudioChannels
field) from "LimitationAudioChannels" (CodecProfile rule constant). The
regression test bypasses the former, not the latter.
2026-04-11 23:15:07 -04:00
..
doc.go docs: documents how subsonic e2e tests are structured 2026-02-11 22:49:41 -05:00
e2e_suite_test.go fix(transcoding): clamp target channels to codec limit (#5336) (#5345) 2026-04-11 23:15:07 -04:00
subsonic_album_lists_test.go test(e2e): add transcode endpoint e2e tests and clean up test helpers 2026-03-09 09:43:55 -04:00
subsonic_bookmarks_test.go fix(subsonic): always return required playqueue fields (#5172) 2026-03-12 08:29:37 -04:00
subsonic_browsing_test.go test(e2e): add transcode endpoint e2e tests and clean up test helpers 2026-03-09 09:43:55 -04:00
subsonic_media_annotation_test.go test(subsonic): add comprehensive e2e test suite for Subsonic API (#5003) 2026-02-09 08:24:37 -05:00
subsonic_media_retrieval_test.go fix: implement fallback to DefaultDownsamplingFormat for unknown formats 2026-03-11 09:46:13 -04:00
subsonic_multilibrary_test.go feat: add artist image uploads and image-folder artwork source (#5198) 2026-03-15 22:19:55 -04:00
subsonic_multiuser_test.go test(subsonic): add comprehensive e2e test suite for Subsonic API (#5003) 2026-02-09 08:24:37 -05:00
subsonic_playlists_test.go refactor: move playlist business logic from repositories to service layer (#5027) 2026-02-21 19:57:13 -05:00
subsonic_radio_test.go test(subsonic): add comprehensive e2e test suite for Subsonic API (#5003) 2026-02-09 08:24:37 -05:00
subsonic_scan_test.go refactor: move playlist business logic from repositories to service layer (#5027) 2026-02-21 19:57:13 -05:00
subsonic_searching_test.go fix(transcoding): clamp target channels to codec limit (#5336) (#5345) 2026-04-11 23:15:07 -04:00
subsonic_sharing_test.go test(subsonic): add comprehensive e2e test suite for Subsonic API (#5003) 2026-02-09 08:24:37 -05:00
subsonic_stream_test.go fix(transcoding): clamp target channels to codec limit (#5336) (#5345) 2026-04-11 23:15:07 -04:00
subsonic_system_test.go test(subsonic): add comprehensive e2e test suite for Subsonic API (#5003) 2026-02-09 08:24:37 -05:00
subsonic_transcode_test.go fix(transcoding): clamp target channels to codec limit (#5336) (#5345) 2026-04-11 23:15:07 -04:00
subsonic_users_test.go test(subsonic): add comprehensive e2e test suite for Subsonic API (#5003) 2026-02-09 08:24:37 -05:00