feat: harden recording lifecycle and refresh fnOS UI
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using LiveRecorder.Application.Abstractions.Storage;
|
||||
using LiveRecorder.Application.Models.Settings;
|
||||
using LiveRecorder.Infrastructure.Services;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace LiveRecorder.Tests;
|
||||
|
||||
public sealed class StorageGuardServiceTests
|
||||
{
|
||||
private readonly StorageGuardService _service = new(NullLogger<StorageGuardService>.Instance);
|
||||
|
||||
[Fact]
|
||||
public void DisabledProtection_StillReportsActualCapacityWithoutBlockingRecording()
|
||||
{
|
||||
var settings = CreateSettings(enableStorageGuard: false);
|
||||
|
||||
var result = _service.CheckCanStartOrResume(settings);
|
||||
|
||||
Assert.False(result.IsEnabled);
|
||||
Assert.True(result.IsAvailable);
|
||||
Assert.True(result.HasEnoughSpace);
|
||||
Assert.True(result.CanStartNewRecording);
|
||||
Assert.False(result.ShouldPauseActive);
|
||||
Assert.True(result.TotalBytes > 0);
|
||||
Assert.Equal(result.TotalBytes, result.UsedBytes + result.AvailableBytes);
|
||||
Assert.InRange(result.UsagePercent, 0, 100);
|
||||
Assert.InRange(result.FreePercent, 0, 100);
|
||||
Assert.InRange(result.UsagePercent + result.FreePercent, 99.8, 100.2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnabledProtection_ReportsConfiguredThresholdsAndConsistentPercentages()
|
||||
{
|
||||
var settings = CreateSettings(enableStorageGuard: true);
|
||||
settings.StorageGreenThresholdPercent = 35;
|
||||
settings.StorageRedThresholdPercent = 12;
|
||||
|
||||
var result = _service.CheckCanStartOrResume(settings);
|
||||
|
||||
Assert.True(result.IsEnabled);
|
||||
Assert.True(result.IsAvailable);
|
||||
Assert.Equal(35, result.GreenThresholdPercent);
|
||||
Assert.Equal(12, result.RedThresholdPercent);
|
||||
Assert.Equal(result.TotalBytes, result.UsedBytes + result.AvailableBytes);
|
||||
Assert.InRange(result.UsagePercent + result.FreePercent, 99.8, 100.2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidPath_ReturnsUnavailableStateInsteadOfThrowing()
|
||||
{
|
||||
var settings = CreateSettings(enableStorageGuard: true);
|
||||
settings.OutputRoot = "invalid\0path";
|
||||
|
||||
var result = _service.CheckCanStartOrResume(settings);
|
||||
|
||||
Assert.True(result.IsEnabled);
|
||||
Assert.False(result.IsAvailable);
|
||||
Assert.False(result.HasEnoughSpace);
|
||||
Assert.False(result.CanStartNewRecording);
|
||||
Assert.Equal(StorageTier.Red, result.Tier);
|
||||
Assert.Equal(0, result.TotalBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RedPercentageTier_DoesNotBlockFinalizeWhenAbsoluteTemporarySpaceIsAvailable()
|
||||
{
|
||||
var settings = CreateSettings(enableStorageGuard: true);
|
||||
settings.PauseRecordingWhenFreeSpaceBelowMegabytes = 0;
|
||||
settings.ResumeRecordingWhenFreeSpaceAboveMegabytes = 0;
|
||||
settings.StorageGreenThresholdPercent = 90;
|
||||
settings.StorageRedThresholdPercent = 85;
|
||||
|
||||
var result = _service.CheckCanFinalize(settings, estimatedTemporaryBytes: 1);
|
||||
|
||||
Assert.Equal(StorageTier.Red, result.Tier);
|
||||
Assert.True(result.HasEnoughSpace);
|
||||
Assert.True(result.ShouldPauseActive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Finalize_ReservesSourceEstimateInAdditionToPauseThreshold()
|
||||
{
|
||||
var settings = CreateSettings(enableStorageGuard: true);
|
||||
settings.PauseRecordingWhenFreeSpaceBelowMegabytes = int.MaxValue;
|
||||
|
||||
var result = _service.CheckCanFinalize(settings, estimatedTemporaryBytes: 1024);
|
||||
|
||||
Assert.False(result.HasEnoughSpace);
|
||||
Assert.True(result.RequiredBytes > 1024);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MultiSegmentFinalize_UsesConcatDemuxerWithoutMaterializingCombinedTs()
|
||||
{
|
||||
var arguments = FfmpegService.BuildMp4FinalizeArgumentList(
|
||||
"/records/input.ffconcat",
|
||||
"/records/output.remux.mp4",
|
||||
strategy: default,
|
||||
useConcatDemuxer: true);
|
||||
|
||||
Assert.Contains("concat", arguments);
|
||||
Assert.Contains("-safe", arguments);
|
||||
Assert.Contains("/records/input.ffconcat", arguments);
|
||||
Assert.DoesNotContain(".concat.ts", arguments);
|
||||
}
|
||||
|
||||
private static SystemSettingsDto CreateSettings(bool enableStorageGuard) => new()
|
||||
{
|
||||
OutputRoot = Path.GetTempPath(),
|
||||
EnableStorageGuard = enableStorageGuard,
|
||||
PauseRecordingWhenFreeSpaceBelowMegabytes = 1024,
|
||||
ResumeRecordingWhenFreeSpaceAboveMegabytes = 4096,
|
||||
StorageGreenThresholdPercent = 30,
|
||||
StorageRedThresholdPercent = 10
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user