From 280f3b3fe94311d00abb0ee7d0fd7358e03ce55d Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 28 Jul 2026 18:05:54 +0200 Subject: [PATCH] fix(test): stop the streaming priority-apply tests reading a warm JIT Five tests in StreamingControllerPriorityApplyTests passed only when a sibling ran first in the same process. Run alone, they failed on assertions about world-state residency and completion backlog: DungeonCollapseBeforePromotionBase (line 355), InFlightNearLoad_DemotedBeforeFirstCompletion (536), HardRecenter_RejectsOldOverlappingLoadAndUnloadGenerations (582), HardRecenter_DropsStaleOutboxThroughBoundedAdmission (626), and DeferredCompaction_ApplyFailureRetainsExactResult. The state a sibling supplied was not data. It was compiled code. StreamingController meters each Tick against a wall-clock ceiling and StreamingWorkBudgetOptions.Default allows 2 ms per frame; these tests took that default. A cold first Tick has to JIT the whole publication path, and the meter's own diagnostics measured it at 10.55 ms with LastLimit=Time and one yield at stage publication-spatial-commit. The frame's first operation is admitted unconditionally through ensureProgress, so applyTerrain ran and the terrain assertion passed; the very next reservation, the GpuWorldState spatial commit, was refused, so the landblock never became resident in that frame. Any sibling that publishes a landblock first (DuplicateNearCompletions, for instance) warms that path and the same Tick then fits inside 2 ms. Pairing the failing test with that sibling passed; pairing it with DestinationReservation_StaleGenerationCannotClearReplacement, which drains no completions and therefore JITs nothing, still failed. Yielding mid-publication and resuming next frame is correct production behavior and other tests in this file assert exactly that. The defect was the setup: these tests assert which results publish, in what order, and under which generation, yet left the elapsed-time dimension at a value that made every assertion a function of machine speed and test order. Every controller in the class now takes a budget whose time ceiling cannot bind, applied uniformly so the next test added here does not reacquire the dependency. Count and byte ceilings keep their real values, including the deliberately small MaxCompletionAdmissions of ForceReloadWindow_DiscardsBufferedCompletionsFromOldWindow and the MaxCompletionsPerFrame scaling of the two tests that use it, so the bounded-admission behavior under test is untouched. No assertion was relaxed and no production code changed. All fourteen tests in the class now pass individually and together; Core is 3295 passed / 2 skipped, and two consecutive full-solution Release runs are 8826 passed / 5 skipped. Co-Authored-By: Claude Fable 5 --- .../StreamingControllerPriorityApplyTests.cs | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) 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(