testcontainers-node icon indicating copy to clipboard operation
testcontainers-node copied to clipboard

Memory leak when running testcontainers with jest

Open Zomono opened this issue 3 years ago • 0 comments

Hi, I have some problems with high memory allocation in my unit test running with jest and node-testcontainers. I have reduced the problem to a single test file that only starts and stops a single GenericContainer. After running this test a small amount of memory does not get garbage collected. This could be tested by running the test suite multiple times (in a single jest run) with and without the GenericContainer.

Expected Behaviour If I am running the exact same test suite in jest that starts and stops a single GenericContainer instance, I expect the maximum amount of used memory to be the same for all test suites.

Actual Behaviour The amount of used memory increases from run to run by ~15Mb. Running the same tests without the generic container stuff, the memory does not increase.

Testcontainer Logs If you need any logs, please tell me.

Steps to Reproduce

  1. Create a little project with jest installed. I am using typescript with ts-jest, but I do not think it is related to typescript. So a pure javascript version should be fine.
  2. Create a basic jest config
  3. Create a file MemoryLeakBase.ts with content like shown below.
  4. Create a up to 10 copies of the test suite MemoryLeak1 as shown below.
  5. Run these tests with "node --inspect --expose-gc node_modules/jest/bin/jest.js --runInBand --logHeapUsage --no-cache --config ./jest.config.js MemoryLeak"
  6. Inspect the console output from jest showing the used memory per test suite.
  7. Remove the creation of the GenericContainer from the test function and try again.

Environment Information

  • Operating System: Windows 10 64 bit
  • Docker Version: 20.10.17, build 100c701
  • Node version: 18.6.0
  • Testcontainers version: 8.12.0

My Console output ~: node --inspect --expose-gc node_modules/jest/bin/jest.js --runInBand --logHeapUsage --no-cache --config ./jest.config.ts MemoryLeak Debugger listening on ws://127.0.0.1:9229/41af492b-a25e-46e6-9971-9e5edcc9db1e For help, see: https://nodejs.org/en/docs/inspector Debugger attached. PASS tests/MemoryLeak6.test.ts (17.248 s, 657 MB heap size) PASS tests/MemoryLeak5.test.ts (10.122 s, 672 MB heap size) PASS tests/MemoryLeak4.test.ts (10.882 s, 685 MB heap size) PASS tests/MemoryLeak3.test.ts (10.142 s, 698 MB heap size) PASS tests/MemoryLeak2.test.ts (10.227 s, 710 MB heap size) PASS tests/MemoryLeak1.test.ts (10.542 s, 723 MB heap size)

MemoryLeakBase

import { GenericContainer, StartedTestContainer, Wait } from "testcontainers"

export function runMemoryLeakTest() {
    let dockerContainer: StartedTestContainer
    jest.setTimeout(300_000)
    
    beforeAll(async () => {
        // testDb = await TestDb.create(databaseName);
        dockerContainer = await new GenericContainer("mcr.microsoft.com/mssql/server:2022-latest")
            .withEnv("ACCEPT_EULA", "Y")
            .withEnv("MSSQL_SA_PASSWORD", "Aa123456#")
            .withEnv("MSSQL_PID", "Express")
            .withExposedPorts(1433)
            .withWaitStrategy(Wait.forLogMessage(/.*Server is listening on.*1433.*/))
            .start()
    })
    
    afterAll(async () => dockerContainer?.stop({timeout: 30_000}))
    
    test("emptyTest", async () => {})
}

MemoryLeak1

import {runMemoryLeakTest} from "./MemoryLeakBase"

runMemoryLeakTest()

Zomono avatar Jul 25 '22 12:07 Zomono