fix(test): make leaderboard opt-in/opt-out tests robust under parallel runner (closes #5)
The four tests polled the async task pool with a fixed budget of five app.update() calls. Under cargo test --workspace the pool's background threads are starved by other tests, so even an instantly-resolving future can take more than five frames to be polled. Replace the fixed loop with a deadline-bounded loop (5 s timeout) that exits early once the expected side-effect is observable — the same pattern used in sync_plugin.rs tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1159,9 +1159,23 @@ mod tests {
|
|||||||
.spawn(async { Err::<(), String>("network error".to_string()) });
|
.spawn(async { Err::<(), String>("network error".to_string()) });
|
||||||
app.world_mut().resource_mut::<OptInTask>().0 = Some(failed_task);
|
app.world_mut().resource_mut::<OptInTask>().0 = Some(failed_task);
|
||||||
|
|
||||||
// Allow the task to complete and be polled.
|
// Pump until the task is polled or a deadline elapses. A fixed
|
||||||
for _ in 0..5 {
|
// update count is unreliable under parallel `cargo test --workspace`
|
||||||
|
// load — the AsyncComputeTaskPool background threads can be starved
|
||||||
|
// long enough that 5 updates finish before the task completes.
|
||||||
|
// Mirrors the deadline-loop pattern used in sync_plugin tests.
|
||||||
|
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
|
||||||
|
loop {
|
||||||
app.update();
|
app.update();
|
||||||
|
let msgs = app.world().resource::<Messages<WarningToastEvent>>();
|
||||||
|
let mut cursor = msgs.get_cursor();
|
||||||
|
if cursor.read(msgs).next().is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if std::time::Instant::now() >= deadline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::thread::yield_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
let msgs = app.world().resource::<Messages<WarningToastEvent>>();
|
let msgs = app.world().resource::<Messages<WarningToastEvent>>();
|
||||||
@@ -1183,8 +1197,19 @@ mod tests {
|
|||||||
.spawn(async { Err::<(), String>("network error".to_string()) });
|
.spawn(async { Err::<(), String>("network error".to_string()) });
|
||||||
app.world_mut().resource_mut::<OptOutTask>().0 = Some(failed_task);
|
app.world_mut().resource_mut::<OptOutTask>().0 = Some(failed_task);
|
||||||
|
|
||||||
for _ in 0..5 {
|
// Deadline-bounded pump — see opt_in_error_fires_warning_toast for rationale.
|
||||||
|
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
|
||||||
|
loop {
|
||||||
app.update();
|
app.update();
|
||||||
|
let msgs = app.world().resource::<Messages<WarningToastEvent>>();
|
||||||
|
let mut cursor = msgs.get_cursor();
|
||||||
|
if cursor.read(msgs).next().is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if std::time::Instant::now() >= deadline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::thread::yield_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
let msgs = app.world().resource::<Messages<WarningToastEvent>>();
|
let msgs = app.world().resource::<Messages<WarningToastEvent>>();
|
||||||
@@ -1210,8 +1235,22 @@ mod tests {
|
|||||||
let ok_task = AsyncComputeTaskPool::get().spawn(async { Ok::<(), String>(()) });
|
let ok_task = AsyncComputeTaskPool::get().spawn(async { Ok::<(), String>(()) });
|
||||||
app.world_mut().resource_mut::<OptInTask>().0 = Some(ok_task);
|
app.world_mut().resource_mut::<OptInTask>().0 = Some(ok_task);
|
||||||
|
|
||||||
for _ in 0..5 {
|
// Deadline-bounded pump — see opt_in_error_fires_warning_toast for rationale.
|
||||||
|
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
|
||||||
|
loop {
|
||||||
app.update();
|
app.update();
|
||||||
|
if app
|
||||||
|
.world()
|
||||||
|
.resource::<SettingsResource>()
|
||||||
|
.0
|
||||||
|
.leaderboard_opted_in
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if std::time::Instant::now() >= deadline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::thread::yield_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
@@ -1237,8 +1276,22 @@ mod tests {
|
|||||||
let ok_task = AsyncComputeTaskPool::get().spawn(async { Ok::<(), String>(()) });
|
let ok_task = AsyncComputeTaskPool::get().spawn(async { Ok::<(), String>(()) });
|
||||||
app.world_mut().resource_mut::<OptOutTask>().0 = Some(ok_task);
|
app.world_mut().resource_mut::<OptOutTask>().0 = Some(ok_task);
|
||||||
|
|
||||||
for _ in 0..5 {
|
// Deadline-bounded pump — see opt_in_error_fires_warning_toast for rationale.
|
||||||
|
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
|
||||||
|
loop {
|
||||||
app.update();
|
app.update();
|
||||||
|
if !app
|
||||||
|
.world()
|
||||||
|
.resource::<SettingsResource>()
|
||||||
|
.0
|
||||||
|
.leaderboard_opted_in
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if std::time::Instant::now() >= deadline {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::thread::yield_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
|
|||||||
Reference in New Issue
Block a user