Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ public override async Task RunAsync()
res!.TotalCount == 200);

// Pull next 4 pages by walking ItemAt (simulating virtualized scroll).
// Three pumps per page so the 10ms Task.Delay in FetchPageAsync plus
// the Apply continuation reliably lands before the next ItemAt — the
// 2-pump variant flaked under CI load (got 4 / expected >= 5).
for (int i = 0; i < 5; i++)
{
_ = res!.ItemAt(25 * i + 12);
await Harness.Render();
await Harness.Render();
await Harness.Render();
}

H.Check($"InfiniteBasic_MultiplePagesFetched (got {pageFetches})",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,12 @@ internal class RefreshMidScroll(Harness h) : SelfTestFixtureBase(h)
{
public override async Task RunAsync()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});

int unobserved = 0;
EventHandler<UnobservedTaskExceptionEventArgs> handler = (_, e) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,12 @@ public override async Task RunAsync()
// Give any lingering continuations one more frame to settle and force a GC
// to trigger finalization of any tasks that might throw unobserved.
await Harness.Render();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
await Harness.Render();

H.Check($"AsyncResource_UnmountDuringFetch_NoUnobserved (got {unobserved})",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ public override async Task RunAsync()
{
// Drain any unobserved tasks that earlier fixtures finalized but whose
// events haven't fired yet — otherwise the test "inherits" unrelated
// noise and flakes.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// noise and flakes. Marshal off the UI dispatcher: a finalizer that
// needs to release a UI-thread-affine RCW would deadlock if the
// dispatcher were blocked inside WaitForPendingFinalizers.
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});

int unobserved = 0;
EventHandler<UnobservedTaskExceptionEventArgs> handler = (_, e) =>
Expand Down Expand Up @@ -120,9 +125,12 @@ public override async Task RunAsync()
// cancelled via UseEffect teardown before we drain for unobserved exceptions.
host.Dispose();
await Harness.Render();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
await Harness.Render();
H.Check($"DepsThrashing_NoUnobserved (got {unobserved})", unobserved == 0);
}
Expand Down Expand Up @@ -302,9 +310,12 @@ internal class FastRemount(Harness h) : SelfTestFixtureBase(h)
{
public override async Task RunAsync()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});

int unobserved = 0;
EventHandler<UnobservedTaskExceptionEventArgs> handler = (_, e) =>
Expand Down Expand Up @@ -345,9 +356,12 @@ public override async Task RunAsync()
// Final unmount and let any cancellation callbacks drain.
setVisible!(false);
for (int i = 0; i < 4; i++) await Harness.Render();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
await Harness.Render();

// Every mount should have kicked off a fetch. Every one must be cancelled
Expand Down Expand Up @@ -405,9 +419,12 @@ internal class DataGridEditMutation(Harness h) : SelfTestFixtureBase(h)
{
public override async Task RunAsync()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});

int unobserved = 0;
EventHandler<UnobservedTaskExceptionEventArgs> handler = (_, e) =>
Expand Down Expand Up @@ -531,9 +548,12 @@ public override async Task RunAsync()
finalInRange);

// Invariant 7: no unobserved exceptions leaked from any pending mutator.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
await Harness.Render();
H.Check($"DataGridEditMutation_NoUnobserved (got {unobserved})", unobserved == 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ private async Task RunInner()
sv.ChangeView(null, 0, null, disableAnimation: true);
await Harness.Render(600);

GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
await Task.Run(() => { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); });

H.Check("HookPaging_Framerate_FinalData",
H.FindTextContaining("Emp-") is not null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,15 @@ public override async Task RunAsync()
host.Mount(_ => TextBlock("warmup-done"));
await Harness.Render();

// Force GC so the baseline reflects steady state.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// Force GC so the baseline reflects steady state. Marshal off
// the UI dispatcher to avoid a finalizer-deadlock on UI-thread-
// affine RCWs.
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});

long baseline = GC.GetAllocatedBytesForCurrentThread();

Expand All @@ -568,9 +573,12 @@ public override async Task RunAsync()
await Harness.Render();
}

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
await Task.Run(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
});
long after = GC.GetAllocatedBytesForCurrentThread();
long delta = after - baseline;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1047,10 +1047,10 @@ DockNode BuildInitial()
var liveLayout = BuildInitial();
host.Mount(_ => new DockManager { Layout = liveLayout });
await Harness.Render();
// Visual-demo "let the eye register" pauses kept short so the
// 20-step walk stays well inside the default fixture timeout
// (15s) under CI load. Bump back up locally for slow-motion runs.
await Task.Delay(50);
// Visual-demo "let the eye register" pauses — tightened for
// CI stress runs (target ~4s total). Bump back up locally
// for slow-motion manual viewing.
await Task.Delay(20);

