test: move common.onGC to individual module
Incrementally making `require('../common')` less of a monolith. Move the `common.onGC()` utility to a separate standalone module that is only imported when it's actually needed. PR-URL: https://github.com/nodejs/node/pull/22446 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Weijia Wang <starkwang@126.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
3579ec4171
commit
d495e40bf7
@ -296,21 +296,6 @@ 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>]
|
||||
|
||||
@ -759,6 +744,34 @@ via `NODE_TEST_*` environment variables. For example, to configure
|
||||
`internet.addresses.INET_HOST`, set the environment
|
||||
variable `NODE_TEST_INET_HOST` to a specified host.
|
||||
|
||||
## ongc Module
|
||||
|
||||
The `ongc` module allows a garbage collection listener to be installed. The
|
||||
module exports a single `onGC()` function.
|
||||
|
||||
```js
|
||||
require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
onGC({}, { ongc() { console.log('collected'); } });
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
## tmpdir Module
|
||||
|
||||
The `tmpdir` module supports the use of a temporary directory for testing.
|
||||
|
@ -805,30 +805,3 @@ 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;
|
||||
};
|
||||
|
32
test/common/ongc.js
Normal file
32
test/common/ongc.js
Normal file
@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const gcTrackerMap = new WeakMap();
|
||||
const gcTrackerTag = 'NODE_TEST_COMMON_GC_TRACKER';
|
||||
|
||||
function onGC(obj, gcListener) {
|
||||
const async_hooks = require('async_hooks');
|
||||
|
||||
const onGcAsyncHook = async_hooks.createHook({
|
||||
init: common.mustCallAtLeast(function(id, type) {
|
||||
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;
|
||||
}
|
||||
|
||||
module.exports = onGC;
|
@ -1,15 +1,14 @@
|
||||
'use strict';
|
||||
// Flags: --expose-gc
|
||||
const common = require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
{
|
||||
const gcListener = { ongc: common.mustCall() };
|
||||
common.onGC({}, gcListener);
|
||||
onGC({}, { ongc: common.mustCall() });
|
||||
global.gc();
|
||||
}
|
||||
|
||||
{
|
||||
const gcListener = { ongc: common.mustNotCall() };
|
||||
common.onGC(process, gcListener);
|
||||
onGC(process, { ongc: common.mustNotCall() });
|
||||
global.gc();
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
// just like test-gc-http-client.js,
|
||||
// but aborting every connection that comes in.
|
||||
|
||||
const common = require('../common');
|
||||
require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
function serverHandler(req, res) {
|
||||
res.connection.destroy();
|
||||
@ -36,7 +37,7 @@ function getall() {
|
||||
}, cb).on('error', cb);
|
||||
|
||||
count++;
|
||||
common.onGC(req, { ongc });
|
||||
onGC(req, { ongc });
|
||||
})();
|
||||
|
||||
setImmediate(getall);
|
||||
|
@ -3,7 +3,8 @@
|
||||
// just like test-gc-http-client.js,
|
||||
// but with an on('error') handler that does nothing.
|
||||
|
||||
const common = require('../common');
|
||||
require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
function serverHandler(req, res) {
|
||||
req.resume();
|
||||
@ -42,7 +43,7 @@ function getall() {
|
||||
}, cb).on('error', onerror);
|
||||
|
||||
count++;
|
||||
common.onGC(req, { ongc });
|
||||
onGC(req, { ongc });
|
||||
})();
|
||||
|
||||
setImmediate(getall);
|
||||
|
@ -3,7 +3,8 @@
|
||||
// just like test-gc-http-client.js,
|
||||
// but with a timeout set
|
||||
|
||||
const common = require('../common');
|
||||
require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
function serverHandler(req, res) {
|
||||
setTimeout(function() {
|
||||
@ -45,7 +46,7 @@ function getall() {
|
||||
});
|
||||
|
||||
count++;
|
||||
common.onGC(req, { ongc });
|
||||
onGC(req, { ongc });
|
||||
})();
|
||||
|
||||
setImmediate(getall);
|
||||
|
@ -3,6 +3,7 @@
|
||||
// just a simple http server and client.
|
||||
|
||||
const common = require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
function serverHandler(req, res) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
@ -34,7 +35,7 @@ function getall() {
|
||||
}, cb);
|
||||
|
||||
count++;
|
||||
common.onGC(req, { ongc });
|
||||
onGC(req, { ongc });
|
||||
|
||||
setImmediate(getall);
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
// just like test-gc-http-client-timeout.js,
|
||||
// but using a net server/client instead
|
||||
|
||||
const common = require('../common');
|
||||
require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
|
||||
function serverHandler(sock) {
|
||||
sock.setTimeout(120000);
|
||||
@ -44,7 +45,7 @@ function getall() {
|
||||
});
|
||||
|
||||
count++;
|
||||
common.onGC(req, { ongc });
|
||||
onGC(req, { ongc });
|
||||
|
||||
setImmediate(getall);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
// Flags: --expose-gc
|
||||
|
||||
const common = require('../common');
|
||||
const onGC = require('../common/ongc');
|
||||
const assert = require('assert');
|
||||
const net = require('net');
|
||||
|
||||
@ -36,7 +37,7 @@ const gcListener = { ongc() { collected = true; } };
|
||||
|
||||
{
|
||||
const gcObject = {};
|
||||
common.onGC(gcObject, gcListener);
|
||||
onGC(gcObject, gcListener);
|
||||
|
||||
const sock = net.createConnection(
|
||||
server.address().port,
|
||||
|
@ -26,6 +26,7 @@ const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const onGC = require('../common/ongc');
|
||||
const assert = require('assert');
|
||||
const tls = require('tls');
|
||||
const fixtures = require('../common/fixtures');
|
||||
@ -43,7 +44,7 @@ const gcListener = { ongc() { collected = true; } };
|
||||
|
||||
{
|
||||
const gcObject = {};
|
||||
common.onGC(gcObject, gcListener);
|
||||
onGC(gcObject, gcListener);
|
||||
|
||||
const sock = tls.connect(
|
||||
server.address().port,
|
||||
|
Loading…
x
Reference in New Issue
Block a user