`jest --detectLeaks` is detecting leaks on the getting started example
PS: I have read https://github.com/testcontainers/testcontainers-node/issues/383, but I'm reopening since no solution was provided there.
Expected Behaviour Not to leak anything. Deno's test runner won't allow tests to pass if leaks are detected, for example.
Actual Behaviour
Leaks are reported. When using TESTCONTAINERS_RYUK_DISABLED=true, less leaks are reported, though.
Testcontainer Logs
❯ npx jest --detectLeaks
FAIL ./customer-repository.test.js
● Test suite failed to run
EXPERIMENTAL FEATURE!
Your test suite is leaking memory. Please ensure all references are cleaned.
There is a number of things that can leak memory:
- Async operations that have not finished (e.g. fs.readFile).
- Timers not properly mocked (e.g. setInterval, setTimeout).
- Keeping references to the global scope.
at onResult (node_modules/@jest/core/build/TestScheduler.js:150:18)
at node_modules/@jest/core/build/TestScheduler.js:254:19
at node_modules/emittery/index.js:363:13
at Array.map (<anonymous>)
at Emittery.emit (node_modules/emittery/index.js:361:23)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 5.484 s, estimated 17 s
Ran all test suites.
Steps to Reproduce
- Setup the getting started example: https://testcontainers.com/guides/getting-started-with-testcontainers-for-nodejs/
-
npx jest --detectLeaks
Environment Information
- Operating System: Ubuntu 24.04.2 LTS
- Docker Version: 28.0.4
- Node version: 22.14.0
- Testcontainers version: 10.23.0
- Jest: 29.7.0
To do: run with --logHeapUsage and assess the impact. I'm aware in some places we might add a UUID to an array or something and not clear it up, but I'm not too concerned about that. Running with --detectOpenHandles returns OK.
For example run a single test, record the heap usage. Run the entire test suite, record the heap usage, compare.
@cristianrgreco, just to be sure, is that "to do" on me or on you?
Haha sorry I could've been more clear. It's on anyone really. If you'd like do it that'd be amazing. If not I'm sure I'll get round to it eventually.
FWIW, in a simpler example I could get rid of the leaks as long as TESTCONTAINERS_RYUK_DISABLED=true. With ryuk enabled, the socket connection initiated here is never closed and there is no simple way around that I can see.
const socket = await connectToReaperSocket(host, reaperPort, reaperContainer.Id);
Here is deno reporting on it:
TestContainers hello world with local socat proxy => ./utils/tcproxy.e2e.ts:5:6
error: Leaks detected:
- A TCP connection was opened/accepted during the test, but not closed during the test. Close the TCP connection by calling `tcpConn.close()`.
(notice testing in deno requires working around https://github.com/denoland/deno/issues/20255 as well)
In a simpler example I could get rid of the leaks as long as TESTCONTAINERS_RYUK_DISABLED=true
Hi @bonitao, I have this example:
const { GenericContainer } = require("testcontainers");
it("should return first mapped port", async () => {
const container = await new GenericContainer("cristianrgreco/testcontainer:1.1.14")
.withExposedPorts(8080)
.start();
expect(container.getFirstMappedPort()).toBe(container.getMappedPort(8080));
await container.stop();
});
When I run:
TESTCONTAINERS_RYUK_DISABLED=true npx jest --detectLeaks simple.test.js
It still fails with:
● Test suite failed to run
EXPERIMENTAL FEATURE!
Your test suite is leaking memory. Please ensure all references are cleaned.
There is a number of things that can leak memory:
- Async operations that have not finished (e.g. fs.readFile).
- Timers not properly mocked (e.g. setInterval, setTimeout).
- Keeping references to the global scope.
at onResult (node_modules/@jest/core/build/TestScheduler.js:150:18)
at node_modules/@jest/core/build/TestScheduler.js:254:19
at node_modules/emittery/index.js:363:13
at Array.map (<anonymous>)
at Emittery.emit (node_modules/emittery/index.js:361:23)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 3.372 s
Ran all test suites matching /simple.test.js/i.
This is with NodeJS instead of Deno.