diff --git a/scripts/check-admin-account-procedures.mjs b/scripts/check-admin-account-procedures.mjs index 1fff5253b..4880f09f6 100644 --- a/scripts/check-admin-account-procedures.mjs +++ b/scripts/check-admin-account-procedures.mjs @@ -144,6 +144,10 @@ async function stopStandalone(child) { if (child.exitCode !== null) { return; } + if (process.platform === 'win32') { + await stopWindowsProcessTree(child); + return; + } child.kill('SIGTERM'); const exited = await Promise.race([ once(child, 'exit').then(() => true), @@ -155,6 +159,37 @@ async function stopStandalone(child) { } } +async function stopWindowsProcessTree(child) { + if (typeof child.pid === 'number') { + await runTaskKill(child.pid); + } + const exited = await Promise.race([ + once(child, 'exit').then(() => true), + delay(5_000).then(() => false), + ]); + if (!exited && child.exitCode === null) { + child.kill('SIGKILL'); + await once(child, 'exit'); + } +} + +function runTaskKill(pid) { + return new Promise((resolve, reject) => { + const taskKill = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], { + stdio: 'ignore', + shell: false, + }); + taskKill.once('error', reject); + taskKill.once('exit', (code, signal) => { + if (code === 0 || code === 128 || code === 1) { + resolve(); + return; + } + reject(new Error(`taskkill exited with ${signal ?? code}`)); + }); + }); +} + async function callProcedure(serverUrl, token, procedureName, input) { const response = await fetch( `${serverUrl}/v1/database/${database}/call/${procedureName}`, diff --git a/scripts/spacetime-editor-idempotency-smoke.mjs b/scripts/spacetime-editor-idempotency-smoke.mjs index 4003b92ed..3b79c0836 100644 --- a/scripts/spacetime-editor-idempotency-smoke.mjs +++ b/scripts/spacetime-editor-idempotency-smoke.mjs @@ -228,6 +228,10 @@ export async function stopStandalone(child) { if (child.exitCode !== null) { return; } + if (process.platform === 'win32') { + await stopWindowsProcessTree(child); + return; + } child.kill('SIGTERM'); const exited = await Promise.race([ once(child, 'exit').then(() => true), @@ -239,6 +243,37 @@ export async function stopStandalone(child) { } } +async function stopWindowsProcessTree(child) { + if (typeof child.pid === 'number') { + await runTaskKill(child.pid); + } + const exited = await Promise.race([ + once(child, 'exit').then(() => true), + delay(5_000).then(() => false), + ]); + if (!exited && child.exitCode === null) { + child.kill('SIGKILL'); + await once(child, 'exit'); + } +} + +function runTaskKill(pid) { + return new Promise((resolve, reject) => { + const taskKill = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], { + stdio: 'ignore', + shell: false, + }); + taskKill.once('error', reject); + taskKill.once('exit', (code, signal) => { + if (code === 0 || code === 128 || code === 1) { + resolve(); + return; + } + reject(new Error(`taskkill exited with ${signal ?? code}`)); + }); + }); +} + function cliPrefix(configPath) { return ['--config-path', configPath]; }