using System.IO.Pipes; using System.Text.Json; using System.Text.Json.Nodes; using XFEEDToolBox.Core.Navigation; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public class LocalFlightCapabilityContractTests { private const string Hash="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; private static readonly SystemNavigationTarget Orbit=new(1,101,"Body",SystemTargetKind.Orbit); private static async Task Inspect(Action? alter=null,bool nativeSca=false) { var pid=Random.Shared.Next(200000000,290000000);using var timeout=new CancellationTokenSource(TimeSpan.FromSeconds(5)); var result=JsonSerializer.SerializeToNode(new{schema=1,name="XFEEDToolBox.Navigation",processId=pid,gameSha256=Hash,verified=true, owningThread=8,ready=true,inGame=true,continuousPose=true,continuousHeat=true,continuousShipHealth=true,independentShipHealth=true, localTargets=true,localNavigationSchema=1,localApplicationFlightControl=true,localApplicationFlightSchema=1,physicalInputSourceGuardSchema=1, applicationSteeringAxes=true,nativeSteering=true,referenceGeometry=true,adaptiveFlightControl=true,chargeAndCommitInterlock=true, localCruiseControl=false,localDockingRequests=false,localNativeAssists=false,localDockingPaths=false,localPlanetaryApproach=false,evidence="Isolated verified application-flight contract"})!.AsObject(); alter?.Invoke(result); await using var server=new NamedPipeServerStream($"XFEEDToolBox.Navigation.{pid}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous); var serve=Task.Run(async()=> { await server.WaitForConnectionAsync(timeout.Token);var buffer=new byte[1024];var count=await server.ReadAsync(buffer,timeout.Token); using var request=JsonDocument.Parse(buffer.AsMemory(0,count));Check.Equal("describe",request.RootElement.GetProperty("op").GetString()!); await server.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(new{ok=true,result}),timeout.Token);await server.WriteAsync(new byte[]{10},timeout.Token); if(OperatingSystem.IsWindows())server.WaitForPipeDrain(); }); try{return await new NativeSystemFlightControlDriver(pid,Hash,()=>new(),useNativeSupercruiseAssist:nativeSca).InspectAsync(timeout.Token);} finally{await serve;} } [Test]public async Task GeometryFlightDoesNotRequireAnSCOChannelOrEveryLandingFeature() { var value=await Inspect();Check.That(value.LocalFlightReady&&value.ApplicationFlightControlVerified&&value.TelemetryReady); Check.That(!value.OriginalOverchargeConfigured&&!value.OriginalDockingConfigured&&!value.Ready); Check.That(value.Supports(Orbit,new(false,false,true)),"Installed SCA hardware is irrelevant when this driver explicitly does not use SCA."); } [Test]public async Task OldOrIncompletePhysicalControlContractsCannotEnableFlight() { foreach(var name in new[]{"localApplicationFlightControl","physicalInputSourceGuardSchema","independentShipHealth","chargeAndCommitInterlock","applicationSteeringAxes"}) { var value=await Inspect(row=>row.Remove(name));Check.That(!value.LocalFlightReady&&!value.Supports(Orbit,new(false,false,false))); Check.That(value.ControlUnavailableReason?.Contains("更新")==true); } Check.That(!(await Inspect(row=>row["localApplicationFlightSchema"]=2)).LocalFlightReady); } [Test]public async Task UnopenedNativeScaCannotMasqueradeAsApplicationFlight() { var value=await Inspect(nativeSca:true);Check.That(!value.LocalFlightReady&&!value.ApplicationFlightControlVerified); Check.That(value.ControlUnavailableReason?.Contains("自主驾驶")==true); } [Test]public async Task TemporaryPoseLossRemainsDistinctFromAnUnsupportedPlugin() { var value=await Inspect(row=>row["continuousPose"]=false);Check.That(value.LocalFlightReady&&!value.TelemetryReady); Check.That(value.ControlUnavailableReason is null&&value.TelemetryIssue?.Contains("恢复")==true); } [Test]public async Task StationAndSurfaceSupportRemainTargetSpecific() { var value=await Inspect();var station=new SystemNavigationTarget(1,102,"Station",SystemTargetKind.Station,77); Check.That(!value.Supports(station,new(false,true,false))&&value.UnsupportedReason(station,new(false,true,false))?.Contains("停靠扩展")==true); var connected=value with{DockingRequests=true,NativeAssists=true,OriginalDockingConfigured=true}; Check.That(connected.Supports(station,new(false,true,true))); Check.That(!connected.Supports(station,new(false,false,false))); Check.That(!connected.Supports(station with{Kind=SystemTargetKind.SurfacePort},new(false,true,false))); } }