From ca9f801332cd177bb06fecf55c2ec1abd5232520 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 7 Aug 2023 16:24:06 +0200 Subject: [PATCH] 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 Reviewed-By: Yagiz Nizipli Reviewed-By: Rafael Gonzaga Reviewed-By: Benjamin Gruenbaum --- test/fixtures/snapshot/weak-reference-gc.js | 21 ++++++++++++++----- .../parallel/test-domain-async-id-map-leak.js | 17 +++++++++++---- .../test-internal-util-weakreference.js | 12 ++++++----- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/test/fixtures/snapshot/weak-reference-gc.js b/test/fixtures/snapshot/weak-reference-gc.js index d8bfdf95d1772a..8dada530e77c2a 100644 --- a/test/fixtures/snapshot/weak-reference-gc.js +++ b/test/fixtures/snapshot/weak-reference-gc.js @@ -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; -setDeserializeMainFunction(() => { - obj = null; +function run() { globalThis.gc(); - setImmediate(() => { - assert.strictEqual(ref.get(), undefined); + 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; + run(); }); diff --git a/test/parallel/test-domain-async-id-map-leak.js b/test/parallel/test-domain-async-id-map-leak.js index 8c03aa9401259a..12e93ef3594eaa 100644 --- a/test/parallel/test-domain-async-id-map-leak.js +++ b/test/parallel/test-domain-async-id-map-leak.js @@ -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(); diff --git a/test/parallel/test-internal-util-weakreference.js b/test/parallel/test-internal-util-weakreference.js index b48b34fe2309ea..75a00176bb095b 100644 --- a/test/parallel/test-internal-util-weakreference.js +++ b/test/parallel/test-internal-util-weakreference.js @@ -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();