From e9aac53fdec49c951db97f8a1c2e677c35818d98 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Sun, 19 Jul 2026 12:53:41 +0800 Subject: [PATCH] test(acp-snapshot): cover pre-fallback Windows exit state Model the requested signal setting a child termination marker before the launcher begins fallback handling. The regression proves close drains inherited stdio and propagates the original process error without sending a redundant SIGKILL. This complements the post-check fallback-refusal race and restores the launcher's required 100% per-file statement and branch coverage. --- .../acp-snapshot/tests/harness.spec.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/support/acp-snapshot/tests/harness.spec.ts b/packages/support/acp-snapshot/tests/harness.spec.ts index 08b069338c..61b40010df 100644 --- a/packages/support/acp-snapshot/tests/harness.spec.ts +++ b/packages/support/acp-snapshot/tests/harness.spec.ts @@ -179,6 +179,29 @@ describe('runScenario', () => { } }) + it('preserves the child error when the requested signal sets an exit marker', async () => { + const { dir } = await scenario({}) + const launched = launchAcpTestAgent({ agent: AGENT, cwd: dir }) + await launched.spawned + + const childFailure = Object.assign(new Error('signal failed as the child exited'), { code: 'EPERM' }) + const originalKill = launched.child.kill.bind(launched.child) + const kill = vi.spyOn(launched.child, 'kill').mockImplementation((signal) => { + expect(signal).toBe('SIGTERM') + originalKill('SIGKILL') + Object.defineProperty(launched.child, 'signalCode', { configurable: true, enumerable: true, writable: true, value: 'SIGTERM' }) + return true + }) + try { + launched.child.emit('error', childFailure) + await expect(launched.close('SIGTERM')).rejects.toBe(childFailure) + expect(kill).toHaveBeenCalledOnce() + } finally { + kill.mockRestore() + if (launched.child.exitCode === null && launched.child.signalCode === null) originalKill('SIGKILL') + } + }) + it('preserves the child error when fallback refusal races with an exit marker', async () => { const { dir } = await scenario({}) const launched = launchAcpTestAgent({ agent: AGENT, cwd: dir })