Skip to content
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

jest-worker fails with "Do not know how to serialize a BigInt" in messageParent.ts instead of showing the actual assertion error message when there are 2 or more test suite files executing in parallel #11617

Closed
klesun opened this issue Jun 28, 2021 · 28 comments · Fixed by #15191

Comments

@klesun
Copy link

klesun commented Jun 28, 2021

Link to repl or repo (highly encouraged)

Minimal reproduction repo: jest-bigint-worker-issue

🐛 Bug Report

When you have multiple test suite files executing in parallel, and some of the tests are asserting values with bigint numbers in them and the assertion fails, instead of showing this assertion error message, jest-worker fails itself on attempt to serialise this value during the call to the:

parentProcess.send([_types().PARENT_MESSAGE_CUSTOM, message]);

(in messageParent.js)

I assume that's because message includes failureDetails.matcherResult holding the compared bigint values that can't be passed to process.send(), as unlike worker_threads it does not support non-json values out of the box.

To Reproduce

Steps to reproduce the behavior:

git clone git@github.com:klesun-productions/jest-bigint-worker-issue.git # clone minimal reproduction repo
cd jest-bigint-worker-issue
npm ci # install jest dependency
npm test # run the test that reproduces the issue

Expected behavior

You should have seen the assertion error informing you that expect(1n).toEqual(2n); expectation failed

Actual behavior

But instead you get following output due to an internal jest-worker error:

 PASS  tests/some-other.test.js
  ✓ should succeed (2 ms)

 FAIL  tests/bigint.test.js
  ● Test suite failed to run

    TypeError: Do not know how to serialize a BigInt
        at stringify (<anonymous>)

      at messageParent (node_modules/jest-worker/build/workers/messageParent.js:42:19)

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.777 s

With no details of what the actual error that jest-worker tried to report was in tests/bigint.test.js.

envinfo

  System:
    OS: macOS 11.3.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 14.17.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.13 - /usr/local/bin/npm
  npmPackages:
    jest: ^27.0.5 => 27.0.5

Misc

I assume that's a transport issue that user of jest is not supposed to be aware of. One thing I did that at least somehow solved the absence of the real message was patching the jest-worker wrapping the call to parentProcess.send() in a try-catch and console.log-ing the message whose serialisation failed:

try {
  parentProcess.send([_types().PARENT_MESSAGE_CUSTOM, message]);
} catch (error) {
  console.error('jest-worker message serialisation failed', error);
  console.dir(message, {depth: 10});
  throw error;
}

There is likely a number of ways how to better address this problem...

@klesun
Copy link
Author

klesun commented Jun 28, 2021

@SimenB, since you changed this part of jest-worker not so long ago, maybe you could, please, give us an advice here for the discussion to move in the right direction?

@klesun
Copy link
Author

klesun commented Jun 28, 2021

Related: #10293

@kunal-kushwaha fyi

@kunal-kushwaha
Copy link
Contributor

cc @sauravhiremath

@sauravhiremath
Copy link
Contributor

Will look into this tomorrow!

@SHaTRO
Copy link

SHaTRO commented Sep 5, 2021

The choice to use JSON stock JSON serialization moving forward is not helpful. While Jest has been doing better and better with comparison support of native BigInt, the reporting of assertion failures (for me, OOB) still consistently reports an inability to serialize the bigint. With this configuration (OOB) of Jest, polyfills to fix this problem are inconsistent at best.

There are new serializers that can be configured and dropped in for the one way (or even two-way if you configure them correctly) representations for error reports, for example: json-bigint

@gomain
Copy link

gomain commented Feb 3, 2022

For those of you that got here because a failing test involves some BigInt, you can temporarily circumvent this issue by setting maxWorkers: 1 in your jest configuration.

@JCastrejonE
Copy link

For those of you that got here because a failing test involves some BigInt, you can temporarily circumvent this issue by setting maxWorkers: 1 in your jest configuration.

@gomain That actually works, but I cannot understand why turning down the maxworkers do the trick. Have you found any other solution that does not have impact on the total test time?

@gomain
Copy link

gomain commented Mar 16, 2022

@JCastrejonE serialization (currently using JSON, it does not support BigInt) only happens when sending data between worker threads. Limiting workers to 1 eliminates the need to serialize at all. Until a fix for this, we wait for our single worker to finish.

If only a small number of tests involve BigInt you could separate them, such as (!!! not tested !!!)

