Skip to content

test: fix flaky hfHubOfflineThrowsWithoutWaitingForStubbornProvider (hang guard opened the gate on cancel) - #101

Merged
solderzzc merged 1 commit into
mainfrom
fix/offline-guard-test-hang-guard
Nov 1, 2026
Merged

solderzzc merged 1 commit into
mainfrom
fix/offline-guard-test-hang-guard

Conversation

@solderzzc

Copy link
Copy Markdown
Member

Problem

Build and Test (macOS 15) fails on main (c029688, 7a4d1d0) and on #100 at ConformanceOfflineGuardTests.swift:213: finished.value == nil ("the provider must still be blocked when the error is thrown") sees true. The last green main run was 71bff98.

Cause

It is a test-helper bug, not a bug in HubOfflineDownloader. Gate.openAfterHangGuard wrote try? await Task.sleep(60s); gate.open(). The tests call guardTask.cancel() right after the download returns; cancelling makes the sleep throw, try? swallows it, and gate.open() runs at once. That releases the stubborn provider, which sets finished = true, racing the next assertion. Under load the provider wins; on an idle machine it usually does not (40/40 local runs of the two gated tests passed before the fix, so it is not reproducible by repetition).

Fix

A cancelled guard returns without opening the gate; only the timeout opens it (do { try await Task.sleep } catch { return }).

Tests

  • New hangGuardDoesNotOpenTheGateWhenCancelled: deterministic. Fails on the old helper (Expectation failed: !gate.opened), passes with the fix.
  • New hangGuardOpensTheGateOnTimeout: the timeout path still opens the gate.
  • ConformanceOfflineGuard suite: 19 tests pass; 30 further local runs, 0 failures.

Test-only change; no library code is touched.

🤖 Generated with Claude Code

…ncelled

Gate.openAfterHangGuard used try? around Task.sleep, so guardTask.cancel()
made the sleep throw, the error was swallowed, and gate.open() ran. That
released the stubborn provider while hfHubOfflineThrowsWithoutWaitingForStubbornProvider
was about to assert finished.value == nil, so under CI load the provider
had already set finished = true (main failed at ConformanceOfflineGuardTests.swift:213
on c029688 and 7a4d1d0). A cancelled guard now returns without opening the gate.

Adds two deterministic tests: cancelling the guard leaves the gate shut
(fails on the old helper), and the timeout path still opens it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@solderzzc
solderzzc merged commit 5cbd33a into main Nov 1, 2026
8 checks passed
@solderzzc
solderzzc deleted the fix/offline-guard-test-hang-guard branch November 4, 2026 05:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant