-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[test] Fix flaky data source tests in DataGrid #16395
Conversation
Deploy preview: https://deploy-preview-16395--material-ui-x.netlify.app/ |
let mockServer: ReturnType<typeof useMockServer>; | ||
|
||
// TODO: Resets strictmode calls, need to find a better fix for this, maybe an AbortController? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also be in favor of removing strict mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if you know this, but useGridRegisterPipeProcessor
is semi-broken in StrictMode. We can't control whether developers use StrictMode though, so turning it off doesn't just fix it.
- StrictMode call – invokes
useFirstRender
(it will only invoke the callback in StrictMode, since theisFirstRender
ref doesn't restore, and we cannot restore it back) - StrictMode call – runs
useEffect
inuseGridRegisterPipeProcessor
, that setsisFirstRender
to false, and returns cleanup, that will remove the processor at the end of StrictMode invocation - Normal call –
useFirstRender
has no effect, but processor is cleaned up - Normal call – Processor is re-added only in
useEffect
, so anything that calls it before (even in useEffect level, but from previous hooks), it fails. Which is the reason why I reordered the hooks inuseDatagridPremiumComponents
I'm not sure what a good fix is, besides following the rules of react, and do it in a simple useLayoutEffect
to minimise the importance of ordering hooks.
We could prevent returning a cleanup function if isFirstRender
is true, but then the processor never gets cleaned up without StrictMode, if it only registers once. Which may or may not be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
useGridAggregation(apiRef, props); | ||
useGridDataSource(apiRef, props); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixing this order in this PR to fix another bug, this change might be skipped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine as long as it comes after useGridAggregation
, but if we fix the below, then the order won't matter (for this use case at least):
#16395 (comment)
packages/x-data-grid-premium/src/tests/dataSourceAggregation.DataGridPremium.test.tsx
Outdated
Show resolved
Hide resolved
packages/x-data-grid-premium/src/tests/dataSourceAggregation.DataGridPremium.test.tsx
Outdated
Show resolved
Hide resolved
@@ -367,5 +368,6 @@ export const useMockServer = ( | |||
loadNewData: () => { | |||
setIndex((oldIndex) => oldIndex + 1); | |||
}, | |||
isReady: Boolean(data?.rows?.length), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could probably be used in the demos too, let's leave it for later though.
Side note: When doing loadNewData
it might not convey the correct information initially since the previous data would be there but outdated, isn't much of a problem though since updating the fetchRows
would reset the dataSource
retriggering a fetch call anyways.
bc0dbca
to
e3985e1
Compare
@MBilalShafi, I force pushed over the last change, since I fixed the root cause why the test failed – it was a completely valid failure. Throttling was never cleaned up, which caused race conditions when changing models (throttled Your commit, if you want to reincorporate any of those changes: It's not the first time throttling has caused issues, so I suggest creating a custom hook that takes care of cleanups. Easy to forget otherwise with manual implementations each time. |
Absolutely, I also started looking into the root cause, you got it first. |
127aa5b
to
c94cecf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, let's see if @arminmeh has to add something
Looks good. Thanks for the improvements |
Can you please merge please @MBilalShafi? 🙏 |
Cherry-pick PRs will be created targeting branches: v7.x |
Cherry-pick failed, so I have added the changes manually to #16382 |
Co-authored-by: Bilal Shafi <bilalshafidev@gmail.com>
Randomly failing datasource tests have given me so much grief. It seems like there's a timing issue with
useMockServer
and datasource tests. I'm not 100% sure if I got to the bottom of it, but the problem is somewhere inuseMockServer
initialisation (doesn't happen synchronously), so every timefetchRows
function reference changes,fetchRowSpy
gets reset, but there could be timing issues still where previous fetches happen afterfetchRowSpy
has been reset, but fetch comes in later.With delayed mounting, and waiting for mockServer, we now have to deal with StrictMode as well, since they don't get reset anymore in the
useMemo
that also runs twice (at least). Added a monkeypatch for now (a component) to see the actual problematic tests, since I didn't want to meddle with every single test.Ideally
fetchRowSpy
should only be reset once per test, or within the test itself, not within the component lifecycle, otherwise these tests can be very flaky. I think for testing purposes, it would be better ifmockServer
wasn't a hook.However, now we also have to deal with StrictMode fetches, since with delayed rendering, on mount it will fetch twice (always has, but previously it was reset in
useMemo
that also runs twice, at least, sometimes more).Edit: fixed the tests.