Skip to content

test: [SDK-5663] fix flaky User and Core unit tests - #1794

Merged
fadi-george merged 1 commit into
mainfrom
fadi/sdk-5663
Nov 6, 2026
Merged

fadi-george merged 1 commit into
mainfrom
fadi/sdk-5663

Conversation

@fadi-george

Copy link
Copy Markdown
Collaborator

Description

One Line Summary

Fix the data races and timing assumptions behind the intermittent User and Core unit test failures on CI, and make CI print test failure messages.

Details

Motivation

The "Build and Test using any available iPhone simulator" job failed intermittently on tests unrelated to the PR under test. With all cores loaded locally, UserJwtLifecycleTests.testUpdateUserJwtSendsTheCreateUserThatARejectedTokenHeld failed 3/15 runs, and another JWT test crashed with heap corruption. Causes:

  • MockOneSignalClient recorded a request as executed before choosing its mock response. A test that saw "executed" and then registered the retry's success response could turn the first attempt's 401 into a success, so nothing was re-sent.
  • The mock's response tables and request lists were read from the test thread while requests completed on a background queue, with no lock.
  • Tests read OSUserExecutor.userRequestQueue directly while the executor mutated it on its own queue (likely source of the heap corruption).
  • OSConsistencyManagerTests.testMultipleConditionsWithDifferentKeys relied on fixed 1.0s + 0.1s delays fitting inside a 3s wait.

CI ran with -quiet and only listed failing test names, so none of this was visible.

Scope

  • MockOneSignalClient: record and pick the response in one locked step; all shared state behind the lock.
  • New test-only snapshotUserRequestQueue() reads the queue on the executor's queue (same pattern as snapshotDeltaQueue()). OSUserExecutor.dispatchQueue goes from private to internal for this; no other production change.
  • testUpdateUserJwt... waits for the 401 to be fully handled before supplying the new token.
  • The consistency test registers both waiters then releases them one at a time, with no fixed delays.
  • CI: writes an .xcresult, prints failures as error annotations, and uploads the bundle on failure.

Not covered: the SwitchUserIntegrationTests and FileLogStoreRecordDatingTests failures did not reproduce locally. The new CI output will show their messages if they recur. The iOS 27 scene lifecycle crash is separate.

Testing

Unit testing

Temporary iOS 26.5 simulator, all 14 cores loaded with yes, -maximum-parallel-testing-workers 1 like CI:

  • Flaky classes, 15 iterations: before 3 failures + 1 crash, after 1,095 passed / 0 failed.
  • Full reduced plan, 4 iterations: 638/638 passed each time.

Manual testing

Not applicable, test and CI only.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

🤖 Generated with Claude Code

- MockOneSignalClient: record a request and choose its response in one
  locked step, and lock all shared state read from the test thread.
- Read OSUserExecutor's request queue through its dispatch queue in tests.
- UserJwtLifecycleTests: wait for the 401 to be fully handled before
  supplying the replacement token.
- OSConsistencyManagerTests: drop fixed delays from the multi-key test.
- CI: save the xcresult, print failure messages, and upload it on failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fadi-george
fadi-george requested a review from nan-li November 6, 2026 19:43
@fadi-george
fadi-george merged commit 123cbea into main Nov 6, 2026
5 checks passed
@fadi-george
fadi-george deleted the fadi/sdk-5663 branch November 6, 2026 20:54
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.

2 participants