Unit tests for SceneHandoffPolicy behavior. Exercises EvaluatePredecessor with successful drain, reported failure, faulted drain task, and verifies that successor always proceeds to recovery regardless of predecessor outcome.
#nullable enable
using System;
using Hexagon.V2.Kernel;
using Hexagon.V2.Runtime;
namespace Hexagon.V2.Tests.Runtime;
[TestClass]
public sealed class SceneHandoffPolicyTests
{
[TestMethod]
public void CleanPredecessorProceedsWithoutWarning()
{
var verdict = SceneHandoffPolicy.EvaluatePredecessor(
OperationOutcome<OperationResult>.Success( OperationResult.Success() ) );
Assert.AreEqual( SceneHandoffPredecessorState.Clean, verdict.State );
Assert.IsFalse( verdict.ShouldWarn );
Assert.IsNull( verdict.Diagnostic );
Assert.IsTrue( verdict.ProceedsToRecovery );
}
[TestMethod]
public void FailedDrainResultProceedsWithDiagnostic()
{
var verdict = SceneHandoffPolicy.EvaluatePredecessor(
OperationOutcome<OperationResult>.Success(
OperationResult.Failure( ErrorCode.InternalError, "host resources did not close cleanly" ) ) );
Assert.AreEqual( SceneHandoffPredecessorState.DrainReportedFailure, verdict.State );
Assert.IsTrue( verdict.ShouldWarn );
StringAssert.Contains( verdict.Diagnostic, "did not close cleanly" );
Assert.IsTrue( verdict.ProceedsToRecovery );
}
[TestMethod]
public void FaultedDrainTaskProceedsWithDiagnostic()
{
var verdict = SceneHandoffPolicy.EvaluatePredecessor(
OperationOutcome<OperationResult>.Failure( new InvalidOperationException( "teardown NRE" ) ) );
Assert.AreEqual( SceneHandoffPredecessorState.DrainFaulted, verdict.State );
Assert.IsTrue( verdict.ShouldWarn );
StringAssert.Contains( verdict.Diagnostic, "teardown NRE" );
Assert.IsTrue( verdict.ProceedsToRecovery );
}
[TestMethod]
public void NoPredecessorOutcomeEverBlocksTheSuccessor()
{
// The load-bearing invariant of the self-heal: whatever the predecessor's drain did, the
// successor proceeds to the exclusive lease and WAL recovery, which are the sole authorities
// on ownership and integrity. A regression back to a fail-closed handoff must trip here.
var outcomes = new[]
{
OperationOutcome<OperationResult>.Success( OperationResult.Success() ),
OperationOutcome<OperationResult>.Success(
OperationResult.Failure( ErrorCode.InternalError, "drain failed" ) ),
OperationOutcome<OperationResult>.Failure( new InvalidOperationException( "faulted" ) )
};
foreach ( var outcome in outcomes )
Assert.IsTrue( SceneHandoffPolicy.EvaluatePredecessor( outcome ).ProceedsToRecovery );
}
}