test: add gc tracking to common API

PR-URL: https://github.com/nodejs/node/pull/21794
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Anna Henningsen 2018-07-13 18:32:17 +02:00
parent d94950e960
commit d37a47754d
No known key found for this signature in database
GPG Key ID: 9C63F3A6CD2AD8F9
3 changed files with 57 additions and 0 deletions

View File

@ -322,6 +322,21 @@ otherwise.
### noWarnCode
See `common.expectWarning()` for usage.
### onGC(target, listener)
* `target` [&lt;Object>]
* `listener` [&lt;Object>]
* `ongc` [&lt;Function>]
Installs a GC listener for the collection of `target`.
This uses `async_hooks` for GC tracking. This means that it enables
`async_hooks` tracking, which may affect the test functionality. It also
means that between a `global.gc()` call and the listener being invoked
a full `setImmediate()` invocation passes.
`listener` is an object to make it easier to use a closure; the target object
should not be in scope when `listener.ongc()` is created.
### opensslCli
* [&lt;boolean>]

View File

@ -882,3 +882,30 @@ exports.isCPPSymbolsNotMapped = exports.isWindows ||
exports.isAIX ||
exports.isLinuxPPCBE ||
exports.isFreeBSD;
const gcTrackerMap = new WeakMap();
const gcTrackerTag = 'NODE_TEST_COMMON_GC_TRACKER';
exports.onGC = function(obj, gcListener) {
const async_hooks = require('async_hooks');
const onGcAsyncHook = async_hooks.createHook({
init: exports.mustCallAtLeast(function(id, type, trigger, resource) {
if (this.trackedId === undefined) {
assert.strictEqual(type, gcTrackerTag);
this.trackedId = id;
}
}),
destroy(id) {
assert.notStrictEqual(this.trackedId, -1);
if (id === this.trackedId) {
this.gcListener.ongc();
onGcAsyncHook.disable();
}
}
}).enable();
onGcAsyncHook.gcListener = gcListener;
gcTrackerMap.set(obj, new async_hooks.AsyncResource(gcTrackerTag));
obj = null;
};

View File

@ -0,0 +1,15 @@
'use strict';
// Flags: --expose-gc
const common = require('../common');
{
const gcListener = { ongc: common.mustCall() };
common.onGC({}, gcListener);
global.gc();
}
{
const gcListener = { ongc: common.mustNotCall() };
common.onGC(process, gcListener);
global.gc();
}