From d199e71a8e99cf125e43369fb2429d8faa1acaaf Mon Sep 17 00:00:00 2001 From: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com> Date: Mon, 21 Sep 2026 07:51:12 -0400 Subject: [PATCH] test(config): wait for the benchmark fixture before timing out its group (#21982) The owner-loss group case spawned its fixture with a 100ms kill timeout and then read the child.pid handshake the fixture writes, so under full-suite load the launcher was SIGKILLed before it booted and the read failed with ENOENT. Start the launcher detached, wait for the handshake, and only then send the trial timeout's own SIGKILL, which leaves the same orphaned group the cleanup path validates. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb --- ...puter-helper-owner-loss-processes.test.mjs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/config/scripts/macos-computer-helper-owner-loss-processes.test.mjs b/config/scripts/macos-computer-helper-owner-loss-processes.test.mjs index 764eb73009f..e56f1bc224c 100644 --- a/config/scripts/macos-computer-helper-owner-loss-processes.test.mjs +++ b/config/scripts/macos-computer-helper-owner-loss-processes.test.mjs @@ -133,25 +133,34 @@ describeMacOS('macOS helper owner-loss benchmark process cleanup', () => { writeFileSync(${JSON.stringify(childPidPath)}, String(child.pid)) setInterval(() => {}, 1000) ` - const result = spawnBenchmarkProcess(process.execPath, ['-e', fixture], { + const launcher = spawn(process.execPath, ['-e', fixture], { + detached: true, env: { ...process.env, [environmentName]: environmentValue }, - stdio: 'ignore', - timeout: 100 + stdio: 'ignore' }) + spawnedPids.add(launcher.pid) + launcher.unref() + const launcherExited = new Promise((resolve) => launcher.once('exit', resolve)) + await expect.poll(() => existsSync(childPidPath), { timeout: 10_000 }).toBe(true) const childPid = Number(readFileSync(childPidPath, 'utf8')) spawnedPids.add(childPid) + // Send the trial timeout's own kill signal once the group is up; a real timeout would race its startup. + process.kill(launcher.pid, 'SIGKILL') + await launcherExited + spawnedPids.delete(launcher.pid) const environmentFragment = `${environmentName}=${environmentValue}` const groupState = { stopped: false } + expect(() => process.kill(launcher.pid, 0)).toThrow() expect(() => - signalValidatedProcessGroup(result.pid, `${environmentName}=wrong`, 'SIGSTOP') + signalValidatedProcessGroup(launcher.pid, `${environmentName}=wrong`, 'SIGSTOP') ).toThrow('Benchmark process group no longer belongs to this trial') expect(() => process.kill(childPid, 0)).not.toThrow() expect( - signalValidatedProcessGroup(result.pid, environmentFragment, 'SIGSTOP', groupState) + signalValidatedProcessGroup(launcher.pid, environmentFragment, 'SIGSTOP', groupState) ).toBe(true) expect( - signalValidatedProcessGroup(result.pid, environmentFragment, 'SIGKILL', groupState) + signalValidatedProcessGroup(launcher.pid, environmentFragment, 'SIGKILL', groupState) ).toBe(true) await expect .poll(() => {