diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-03 19:17:04 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-03 19:17:04 +0300 |
| commit | 30c2b0fe8232cc748ab2bded6ab4d76febe32425 (patch) | |
| tree | 985578b326a1ff8fe7af395bf08471857376b8fc /internal/thumb/thumb_test.go | |
| parent | 687b86cdeef2192272f0945ddd496322a9113f9e (diff) | |
fix(admin): fix rescan goroutine lifecycle and race on shared ScanProgress
- Protect adminService scan state (cancel func + progress pointer) with sync.Mutex.
- Allocate fresh ScanProgress per trigger and pass it to the scanner,
eliminating races on the previously shared progress struct.
- Cancel previous scan context before starting a new one.
- Add tests for cancellation, fresh progress per scan, concurrent triggers,
and empty progress when never started.
- Fix race-prone tests by polling Running==true before waiting for completion.
Diffstat (limited to 'internal/thumb/thumb_test.go')
| -rw-r--r-- | internal/thumb/thumb_test.go | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/internal/thumb/thumb_test.go b/internal/thumb/thumb_test.go index d6272a9..3ed9dfd 100644 --- a/internal/thumb/thumb_test.go +++ b/internal/thumb/thumb_test.go @@ -13,14 +13,14 @@ import ( func TestFFmpegGenerator_Generate(t *testing.T) { ctx := context.Background() - called := false - fakeExecer := func(_ context.Context, name string, arg ...string) *exec.Cmd { - called = true + // Video with duration > 0 should include -ss. + videoCalled := false + fakeExecerVideo := func(_ context.Context, name string, arg ...string) *exec.Cmd { + videoCalled = true if name != "ffmpeg" { t.Errorf("expected ffmpeg, got %s", name) } - // Verify some expected flags exist. args := strings.Join(arg, " ") if !strings.Contains(args, "-ss") { t.Error("missing -ss flag") @@ -34,25 +34,35 @@ func TestFFmpegGenerator_Generate(t *testing.T) { if !strings.Contains(args, "-y") { t.Error("missing -y flag") } - // Return a command that does nothing successfully. return exec.Command("true") } - - g := &FFmpegGenerator{execer: fakeExecer, rnd: rand.New(rand.NewSource(1))} - if err := g.Generate(ctx, "input.mp4", "output.jpg", 120.0); err != nil { + g := &FFmpegGenerator{execer: fakeExecerVideo, rnd: rand.New(rand.NewSource(1))} + if err := g.Generate(ctx, "input.mp4", "out.jpg", 120.0); err != nil { t.Fatalf("unexpected error: %v", err) } - if !called { + if !videoCalled { t.Fatal("expected fake execer to be called") } - // Duration zero or negative should still call execer with valid offset. - called = false - if err := g.Generate(ctx, "input.mp4", "output.jpg", 0); err != nil { + // Image with duration == 0 should NOT include -ss. + imgCalled := false + fakeExecerImage := func(_ context.Context, name string, arg ...string) *exec.Cmd { + imgCalled = true + args := strings.Join(arg, " ") + if strings.Contains(args, "-ss") { + t.Error("unexpected -ss flag for image") + } + if !strings.Contains(args, "-i") { + t.Error("missing -i flag") + } + return exec.Command("true") + } + gi := &FFmpegGenerator{execer: fakeExecerImage, rnd: rand.New(rand.NewSource(1))} + if err := gi.Generate(ctx, "photo.jpg", "thumb.jpg", 0); err != nil { t.Fatalf("unexpected error: %v", err) } - if !called { - t.Fatal("expected fake execer to be called for zero duration") + if !imgCalled { + t.Fatal("expected fake execer to be called for image") } } |
