Skip to content

Commit ca9f801

Browse files
joyeecheungUlisesGascon
authored andcommitted
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: #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>
1 parent 772496c commit ca9f801

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

test/fixtures/snapshot/weak-reference-gc.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@ const { WeakReference } = internalBinding('util');
55
const {
66
setDeserializeMainFunction
77
} = require('v8').startupSnapshot
8-
const assert = require('assert');
98

109
let obj = { hello: 'world' };
1110
const ref = new WeakReference(obj);
11+
let gcCount = 0;
12+
let maxGC = 10;
1213

13-
setDeserializeMainFunction(() => {
14-
obj = null;
14+
function run() {
1515
globalThis.gc();
16-
1716
setImmediate(() => {
18-
assert.strictEqual(ref.get(), undefined);
17+
gcCount++;
18+
if (ref.get() === undefined) {
19+
return;
20+
} else if (gcCount < maxGC) {
21+
run();
22+
} else {
23+
throw new Error(`Reference is still around after ${maxGC} GC`);
24+
}
1925
});
26+
}
27+
28+
setDeserializeMainFunction(() => {
29+
obj = null;
30+
run();
2031
});

test/parallel/test-domain-async-id-map-leak.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const isEnumerable = Function.call.bind(Object.prototype.propertyIsEnumerable);
1313
// See: https://github.com/nodejs/node/issues/23862
1414

1515
let d = domain.create();
16+
let resourceGCed = false; let domainGCed = false; let
17+
emitterGCed = false;
1618
d.run(() => {
1719
const resource = new async_hooks.AsyncResource('TestResource');
1820
const emitter = new EventEmitter();
@@ -30,10 +32,17 @@ d.run(() => {
3032
// emitter → resource → async id ⇒ domain → emitter.
3133
// Make sure that all of these objects are released:
3234

33-
onGC(resource, { ongc: common.mustCall() });
34-
onGC(d, { ongc: common.mustCall() });
35-
onGC(emitter, { ongc: common.mustCall() });
35+
onGC(resource, { ongc: common.mustCall(() => { resourceGCed = true; }) });
36+
onGC(d, { ongc: common.mustCall(() => { domainGCed = true; }) });
37+
onGC(emitter, { ongc: common.mustCall(() => { emitterGCed = true; }) });
3638
});
3739

3840
d = null;
39-
global.gc();
41+
42+
async function main() {
43+
await common.gcUntil(
44+
'All objects garbage collected',
45+
() => resourceGCed && domainGCed && emitterGCed);
46+
}
47+
48+
main();
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Flags: --expose-internals --expose-gc
22
'use strict';
3-
require('../common');
3+
const common = require('../common');
44
const assert = require('assert');
55
const { internalBinding } = require('internal/test/binding');
66
const { WeakReference } = internalBinding('util');
@@ -9,9 +9,11 @@ let obj = { hello: 'world' };
99
const ref = new WeakReference(obj);
1010
assert.strictEqual(ref.get(), obj);
1111

12-
setImmediate(() => {
12+
async function main() {
1313
obj = null;
14-
global.gc();
14+
await common.gcUntil(
15+
'Reference is garbage collected',
16+
() => ref.get() === undefined);
17+
}
1518

16-
assert.strictEqual(ref.get(), undefined);
17-
});
19+
main();

0 commit comments

Comments
 (0)