nock: Memory leak issue with jest

What is the expected behavior? Node heap size shouldn’t grow in every test.

What is the actual behavior? Heap size increases after every test file.

With nock:

PASS  test/function-86.js (22 MB heap size)
PASS  test/function-75.js (22 MB heap size)
PASS  test/function-1.js (22 MB heap size)
PASS  test/function-43.js (26 MB heap size)
PASS  test/function-24.js (26 MB heap size)
...
PASS  test/function-48.js (133 MB heap size)
PASS  test/function-82.js (137 MB heap size)
PASS  test/function-87.js (137 MB heap size)
PASS  test/function-20.js (137 MB heap size)
PASS  test/function-79.js (140 MB heap size)

Test Suites: 100 passed, 100 total
Tests:       100 passed, 100 total
Snapshots:   0 total
Time:        25.506s, estimated 26s

Without nock:

PASS  test/function-86.js (19 MB heap size)
PASS  test/function-75.js (19 MB heap size)
PASS  test/function-1.js (19 MB heap size)
PASS  test/function-65.js (19 MB heap size)
PASS  test/function-96.js (19 MB heap size)
...
PASS  test/function-93.js (20 MB heap size)
PASS  test/function-61.js (20 MB heap size)
PASS  test/function-49.js (20 MB heap size)
PASS  test/function-87.js (20 MB heap size)
PASS  test/function-79.js (20 MB heap size)

Test Suites: 100 passed, 100 total
Tests:       100 passed, 100 total
Snapshots:   0 total
Time:        27.079s

How to reproduce the issue

Even a single require/import of nock seems to cause the issue.

Minimal test case: https://github.com/juhosuominen/jest-nock-memory-leak

Versions

Software Version(s)
Nock 11.7.0
Node 11.15.0

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 10
  • Comments: 21 (13 by maintainers)

Most upvoted comments

This still seems to be an issue, though I can confirm that when I use node 11.15.0 and jest ^26 that there is no leak. As soon as I upgrade to node 16 (16.10.0) this is an issue again https://github.com/nock/nock/issues/2383

It’s hard to call this a bug, since Jest is the one breaking from how Node is suppose to work.

Ahh now I see what your statement means. A single require of Nock in each test suite causes the issue. Yes, I can reproduce this. Having many Jest test suite whose contents are simply the following demonstrates the leak

require('nock');

it('should do nothing', async () => {
	// do nothing
});

So far I’ve been able to determine that this has to do with Jest not respecting the require.cache across suites (ref, example) and the fact that Nock mutates the global http module on import. A known shortcoming.

I’m not sure why there is a memory leak. I’m still leaning towards something related to Babel.

cleanAll removes out all the registered interceptors, but does not remove the monkey patched functions and class from the builtins. So it won’t be enough in this case.

What’s confusing is that if I do the dance to store the original ClientRequest on the http lib then reuse that to inherit from, the leak is still present. It seems Babel Generator notices the class has changed and re-processes it, while keeping a ref to the old classes.

This issue also exists for the http[s].request and get methods.

We end up extending our own subclass over and over?

yes.