using XFEEDToolBox.Core.Navigation; using XFEEDToolBox.Core.Session; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public sealed class NativeFlightHealthGapPolicyTests { private static readonly DateTimeOffset Now=DateTimeOffset.Parse("2026-10-27T07:41:46+08:00"); [Test]public void AReleasedInputJumpMayOutlastThirtySecondsButNeverExceedsItsBoundedReadOnlyWindow() { var gap=new NativeFlightHealthGapPolicy();var error=new InvalidOperationException("Native main-ship health unavailable or stale"); Check.That(!gap.Observe(error,Now,false).PauseMonitoring); Check.Equal("health-gap",gap.Observe(error,Now.AddSeconds(29),true).Phase); var loading=gap.Observe(error,Now.AddSeconds(30),true); Check.That(!loading.PauseMonitoring&&!loading.SafetyStop&&loading.ExpectedInputFreeJumpLoading); Check.Equal("input-free-jump-loading",loading.Phase);Check.Equal(Now,loading.UnavailableSince!.Value); Check.That(!gap.Observe(error,Now.AddMilliseconds(74999),true).PauseMonitoring); Check.That(gap.Observe(error,Now.AddSeconds(75),true).PauseMonitoring); } [Test]public void MissingReleaseEvidenceAndTheOriginalJumpDeadlineNeverBorrowTheLoadingExemption() { var gap=new NativeFlightHealthGapPolicy();var error=new IOException("health transport"); gap.Observe(error,Now,false); Check.That(gap.Observe(error,Now.AddSeconds(30),false).PauseMonitoring); var witnessed=new NativeFlightHealthGapPolicy();witnessed.Observe(error,Now,true); Check.That(!witnessed.Observe(error,Now.AddSeconds(31),true).PauseMonitoring); // The coordinator withdraws its witness at the original jump's 75s, // independent of this gap's later start or any intermediate polling. Check.That(witnessed.Observe(error,Now.AddSeconds(60),false).PauseMonitoring); } [Test]public void UnknownIdentityAndWrappedProtocolErrorsNeverBecomeExpectedLoading() { foreach(var error in new Exception[]{new InvalidDataException("wrong ship"),new InvalidOperationException("Another controller owns navigation"), new IOException("transport wrapper",new InvalidDataException("wrong build")),new IOException("unknown inner",new InvalidOperationException("unverified interface")), new AggregateException(new IOException("pipe"),new InvalidDataException("reordered entity")),new FormatException("bad native value")}) { Check.That(!NativeFlightHealthGapPolicy.RecoverableGap(error,default)); var result=new NativeFlightHealthGapPolicy().Observe(error,Now,true); Check.That(result.PauseMonitoring&&!result.SafetyStop&&!result.ExpectedInputFreeJumpLoading); } } [Test]public void OnlyKnownMissingHealthAndTransportErrorsReceiveReadOnlyGrace() { foreach(var error in new Exception[]{new FlightTelemetryUnavailableException("stale health"),new IOException("broken pipe"),new TimeoutException("read timeout"), new OperationCanceledException("IPC read deadline"),new InvalidOperationException("Native player telemetry unavailable or stale"), new AggregateException(new IOException("pipe"),new FlightTelemetryUnavailableException("stale"))}) Check.That(NativeFlightHealthGapPolicy.RecoverableGap(error,default)); using var stop=new CancellationTokenSource();stop.Cancel(); Check.That(!NativeFlightHealthGapPolicy.RecoverableGap(new IOException("pipe"),stop.Token)); var cancelled=false;try{new NativeFlightHealthGapPolicy().Observe(new IOException("pipe"),Now,true,stop.Token);}catch(OperationCanceledException){cancelled=true;} Check.That(cancelled); } [Test]public void ALoadingWitnessNeverRenewsHealthInputAuthorityAndRecoveryNeedsAnActualNewSample() { var gap=new NativeFlightHealthGapPolicy();var sampled=Now;var error=new FlightTelemetryUnavailableException("stale"); Check.That(NativeFlightHealthGapPolicy.InputSampleFresh(sampled,Now.AddMilliseconds(500))); Check.That(!NativeFlightHealthGapPolicy.InputSampleFresh(sampled,Now.AddMilliseconds(501))); gap.Observe(error,Now,true);Check.That(!gap.Observe(error,Now.AddSeconds(31),true).PauseMonitoring); Check.That(!NativeFlightHealthGapPolicy.InputSampleFresh(sampled,Now.AddSeconds(31))); gap.Recovered();Check.That(gap.UnavailableSince is null); Check.That(!NativeFlightHealthGapPolicy.InputSampleFresh(sampled,Now.AddSeconds(32))); Check.That(NativeFlightHealthGapPolicy.InputSampleFresh(Now.AddSeconds(32),Now.AddSeconds(32))); Check.That(!NativeFlightHealthGapPolicy.InputSampleFresh(Now.AddSeconds(33),Now.AddSeconds(32))); } [Test]public void RealHealthAndThreatProtectionPreemptsAnyLoadingWitness() { foreach(var error in new Exception[]{new FlightHealthPauseException(),new FlightThreatPauseException(),new AggregateException(new IOException("pipe"),new FlightHealthPauseException())}) { var result=new NativeFlightHealthGapPolicy().Observe(error,Now,true); Check.That(result.SafetyStop&&!result.PauseMonitoring&&!result.ExpectedInputFreeJumpLoading);Check.Equal("safety-stop",result.Phase); } } }