using AcDream.App.Rendering; using Xunit; namespace AcDream.App.Tests.Rendering; public sealed class ClipFrameUploadTests { [Theory] [InlineData(1, 144)] [InlineData(16, 144)] [InlineData(64, 192)] [InlineData(256, 256)] [InlineData(512, 512)] public void TerrainArena_RecordStride_RespectsDriverAlignment( int alignment, int expectedStride) { Assert.Equal(expectedStride, ClipFrameArenaLayout.RecordStride(alignment)); } [Fact] public void TerrainArena_AssignsEverySliceAUniqueOrderedRange() { const int stride = 256; Assert.Equal(0, ClipFrameArenaLayout.RecordOffset(0, stride)); Assert.Equal(256, ClipFrameArenaLayout.RecordOffset(1, stride)); Assert.Equal(512, ClipFrameArenaLayout.RecordOffset(2, stride)); Assert.Equal(1280, ClipFrameArenaLayout.RequiredBytes(5, stride)); } [Fact] public void UploadState_RegionsOnce_AndTerrainRangesInSubmissionOrder() { var state = new ClipFrameUploadState(); state.BeginFrame(); state.ValidateRegionsNotUploaded(); state.MarkRegionsUploaded(); Assert.True(state.RegionsUploaded); Assert.Throws(state.ValidateRegionsNotUploaded); state.ValidateTerrainReservation(4); state.CommitTerrainReservation(4); Assert.Equal(new[] { 0, 1, 2, 3 }, new[] { state.NextTerrainRecord(), state.NextTerrainRecord(), state.NextTerrainRecord(), state.NextTerrainRecord(), }); Assert.Equal(4, state.TerrainUploaded); Assert.Throws(() => state.NextTerrainRecord()); state.BeginFrame(); Assert.False(state.RegionsUploaded); Assert.Equal(0, state.TerrainReserved); Assert.Equal(0, state.TerrainUploaded); } [Fact] public void ResourceRing_RetainsAtMostOneResourcePerFencedFrameSlot() { var ring = new ClipFrameResourceRing(ClipFrame.FrameSlotCount); for (int slot = 0; slot < ClipFrame.FrameSlotCount; slot++) ring.Set(slot, new object()); // Pathological slice counts reuse ranges in the frame slot's one arena; // they cannot add another GL object to the ring. for (int slice = 0; slice < 10_000; slice++) Assert.True(ring.TryGet(slice % ClipFrame.FrameSlotCount, out _)); Assert.Equal(ClipFrame.FrameSlotCount, ring.Count); Assert.Throws(() => ring.Set(0, new object())); } [Fact] public void CapacityPolicy_ShrinksOneOffPathologicalPeakAfterHysteresis() { var policy = new ClipBufferCapacityPolicy(); int peak = policy.SelectCapacity(0, 1_000_000); Assert.True(peak >= 1_000_000); int first = policy.SelectCapacity(peak, 4_096); int second = policy.SelectCapacity(first, 4_096); int third = policy.SelectCapacity(second, 4_096); Assert.Equal(peak, first); Assert.Equal(peak, second); Assert.Equal(4_096, third); } [Fact] public void CapacityPolicy_OrdinaryDemandJitterCancelsPendingShrink() { var policy = new ClipBufferCapacityPolicy(); int capacity = policy.SelectCapacity(0, 65_536); capacity = policy.SelectCapacity(capacity, 4_096); capacity = policy.SelectCapacity(capacity, 20_000); // above 25% utilization capacity = policy.SelectCapacity(capacity, 4_096); capacity = policy.SelectCapacity(capacity, 4_096); Assert.Equal(65_536, capacity); } [Fact] public void CapacityTransaction_PublishesOnlySuccessfulResize() { int capacity = 4_096; Assert.Throws(() => ClipBufferCapacityTransaction.Resize( ref capacity, 8_192, (_, _) => throw new InvalidOperationException("BufferData failed"))); Assert.Equal(4_096, capacity); ClipBufferCapacityTransaction.Resize( ref capacity, 8_192, (previous, next) => { Assert.Equal(4_096, previous); Assert.Equal(8_192, next); }); Assert.Equal(8_192, capacity); // A later stage failure must not roll accounting back to the old store. Action laterFailure = () => throw new InvalidOperationException("later bind failed"); Assert.Throws(laterFailure); Assert.Equal(8_192, capacity); } }