[No QA] test: add a test for API.write() persistence ordering#82434
[No QA] test: add a test for API.write() persistence ordering#82434mountiny merged 4 commits intoExpensify:mainfrom
Conversation
…y#80759) Adds an it.failing() test asserting that Onyx.set(PERSISTED_REQUESTS) is called before Onyx.update(optimisticData) during API.write(). Currently the order is reversed, meaning a crash after optimistic updates but before persistence would lose the write request. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sify#80759) Replace spy-ordering approach with a marker key that filters the exact Onyx.update call, preventing false passes caused by unpredictable invocationCallOrder across environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@mananjadhav Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6c264cb1a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // We use ONYXKEYS.IS_CHECKING_PUBLIC_ROOM as a sample key to identify the marker | ||
| const hasMarker = data.some((entry) => entry.key === ONYXKEYS.IS_CHECKING_PUBLIC_ROOM); | ||
| if (hasMarker) { | ||
| requestPersistedBeforeOptimistic = PersistedRequests.getAll().some((r) => r.command === 'MockCommand'); |
There was a problem hiding this comment.
Assert durable persistence rather than queue memory state
This check records success from PersistedRequests.getAll() during optimistic Onyx.update, but getAll() only reflects in-memory state, not whether the request has been written to storage. In src/libs/actions/PersistedRequests.ts, save() updates the in-memory array before calling Onyx.set(...), so this test can pass even when the request is not yet durable and a crash would still drop it. As written, the test does not actually guard the persistence guarantee described in the PR.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The test is marked it.failing to document a known bug where the request isn't even in the in-memory queue before optimistic data fires. If the weaker (in-memory) ordering invariant doesn't hold, the stronger (disk durability) guarantee is certainly broken too.
Added a clarifying code comment to make this explicit. Once the fix lands and the ordering is corrected, save() will complete Onyx.set() before optimistic data is applied, satisfying both properties.
| }); | ||
|
|
||
| try { | ||
| API.write('MockCommand' as WriteCommand, {param1: 'value1'} as ApiRequestCommandParameters[WriteCommand], { |
There was a problem hiding this comment.
Await write completion before asserting ordering flag
The test calls API.write(...) and immediately asserts requestPersistedBeforeOptimistic without awaiting the returned promise or a queue flush. If the eventual fix makes persistence ordering asynchronous (for example by waiting for Onyx.set), this assertion can run too early and fail for timing reasons, causing it.failing to pass for the wrong reason and masking regressions.
Useful? React with 👍 / 👎.
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
mountiny
left a comment
There was a problem hiding this comment.
Can you address the AI comments please
|
Might be valid, I will address them in the morning |
…sify#80759) it.failing masks regressions since any error counts as expected failure. Replace with a regular test that guards the mock fired, then explicitly asserts the current buggy ordering (toBe(false)). When fixed, flip to toBe(true). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
I have addressed them where valid, most importantly changing |
|
Let's rerun codex here as well |
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
🚀 Deployed to staging by https://github.com/mountiny in version: 9.3.22-0 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.3.22-4 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.3.22-4 🚀
|
@OlimpiaZurek @TMisiukiewicz @mountiny
Explanation of Change
Adds a test asserting that Onyx.set(PERSISTED_REQUESTS) is called before Onyx.update(optimisticData) during API.write(). Currently the order is reversed, meaning a crash after optimistic updates but before persistence would lose the write request.
Fixed Issues
$ #80759
PROPOSAL: #80759 (comment)
Tests
This cannot be tested in-app (easily) as per the linked issue, as we're chasing a really long-running issue with the sequential queue. Adding NO QA.
Offline tests
QA Steps
Same as tests.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari