test: add maxCount and gcOptions to gcUntil() · nodejs/node@08bde67

@@ -3,6 +3,8 @@

33

const wait = require('timers/promises').setTimeout;

44

const assert = require('assert');

55

const common = require('../common');

6+

// TODO(joyeecheung): rewrite checkIfCollectable to use this too.

7+

const { setImmediate: setImmediatePromisified } = require('timers/promises');

68

const gcTrackerMap = new WeakMap();

79

const gcTrackerTag = 'NODE_TEST_COMMON_GC_TRACKER';

810

@@ -40,32 +42,26 @@ function onGC(obj, gcListener) {

40424143

/**

4244

* Repeatedly triggers garbage collection until a specified condition is met or a maximum number of attempts is reached.

45+

* This utillity must be run in a Node.js instance that enables --expose-gc.

4346

* @param {string|Function} [name] - Optional name, used in the rejection message if the condition is not met.

4447

* @param {Function} condition - A function that returns true when the desired condition is met.

48+

* @param {number} maxCount - Maximum number of garbage collections that should be tried.

49+

* @param {object} gcOptions - Options to pass into the global gc() function.

4550

* @returns {Promise} A promise that resolves when the condition is met, or rejects after 10 failed attempts.

4651

*/

47-

function gcUntil(name, condition) {

48-

if (typeof name === 'function') {

49-

condition = name;

50-

name = undefined;

51-

}

52-

return new Promise((resolve, reject) => {

53-

let count = 0;

54-

function gcAndCheck() {

55-

setImmediate(() => {

56-

count++;

57-

global.gc();

58-

if (condition()) {

59-

resolve();

60-

} else if (count < 10) {

61-

gcAndCheck();

62-

} else {

63-

reject(name === undefined ? undefined : 'Test ' + name + ' failed');

64-

}

65-

});

52+

async function gcUntil(name, condition, maxCount = 10, gcOptions) {

53+

for (let count = 0; count < maxCount; ++count) {

54+

await setImmediatePromisified();

55+

if (gcOptions) {

56+

await global.gc(gcOptions);

57+

} else {

58+

await global.gc(); // Passing in undefined is not the same as empty.

6659

}

67-

gcAndCheck();

68-

});

60+

if (condition()) {

61+

return;

62+

}

63+

}

64+

throw new Error(`Test ${name} failed`);

6965

}

70667167

// This function can be used to check if an object factor leaks or not,