test: make WeakReference tests robust
Previously we assume that the objects are GC'ed after one global.gc() returns, which is not necessarily always the case. Use gcUntil() to run GC multiple times if they are not GC'ed in the first time around. PR-URL: https://github.com/nodejs/node/pull/49053 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
parent
72151769b8
commit
c64c9149ad
23
test/fixtures/snapshot/weak-reference-gc.js
vendored
23
test/fixtures/snapshot/weak-reference-gc.js
vendored
@ -5,16 +5,27 @@ const { WeakReference } = internalBinding('util');
|
||||
const {
|
||||
setDeserializeMainFunction
|
||||
} = require('v8').startupSnapshot
|
||||
const assert = require('assert');
|
||||
|
||||
let obj = { hello: 'world' };
|
||||
const ref = new WeakReference(obj);
|
||||
let gcCount = 0;
|
||||
let maxGC = 10;
|
||||
|
||||
function run() {
|
||||
globalThis.gc();
|
||||
setImmediate(() => {
|
||||
gcCount++;
|
||||
if (ref.get() === undefined) {
|
||||
return;
|
||||
} else if (gcCount < maxGC) {
|
||||
run();
|
||||
} else {
|
||||
throw new Error(`Reference is still around after ${maxGC} GC`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setDeserializeMainFunction(() => {
|
||||
obj = null;
|
||||
globalThis.gc();
|
||||
|
||||
setImmediate(() => {
|
||||
assert.strictEqual(ref.get(), undefined);
|
||||
});
|
||||
run();
|
||||
});
|
||||
|
@ -13,6 +13,8 @@ const isEnumerable = Function.call.bind(Object.prototype.propertyIsEnumerable);
|
||||
// See: https://github.com/nodejs/node/issues/23862
|
||||
|
||||
let d = domain.create();
|
||||
let resourceGCed = false; let domainGCed = false; let
|
||||
emitterGCed = false;
|
||||
d.run(() => {
|
||||
const resource = new async_hooks.AsyncResource('TestResource');
|
||||
const emitter = new EventEmitter();
|
||||
@ -30,10 +32,17 @@ d.run(() => {
|
||||
// emitter → resource → async id ⇒ domain → emitter.
|
||||
// Make sure that all of these objects are released:
|
||||
|
||||
onGC(resource, { ongc: common.mustCall() });
|
||||
onGC(d, { ongc: common.mustCall() });
|
||||
onGC(emitter, { ongc: common.mustCall() });
|
||||
onGC(resource, { ongc: common.mustCall(() => { resourceGCed = true; }) });
|
||||
onGC(d, { ongc: common.mustCall(() => { domainGCed = true; }) });
|
||||
onGC(emitter, { ongc: common.mustCall(() => { emitterGCed = true; }) });
|
||||
});
|
||||
|
||||
d = null;
|
||||
global.gc();
|
||||
|
||||
async function main() {
|
||||
await common.gcUntil(
|
||||
'All objects garbage collected',
|
||||
() => resourceGCed && domainGCed && emitterGCed);
|
||||
}
|
||||
|
||||
main();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Flags: --expose-internals --expose-gc
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const { internalBinding } = require('internal/test/binding');
|
||||
const { WeakReference } = internalBinding('util');
|
||||
@ -9,9 +9,11 @@ let obj = { hello: 'world' };
|
||||
const ref = new WeakReference(obj);
|
||||
assert.strictEqual(ref.get(), obj);
|
||||
|
||||
setImmediate(() => {
|
||||
async function main() {
|
||||
obj = null;
|
||||
global.gc();
|
||||
await common.gcUntil(
|
||||
'Reference is garbage collected',
|
||||
() => ref.get() === undefined);
|
||||
}
|
||||
|
||||
assert.strictEqual(ref.get(), undefined);
|
||||
});
|
||||
main();
|
||||
|
Loading…
x
Reference in New Issue
Block a user