gorules / zen

Open-source Business Rules Engine for your Rust, NodeJS, Python or Go applications.
https://gorules.io
MIT License
783 stars 73 forks source link

NodeJS Jest Open Handles Detected #254

Open alexstaroselsky opened 4 days ago

alexstaroselsky commented 4 days ago

Jest testing framework, which is used for the tests in this repository for the NodeJS bindings, provides an optional command line open detectOpenHandles which:

Attempt to collect and print open handles preventing Jest from exiting cleanly

Open handles can indicate that cleanup is not effectively happening. This can often happen with other libraries/utilities such as database connections not being closed/disposed.

Noticing that if --detectOpenHandles is added to the test command in bindings/nodejs/package.json Jest does in fact detect an open handle.

Even if dispose() is called in hooks such as afterEach or afterAll this issue still happens.

Would you have any insight into why a handle remains open? Is this an issue with napi or is there possibly cleanup not actually happening? Outside of tests it could concerning if one can't completely close/dispose/destroy an engine instance. The use of --forceExit is described by Jest as:

This feature is an escape-hatch. If Jest doesn't exit at the end of a test run, it means external resources are still being held on to or timers are still pending in your code. It is advised to tear down external resources after each test to make sure Jest can shut down cleanly.

Thank you for any insight you can provide.

stefan-gorules commented 3 days ago

From what I can gather this is an issue with napi, I am able to replicate this on sample repository provided by napi new + installing jest and adding settings:

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  detectOpenHandles: true,
  detectLeaks: true,
};

It leads to the same error:

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.547 s, estimated 1 s
Ran all test suites.

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  CustomGC

      137 |         try {
      138 |           if (localFileExisted) {
    > 139 |             nativeBinding = require('./napi-add.darwin-arm64.node')
          |                             ^
      140 |           } else {
      141 |             nativeBinding = require('napi-add-darwin-arm64')
      142 |           }

      at Runtime._loadModule (node_modules/.pnpm/jest-runtime@29.7.0/node_modules/jest-runtime/build/index.js:1018:29)
      at Object.<anonymous> (index.js:139:29)
      at Object.<anonymous> (__test__/main.spec.ts:2:1)

And the error is triggered by simply importing 'index.js'. You don't have to use any function within it. The similar issue was faced by Prisma client as well, see: https://github.com/prisma/prisma/issues/18146.

Happy to accept contribution on this if you are familiar with the issue or know how to resolve it. Cheers!