test(android): Fix flaky AnrV2 scope persistence assertion - #6031
Merged
Conversation
The final assertions of the AnrV2 enrichment test read transaction.json and release.json straight off disk, but both are written from the Sentry executor and nothing in the test joins it. The awaited beforeSend callback runs on the ANR processing task, which is queued ahead of the scope flush, so it flipping says nothing about whether the writes have landed. Awaitility's 100ms poll interval normally hides this; on a loaded CI runner it does not, and the read returns the value prefilled by the test setup instead of the new one. Poll for the persisted values rather than reading them once.
📲 Install BuildsAndroid
|
Awaitility's 10 second default is the wait a genuine regression now pays before the test reports it. By this point the only work left in the executor queue is two short file writes: the long ANR processing task has already run, which is what let the awaited beforeSend callback flip. Scheduler starvation on a loaded runner is the only plausible source of delay, so 5 seconds leaves ample headroom while halving the failure wait.
The remaining executor work is two short file writes, so the cap only has to cover scheduler starvation on a loaded runner. 2 seconds still leaves an order of magnitude of headroom and shortens the wait a genuine regression pays before the test reports it.
runningcode
marked this pull request as ready for review
August 31, 2026 16:37
runningcode
requested review from
0xadam-brown,
adinauer,
markushi and
romtsn
as code owners
August 31, 2026 16:37
0xadam-brown
approved these changes
Sep 1, 2026
0xadam-brown
left a comment
Member
There was a problem hiding this comment.
A possible alt approach if you want it; looks good regardless 👍
resetCache() cleared every other persisted scope value on init but left replay.json in place, so a replay id written by a previous process could still be attached to events from the current one. The reset already runs after the integrations that consume those values, so deleting it here is safe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… them The reset assertions were submitted to the Sentry executor and their Future discarded, so an AssertionError never reached the test runner and the test passed regardless of what they found. Joining the Future revives them; the replay expectation is corrected to assertNull to match what resetCache does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The join only guards against a wedged executor; the task is expected to be long finished by then. 30 seconds was arbitrary and 15x the cap the sibling assertion in this test uses, so a hang burned CI time for no added coverage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The scope-reset assertion revived by the previous commit expected resetCache() to clear replay.json, which it has never done. Fixing that is a product change unrelated to the flaky assertion this branch is about, so it moves to its own PR along with its test and changelog entry. The replay expectation is dropped rather than corrected: resetCache's behaviour belongs in PersistingScopeObserverBatchingTest, not incidental to a test about ANR enrichment. The breadcrumbs assertion beside it stays and is now observed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📜 Description
The final assertions of
SentryAndroidTest."AnrV2 events get enriched with previously persisted scope and options data, the new data gets persisted after that"readtransaction.jsonandrelease.jsonstraight off disk. Both are written from the Sentry executor, and nothing in the test joins it. Poll for the persisted values instead of reading them once.💡 Motivation and Context
The test is flaky on CI. https://scans.gradle.com/s/x5fecocehp2i4/tests/task/:sentry-android-core:testReleaseUnitTest/details/io.sentry.android.core.SentryAndroidTest/AnrV2%20events%20get%20enriched%20with%20previously%20persisted%20scope%20and%20options%20data%2C%20the%20new%20data%20gets%20persisted%20after%20that?focused-exception-line=0-0&page=eyJvdXRwdXQiOnsiMCI6Mn19&top-execution=1
💚 How did you test it?
Ran
:sentry-android-core:testReleaseUnitTest --tests io.sentry.android.core.SentryAndroidTest— passes, with no change to the class's wall-clock time.To confirm the polling actually engages rather than the assertion just passing on the first read, I temporarily changed the expected value to one never written. The test then polled until the timeout and reported
was:<[Test]Activity>, showing both that the write does land and that the retry loop is active.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
None.
#skip-changelog