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
|
### noWarnCode
|
||||||
See `common.expectWarning()` for usage.
|
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
|
### opensslCli
|
||||||
* [<boolean>]
|
* [<boolean>]
|
||||||
|
|
||||||
@ -759,6 +744,34 @@ via `NODE_TEST_*` environment variables. For example, to configure
|
|||||||
`internet.addresses.INET_HOST`, set the environment
|
`internet.addresses.INET_HOST`, set the environment
|
||||||
variable `NODE_TEST_INET_HOST` to a specified host.
|
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
|
## tmpdir Module
|
||||||
|
|
||||||
The `tmpdir` module supports the use of a temporary directory for testing.
|
The `tmpdir` module supports the use of a temporary directory for testing.
|
||||||
|
@ -805,30 +805,3 @@ exports.isCPPSymbolsNotMapped = exports.isWindows ||
|
|||||||
exports.isAIX ||
|
exports.isAIX ||
|
||||||
exports.isLinuxPPCBE ||
|
exports.isLinuxPPCBE ||
|
||||||
exports.isFreeBSD;
|
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';
|
'use strict';
|
||||||
// Flags: --expose-gc
|
// Flags: --expose-gc
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
|
|
||||||
{
|
{
|
||||||
const gcListener = { ongc: common.mustCall() };
|
onGC({}, { ongc: common.mustCall() });
|
||||||
common.onGC({}, gcListener);
|
|
||||||
global.gc();
|
global.gc();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const gcListener = { ongc: common.mustNotCall() };
|
onGC(process, { ongc: common.mustNotCall() });
|
||||||
common.onGC(process, gcListener);
|
|
||||||
global.gc();
|
global.gc();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
// just like test-gc-http-client.js,
|
// just like test-gc-http-client.js,
|
||||||
// but aborting every connection that comes in.
|
// but aborting every connection that comes in.
|
||||||
|
|
||||||
const common = require('../common');
|
require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
|
|
||||||
function serverHandler(req, res) {
|
function serverHandler(req, res) {
|
||||||
res.connection.destroy();
|
res.connection.destroy();
|
||||||
@ -36,7 +37,7 @@ function getall() {
|
|||||||
}, cb).on('error', cb);
|
}, cb).on('error', cb);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
common.onGC(req, { ongc });
|
onGC(req, { ongc });
|
||||||
})();
|
})();
|
||||||
|
|
||||||
setImmediate(getall);
|
setImmediate(getall);
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
// just like test-gc-http-client.js,
|
// just like test-gc-http-client.js,
|
||||||
// but with an on('error') handler that does nothing.
|
// but with an on('error') handler that does nothing.
|
||||||
|
|
||||||
const common = require('../common');
|
require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
|
|
||||||
function serverHandler(req, res) {
|
function serverHandler(req, res) {
|
||||||
req.resume();
|
req.resume();
|
||||||
@ -42,7 +43,7 @@ function getall() {
|
|||||||
}, cb).on('error', onerror);
|
}, cb).on('error', onerror);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
common.onGC(req, { ongc });
|
onGC(req, { ongc });
|
||||||
})();
|
})();
|
||||||
|
|
||||||
setImmediate(getall);
|
setImmediate(getall);
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
// just like test-gc-http-client.js,
|
// just like test-gc-http-client.js,
|
||||||
// but with a timeout set
|
// but with a timeout set
|
||||||
|
|
||||||
const common = require('../common');
|
require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
|
|
||||||
function serverHandler(req, res) {
|
function serverHandler(req, res) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@ -45,7 +46,7 @@ function getall() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
common.onGC(req, { ongc });
|
onGC(req, { ongc });
|
||||||
})();
|
})();
|
||||||
|
|
||||||
setImmediate(getall);
|
setImmediate(getall);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// just a simple http server and client.
|
// just a simple http server and client.
|
||||||
|
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
|
|
||||||
function serverHandler(req, res) {
|
function serverHandler(req, res) {
|
||||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||||
@ -34,7 +35,7 @@ function getall() {
|
|||||||
}, cb);
|
}, cb);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
common.onGC(req, { ongc });
|
onGC(req, { ongc });
|
||||||
|
|
||||||
setImmediate(getall);
|
setImmediate(getall);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
// just like test-gc-http-client-timeout.js,
|
// just like test-gc-http-client-timeout.js,
|
||||||
// but using a net server/client instead
|
// but using a net server/client instead
|
||||||
|
|
||||||
const common = require('../common');
|
require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
|
|
||||||
function serverHandler(sock) {
|
function serverHandler(sock) {
|
||||||
sock.setTimeout(120000);
|
sock.setTimeout(120000);
|
||||||
@ -44,7 +45,7 @@ function getall() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
common.onGC(req, { ongc });
|
onGC(req, { ongc });
|
||||||
|
|
||||||
setImmediate(getall);
|
setImmediate(getall);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
// Flags: --expose-gc
|
// Flags: --expose-gc
|
||||||
|
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const net = require('net');
|
const net = require('net');
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ const gcListener = { ongc() { collected = true; } };
|
|||||||
|
|
||||||
{
|
{
|
||||||
const gcObject = {};
|
const gcObject = {};
|
||||||
common.onGC(gcObject, gcListener);
|
onGC(gcObject, gcListener);
|
||||||
|
|
||||||
const sock = net.createConnection(
|
const sock = net.createConnection(
|
||||||
server.address().port,
|
server.address().port,
|
||||||
|
@ -26,6 +26,7 @@ const common = require('../common');
|
|||||||
if (!common.hasCrypto)
|
if (!common.hasCrypto)
|
||||||
common.skip('missing crypto');
|
common.skip('missing crypto');
|
||||||
|
|
||||||
|
const onGC = require('../common/ongc');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const tls = require('tls');
|
const tls = require('tls');
|
||||||
const fixtures = require('../common/fixtures');
|
const fixtures = require('../common/fixtures');
|
||||||
@ -43,7 +44,7 @@ const gcListener = { ongc() { collected = true; } };
|
|||||||
|
|
||||||
{
|
{
|
||||||
const gcObject = {};
|
const gcObject = {};
|
||||||
common.onGC(gcObject, gcListener);
|
onGC(gcObject, gcListener);
|
||||||
|
|
||||||
const sock = tls.connect(
|
const sock = tls.connect(
|
||||||
server.address().port,
|
server.address().port,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user