Skip to content

Make the download cancel test deterministic - #503

Merged
KnifeLemon merged 1 commit into
mainfrom
test/deterministic-download-cancel
Oct 23, 2026
Merged

KnifeLemon merged 1 commit into
mainfrom
test/deterministic-download-cancel

Conversation

@KnifeLemon

Copy link
Copy Markdown
Owner

WebDownloaderTests.Cancelling_stops_the_download_and_removes_the_partial_file failed intermittently on busy runners: on the Windows build job of run 39965468348 (PR #360, which doesn't touch the downloader) it hit a TimeoutException at line 238, the 10-second wait for the fake server to start answering.

The test also didn't check what it said it did. The server sent 16 bytes, but the downloader reads 64 (WebFormats.SniffLength) before it creates the file. So WaitUntil(file exists) ran out its 10 s deadline without saying so, and the test cancelled before any partial file existed.

Changes

  • The fake server sends a first chunk larger than the sniffed head, then blocks until the test is disposed.
  • The test cancels on the first progress report. That report comes right after the file is created and the head is written, so the test first asserts the file exists.
  • After the cancellation reaches the test, it asserts the folder is empty. The downloader deletes the file before rethrowing, so nothing has to be polled.
  • The wait is Task.WhenAny(written, download), so a download that fails before writing fails the test with its own error, not a timeout.
  • The unused WaitUntil helper is gone.

Testing

  • Ran the test 20 times locally with FILEE_DATA_DIR pointed at a temp folder: 20/20 passed, about 0.5 s each. The whole WebDownloaderTests class passes (12/12).
  • Mutation check: with the partial-file delete in WebDownloader.SaveAsync commented out, the test fails (reverted afterwards).
  • dotnet format Filee.slnx --verify-no-changes is clean.

🤖 Generated with Claude Code

The test waited up to 10 s on wall-clock timers: for the server to start
answering, then for the partial file to appear. On a busy Windows runner the
first wait timed out (run 39965468348). The second never really held either:
the server sent 16 bytes, fewer than the 64 the downloader sniffs before it
creates the file, so WaitUntil ran out its deadline silently and the test
cancelled before any partial file existed.

Now the server sends a first chunk past the sniffed head and then blocks
until the test is over. The test cancels on the first progress report, which
comes right after the file is created and written to, checks the file is
there, and after the cancellation reaches it checks the file is gone; the
downloader deletes it before rethrowing, so no polling is needed. A download
that fails before writing fails the test with its own reason instead of a
timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KnifeLemon KnifeLemon added the build Build and release label Oct 23, 2026
@KnifeLemon KnifeLemon self-assigned this Oct 23, 2026
@KnifeLemon
KnifeLemon merged commit a97a07c into main Oct 23, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Build and release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant