diff --git a/tests/AcDream.Core.Tests/Streaming/StreamingControllerPriorityApplyTests.cs b/tests/AcDream.Core.Tests/Streaming/StreamingControllerPriorityApplyTests.cs index d9bdd3e4..27b86b6c 100644 --- a/tests/AcDream.Core.Tests/Streaming/StreamingControllerPriorityApplyTests.cs +++ b/tests/AcDream.Core.Tests/Streaming/StreamingControllerPriorityApplyTests.cs @@ -11,6 +11,29 @@ namespace AcDream.Core.Tests.Streaming; public class StreamingControllerPriorityApplyTests { + /// + /// One frame of streaming work is bounded by a wall-clock ceiling + /// ( allows 2 ms). That + /// ceiling is a production scheduling knob, not the subject of these + /// tests: every assertion here is about which results publish, in what + /// order, and under which generation. Leaving the elapsed-time dimension + /// at its production value makes each assertion depend on how much of the + /// publication path a previous test already JIT-compiled in this process — + /// a cold first Tick spends about 10 ms inside publication, the + /// meter yields at publication-spatial-commit, and the landblock + /// never reaches in that frame. Raising only + /// the time dimension removes that hidden input; every count and byte + /// ceiling keeps its real value so bounded-admission behavior under test + /// is unchanged. + /// + private const double UntimedFrameMilliseconds = 3_600_000d; + + private static StreamingWorkBudgetOptions UntimedBudget() => + StreamingWorkBudgetOptions.Default with + { + MaxUpdateMilliseconds = UntimedFrameMilliseconds, + }; + private static LandblockStreamResult.Loaded LoadedOf(uint canonicalId, ulong generation = 0) => new(canonicalId, LandblockStreamTier.Near, new LoadedLandblock(canonicalId, new LandBlock(), Array.Empty()), @@ -85,7 +108,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (lb, _) => applied.Add(lb.LandblockId), state: state, nearRadius: 4, - farRadius: 12) + farRadius: 12, + workBudgetOptions: UntimedBudget()) { MaxCompletionsPerFrame = 4 }; ctrl.BeginDestinationReservation(1, priority, 0); @@ -130,7 +154,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (lb, _) => applied.Add(lb.LandblockId), state: state, nearRadius: 4, - farRadius: 12) + farRadius: 12, + workBudgetOptions: UntimedBudget()) { MaxCompletionsPerFrame = 4 }; // Set a priority id that will NEVER appear in the outbox. @@ -152,7 +177,7 @@ public class StreamingControllerPriorityApplyTests } private static StreamingWorkBudgetOptions GenerousBudget() => new( - MaxUpdateMilliseconds: 100, + MaxUpdateMilliseconds: UntimedFrameMilliseconds, MaxCompletionAdmissions: 64, MaxAdoptedCpuBytes: 16 * StreamingWorkBudgetOptions.MiB, MaxEntityOperations: 10_000, @@ -170,7 +195,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (_, _) => { }, state: new GpuWorldState(), nearRadius: 1, - farRadius: 2); + farRadius: 2, + workBudgetOptions: UntimedBudget()); controller.BeginDestinationReservation(1, 0x11340021u, 1); controller.BeginDestinationReservation(2, 0x20210123u, 0); @@ -220,7 +246,8 @@ public class StreamingControllerPriorityApplyTests }, state: new GpuWorldState(), nearRadius: 4, - farRadius: 12) + farRadius: 12, + workBudgetOptions: UntimedBudget()) { MaxCompletionsPerFrame = 3, }; @@ -259,7 +286,7 @@ public class StreamingControllerPriorityApplyTests nearRadius: 4, farRadius: 12, workBudgetOptions: new StreamingWorkBudgetOptions( - MaxUpdateMilliseconds: 100, + MaxUpdateMilliseconds: UntimedFrameMilliseconds, MaxCompletionAdmissions: 4, MaxAdoptedCpuBytes: 1_000_000, MaxEntityOperations: 1_000, @@ -296,7 +323,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (build, _) => applied.Add(build.LandblockId), state: state, nearRadius: 1, - farRadius: 2); + farRadius: 2, + workBudgetOptions: UntimedBudget()); ctrl.Tick(10, 10); ctrl.ForceReloadWindow(); @@ -348,7 +376,8 @@ public class StreamingControllerPriorityApplyTests state: state, nearRadius: 0, farRadius: 2, - removeTerrain: id => terrainRemoved.Add(id)); + removeTerrain: id => terrainRemoved.Add(id), + workBudgetOptions: UntimedBudget()); ctrl.Tick(10, 10); // generation 0 promotion supersedes its queued Far base. Assert.Equal(new[] { outdoorId }, terrainApplied); @@ -403,7 +432,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (build, _) => applied.Add(build.LandblockId), state: state, nearRadius: 0, - farRadius: 3); + farRadius: 3, + workBudgetOptions: UntimedBudget()); ctrl.Tick(10, 10); // target starts Far. ctrl.Tick(10, 13); // target becomes Near; promotion is now in flight. @@ -503,7 +533,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (build, _) => applied.Add(build), state: state, nearRadius: 0, - farRadius: 3); + farRadius: 3, + workBudgetOptions: UntimedBudget()); ctrl.Tick(10, 10); // target's initial LoadNear is now in flight. ctrl.Tick(10, 13); // target becomes desired Far before it completes. @@ -559,7 +590,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (build, _) => applied.Add(build.LandblockId), state: state, nearRadius: 1, - farRadius: 2); + farRadius: 2, + workBudgetOptions: UntimedBudget()); ctrl.Tick(10, 10); ulong oldGeneration = loads.Single(load => load.Id == overlap).Generation; @@ -602,7 +634,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (build, _) => applied.Add(build.LandblockId), state: new GpuWorldState(), nearRadius: 1, - farRadius: 2) + farRadius: 2, + workBudgetOptions: UntimedBudget()) { MaxCompletionsPerFrame = 1 }; ctrl.Tick(10, 10); @@ -644,7 +677,8 @@ public class StreamingControllerPriorityApplyTests applyTerrain: (_, _) => { }, state: state, nearRadius: 0, - farRadius: 0); + farRadius: 0, + workBudgetOptions: UntimedBudget()); ctrl.Tick(10, 10); state.AddLandblock(