diff --git a/cmuxTests/CLICodexHookTimeoutRegressionTestSupport.swift b/cmuxTests/CLICodexHookTimeoutRegressionTestSupport.swift index e244962d3fc8..cf43af0877f2 100644 --- a/cmuxTests/CLICodexHookTimeoutRegressionTestSupport.swift +++ b/cmuxTests/CLICodexHookTimeoutRegressionTestSupport.swift @@ -266,7 +266,18 @@ func waitForFile(_ url: URL, containing expected: String, timeout: TimeInterval) return false } -func waitForCondition(timeout: TimeInterval, pollInterval: TimeInterval = 0.02, _ condition: () -> Bool) -> Bool { +/// Polls `condition` while blocking the calling thread with `Thread.sleep`. +/// +/// Use it only for conditions a background thread satisfies, such as a socket +/// accumulator or a file a child process writes. It runs no run loop, so on the +/// main thread it starves main-queue and main-actor work and the condition can +/// never become true. Main-thread waits belong in the per-file XCTWaiter +/// helpers, which pump the main queue between polls. +func waitForConditionBlocking( + timeout: TimeInterval, + pollInterval: TimeInterval = 0.02, + _ condition: () -> Bool +) -> Bool { let deadline = Date().addingTimeInterval(timeout) while Date() < deadline { if condition() { diff --git a/cmuxTests/CLICodexHookTimeoutRegressionTests.swift b/cmuxTests/CLICodexHookTimeoutRegressionTests.swift index 1f0fb823ac9c..7b8393b78da6 100644 --- a/cmuxTests/CLICodexHookTimeoutRegressionTests.swift +++ b/cmuxTests/CLICodexHookTimeoutRegressionTests.swift @@ -257,7 +257,7 @@ struct CLICodexHookTimeoutRegressionTests { ) #expect(oldPrompt.status == 0, Comment(rawValue: oldPrompt.stderr)) #expect(oldPrompt.stdout == "{}\n") - #expect(waitForCondition(timeout: 2) { + #expect(waitForConditionBlocking(timeout: 2) { commands.snapshot().contains { $0.hasPrefix("set_status codex Running ") } }) @@ -270,7 +270,7 @@ struct CLICodexHookTimeoutRegressionTests { ) #expect(currentPrompt.status == 0, Comment(rawValue: currentPrompt.stderr)) #expect(currentPrompt.stdout == "{}\n") - #expect(waitForCondition(timeout: 2) { + #expect(waitForConditionBlocking(timeout: 2) { let snapshot = commands.snapshot() return snapshot.contains { $0.hasPrefix("clear_notifications ") } && snapshot.contains { $0.hasPrefix("set_status codex Running ") } @@ -286,7 +286,7 @@ struct CLICodexHookTimeoutRegressionTests { ) #expect(staleStop.status == 0, Comment(rawValue: staleStop.stderr)) #expect(staleStop.stdout == "{}\n") - #expect(waitForCondition(timeout: 2) { + #expect(waitForConditionBlocking(timeout: 2) { commands.snapshot().count > staleStopStart })