Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ec1cbbe

Browse filesBrowse files
abhishekSavaniaduh95
authored andcommitted
test_runner: fix memory leaks in runner
- Close readline interface after child process exits Prevents accumulation of event listeners on stderr stream - Extract watch mode event handler to named function Allows proper cleanup when watch mode is aborted These changes prevent unbounded memory growth in long-running test suites and watch mode sessions. PR-URL: #60860 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
1 parent 434fcd7 commit ec1cbbe
Copy full SHA for ec1cbbe

1 file changed

+19-6Lines changed: 19 additions & 6 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎lib/internal/test_runner/runner.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/runner.js
+19-6Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,9 @@ function runTestFile(path, filesWatcher, opts) {
460460
finished(child.stdout, { __proto__: null, signal: t.signal }),
461461
]);
462462

463+
// Close readline interface to prevent memory leak
464+
rl.close();
465+
463466
if (watchMode) {
464467
filesWatcher.runningProcesses.delete(path);
465468
filesWatcher.runningSubtests.delete(path);
@@ -522,7 +525,7 @@ function watchFiles(testFiles, opts) {
522525
}
523526

524527
// Watch for changes in current filtered files
525-
watcher.on('changed', ({ owners, eventType }) => {
528+
const onChanged = ({ owners, eventType }) => {
526529
if (!opts.hasFiles && (eventType === 'rename' || eventType === 'change')) {
527530
const updatedTestFiles = createTestFileList(opts.globPatterns, opts.cwd);
528531
const newFileName = ArrayPrototypeFind(updatedTestFiles, (x) => !ArrayPrototypeIncludes(testFiles, x));
@@ -563,19 +566,29 @@ function watchFiles(testFiles, opts) {
563566
triggerUncaughtException(error, true /* fromPromise */);
564567
}));
565568
}
566-
});
569+
};
570+
571+
watcher.on('changed', onChanged);
572+
573+
// Cleanup function to remove event listener and prevent memory leak
574+
const cleanup = () => {
575+
watcher.removeListener('changed', onChanged);
576+
opts.root.harness.watching = false;
577+
opts.root.postRun();
578+
};
579+
567580
if (opts.signal) {
568581
kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation;
569582
opts.signal.addEventListener(
570583
'abort',
571-
() => {
572-
opts.root.harness.watching = false;
573-
opts.root.postRun();
574-
},
584+
cleanup,
575585
{ __proto__: null, once: true, [kResistStopPropagation]: true },
576586
);
577587
}
578588

589+
// Expose cleanup method for proper resource management
590+
filesWatcher.cleanup = cleanup;
591+
579592
return filesWatcher;
580593
}
581594

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.