Repository navigation
Mock timers broken with 20.12.0 / 21.7.0 #52325
Description
Version
v20.12.0 v21.7.0
Platform
Darwin ApolloMac.lan 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000 arm64 arm Darwin
Subsystem
No response
What steps will reproduce the bug?
This test repeatedly fails in Node v20.12.0 and v21.7.0, but works in v21.11.1 and v21.6.1:
The line that fails is https://github.com/apollographql/apollo-client-nextjs/blob/a4e19844a05d6933a4454ff80ec784394525dc7f/packages/client-react-streaming/src/AccumulateMultipartResponsesLink.test.ts#L145
mock.timers.tick(2);
which triggers a callback scheduled by setTimeout here.
How often does it reproduce? Is there a required condition?
It fails on almost every run.
I believe in CI I could retry multiple times to make it succeed at some point, but locally it fails every time.
What is the expected behavior? Why is that the expected behavior?
The test passes in older versions without a problem.
What do you see instead?
✖ `next` call will be debounced and results will be merged together (0.971291ms)
TypeError [Error]: Cannot read properties of undefined (reading 'id')
at MockTimers.tick (node:internal/test_runner/mock/mock_timers:655:25)
at TestContext.<anonymous> (file:///Users/tronic/tmp/apollo-next/packages/client-react-streaming/src/AccumulateMultipartResponsesLink.test.ts:22:793)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:641:25)
at Test.start (node:internal/test_runner/test:550:17)
at startSubtest (node:internal/test_runner/harness:218:17)
at async file:///Users/tronic/tmp/apollo-next/packages/client-react-streaming/src/AccumulateMultipartResponsesLink.test.ts:12:543
Additional information
I'm running these tests through tsx, but I believe this doesn't play a role here.
This is the run command:
NODE_OPTIONS="$NODE_OPTIONS --conditions=browser" TSX_TSCONFIG_PATH=./tsconfig.tests.json node --import tsx/esm --no-warnings --test src/AccumulateMultipartResponsesLink.test.tsYou can also observe this happening in our CI here so I believe this problem is not Darwin-specific.
Activity
cjihrig commentedon Apr 2, 2024
There were two changes to mock timers in those new releases: #51809 and #51673. My guess would be that #51673 is the culprit.
As an aside, I don't believe the extra awaits added in apollographql/apollo-client-integrations#266 are necessary. As a general rule, you should only need to
awaittests if you are inside of another test.cjihrig commentedon Apr 2, 2024
I haven't worked on the mock timers code before, so cc @Benricheson101 and @benjamingr, but the problem seems to be that this line assumes that
afterCallbackalways exists. When it doesn't exist, we get the error in the OP. Fixing that line seems straightforward, but we should include a test for it as well.phryneas commentedon Apr 2, 2024
Thanks for looking into this!
And thanks for this as well, good to know!
Benricheson101 commentedon Apr 2, 2024
Good catch. I see what's happening, this would definitely be a pretty easy fix. I can go ahead and open a fix for it.
test_runner: fix clearing final timeout in own callback
test_runner: fix clearing final timeout in own callback
test_runner: fix clearing final timeout in own callback