From 2df0f0738d0cfb578caa98f3ae5e419b1fa24eb5 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 6 Apr 2023 20:09:19 +0200 Subject: [PATCH] test: report and kill child processes which are leaking after test (#22237) --- tests/config/commonFixtures.ts | 17 +++++++++++++---- tests/library/inspector/inspectorTest.ts | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/config/commonFixtures.ts b/tests/config/commonFixtures.ts index edd464465b..e9c4932b1e 100644 --- a/tests/config/commonFixtures.ts +++ b/tests/config/commonFixtures.ts @@ -87,19 +87,19 @@ export class TestChildProcess { } async close() { - if (!this.process.killed) + if (this.process.kill(0)) this._killProcessGroup('SIGINT'); return this.exited; } async kill() { - if (!this.process.killed) + if (this.process.kill(0)) this._killProcessGroup('SIGKILL'); return this.exited; } private _killProcessGroup(signal: 'SIGINT' | 'SIGKILL') { - if (!this.process.pid || this.process.killed) + if (!this.process.pid || !this.process.kill(0)) return; try { if (process.platform === 'win32') @@ -150,7 +150,16 @@ export const commonFixtures: Fixtures = { processes.push(process); return process; }); - await Promise.all(processes.map(child => child.close())); + await Promise.all(processes.map(async child => { + await Promise.race([ + child.exited, + new Promise(f => setTimeout(f, 3_000)), + ]); + if (child.process.kill(0)) { + await child.kill(); + throw new Error(`Process ${child.params.command.join(' ')} is still running. Leaking process?\nOutput:${child.output}`); + } + })); if (testInfo.status !== 'passed' && testInfo.status !== 'skipped' && !process.env.PWTEST_DEBUG) { for (const process of processes) { console.log('====== ' + process.params.command.join(' ')); diff --git a/tests/library/inspector/inspectorTest.ts b/tests/library/inspector/inspectorTest.ts index 0b12686468..30e1c65432 100644 --- a/tests/library/inspector/inspectorTest.ts +++ b/tests/library/inspector/inspectorTest.ts @@ -73,8 +73,8 @@ export const test = contextTest.extend({ cli = new CLIMock(childProcess, browserName, channel, headless, cliArgs, launchOptions.executablePath, noAutoExit); return cli; }); - if (cli) - await cli.exited.catch(() => {}); + // Discard any exit error and let childProcess fixture report leaking processes (processwes which do not exit). + cli?.exited.catch(() => {}); }, openRecorder: async ({ page, recorderPageGetter }, run) => {