[No QA] Allow stress testing with API traffic from NewDot#88487
Conversation
- Drop unused isFromSequentialQueue parameter from LoadTest middleware
- Type fetch mock calls so the test helper passes no-unsafe-return/member-access
- Construct Headers with tuple syntax to avoid naming-convention error on the X-Load-Test property name
- Rephrase comments to avoid cspell unknown words ("preflights", "unparseable")
Made-with: Cursor
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fde14a4d14
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (multiplier > 1 && expire && Number.isFinite(expireTime) && Date.now() < expireTime) { | ||
| return multiplier - 1; |
There was a problem hiding this comment.
Clamp load-test multiplier before fan-out
getDuplicateRequestCount() trusts the multiplier parsed from X-Load-Test without validating it is a finite, bounded integer. If the header contains an oversized JSON number (for example 1e309), JSON.parse yields Infinity, this condition passes, and the function returns an unbounded count; triggerDuplicates() then runs for (let i = 0; i < count; i++), which can effectively hang the JS thread and flood requests. Please sanitize multiplier (finite integer + max cap) before returning it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — fixed in 19ce660. The sanitizer now:
- Rejects non-numbers and non-finite values (so
Infinity/NaNshort-circuit to 0 duplicates). - Floors fractional multipliers so the for-loop counter is always an integer.
- Caps at
MAX_MULTIPLIER = 100, which is well above any legitimate real-world load-test value (typically 3–10) but small enough that even a worst-case server response can't lock up the JS thread or self-DDOS. - Rejects multipliers
< 2(anything wheremultiplier - 1 <= 0).
Added unit tests covering Infinity (1e309 JSON), NaN, negative, fractional, and oversized multipliers — 24/24 passing.
The multiplier parsed from the X-Load-Test response header was trusted as-is, which meant a malicious or misconfigured server could send `multiplier: 1e309` (parses to Infinity) and turn the duplicate-firing for-loop into an infinite loop that hangs the JS thread and floods the server. It also accepted fractional, negative, and non-number multipliers without sanitization. - Reject anything that is not a finite number outright - Floor fractional values so the loop counter is always an integer - Cap at MAX_MULTIPLIER (100) which is well above any plausible real load test - Add unit tests covering Infinity, NaN, negative, fractional, and oversized multipliers Caught by codex review. Made-with: Cursor
`Array.prototype.at()` returns `T | undefined`, so the cast straight to
`[string, {body: FormData}]` failed under TS2352 (insufficient overlap with
the `undefined` branch). Replace the blind cast with an explicit guard that
throws a useful error if the expected fetch call is missing, then narrow the
body through `unknown` to satisfy the strict cast.
Made-with: Cursor
|
@DylanDylann 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: 78216c6633
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return; | ||
| } | ||
| try { | ||
| loadTest = JSON.parse(headerString) as LoadTestParameters; |
There was a problem hiding this comment.
Reject non-object X-Load-Test payloads
setLoadTestParameters() assigns JSON.parse(headerString) directly to loadTest, but valid JSON like "null" parses to null and is still accepted here. On the next request, getDuplicateRequestCount() reads loadTest.multiplier, which throws a TypeError for that payload and forces the middleware’s try/catch path, silently disabling load-test fan-out. Treating non-object parsed values as invalid and resetting to {} avoids this runtime fault.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Eh, I don't think we need to be overly defensive or descriptive here and I think it's OK for the try/catch to do it's thing.
|
No product review needed |
|
Does this require (or is even possible to test) C+ review? |
|
@Ollyws It can only be tested by an internal engineer. A code review would still be good though. |
|
@flodnv do you want to merge this, or close it? I think it would be good to have the code deployed so that it's ready for stress testing at some point, even if we're not going to be doing one soon. |
flodnv
left a comment
There was a problem hiding this comment.
Thanks for the ping, yes, let's merge it.
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
|
🚧 @flodnv has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/flodnv in version: 9.3.74-7 🚀
Bundle Size Analysis (Sentry): |
|
No help site changes are required for this PR. This PR adds internal stress testing infrastructure (a |
|
🚀 Deployed to production by https://github.com/Beamanator in version: 9.3.74-7 🚀
|
Explanation of Change
This PR listens for the X-Load-Test header, and then multiplies requests accordingly. Allowing us to perform stress testing with API traffic from NewDot.
Fixed Issues
$ #88480
Tests
define('LOAD_TEST', ['multiplier' => 3, 'expire' => '2099-01-01T00:00:00']);to your_config.local.phpfile in Web-Expensify_config.local.phpOffline tests
None, this requires online access.
QA Steps
None. We will QA this in production during the next stress test
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand 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