// Targets we walk through in each group.
var targets = new[]
Expand Down Expand Up @@ -1085,7 +1085,7 @@ DockNode BuildInitial()
liveLayout = BuildInitial();
host.Mount(_ => new DockManager { Layout = liveLayout });
await Harness.Render();
await Task.Delay(20);
await Task.Delay(5);

// Find the target group in the fresh tree by anchor.
var targetGroup = FindGroupContaining(liveLayout, anchor);
Expand Down Expand Up @@ -1117,7 +1117,7 @@ DockNode BuildInitial()
int splits = CountSplits(liveLayout);
if (target != DockTarget.Center && splits > 3) splitObserved++;

await Task.Delay(30); // observer pause — minimal for CI; bump for manual demo
await Task.Delay(5); // observer pause — minimal for CI; bump for manual demo
}
}

Expand Down Expand Up @@ -1233,16 +1233,17 @@ public override async Task RunAsync()

host.Mount(_ => Build());
await Harness.Render();
// Timing budget (must fit under the default fixture timeout):
// initial settle: 700ms
// 5 loops × (5 nudges × 200ms + after-final 400ms): 7000ms
// total delay budget: ~7.7s
// Timing budget (target ~5s, 15s timeout):
// initial settle: 200ms
// 5 loops × (5 nudges × 60ms + after-final 120ms): 2100ms
// total delay budget: ~2.3s
// render overhead (~80ms × ~26 renders): ~2s
// grand total: ~9.7s → comfortable margin under 15s
// The fixture is meant as a paced visual demo — 200ms per
// nudge is still humanly observable (5 frames/sec); the prior
// 400ms × 25 nudges + extras blew past the timeout by ~1s.
await Task.Delay(700);
// grand total: ~4.4s → comfortable margin under 5s
// Nudge pacing still leaves the resize visible (~17fps);
// tighter than the original 200ms but still observable for
// manual debug runs. Stress runs benefit from the shorter
// wall clock per shard.
await Task.Delay(200);

var splitters = H.FindAllControls<DockSplitterControl>(_ => true);
var rowSplitter = splitters.FirstOrDefault(s => s.Direction == DockSplitterDirection.Rows);
Expand All @@ -1256,55 +1257,55 @@ public override async Task RunAsync()
{
FireResizeDelta(rowSplitter!, delta: 40, isFinal: false);
await Harness.Render();
await Task.Delay(200);
await Task.Delay(60);
}
FireResizeDelta(rowSplitter!, delta: 0, isFinal: true);
await Harness.Render();
await Task.Delay(400);
await Task.Delay(120);

// 2) Grow the top row back — five -40-DIP nudges.
for (int i = 0; i < 5; i++)
{
FireResizeDelta(rowSplitter!, delta: -40, isFinal: false);
await Harness.Render();
await Task.Delay(200);
await Task.Delay(60);
}
FireResizeDelta(rowSplitter!, delta: 0, isFinal: true);
await Harness.Render();
await Task.Delay(400);
await Task.Delay(120);

// 3) Shrink the top-row's left column (editor) — five 40 DIP.
for (int i = 0; i < 5; i++)
{
FireResizeDelta(colSplitters[0], delta: 40, isFinal: false);
await Harness.Render();
await Task.Delay(200);
await Task.Delay(60);
}
FireResizeDelta(colSplitters[0], delta: 0, isFinal: true);
await Harness.Render();
await Task.Delay(400);
await Task.Delay(120);

// 4) Restore the top-row's left column — five -40 DIP.
for (int i = 0; i < 5; i++)
{
FireResizeDelta(colSplitters[0], delta: -40, isFinal: false);
await Harness.Render();
await Task.Delay(200);
await Task.Delay(60);
}
FireResizeDelta(colSplitters[0], delta: 0, isFinal: true);
await Harness.Render();
await Task.Delay(400);
await Task.Delay(120);

// 5) Shrink the bottom-row's left column (output) — five 40 DIP.
for (int i = 0; i < 5; i++)
{
FireResizeDelta(colSplitters[1], delta: 40, isFinal: false);
await Harness.Render();
await Task.Delay(200);
await Task.Delay(60);
}
FireResizeDelta(colSplitters[1], delta: 0, isFinal: true);
await Harness.Render();
await Task.Delay(400);
await Task.Delay(120);

H.Check("VizDemo_CompletedAllFourQuadrants", true);

Expand Down
Loading