81 lines
2.8 KiB
C#
81 lines
2.8 KiB
C#
using LiveRecorder.Domain.Entities;
|
|
using LiveRecorder.Domain.Enums;
|
|
using LiveRecorder.Infrastructure.Persistence;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace LiveRecorder.Tests;
|
|
|
|
public sealed class ShutdownRecoveryDispatchTests : IDisposable
|
|
{
|
|
private readonly string _temporaryDirectory = Path.Combine(
|
|
Path.GetTempPath(),
|
|
$"liverecorder-shutdown-dispatch-{Guid.NewGuid():N}");
|
|
|
|
[Fact]
|
|
public async Task RecoveredProcessingTask_CreatesDurableCompletionDispatch()
|
|
{
|
|
Directory.CreateDirectory(_temporaryDirectory);
|
|
var outputPath = Path.Combine(_temporaryDirectory, "recovered.mp4");
|
|
await File.WriteAllBytesAsync(outputPath, [1, 2, 3, 4]);
|
|
|
|
var options = new DbContextOptionsBuilder<LiveRecorderDbContext>()
|
|
.UseInMemoryDatabase($"shutdown-recovery-dispatch-{Guid.NewGuid():N}")
|
|
.Options;
|
|
await using var context = new LiveRecorderDbContext(options);
|
|
var now = DateTimeOffset.UtcNow;
|
|
var room = new LiveRoom(
|
|
LivePlatformType.Douyin,
|
|
"https://live.example/recovery",
|
|
"recovery-room",
|
|
"https://live.example/recovery",
|
|
now.AddHours(-1));
|
|
var session = new RecordSession(
|
|
room.Id,
|
|
"origin",
|
|
RecordOutputFormat.Mp4,
|
|
RecordSaveMode.Segmented,
|
|
now.AddMinutes(-30));
|
|
session.MarkStopped(now, "Application shutdown deferred MP4 finalization.");
|
|
var task = new RecordTask(
|
|
room.Id,
|
|
session.Id,
|
|
1,
|
|
"origin",
|
|
RecordOutputFormat.Mp4,
|
|
now.AddMinutes(-30));
|
|
task.MarkStarting("https://stream.example/recovery", outputPath, now.AddMinutes(-30));
|
|
task.MarkProcessing("Waiting for restart recovery.", now);
|
|
var result = new RecordResult(
|
|
task.Id,
|
|
outputPath,
|
|
new FileInfo(outputPath).Length,
|
|
1_800,
|
|
null,
|
|
0,
|
|
RecordTaskStatus.Processing,
|
|
task.ErrorMessage,
|
|
now);
|
|
|
|
context.AddRange(room, session, task, result);
|
|
await context.SaveChangesAsync();
|
|
Assert.Empty(context.RecordCompletionDispatches);
|
|
|
|
task.MarkCompleted(now.AddMinutes(1), 1_800);
|
|
session.MarkCompleted(now.AddMinutes(1));
|
|
await context.SaveChangesAsync();
|
|
|
|
var dispatch = await context.RecordCompletionDispatches.SingleAsync();
|
|
Assert.Equal(task.Id, dispatch.RecordTaskId);
|
|
Assert.False(dispatch.UploadDispatched);
|
|
Assert.Null(dispatch.CompletedAt);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(_temporaryDirectory))
|
|
{
|
|
Directory.Delete(_temporaryDirectory, recursive: true);
|
|
}
|
|
}
|
|
}
|