XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.IO.Pipes;
using System.Text.Json;
using XFEEDToolBox.Core.Galaxy;
using XFEExtension.NetCore.XUnit.Attributes;

namespace XFEEDToolBox.Test;

[TestFixture]
public class NativeGalaxyCellsTests
{
    private static async Task Serve(int id,object result,CancellationToken token,Action<JsonElement>? inspect=null)
    {
        await using var server=new NamedPipeServerStream($"XFEEDToolBox.Navigation.{id}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous);
        await server.WaitForConnectionAsync(token);var buffer=new byte[65536];var size=await server.ReadAsync(buffer,token);
        using(var request=JsonDocument.Parse(buffer.AsMemory(0,size)))inspect?.Invoke(request.RootElement);
        await server.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(new{ok=true,result}),token);await server.WriteAsync(new byte[]{10},token);
        if(OperatingSystem.IsWindows())server.WaitForPipeDrain();
    }

    [Test] public async Task ExactCellsPublishRealRowsBeforeDoneAndKeepTheWholeCellCorner()
    {
        var id=Random.Shared.Next(100000000,110000000);using var deadline=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var completed=false;var partialBeforeDone=false;var address=(1UL<<44)|7;
        var server=Task.Run(async()=>
        {
            await Serve(id,new{generation=7,done=false,error="",total=1,items=new[]{new{name="Cell corner",systemAddress=address.ToString(),position=new[]{1000d,1000d,1000d},starClass="M"}},
                scope="requested-cells",requestedCells=1,minimumMassCode=7,processedCells=0,totalCells=1,failedCells=0,truncated=false,complete=false,origin=new[]{1d,2d,3d}},deadline.Token,r=>
                {Check.Equal("galaxy.cells",r.GetProperty("op").GetString());Check.Equal("7",r.GetProperty("cellAddresses")[0].GetString());Check.Equal(8,r.GetProperty("radii").GetArrayLength());});
            await Serve(id,new{generation=7,done=true,error="",total=1,items=Array.Empty<object>(),scope="requested-cells",requestedCells=1,
                minimumMassCode=7,processedCells=1,totalCells=1,failedCells=0,truncated=false,complete=true,origin=new[]{1d,2d,3d}},deadline.Token,r=>
                {Check.Equal(1,r.GetProperty("offset").GetInt32());completed=true;});
        });
        var catalog=new NativeGalaxyCatalog(id);catalog.RegionProgress+=progress=>
        {if(progress.Systems.Count>0)partialBeforeDone=!completed&&!progress.Done;};
        var result=await catalog.CellsAsync(new(0,0,0),Enumerable.Repeat(1d,8).ToArray(),new[]{7UL},deadline.Token);await server;
        Check.That(partialBeforeDone);Check.Equal(1,result.Systems.Count);Check.Equal(1000d,result.Systems[0].Position.X);
        Check.That(result.AreRequestedCellsCovered&&!result.IsFullyCovered);Check.Equal(7,result.MinimumMassCode);
        Check.Equal(2d,result.Origin!.Y);
    }

    [Test] public void RequestedMassSevenCoverageDoesNotClaimAllMassSphereCoverage()
    {
        using var json=JsonDocument.Parse("{\"scope\":\"requested-cells\",\"requestedCells\":1,\"minimumMassCode\":7,\"processedCells\":1,\"totalCells\":1,\"failedCells\":0,\"truncated\":false,\"complete\":true}");
        var result=NativeGalaxyCatalog.ReadCoverage(json.RootElement,[]);
        Check.That(result.AreRequestedCellsCovered&&!result.IsFullyCovered);Check.Equal(1,result.RequestedCells);
        using var changed=JsonDocument.Parse("{\"scope\":\"requested-cells\",\"requestedCells\":2,\"minimumMassCode\":7,\"processedCells\":1,\"totalCells\":1}");
        Check.Throws<InvalidDataException>(()=>NativeGalaxyCatalog.ReadCoverage(changed.RootElement,[]));
    }

    [Test] public void CellRequestRejectsNoncanonicalAddressesAndUnsupportedKnownProtocolBeforeIpc()
    {
        var catalog=new NativeGalaxyCatalog(123);var radii=Enumerable.Repeat(1d,8).ToArray();
        Check.Throws<ArgumentException>(()=>catalog.CellsAsync(new(0,0,0),radii,new[]{1UL<<44}));
        Check.Throws<ArgumentException>(()=>catalog.CellsAsync(new(0,0,0),radii,new[]{7UL,7UL}));
        using var description=JsonDocument.Parse("{\"processId\":123}");catalog.ApplyProtocolDescription(description.RootElement);
        Check.Throws<NotSupportedException>(()=>catalog.CellsAsync(new(0,0,0),radii,new[]{7UL}));
    }
    [Test] public async Task CellPagesRejectMissingOrChangedOriginsAndConflictingStarIdentities()
    {
        for(var scenario=0;scenario<4;scenario++)
        {
            var id=Random.Shared.Next(114000000,115000000);using var deadline=new CancellationTokenSource(TimeSpan.FromSeconds(5));
            var variant=scenario;var address=1UL<<44;
            object Reply(bool first)
            {
                var origin=variant==0&&first||variant==2&&!first?null:new[]{variant==1&&!first?4d:1d,2d,3d};
                var row=new{name=variant==3&&!first?"Conflicting name":"Fixture star",systemAddress=address.ToString(),position=new[]{0d,0d,0d},starClass="M"};
                return new{generation=72,done=!first,error="",total=2,items=new[]{row},scope="requested-cells",requestedCells=1,
                    minimumMassCode=0,processedCells=first?0:1,totalCells=1,failedCells=0,truncated=false,complete=!first,origin};
            }
            var server=Task.Run(async()=>
            {
                await Serve(id,Reply(true),deadline.Token);
                if(variant!=0)await Serve(id,Reply(false),deadline.Token);
                await Serve(id,new{generation=72,done=true},deadline.Token,r=>Check.Equal("galaxy.cancel",r.GetProperty("op").GetString()));
                await Serve(id,new{generation=72,done=true},deadline.Token,r=>Check.Equal("galaxy.result",r.GetProperty("op").GetString()));
            });
            try
            {
                await new NativeGalaxyCatalog(id).CellsAsync(new(0,0,0),Enumerable.Repeat(1d,8).ToArray(),new[]{0UL},deadline.Token);
                throw new Exception("Invalid cell page was accepted");
            }
            catch(InvalidDataException){}
            await server;
        }
    }
}