diff --git a/tests/ClaudeDo.Worker.Tests/Services/QueueServiceTests.cs b/tests/ClaudeDo.Worker.Tests/Services/QueueServiceTests.cs index e79d6819..527166dc 100644 --- a/tests/ClaudeDo.Worker.Tests/Services/QueueServiceTests.cs +++ b/tests/ClaudeDo.Worker.Tests/Services/QueueServiceTests.cs @@ -671,7 +671,9 @@ public sealed class QueueServiceTests : IDisposable // The picker's retry must have registered the CTS actually driving this run. Assert.True(service.CancelTask(task.Id)); - await Task.Delay(200); + var deadline = DateTime.UtcNow + TimeSpan.FromSeconds(10); + while (!cancelled && DateTime.UtcNow < deadline) + await Task.Delay(25); Assert.True(cancelled); cts.Cancel(); @@ -696,13 +698,19 @@ public sealed class QueueServiceTests : IDisposable await service.StartAsync(cts.Token); _waker.Wake(); - // Max retry window is 10 * 20ms; give it comfortable headroom. - await Task.Delay(600); + // The retry window is 10 * 20ms of Task.Delay, but under full-suite load those delays + // stretch — poll for the terminal state instead of guessing a fixed headroom. + TaskEntity? reloaded = null; + var deadline = DateTime.UtcNow + TimeSpan.FromSeconds(10); + while (DateTime.UtcNow < deadline) + { + reloaded = await _taskRepo.GetByIdAsync(task.Id); + if (reloaded!.Status == TaskStatus.Failed) break; + await Task.Delay(25); + } cts.Cancel(); Assert.Equal(0, fake.CallCount); - - var reloaded = await _taskRepo.GetByIdAsync(task.Id); Assert.Equal(TaskStatus.Failed, reloaded!.Status); // The still-registered "other" run must be untouched.