|
8 | 8 | /* eslint-disable local/ban-types-eventually */
|
9 | 9 |
|
10 | 10 | import * as asyncHooks from 'async_hooks';
|
| 11 | +import {promisify} from 'util'; |
| 12 | +import {setFlagsFromString} from 'v8'; |
| 13 | +import {runInNewContext} from 'vm'; |
11 | 14 | import stripAnsi = require('strip-ansi');
|
12 | 15 | import type {Config} from '@jest/types';
|
13 | 16 | import {formatExecError} from 'jest-message-util';
|
14 | 17 | import {ErrorWithStack} from 'jest-util';
|
15 | 18 |
|
16 |
| -export type HandleCollectionResult = () => Array<Error>; |
| 19 | +export type HandleCollectionResult = () => Promise<Array<Error>>; |
17 | 20 |
|
18 | 21 | function stackIsFromUser(stack: string) {
|
19 | 22 | // Either the test file, or something required by it
|
@@ -41,6 +44,21 @@ const alwaysActive = () => true;
|
41 | 44 |
|
42 | 45 | const hasWeakRef = typeof WeakRef === 'function';
|
43 | 46 |
|
| 47 | +const tick = promisify(setImmediate); |
| 48 | + |
| 49 | +function runGarbageCollector() { |
| 50 | + const isGarbageCollectorHidden = !global.gc; |
| 51 | + |
| 52 | + // GC is usually hidden, so we have to expose it before running. |
| 53 | + setFlagsFromString('--expose-gc'); |
| 54 | + runInNewContext('gc')(); |
| 55 | + |
| 56 | + // The GC was not initially exposed, so let's hide it again. |
| 57 | + if (isGarbageCollectorHidden) { |
| 58 | + setFlagsFromString('--no-expose-gc'); |
| 59 | + } |
| 60 | +} |
| 61 | + |
44 | 62 | // Inspired by https://github.com/mafintosh/why-is-node-running/blob/master/index.js
|
45 | 63 | // Extracted as we want to format the result ourselves
|
46 | 64 | export default function collectHandles(): HandleCollectionResult {
|
@@ -100,7 +118,14 @@ export default function collectHandles(): HandleCollectionResult {
|
100 | 118 |
|
101 | 119 | hook.enable();
|
102 | 120 |
|
103 |
| - return () => { |
| 121 | + return async () => { |
| 122 | + runGarbageCollector(); |
| 123 | + |
| 124 | + // wait some ticks to allow GC to run properly, see https://github.com/nodejs/node/issues/34636#issuecomment-669366235 |
| 125 | + for (let i = 0; i < 10; i++) { |
| 126 | + await tick(); |
| 127 | + } |
| 128 | + |
104 | 129 | hook.disable();
|
105 | 130 |
|
106 | 131 | // Get errors for every async resource still referenced at this moment
|
|
0 commit comments