From 67c150bd7b774cf4a1bf4519f0c9322a65e51353 Mon Sep 17 00:00:00 2001 From: funman300 Date: Thu, 7 May 2026 03:54:51 +0000 Subject: [PATCH] test(engine): wall-clock-bounded loop for pull_failure flake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fixed 5-update budget in `pull_failure_sets_error_status` was the last test still subject to the AsyncComputeTaskPool starvation mode that v0.19.0's auto-save fix already cleared. Under heavy parallel cargo-test load, 5 updates wasn't always enough for the failing pull task to surface its Err and flip SyncStatusResource to Error. Pumps updates in a loop bounded by a 5-second deadline (with std::thread::yield_now between iterations to give the task pool a chance to run), exiting as soon as the status flips. Mirrors the auto-save flake fix shape — a healthy run hits the assertion in a handful of frames, while a starved run gets the budget it needs without hanging the suite. Co-Authored-By: Claude Opus 4.7 (1M context) --- solitaire_engine/src/sync_plugin.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/solitaire_engine/src/sync_plugin.rs b/solitaire_engine/src/sync_plugin.rs index 63f3d4e..408836a 100644 --- a/solitaire_engine/src/sync_plugin.rs +++ b/solitaire_engine/src/sync_plugin.rs @@ -502,10 +502,28 @@ mod tests { #[test] fn pull_failure_sets_error_status() { let mut app = headless_app_with(FailingProvider); - // Pump frames until the task resolves (it's synchronous under - // AsyncComputeTaskPool in test mode, so a few updates suffice). - for _ in 0..5 { + // Wall-clock-bounded loop instead of a fixed 5-update budget. + // Under heavy parallel cargo-test load the AsyncComputeTaskPool + // can be starved long enough that 5 updates aren't sufficient + // for the failing pull to surface. Pumping until either the + // status flips to `Error` or a 5-second deadline elapses + // mirrors the auto-save flake fix and turns this test from + // "pass on a fast machine" into "pass on any machine that + // makes meaningful progress". + let deadline = + std::time::Instant::now() + std::time::Duration::from_secs(5); + loop { app.update(); + if matches!( + app.world().resource::().0, + SyncStatus::Error(_) + ) { + break; + } + if std::time::Instant::now() >= deadline { + break; + } + std::thread::yield_now(); } let status = &app.world().resource::().0; assert!(