mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(e2b): preserve signals after output drain
This commit is contained in:
@@ -512,7 +512,9 @@ export class E2BSubprocessHandle implements SubprocessHandle {
|
||||
this.stdoutReader?.invalidateSpill()
|
||||
this.stderrReader?.invalidateSpill()
|
||||
await handle.disconnect()
|
||||
return { exitCode, signal: null }
|
||||
return this.terminationSignal === null
|
||||
? { exitCode, signal: null }
|
||||
: { exitCode: null, signal: this.terminationSignal }
|
||||
}
|
||||
const completed = await Promise.race([settlement, waitTick().then(() => undefined)])
|
||||
if (completed !== undefined) return this.commandOutcome(completed)
|
||||
|
||||
@@ -103,6 +103,7 @@ class FakeSandbox {
|
||||
readonly signalErrors: unknown[] = []
|
||||
trapsTerm = false
|
||||
delaysKill = false
|
||||
delaysKillCompletion = false
|
||||
sdkKillStops = true
|
||||
alive = true
|
||||
ambient = 'PATH=/ambient/bin\0KEEP=safe\0NPM_TOKEN=secret\0DSH_STALE=old\0BROKEN\0=bad\0'
|
||||
@@ -247,7 +248,7 @@ class FakeSandbox {
|
||||
throw error
|
||||
}
|
||||
if (!this.delaysKill) this.alive = false
|
||||
this.handle.fail(137)
|
||||
if (!this.delaysKillCompletion) this.handle.fail(137)
|
||||
return { exitCode: 0, stdout: '', stderr: '' }
|
||||
}
|
||||
if ((options as StartOptions | undefined)?.background === true) {
|
||||
@@ -473,6 +474,25 @@ describe('E2BSubprocessHandle', () => {
|
||||
expect(fake.handle.disconnects).toBe(0)
|
||||
})
|
||||
|
||||
it('preserves a requested signal when output draining expires', async () => {
|
||||
const fake = new FakeSandbox()
|
||||
fake.trapsTerm = true
|
||||
fake.delaysKill = true
|
||||
fake.delaysKillCompletion = true
|
||||
fake.sdkKillStops = false
|
||||
const handle = new E2BSubprocessHandle(runtime(fake), spec({ graceMs: 5 }), '/runtime/drain-signal')
|
||||
await flush()
|
||||
|
||||
handle.terminate()
|
||||
await vi.waitFor(() => { expect(fake.commandsSeen).toContain('kill -KILL -- -4242') })
|
||||
fake.exitStatus = '143\n'
|
||||
|
||||
await expect(handle.done).resolves.toEqual({ exitCode: null, signal: 'SIGKILL' })
|
||||
expect(fake.handle.disconnects).toBe(1)
|
||||
fake.alive = false
|
||||
await expect(handle.waitForExit()).resolves.toBe(true)
|
||||
})
|
||||
|
||||
it('rejects an invalid direct-command exit status', async () => {
|
||||
const fake = new FakeSandbox()
|
||||
const handle = new E2BSubprocessHandle(runtime(fake), spec(), '/runtime/invalid-status')
|
||||
|
||||
Reference in New Issue
Block a user