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

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using XFESystem.Kernel;
using Xunit;

namespace XFESystem.NativeInterop.Tests;

public sealed class NativePointerFrameProbeTests
{
    [Fact]
    public void RealCounterAndActualConsumedReportBindToPresent()
    {
        var probe = new NativePointerFrameProbe();
        probe.Start(1_000_000, 1000, 50, new(100, 100, 0));
        probe.ObserveConsumed(101, 1100, 1200, 80, 90);
        probe.CapturePresent(51, 1300, 1400);
        var dump = probe.Stop(1500, 51, new(101, 101, 0));
        Assert.False(probe.IsCapturing);
        Assert.Contains("|FramesBefore|50|FramesAfter|51", dump);
        Assert.Contains("|ObservedBefore|100|ObservedAfter|101|ConsumedBefore|100|ConsumedAfter|101", dump);
        Assert.Contains("FRAME|Seq|51|BeginTicks|1300|EndTicks|1400|InputSeq|101|InputTicks|1100|DispatchTicks|1200|X|80|Y|90\n", dump);
        Assert.EndsWith("XFE_POINTER_TIMING_END\n", dump);
    }

    [Fact]
    public void AbortedAndNoOpPresentCallsCannotIncreaseCapturedFrames()
    {
        var probe = new NativePointerFrameProbe(); probe.Start(1000, 10, 50, new(0, 0, 0));
        probe.CapturePresent(50, 12, 13); probe.CapturePresent(50, 14, 15);
        string dump = probe.Stop(20, 50, new(0, 0, 0));
        Assert.DoesNotContain("\nFRAME|", dump);
        Assert.Contains("|IgnoredDuplicatePresentCalls|2", dump);
        Assert.Contains("|FramesBefore|50|FramesAfter|50", dump);
    }

    [Fact]
    public void RingOverflowIsExplicitAndCannotHideSlowFrames()
    {
        var probe = new NativePointerFrameProbe(); probe.Start(1000, 0, 0, new(0, 0, 0));
        for (int index = 1; index <= NativePointerFrameProbe.Capacity + 3; index++) probe.CapturePresent(index, index * 10, index * 10 + 1);
        var dump = probe.Stop(50000, NativePointerFrameProbe.Capacity + 3, new(0, 0, 0));
        Assert.Equal(NativePointerFrameProbe.Capacity, dump.Split('\n').Count(line => line.StartsWith("FRAME|")));
        Assert.Contains("|DroppedFrames|3", dump);
    }

    [Fact]
    public void MissingCounterSequenceAndInvalidInputRemainVisible()
    {
        var probe = new NativePointerFrameProbe(); probe.Start(1000, 10, 10, new(1, 1, 0));
        probe.ObserveConsumed(2, 15, 14, 0, 0);
        probe.CapturePresent(12, 20, 21);
        var dump = probe.Stop(30, 12, new(2, 2, 1));
        Assert.Contains("|DroppedFrames|1|InvalidInputReports|1", dump);
        Assert.Contains("|LostBefore|0|LostAfter|1", dump);
    }

    [Fact]
    public void HotPathHasNoManagedAllocationAfterPreparation()
    {
        var probe = new NativePointerFrameProbe(); probe.Start(1000, 0, 0, new(0, 0, 0));
        // Warm each method before the measured allocation counter is taken.
        probe.ObserveConsumed(1, 1, 2, 1, 1); probe.CapturePresent(1, 3, 4);
        long before = GC.GetAllocatedBytesForCurrentThread();
        for (int index = 2; index <= 3000; index++)
        {
            probe.ObserveConsumed(index, index * 10, index * 10 + 1, index, 1);
            probe.CapturePresent(index, index * 10 + 2, index * 10 + 3);
        }
        Assert.Equal(before, GC.GetAllocatedBytesForCurrentThread());
    }

    [Fact]
    public void RestartDiscardsOnlyPriorMeasurementNotSourceCounters()
    {
        var probe = new NativePointerFrameProbe(); probe.Start(1000, 1, 1, new(1, 1, 0));
        probe.CapturePresent(2, 2, 3); _ = probe.Stop(4, 2, new(1, 1, 0));
        probe.Start(1000, 10, 20, new(30, 30, 0));
        probe.CapturePresent(21, 11, 12);
        var dump = probe.Stop(15, 21, new(30, 30, 0));
        Assert.Contains("|FramesBefore|20|FramesAfter|21", dump);
        Assert.DoesNotContain("FRAME|Seq|2|", dump);
    }

    [Fact]
    public void NativeDumpUsesBoundedChunksAndSealsEveryCapturedFrame()
    {
        var probe = new NativePointerFrameProbe(); probe.Start(1000, 0, 0, new(0, 0, 0));
        for (int index = 1; index <= NativePointerFrameProbe.Capacity; index++) probe.CapturePresent(index, index * 10, index * 10 + 1);
        var chunks = new List<string>();
        probe.Stop(50000, NativePointerFrameProbe.Capacity, new(0, 0, 0), chunks.Add);
        Assert.True(chunks.Count > 1);
        Assert.All(chunks, chunk => Assert.True(chunk.Length <= 16_000));
        string dump = string.Concat(chunks);
        Assert.Equal(NativePointerFrameProbe.Capacity, dump.Split('\n').Count(line => line.StartsWith("FRAME|")));
        Assert.Contains("|FramesPresentedDelta|4096|CapturedFrames|4096|Overflow|0", dump);
    }
}