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<SystemNavigationCapabilities> Inspect(Action<JsonObject>? 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)));
}
}
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<SystemNavigationCapabilities> Inspect(Action<JsonObject>? 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)));
}
}