{
  "scripts": {
    "test:no-bigint": "jest --testPathIgnorePatterns=.*\\.bigint\\.test\\.js",
    "test:bigint": "jest --maxWorkers=1 --testPathPattern=.*\\.bigint\\.test\\.js",
    "test": "npm run test:no-bigint && npm run test:bigint"
  }
}

@spreadred
Copy link

Any update?

@Bast1onCZ
Copy link

This is quite unplesant issue. Testing library cannot handle one of built-in language types? Srsly? Please fix it somebody!

@bmeeder22
Copy link

+1

1 similar comment
@dexterastin
Copy link

+1

@ctsstc
Copy link

ctsstc commented Oct 17, 2023

Realized Prisma is returning BigInt which made my zod parsing fail on a raw query while validating the return data, which lead me to here. Luckily our system is running the latest Node which will support structured cloning and we're up to date to be on a version of Jest that supports the experimental workerThreads, but I would prefer to get away from them, as it seems I do not get a performance boost from the flag, if anything a slow down. I guess another route would have been to just make the type validation on Zod to be looser to accept int or BigInt, but I'd rather be more explicit here...

@ldhbenecia
Copy link

I'm currently developing using NestJS, and when I encountered this issue, I looked it up and found this

I was able to solve it from the following site: https://zenn.dev/serinuntius/scraps/02dfe48b643745

jest.config.ts

"workerThreads": true 

I'm not using jest.config.ts, so I just added that code to the jest part of my package.json and that solved it. I'm not sure why this solves it, though, so if anyone knows how, I'd appreciate a reply.

@ctsstc
Copy link

ctsstc commented Dec 7, 2023

One thing to note is that your error messages on failing tests when utilizing workerThreads are much more confusing and less helpful. I think if I recall correctly this is due to something like workerThreads utilizing the new structured clone, while the other was likely utilizing JSON serialization. So if you utilize something like Decimal JS it does not support structured cloning which will then have Jest blowing up on its internals 😬 ie: MikeMcl/decimal.js#224
It's good to note this is still an experimental feature, so it may be unstable or change.

@leppaott
Copy link

leppaott commented Jan 25, 2024

Same Prisma issue as @ctsstc. It's funny how passing tests work, but then upon failing assertion it errors. I guess it's the failing test results that causes returning the data and fail serialization. And as background we have added support for bigints on our JSON.parse/stringify but this doesn't seem used by the workers then for some reason.

Does someone have skills to revive @sauravhiremath attempt fixing this #11624 (comment)

timostamm added a commit to bufbuild/protobuf-es that referenced this issue Mar 27, 2024
In case of a test failure, we'll see the diff instead of Jest crashing.
See jestjs/jest#11617 (comment)

There don't appear to be any adverse effects of enabling the option. Test failures when strictly comparing message classes are still reported correctly.
@jtomaszewski
Copy link

jtomaszewski commented Mar 28, 2024

FYI Setting just the maxWorkers: 1 in jest config doesn't work for me. I had to set workerThreads: true too.

// Enable worker threads for assertion failures involving BigInt
// See https://github.com/jestjs/jest/issues/11617#issuecomment-1458155552
workerThreads: true,
maxWorkers: 1,

EDIT: But workerThreads is veeery expiremental, a lot of jest built-in matches work terribly then...

We ended up switching to vitest :( Even though there's a few things I preferred in jest over vitest.

@jkristia
Copy link

jkristia commented Mar 29, 2024

I just ran into this issue as well. set maxWorkes: 1 works, but of course it runs very slowly when you have a large number of unit tests.
edit: upgrading to latest "jest": "^29.7.0", fixes the issue for me. This with default 50% maxWorkers

  // maxWorkers: 1,
  maxWorkers: "50%",
  workerThreads: true,

@spalladino
Copy link

spalladino commented Apr 22, 2024

For others running into the same issue, we're trying a fix that doesn't rely on the experimental workerThreads. We're patching jest to use nodejs inter-process advanced serialization instead of JSON. This seems to handle BigInts (and other data types) ok, and haven't yet found any issues with it.

This requires patching the forkOptions used in jest-runner, it's a one-liner. Curious if it'd make sense for jest itself to adopt the change. Happy to send a PR, but it's unclear to me if this'd be breaking other things.

@SimenB
Copy link
Member

SimenB commented Aug 8, 2024

https://github.com/jestjs/jest/releases/tag/v30.0.0-alpha.6

Copy link

github-actions bot commented Sep 8, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.