84 lines
3.3 KiB
C#
84 lines
3.3 KiB
C#
using VideoDownloader.Core.Platform;
|
|
using VideoDownloader.Server;
|
|
using VideoDownloader.Tests.Platform;
|
|
|
|
namespace VideoDownloader.Tests.Server;
|
|
|
|
/// <summary>M2 라이브러리 썸네일/해상도 — ffmpeg 서브프로세스를 Fake 러너로 검증(사이드카 캐시).</summary>
|
|
public class ThumbnailerTests
|
|
{
|
|
private string _dir = "";
|
|
|
|
private string NewMedia()
|
|
{
|
|
_dir = Path.Combine(Path.GetTempPath(), $"vd_thumb_{Guid.NewGuid():N}");
|
|
Directory.CreateDirectory(_dir);
|
|
var p = Path.Combine(_dir, "clip.mp4");
|
|
File.WriteAllBytes(p, new byte[100]);
|
|
return p;
|
|
}
|
|
|
|
private static Task<ProcessResult> FakeFfmpegCreatesJpg(ProcessSpec spec, Action<string, string>? _, CancellationToken __)
|
|
{
|
|
// 출력 경로(마지막 인자)에 가짜 JPEG 생성
|
|
var outPath = spec.Args[^1];
|
|
File.WriteAllBytes(outPath, new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }); // JPEG SOI/APP0
|
|
return Task.FromResult(new ProcessResult(0, "", ""));
|
|
}
|
|
|
|
private static Task<ProcessResult> FakeFfmpegReportsResolution(ProcessSpec spec, Action<string, string>? onLine, CancellationToken _)
|
|
{
|
|
var line = " Stream #0:0[0x1](und): Video: h264 (High), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 5000 kb/s";
|
|
onLine?.Invoke("err", line);
|
|
return Task.FromResult(new ProcessResult(0, "", line));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task 썸네일_생성후_사이드카_캐시로_재실행_없음()
|
|
{
|
|
var media = NewMedia();
|
|
var runner = new FakeProcessRunner { Behavior = FakeFfmpegCreatesJpg };
|
|
var t = new Thumbnailer(runner);
|
|
|
|
var bytes1 = await t.GetThumbnailAsync("ffmpeg", media);
|
|
Assert.NotNull(bytes1);
|
|
Assert.True(bytes1!.Length == 4);
|
|
|
|
runner.Behavior = (_, _, _) => throw new Xunit.Sdk.XunitException("캐시 히트 시 ffmpeg 재실행 없음");
|
|
var bytes2 = await t.GetThumbnailAsync("ffmpeg", media); // 캐시
|
|
Assert.Equal(bytes1, bytes2);
|
|
Directory.Delete(_dir, true);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ffmpeg_실패_시_null()
|
|
{
|
|
var media = NewMedia();
|
|
var runner = new FakeProcessRunner { Behavior = (_, _, _) => Task.FromResult(new ProcessResult(1, "", "boom")) };
|
|
Assert.Null(await new Thumbnailer(runner).GetThumbnailAsync("ffmpeg", media));
|
|
Directory.Delete(_dir, true);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task 해상도_추출후_사이드카_캐시()
|
|
{
|
|
var media = NewMedia();
|
|
var runner = new FakeProcessRunner { Behavior = FakeFfmpegReportsResolution };
|
|
var t = new Thumbnailer(runner);
|
|
|
|
Assert.Equal("1920x1080", await t.GetResolutionAsync("ffmpeg", media));
|
|
|
|
runner.Behavior = (_, _, _) => throw new Xunit.Sdk.XunitException("캐시 히트 시 재실행 없음");
|
|
Assert.Equal("1920x1080", await t.GetResolutionAsync("ffmpeg", media));
|
|
Directory.Delete(_dir, true);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task 해상기_추출_불가_시_null()
|
|
{
|
|
var media = NewMedia();
|
|
var runner = new FakeProcessRunner { Behavior = (_, _, _) => Task.FromResult(new ProcessResult(0, "", "no streams")) };
|
|
Assert.Null(await new Thumbnailer(runner).GetResolutionAsync("ffmpeg", media));
|
|
Directory.Delete(_dir, true);
|
|
}
|
|
}
|