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

3 files changed

Lines changed: 36 additions & 14 deletions

File tree

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

Lines changed: 16 additions & 5 deletions
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-
constassert=require('assert');
98

109
letobj={hello: 'world'};
1110
constref=newWeakReference(obj);
11+
letgcCount=0;
12+
letmaxGC=10;
1213

13-
setDeserializeMainFunction(()=>{
14-
obj=null;
14+
functionrun(){
1515
globalThis.gc();
16-
1716
setImmediate(()=>{
18-
assert.strictEqual(ref.get(),undefined);
17+
gcCount++;
18+
if(ref.get()===undefined){
19+
return;
20+
}elseif(gcCount<maxGC){
21+
run();
22+
}else{
23+
thrownewError(`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‎

Lines changed: 13 additions & 4 deletions
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
letd=domain.create();
16+
letresourceGCed=false;letdomainGCed=false;let
17+
emitterGCed=false;
1618
d.run(()=>{
1719
constresource=newasync_hooks.AsyncResource('TestResource');
1820
constemitter=newEventEmitter();
@@ -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+
asyncfunctionmain(){
43+
awaitcommon.gcUntil(
44+
'All objects garbage collected',
45+
()=>resourceGCed&&domainGCed&&emitterGCed);
46+
}
47+
48+
main();
Lines changed: 7 additions & 5 deletions
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+
constcommon=require('../common');
44
constassert=require('assert');
55
const{ internalBinding }=require('internal/test/binding');
66
const{ WeakReference }=internalBinding('util');
@@ -9,9 +9,11 @@ let obj = { hello: 'world' };
99
constref=newWeakReference(obj);
1010
assert.strictEqual(ref.get(),obj);
1111

12-
setImmediate(()=>{
12+
asyncfunctionmain(){
1313
obj=null;
14-
global.gc();
14+
awaitcommon.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)