diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 929e00d801f8..310d3afd2352 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -848,9 +848,6 @@ importers: tar-stream: specifier: 3.1.7 version: 3.1.7 - tree-kill: - specifier: 1.2.2 - version: 1.2.2 packages: @@ -7768,10 +7765,6 @@ packages: peerDependencies: tslib: '2' - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} @@ -16418,8 +16411,6 @@ snapshots: dependencies: tslib: 2.8.1 - tree-kill@1.2.2: {} - ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 diff --git a/tests/e2e/utils/BUILD.bazel b/tests/e2e/utils/BUILD.bazel index d4493fb14492..dbbda05702cd 100644 --- a/tests/e2e/utils/BUILD.bazel +++ b/tests/e2e/utils/BUILD.bazel @@ -20,6 +20,5 @@ ts_project( "//:node_modules/verdaccio-auth-memory", "//tests:node_modules/@types/tar-stream", "//tests:node_modules/tar-stream", - "//tests:node_modules/tree-kill", ], ) diff --git a/tests/e2e/utils/process.ts b/tests/e2e/utils/process.ts index 91216843086a..54bcf629a69e 100644 --- a/tests/e2e/utils/process.ts +++ b/tests/e2e/utils/process.ts @@ -1,7 +1,7 @@ import { spawn, SpawnOptions } from 'node:child_process'; import * as child_process from 'node:child_process'; import { getGlobalVariable, getGlobalVariablesEnv } from './env'; -import treeKill from 'tree-kill'; +import { setTimeout as sleep } from 'node:timers/promises'; import { delimiter, join, resolve } from 'node:path'; import { stripVTControlCharacters, styleText } from 'node:util'; @@ -255,29 +255,37 @@ export async function waitForAnyProcessOutputToMatch( return matchingProcess; } -export async function killAllProcesses(signal = 'SIGTERM'): Promise { - const processesToKill: Promise[] = []; +/** + * Kills all tracked processes with a retry mechanism. + */ +export async function killAllProcesses(signal: NodeJS.Signals = 'SIGTERM'): Promise { + let attempts = 0; + const maxRetries = 3; + + while (_processes.length > 0 && attempts < maxRetries) { + attempts++; + + // Iterate backwards so we can remove elements while looping if needed. + for (let i = _processes.length - 1; i >= 0; i--) { + const childProc = _processes[i]; - while (_processes.length) { - const childProc = _processes.pop(); - if (!childProc || childProc.pid === undefined) { - continue; + if (!childProc || childProc.killed) { + _processes.splice(i, 1); + continue; + } + + const killed = childProc.kill(signal); + if (killed) { + _processes.splice(i, 1); + continue; + } } - processesToKill.push( - new Promise((resolve) => { - treeKill(childProc.pid!, signal, () => { - // Ignore all errors. - // This is due to a race condition with the `waitForMatch` logic. - // where promises are resolved on matches and not when the process terminates. - // Also in some cases in windows we get `The operation attempted is not supported`. - resolve(); - }); - }), - ); + // If still have processes, wait a bit before the next retry (e.g., 100ms) + if (_processes.length > 0 && attempts < maxRetries) { + await sleep(100); + } } - - await Promise.all(processesToKill); } export function exec(cmd: string, ...args: string[]) { diff --git a/tests/package.json b/tests/package.json index 17660ff2192e..9eb906b8cda5 100644 --- a/tests/package.json +++ b/tests/package.json @@ -2,7 +2,6 @@ "devDependencies": { "@types/tar-stream": "3.1.4", "@angular-devkit/schematics": "workspace:*", - "tar-stream": "3.1.7", - "tree-kill": "1.2.2" + "tar-stream": "3.1.7" } }