Skip to content

Commit b338ff5

Browse files
addaleaxtargos
authored andcommitted
test: add gc tracking to common API
PR-URL: #21794 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 0b3c80c commit b338ff5

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

test/common/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,21 @@ otherwise.
322322
### noWarnCode
323323
See `common.expectWarning()` for usage.
324324

325+
### onGC(target, listener)
326+
* `target` [&lt;Object>]
327+
* `listener` [&lt;Object>]
328+
* `ongc` [&lt;Function>]
329+
330+
Installs a GC listener for the collection of `target`.
331+
332+
This uses `async_hooks` for GC tracking. This means that it enables
333+
`async_hooks` tracking, which may affect the test functionality. It also
334+
means that between a `global.gc()` call and the listener being invoked
335+
a full `setImmediate()` invocation passes.
336+
337+
`listener` is an object to make it easier to use a closure; the target object
338+
should not be in scope when `listener.ongc()` is created.
339+
325340
### opensslCli
326341
* [&lt;boolean>]
327342

test/common/index.js

+27
Original file line numberDiff line numberDiff line change
@@ -883,3 +883,30 @@ exports.isCPPSymbolsNotMapped = exports.isWindows ||
883883
exports.isAIX ||
884884
exports.isLinuxPPCBE ||
885885
exports.isFreeBSD;
886+
887+
const gcTrackerMap = new WeakMap();
888+
const gcTrackerTag = 'NODE_TEST_COMMON_GC_TRACKER';
889+
890+
exports.onGC = function(obj, gcListener) {
891+
const async_hooks = require('async_hooks');
892+
893+
const onGcAsyncHook = async_hooks.createHook({
894+
init: exports.mustCallAtLeast(function(id, type, trigger, resource) {
895+
if (this.trackedId === undefined) {
896+
assert.strictEqual(type, gcTrackerTag);
897+
this.trackedId = id;
898+
}
899+
}),
900+
destroy(id) {
901+
assert.notStrictEqual(this.trackedId, -1);
902+
if (id === this.trackedId) {
903+
this.gcListener.ongc();
904+
onGcAsyncHook.disable();
905+
}
906+
}
907+
}).enable();
908+
onGcAsyncHook.gcListener = gcListener;
909+
910+
gcTrackerMap.set(obj, new async_hooks.AsyncResource(gcTrackerTag));
911+
obj = null;
912+
};

test/parallel/test-common-gc.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
// Flags: --expose-gc
3+
const common = require('../common');
4+
5+
{
6+
const gcListener = { ongc: common.mustCall() };
7+
common.onGC({}, gcListener);
8+
global.gc();
9+
}
10+
11+
{
12+
const gcListener = { ongc: common.mustNotCall() };
13+
common.onGC(process, gcListener);
14+
global.gc();
15+
}

0 commit comments

Comments
 (0)