Skip to content

Retry testGetTasks and testGetAllTasks when the request finishes first - #138

Merged
piercifani merged 1 commit into
mainfrom
fix-testgettasks-race
Oct 20, 2026
Merged

piercifani merged 1 commit into
mainfrom
fix-testgettasks-race

Conversation

@piercifani

Copy link
Copy Markdown
Contributor

What

testGetTasks and testGetAllTasks in TestURLSession failed now and then on CI with:

TestURLSession.swift:201: error: -[SkipFoundationTests.TestURLSession testGetTasks] : XCTAssertEqual failed: ("0") is not equal to ("1")
TestURLSession.swift:204: error: -[SkipFoundationTests.TestURLSession testGetTasks] : XCTAssertTrue failed

Both tests resume a real request against testURL and then expect session.tasks (or allTasks) to list it. If the request completes first, the session no longer lists it and the assertions fail.

The tests already retry up to five times, but only by catching thrown assertion errors. On the Kotlin side that's java.lang.AssertionError. On Darwin, XCTAssert… records the failure without throwing, so the retry never happened there.

Each test now checks for that case before asserting: if nothing is listed and the task is already .completed, it tries again with a new request. The last attempt still asserts, so a real regression still fails.

Testing

  • Forced race: waiting 3 s after resume() on the first attempt only, so the request completes before the listing.
    • Original tests, macOS: both fail with the same ("0") is not equal to ("1") / XCTAssertTrue failed as CI.
    • With this change, macOS: both pass on the second attempt.
    • With this change, Robolectric: both pass on the second attempt. The task's state at the listing was .completed, the same as on Darwin.
  • Without forcing: swift test --filter 'TestURLSession/testGet' passed 10 out of 10 runs on macOS. TestURLSession on Robolectric: 12 tests, 2 skipped as before, 0 failures.
  • I also checked Darwin's behaviour: a data task that hasn't been resumed isn't listed in session.tasks, unlike SkipFoundation, which lists it from creation. So listing before resume() wouldn't be a portable fix.

Skip Pull Request Checklist:

  • REQUIRED: I have signed the Contributor Agreement
  • REQUIRED: I have tested my change locally with swift test
  • OPTIONAL: I have tested my change on an iOS simulator or device
  • OPTIONAL: I have tested my change on an Android emulator or device

  • AI was used to generate or assist with generating this PR. Claude Code wrote the change, reproduced the failure by forcing the race, and confirmed the fix on macOS and Robolectric.

🤖 Generated with Claude Code

Both tests resume a real request and then expect the session to list it.
If the request completes before the listing, the session no longer
lists it and the assertions fail. Their retry loops catch thrown
assertion errors, which only happens on the Kotlin side; XCTest on
Darwin records failures without throwing, so they never retried there.
Detect that case (no tasks listed and the task completed) and retry
with a new request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cla-bot cla-bot Bot added the cla-signed label Oct 20, 2026
@piercifani
piercifani merged commit f800b74 into main Oct 20, 2026
2 checks passed

@marcprux marcprux left a comment

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.

Nice improvement. In an ideal world, this (and other) network tests would be hitting some localhost mini server that we spin up for testing, since testing against the real network is an endless source of flakiness. But for the time being, we can at least reduce the failure rate with this.

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.

2 participants