Skip to content

Fix flaky PhysicalFileProvider TokensFiredForOldAndNewNamesOnRename test#130977

Draft
svick wants to merge 3 commits into
dotnet:mainfrom
svick:physicalfileprovider-token-rename-test
Draft

Fix flaky PhysicalFileProvider TokensFiredForOldAndNewNamesOnRename test#130977
svick wants to merge 3 commits into
dotnet:mainfrom
svick:physicalfileprovider-token-rename-test

Conversation

@svick

@svick svick commented Jul 17, 2026

Copy link
Copy Markdown
Member

Fixes #129027.

Problem

TokensFiredForOldAndNewNamesOnRename waited a fixed 500ms after triggering the rename before asserting that the tokens had fired. PhysicalFilesWatcher.CancelToken cancels the token on a background thread-pool task, so under load (e.g. JitStress on slow arm64) the cancellation was not guaranteed to run within that window, causing the test to intermittently fail.

Fix

Replace the fixed delay with the deterministic RegisterChangeCallback + TaskCompletionSource pattern already used by the sibling TokensFiredForNewDirectoryContentsOnRename test, awaiting the callbacks with a generous timeout instead.

A second commit refactors the test's timeout values: the repeated 30-second token-fire timeout is extracted into a shared s_maxWaitForTokenToFire field, and the existing WaitTimeForTokenToFire/WaitTimeForTokenCallback constants are converted to TimeSpan fields for consistency. No behavioral change.

Note

This PR was generated with the assistance of GitHub Copilot.

svick and others added 2 commits July 17, 2026 17:39
The test waited a fixed 500ms after triggering the rename before asserting
that the tokens had fired. PhysicalFilesWatcher.CancelToken cancels the token
on a background thread-pool task, so under load (e.g. JitStress on slow arm64)
the cancellation was not guaranteed to run within that window, causing the
test to intermittently fail.

Replace the fixed delay with the deterministic RegisterChangeCallback +
TaskCompletionSource pattern already used by the sibling
TokensFiredForNewDirectoryContentsOnRename test, awaiting the callbacks with a
generous timeout instead.

Fixes dotnet#129027

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e73cf9d-189a-4b07-96d7-156844a6d647
Extract the repeated 30-second token-fire timeout into a single
s_maxWaitForTokenToFire field and convert the existing WaitTimeForTokenToFire
and WaitTimeForTokenCallback constants to TimeSpan fields for consistency.
No behavioral change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e73cf9d-189a-4b07-96d7-156844a6d647
Copilot AI review requested due to automatic review settings July 17, 2026 15:43
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-extensions-filesystem
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves reliability of Microsoft.Extensions.FileProviders.Physical tests by removing a timing-based assertion from TokensFiredForOldAndNewNamesOnRename and replacing it with a deterministic callback + TaskCompletionSource wait (with a generous timeout). It also refactors the various timeout constants to TimeSpan fields for consistency and reuse.

Changes:

  • Refactor test timeouts from const int millisecond values to shared TimeSpan fields.
  • Fix TokensFiredForOldAndNewNamesOnRename flakiness by awaiting RegisterChangeCallback completion (instead of Task.Delay(500)).
  • Reuse a shared max-wait timeout (s_maxWaitForTokenToFire) in the rename and polling tests.

Comment on lines +1238 to +1239
var oldTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
oldToken.RegisterChangeCallback(_ => oldTcs.TrySetResult(true), null);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this comment isn't wrong, but the recommendation is a low-value nit that conflicts with the established pattern the PR is intentionally following. I would ignore this comment.

@svick svick Jul 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like TCS<bool> slightly better, so I changed all instances in the file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good too.

Comment on lines +1243 to +1244
var newTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
newToken.RegisterChangeCallback(_ => newTcs.TrySetResult(true), null);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Address review feedback: use TaskCompletionSource<bool> instead of
TaskCompletionSource<object> for the token-fired signals, which keeps the
intent explicit and avoids boxing. Apply the same change to the existing
signals in TokensFiredForNewDirectoryContentsOnRename for consistency.

The non-generic TaskCompletionSource is not used because the test project
also targets .NET Framework, where it is unavailable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e73cf9d-189a-4b07-96d7-156844a6d647
Copilot AI review requested due to automatic review settings July 17, 2026 15:59
@tarekgh tarekgh added this to the 11.0.0 milestone Jul 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test failure: Microsoft.Extensions.FileProviders.PhysicalFileProviderTests.TokensFiredForOldAndNewNamesOnRename

3 participants