fix: harden recording recovery and dashboard metrics

This commit is contained in:
2026-08-14 19:20:24 +08:00
parent 506dca898e
commit 90a67bdf72
24 changed files with 607 additions and 46 deletions
@@ -272,7 +272,7 @@ public sealed class FfmpegFailureClassificationTests
}
[Fact]
public void RecoveryContext_LeavesCurlAfterExitWithoutResettingOneShotBudget()
public void RefreshedFlvRecovery_ReEnablesCurlAfterOverlongHeaders()
{
var curlContext = FfmpegService.InitialRecoveryContext with
{
@@ -280,18 +280,65 @@ public sealed class FfmpegFailureClassificationTests
HasTriedCurlFallback = true
};
var nextContext = FfmpegService.AdvanceRecoveryContext(
curlContext,
curlContext.InputOptionProfile,
var nextContext = FfmpegService.PrepareRefreshedStreamRecoveryContext(
FfmpegService.AdvanceRecoveryContext(
curlContext,
curlContext.InputOptionProfile,
"flv",
"flv",
refreshedStream: true),
"flv",
"flv",
refreshedStream: true);
hasOverlongHeadersFailure: true);
Assert.False(nextContext.UseCurlFallback);
Assert.True(nextContext.UseCurlFallback);
Assert.True(nextContext.HasTriedCurlFallback);
Assert.True(nextContext.HasRetriedWithRefreshedStream);
Assert.False(FfmpegService.ShouldFallbackToCurl("flv", true, nextContext.HasTriedCurlFallback));
}
[Fact]
public void RefreshedNonFlvRecovery_DisablesCurl()
{
var nextContext = FfmpegService.PrepareRefreshedStreamRecoveryContext(
FfmpegService.InitialRecoveryContext with
{
UseCurlFallback = true,
HasTriedCurlFallback = true
},
"hls",
hasOverlongHeadersFailure: true);
Assert.False(nextContext.UseCurlFallback);
Assert.True(nextContext.HasTriedCurlFallback);
}
[Fact]
public void RefreshedFlvRecovery_PreservesCurlRequirementAcrossLaterProcesses()
{
var priorContext = FfmpegService.InitialRecoveryContext with
{
UseCurlFallback = false,
HasTriedCurlFallback = true
};
var nextContext = FfmpegService.PrepareRefreshedStreamRecoveryContext(
priorContext,
"flv",
hasOverlongHeadersFailure: priorContext.HasTriedCurlFallback);
Assert.True(nextContext.UseCurlFallback);
Assert.True(nextContext.HasTriedCurlFallback);
}
[Theory]
[InlineData(false, true, false)]
[InlineData(false, false, true)]
[InlineData(true, true, true)]
public void FfmpegLinePersistence_SuppressesRecoverableStartupHandshakeNoise(
bool hasOpenedFirstSegment,
bool isStreamHandshakeFailure,
bool expected) =>
Assert.Equal(expected, FfmpegService.ShouldPersistFfmpegLine(hasOpenedFirstSegment, isStreamHandshakeFailure));
[Fact]
public void RecoveryContext_PreservesBudgetAcrossHlsFallbackAndReachesTimestampTranscode()
{