Skip to content

Commit dd0285e

Browse files
committed
add unit test, using DI to stub out FFmpeg invocation
1 parent 9b52270 commit dd0285e

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

hlsvod/manager.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ const readyTimeout = 80 * time.Second
2424
// how long can it take for transcode to return first data
2525
const transcodeTimeout = 10 * time.Second
2626

27+
// transcodeSegmentsFn is a package-level hook so tests can stub out the actual
28+
// FFmpeg-based implementation. In production it points to TranscodeSegments.
29+
var transcodeSegmentsFn = TranscodeSegments
30+
2731
type ManagerCtx struct {
2832
mu sync.Mutex
2933
logger zerolog.Logger
@@ -382,7 +386,7 @@ func (m *ManagerCtx) transcodeSegments(offset, limit int) error {
382386
segmentTimes := m.breakpoints[offset : offset+limit+1]
383387
logger.Info().Interface("segments-times", segmentTimes).Msg("transcoding segments")
384388

385-
segments, err := TranscodeSegments(m.ctx, m.config.FFmpegBinary, TranscodeConfig{
389+
segments, err := transcodeSegmentsFn(m.ctx, m.config.FFmpegBinary, TranscodeConfig{
386390
InputFilePath: m.config.MediaPath,
387391
OutputDirPath: m.config.TranscodeDir,
388392
SegmentPrefix: m.config.SegmentPrefix, // This does not need to match.

hlsvod/manager_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package hlsvod
2+
3+
import (
4+
"context"
5+
"testing"
6+
)
7+
8+
// TestTranscodeFromSegmentBufferSize ensures that transcodeFromSegment()
9+
// queues exactly segmentBufferMax segments for transcoding. At the moment
10+
// the implementation appears to queue only segmentBufferMax-1 segments,
11+
// so this test is expected to FAIL until the bug is fixed.
12+
func TestTranscodeFromSegmentBufferSize(t *testing.T) {
13+
const bufferMax = 5
14+
15+
// Prepare a ManagerCtx with exactly bufferMax segments.
16+
m := &ManagerCtx{
17+
breakpoints: make([]float64, bufferMax+1),
18+
segmentBufferMax: bufferMax,
19+
segmentBufferMin: 3, // default value from constructor
20+
segments: make(map[int]string),
21+
segmentQueue: make(map[int]chan struct{}),
22+
}
23+
24+
// Populate the dummy segments map so that len(m.segments) == bufferMax.
25+
for i := 0; i < bufferMax; i++ {
26+
m.segments[i] = ""
27+
}
28+
29+
// Stub out the transcode function so the test doesn't invoke FFmpeg.
30+
origFn := transcodeSegmentsFn
31+
transcodeSegmentsFn = func(_ context.Context, _ string, _ TranscodeConfig) (chan string, error) {
32+
ch := make(chan string)
33+
close(ch)
34+
return ch, nil
35+
}
36+
defer func() { transcodeSegmentsFn = origFn }()
37+
38+
// Execute the code under test.
39+
if err := m.transcodeFromSegment(0); err != nil {
40+
t.Fatalf("transcodeFromSegment returned error: %v", err)
41+
}
42+
43+
// transcodeFromSegment should enqueue `bufferMax` segments
44+
if got := len(m.segmentQueue); got != bufferMax {
45+
t.Fatalf("expected %d queued segments, got %d", bufferMax, got)
46+
}
47+
}

0 commit comments

Comments
 (0)