Skip to content

test: deflake FileWatcher/AuditRunner timing tests + clear nullable warning - #66

Merged
phil-scott-78 merged 2 commits into
mainfrom
chore/test-cleanup
Jul 7, 2026
Merged

phil-scott-78 merged 2 commits into
mainfrom
chore/test-cleanup

Conversation

@phil-scott-78

Copy link
Copy Markdown
Contributor

Why

The ci run on main failed on FileWatcher_CoalescesRapidBurst_IntoSingleNotification — a flaky test, not a product regression. This PR deflakes it, sweeps the suite for the same class of defect (assertions on outcomes the OS/scheduler/clock control), and clears the one build warning that was riding along.

Changes

test: deflake timing-sensitive FileWatcher and AuditRunner tests

  • FileWatcher_CoalescesRapidBurst drove a real OS FileSystemWatcher on the real clock and asserted a 6-write burst debounced to exactly one notification. Under load the watcher's event pump stalls >100 ms mid-burst, elapsing the 100 ms debounce window and splitting the burst into two notifications — the failing CI run. Now driven off a FakeTimeProvider: raw events still arrive in real time, but the debounce timer only fires on Advance, so load can no longer split the window. The production debounce is unchanged.
  • AuditRunner tests — the headless-one-shot test polled the cache for up to 500 ms after ApplicationStarted (can expire under thread-pool starvation); the dev-mode test slept a flat 100 ms before asserting the rendered auditor never ran. Both now await the purpose-built WaitForInitialPassAsync() seam, removing the timing entirely.

test(docsite): fix CS8604 nullable-argument warning in area-home test

  • IElement.GetAttribute("href") returns a nullable string; passing it straight to ShouldContain tripped CS8604. Assert the href is present first, then match — clears the warning and makes a missing href fail loudly.

Audit of the rest of the suite

Swept all four test projects for the same pattern. Everything else is either well-constructed or can't false-fail:

  • BuildHtmlCacheTests concurrent coalesce — TaskCompletionSource-gated, deterministic.
  • RenderedHtmlFetcherTests 50-way concurrent — stub-backed race stress test; a failure signals a real race, not flakiness.
  • RedirectMiddlewareTests (real Kestrel socket) — ephemeral port :0, awaits StartAsync() (no raced sleep).
  • The two other FileWatcherTests real-OS-watcher waits use a generous 5 s ceiling on a positive "did it fire" assertion.

Verification

  • Both test projects build with 0 warnings.
  • Reproduced the original flake 3/8 under CPU saturation on the old FileWatcher test; the rewritten test passes 12/12 and AuditRunner 6/6 under the same load.

Both tests asserted on outcomes the OS/thread-pool scheduler controls, so a
loaded CI runner could fail them though the production code was correct.

FileWatcher_CoalescesRapidBurst drove a real OS FileSystemWatcher on the real
clock and asserted a 6-write burst debounced to exactly one notification. Under
load the watcher event pump stalls >100ms mid-burst, elapsing the debounce
window and splitting the burst into two notifications (the failing main CI run).
Drive the debounce off a FakeTimeProvider instead: the raw events still arrive
in real time, but the timer only fires on Advance, so load can no longer split
the window. Reproduced 3/8 failures under CPU saturation on the old test; 12/12
pass on the new one under the same load.

AuditRunner's headless-one-shot test polled the cache for up to 500ms after
ApplicationStarted, which could expire under thread-pool starvation; the
dev-mode test slept a flat 100ms before asserting the rendered auditor never
ran. Both now await the purpose-built WaitForInitialPassAsync() seam, removing
the timing entirely.
IElement.GetAttribute("href") returns a nullable string, so passing it straight
to ShouldContain tripped CS8604. Assert the href is present first, then match on
it — clears the warning via flow analysis and makes a missing href fail loudly
instead of NRE-ing inside the matcher.
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

🛰️ Docs preview: https://pr-66.pennington-dev.pages.dev

Rebuilt on every push to this PR; torn down when it closes.

@phil-scott-78
phil-scott-78 merged commit 70f63cc into main Jul 7, 2026
4 checks passed
@phil-scott-78
phil-scott-78 deleted the chore/test-cleanup branch July 7, 2026 18:14
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