Skip to content

Commit

Permalink
test: deflake test-diagnostics-channel-memory-leak
Browse files Browse the repository at this point in the history
  • Loading branch information
joyeecheung committed Nov 24, 2023
1 parent 86c7783 commit 386e43f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
36 changes: 36 additions & 0 deletions test/common/gc.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,43 @@ async function runAndBreathe(fn, repeat, waitTime = 20) {
}
}

// This requires --expose-internals
async function checkIfCollectableByCounting(fn, klass, count, waitTime = 20) {
const { internalBinding } = require('internal/test/binding');
const { countObjectsWithPrototype } = internalBinding('heap_utils');
const { prototype, name } = klass;
let initialCount = countObjectsWithPrototype(prototype);
console.log(`Initial count of ${name}: ${initialCount}`);
let totalCreated = 0;
for (let i = 0; i < count; ++i) {
const created = await fn(i);
totalCreated += created;
console.log(`#${i}: created ${created} ${name}, total ${totalCreated}`);
await wait(waitTime); // give GC some breathing room.
const currentCount = countObjectsWithPrototype(prototype);
const collected = totalCreated - (currentCount - initialCount);
console.log(`#${i}: counted ${currentCount} ${name}, collected ${collected}`);
if (collected > 0 ) {
console.log(`Detected ${collected} collected ${name}, finish early`);
return;
}
}

await wait(waitTime); // give GC some breathing room.
const currentCount = countObjectsWithPrototype(prototype);
const collected = totalCreated - (currentCount - initialCount);
console.log(`Last count: counted ${currentCount} ${name}, collected ${collected}`);
// Some objects with the prototype can be collected.
if (collected > 0) {
console.log(`Detected ${collected} collected ${name}`);
return;
}

throw new Error(`${name} cannot be collected`);
}

module.exports = {
checkIfCollectable,
runAndBreathe,
checkIfCollectableByCounting,
};
3 changes: 0 additions & 3 deletions test/parallel/parallel.status
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ prefix parallel
# sample-test : PASS,FLAKY

[true] # This section applies to all platforms
# https://github.com/nodejs/node/pull/50327
# Currently there's no reliable way to test it.
test-diagnostics-channel-memory-leak: SKIP

[$system==win32]
# https://github.com/nodejs/node/issues/41206
Expand Down
30 changes: 14 additions & 16 deletions test/parallel/test-diagnostics-channel-memory-leak.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
// Flags: --expose-gc
// Flags: --expose-internals --max-old-space-size=16
'use strict';

// This test ensures that diagnostic channel references aren't leaked.

require('../common');
const { ok } = require('assert');
const common = require('../common');

const { subscribe, unsubscribe } = require('diagnostics_channel');
const { subscribe, unsubscribe, Channel } = require('diagnostics_channel');
const { checkIfCollectableByCounting } = require('../common/gc');

function noop() {}

const heapUsedBefore = process.memoryUsage().heapUsed;

for (let i = 0; i < 1000; i++) {
subscribe(String(i), noop);
unsubscribe(String(i), noop);
}

global.gc();

const heapUsedAfter = process.memoryUsage().heapUsed;

ok(heapUsedBefore >= heapUsedAfter);
const outer = 64;
const inner = 256;
checkIfCollectableByCounting((i) => {
for (let j = 0; j < inner; j++) {
const key = String(i * inner + j);
subscribe(key, noop);
unsubscribe(key, noop);
}
return inner;
}, Channel, outer).then(common.mustCall());

0 comments on commit 386e43f

Please sign in to comment.