test: add maxCount and gcOptions to gcUntil() · nodejs/node@08bde67
@@ -3,6 +3,8 @@
33const wait = require('timers/promises').setTimeout;
44const assert = require('assert');
55const common = require('../common');
6+// TODO(joyeecheung): rewrite checkIfCollectable to use this too.
7+const { setImmediate: setImmediatePromisified } = require('timers/promises');
68const gcTrackerMap = new WeakMap();
79const 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,