Skip to content

test: Read scripted content in the reloader tests that change a file while retries run - #384

Closed
kinyoklion wants to merge 1 commit into
dotnet-server-sdk-v9from
rlamb/overrides-dotnet-reloader-test-content
Closed

kinyoklion wants to merge 1 commit into
dotnet-server-sdk-v9from
rlamb/overrides-dotnet-reloader-test-content

Conversation

@kinyoklion

@kinyoklion kinyoklion commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Summary

A rewrite of a real file is not atomic. Since an empty file became a document with no entries, a retry that reads a test's file after it is emptied and before it is written applies an empty document, which is correct, and stops retrying. ReportsIdenticalFailureOnlyOnce relied on a retry to see the finished write and timed out on Linux CI (#363). Three other tests have the same exposure: RetriesAfterFailureWithoutFurtherTriggers, SuccessfulReloadNowDisarmsThePendingRetry, and RecoveryAppliesEvenWhenContentIsUnchanged.

The four tests now read their content from a scripted reader, so every read sees one complete content. With the tests' own writes made non-atomic (truncate, pause, write), all four failed before this change, and every reloader test passes after it. Each rewritten test fails against a mutant of the behavior it covers. Test-only; no SDK code changes.

Opened from termag

SDK-3248


Note

Overview
Fixes flaky FileDataReloader tests on Linux CI where automatic retries could read a real file mid-rewrite (empty or partial JSON), apply a valid-but-wrong empty document, and stop retrying before the test’s intended content was visible.

Adds a ScriptedContentReader test double that implements IFileReader and returns atomically updatable in-memory content (or a simulated missing file when set to null). Four retry-focused tests now drive content through that reader instead of Write() / File.Delete: ReportsIdenticalFailureOnlyOnce, RetriesAfterFailureWithoutFurtherTriggers, SuccessfulReloadNowDisarmsThePendingRetry, and RecoveryAppliesEvenWhenContentIsUnchanged. SuccessfulReloadNowDisarmsThePendingRetry also drops a DrainErrors() call that is no longer needed with the scripted reads.

Test-only; no production SDK behavior changes.

Reviewed by Cursor Bugbot for commit bec2b6b. Bugbot is set up for automated code reviews on this repo. Configure here.

@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

1 similar comment
@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit bec2b6b. Configure here.

…while retries run

A rewrite of a real file is not atomic. A retry that reads the file after it is emptied and
before it is written now applies a document with no entries, which is correct, and stops
retrying, so a test that relied on the retry to see the finished write timed out
(ReportsIdenticalFailureOnlyOnce on Linux CI). The four tests that change content while
automatic retries run read it from a scripted reader instead, so every read sees one complete
content. With the test's own writes made non-atomic (truncate, pause, write), the four tests
failed before this change, and every reloader test passes after it.
@kinyoklion
kinyoklion force-pushed the rlamb/overrides-dotnet-reloader-test-content branch from 19fe055 to e4e742b Compare November 4, 2026 22:42
@kinyoklion

Copy link
Copy Markdown
Member Author

This reply was written by an AI agent (Claude Code) working on behalf of @kinyoklion.

Closing this in favor of #394, which fixes the cause in the SDK instead of in the tests. With #394, the reloader holds back a file that a load finds empty while its content is in effect, until it has stayed empty for the retry delay (1 second), and an empty JSON file no longer parses. So a retry that reads a file in the middle of a rewrite keeps the data and reads it again. The reloader tests keep real in-place writes (truncate, pause, write) instead of a scripted reader, including the four tests this PR changed.

@kinyoklion kinyoklion closed this Nov 12, 2026
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