From d37a47754d98ef82dfc5a15fb3accacbb5f09855 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 13 Jul 2018 18:32:17 +0200 Subject: test: add gc tracking to common API PR-URL: https://github.com/nodejs/node/pull/21794 Reviewed-By: Rich Trott Reviewed-By: James M Snell --- test/common/README.md | 15 +++++++++++++++ test/common/index.js | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'test/common') diff --git a/test/common/README.md b/test/common/README.md index c0051ad9f7..41cc88aca1 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -322,6 +322,21 @@ otherwise. ### noWarnCode See `common.expectWarning()` for usage. +### onGC(target, listener) +* `target` [<Object>] +* `listener` [<Object>] + * `ongc` [<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 * [<boolean>] diff --git a/test/common/index.js b/test/common/index.js index 904e5a8ef3..1df37db54b 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -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; +}; -- cgit v1.2.3