using System.IO.Pipes; using System.Text.Json; using XFEEDToolBox.Core.Navigation; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public class NativeCruiseControlCapabilityTests { private const string Hash="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; private static Dictionary Cycle() { var now=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); return new(){["owner"]=new string('a',32),["startRequestId"]=new string('b',32),["releaseRequestId"]=new string('c',32), ["selectionGeneration"]=4UL,["entityId"]="12",["referenceWorldAddress"]="24",["activeSamples"]=5, ["enableAtUnixMilliseconds"]=now-160,["lastActiveAtUnixMilliseconds"]=now-80,["originalStopAtUnixMilliseconds"]=now-40,["offAtUnixMilliseconds"]=now-20}; } private static async Task Inspect(bool qualified,Dictionary? cycle,Action>? alter=null) { var pid=Random.Shared.Next(200000000,290000000);using var timeout=new CancellationTokenSource(TimeSpan.FromSeconds(5)); var result=new Dictionary{["schema"]=1,["processId"]=pid,["service"]=NativeCruiseControlChannel.Service,["gameSha256"]=Hash, ["enabled"]=true,["owningThread"]=8,["overchargeControl"]=true,["originalFuelRangeObservations"]=true,["nativeStopReceipts"]=true, ["expiringOriginalControl"]=true,["componentThermalModel"]=true,["controlTelemetrySchema"]=1,["overchargeControlQualified"]=qualified,["qualifiedCycle"]=cycle}; alter?.Invoke(result); await using var pipe=new NamedPipeServerStream($"XFEEDToolBox.{NativeCruiseControlChannel.Service}.{pid}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous); var serve=Task.Run(async()=> { await pipe.WaitForConnectionAsync(timeout.Token);var buffer=new byte[1024];var count=await pipe.ReadAsync(buffer,timeout.Token); using var request=JsonDocument.Parse(buffer.AsMemory(0,count));Check.Equal("describe",request.RootElement.GetProperty("op").GetString()!); var reply=JsonSerializer.SerializeToUtf8Bytes(new{ok=true,result});await pipe.WriteAsync(reply,timeout.Token);await pipe.WriteAsync(new byte[]{10},timeout.Token); if(OperatingSystem.IsWindows())pipe.WaitForPipeDrain(); }); try{return await new NativeCruiseControlChannel(pid,Hash).InspectAsync(timeout.Token);} finally{await serve;} } private static async Task Reject(Func action) {try{await action();}catch(InvalidDataException){return;}throw new InvalidOperationException("Unverified original SCO capability was accepted.");} [Test]public async Task AnInstalledUnqualifiedModuleStaysUnqualified() {var value=await Inspect(false,null);Check.That(value.Available&&!value.Qualified);} [Test]public async Task OriginalCycleEvidenceConfirmsOnlyItsPinnedModule() {var value=await Inspect(true,Cycle());Check.That(value.Available&&value.Qualified);} [Test]public async Task GlobalCountersWithoutOneOriginalCycleCannotQualify()=>await Reject(async()=>await Inspect(true,null)); [Test]public async Task FourSamplesCannotQualify() {var cycle=Cycle();cycle["activeSamples"]=4;await Reject(async()=>await Inspect(true,cycle));} [Test]public async Task OffMustFollowTheOriginalFalseCall() {var cycle=Cycle();cycle["offAtUnixMilliseconds"]=cycle["originalStopAtUnixMilliseconds"];await Reject(async()=>await Inspect(true,cycle));} [Test]public async Task MissingOwnerOrSelectionCannotQualify() {var cycle=Cycle();cycle["owner"]="";await Reject(async()=>await Inspect(true,cycle));cycle=Cycle();cycle["selectionGeneration"]=0UL;await Reject(async()=>await Inspect(true,cycle));} [Test]public async Task OriginalFuelAndStopContractsCannotBeDisabled() {foreach(var key in new[]{"originalFuelRangeObservations","nativeStopReceipts","componentThermalModel","expiringOriginalControl"})await Reject(async()=>await Inspect(true,Cycle(),row=>row[key]=false));} [Test]public async Task OlderSlopeOnlyControlProtocolCannotClaimTheComponentModel() {await Reject(async()=>await Inspect(true,Cycle(),row=>row["service"]="CruiseControl0514f"));} }