Skip to content

Stabilize immediate WaitsFor assertion test - #6576

Merged
thomhurst merged 1 commit into
mainfrom
agent/stabilize-waitsfor-timing-test
Aug 10, 2026
Merged

Stabilize immediate WaitsFor assertion test#6576
thomhurst merged 1 commit into
mainfrom
agent/stabilize-waitsfor-timing-test

Conversation

@thomhurst

Copy link
Copy Markdown
Owner

Summary

  • replace the wall-clock threshold in the immediate WaitsFor test with an exact attempt-count assertion
  • verify successful assertions complete on the first polling attempt without relying on runner speed

Root cause

Ubuntu CI exceeded the test's 100 ms threshold by 0.6408 ms under load even though the assertion passed immediately. Elapsed time was an indirect and environment-sensitive proxy for retry behavior.

Impact

The test now checks the intended behavior deterministically and no longer flakes on slow CI runners.

Validation

  • dotnet test tests/TUnit.Assertions.Tests/TUnit.Assertions.Tests.csproj --configuration Release --framework net10.0 --no-build --treenode-filter "/*/*/WaitsForAssertionTests/*" — 27 passed
  • focused immediate-success test — passed once with build plus 10 repeated no-build runs

Originating failure: https://github.com/thomhurst/TUnit/actions/runs/31318658536/job/93257973205

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@thomhurst, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 12 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ea96eda3-049f-4501-9ba3-a1f5fcc8b44b

📥 Commits

Reviewing files that changed from the base of the PR and between a3da74c and 93c501d.

📒 Files selected for processing (1)
  • tests/TUnit.Assertions.Tests/WaitsForAssertionTests.cs

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes the immediate WaitsFor test deterministic by checking polling attempts instead of elapsed wall-clock time.

  • Replaces the 100 ms timing threshold with a local attempt counter.
  • Verifies that an immediately successful assertion completes on its first polling attempt.

Confidence Score: 5/5

The PR appears safe to merge with no actionable issues identified.

The revised test directly verifies first-attempt success, and the polling implementation invokes the assertion factory once per attempt and exits immediately when that assertion passes.

Important Files Changed

Filename Overview
tests/TUnit.Assertions.Tests/WaitsForAssertionTests.cs Replaces a flaky elapsed-time assertion with an exact invocation-count check that matches WaitsFor polling semantics.

Reviews (1): Last reviewed commit: "test: remove WaitsFor timing flake" | Re-trigger Greptile

@claude

claude Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Code review

Verified the change against the actual WaitsFor implementation (src/TUnit.Assertions/Conditions/WaitsForAssertion.cs): _assertionBuilder is invoked exactly once per polling attempt, and the loop returns AssertionResult.Passed immediately on success — so attemptCount == 1 is a correct, deterministic assertion for the "passes immediately" case. This is a solid fix: replacing a wall-clock threshold with a direct behavioral assertion (attempt count) removes the CI-load sensitivity that caused the original flake, and does so without weakening what the test actually verifies.

No bugs found, and no CLAUDE.md violations — this is a test-only change with no core engine metadata, source-gen, or public API impact, so the dual-mode/snapshot/AOT rules don't apply here.

One optional, non-blocking observation for future consistency: several other tests in this same file rely on the same environment-sensitive pattern this PR eliminated — e.g. WaitsFor_With_Custom_Polling_Interval asserts stopwatch.Elapsed > 40ms, and the cancellation-propagation tests assert elapsed time < 1s / < 500ms. These carry the same class of risk (failing under CI load despite correct behavior) that caused this flake. Not required for this PR, but worth a follow-up if those ever start flaking too — the attempt-count/counter approach used here would generalize well to them.

@thomhurst
thomhurst merged commit 6f1856d into main Aug 10, 2026
14 checks passed
@thomhurst
thomhurst deleted the agent/stabilize-waitsfor-timing-test branch August 10, 2026 10:35
This was referenced Aug 11, 2026
intellitect-bot pushed a commit to IntelliTect/EssentialCSharp.Web that referenced this pull request Aug 12, 2026
Updated [TUnit](https://github.com/thomhurst/TUnit) from 1.64.6 to
1.64.13.

<details>
<summary>Release notes</summary>

_Sourced from [TUnit's
releases](https://github.com/thomhurst/TUnit/releases)._

## 1.64.13

<!-- Release notes generated using configuration in .github/release.yml
at v1.64.13 -->

## What's Changed
### Other Changes
* Stabilize immediate WaitsFor assertion test by @​thomhurst in
thomhurst/TUnit#6576
* fix: Allow Item.Member after HasSingleItem by @​SnakyBeaky in
thomhurst/TUnit#6583
### Dependencies
* chore(deps): update tunit to 1.64.6 by @​thomhurst in
thomhurst/TUnit#6577
* chore(deps): update dependency nsubstitute to 6.2.0 by @​thomhurst in
thomhurst/TUnit#6580
* chore(deps): update dependency microsoft.playwright to 1.62.0 by
@​thomhurst in thomhurst/TUnit#6582
* chore(deps): update dependency microsoft.net.stringtools to 18.9.6 by
@​thomhurst in thomhurst/TUnit#6584

## New Contributors
* @​SnakyBeaky made their first contribution in
thomhurst/TUnit#6583

**Full Changelog**:
thomhurst/TUnit@v1.64.6...v1.64.13

Commits viewable in [compare
view](thomhurst/TUnit@v1.64.6...v1.64.13).
</details>

Updated [TUnit.AspNetCore](https://github.com/thomhurst/TUnit) from
1.64.6 to 1.64.13.

<details>
<summary>Release notes</summary>

_Sourced from [TUnit.AspNetCore's
releases](https://github.com/thomhurst/TUnit/releases)._

## 1.64.13

<!-- Release notes generated using configuration in .github/release.yml
at v1.64.13 -->

## What's Changed
### Other Changes
* Stabilize immediate WaitsFor assertion test by @​thomhurst in
thomhurst/TUnit#6576
* fix: Allow Item.Member after HasSingleItem by @​SnakyBeaky in
thomhurst/TUnit#6583
### Dependencies
* chore(deps): update tunit to 1.64.6 by @​thomhurst in
thomhurst/TUnit#6577
* chore(deps): update dependency nsubstitute to 6.2.0 by @​thomhurst in
thomhurst/TUnit#6580
* chore(deps): update dependency microsoft.playwright to 1.62.0 by
@​thomhurst in thomhurst/TUnit#6582
* chore(deps): update dependency microsoft.net.stringtools to 18.9.6 by
@​thomhurst in thomhurst/TUnit#6584

## New Contributors
* @​SnakyBeaky made their first contribution in
thomhurst/TUnit#6583

**Full Changelog**:
thomhurst/TUnit@v1.64.6...v1.64.13

Commits viewable in [compare
view](thomhurst/TUnit@v1.64.6...v1.64.13).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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