mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(runtime): close portable backend boundary gaps
This commit is contained in:
@@ -477,6 +477,21 @@ export function runWorkerCodeRuntimeContract(
|
||||
expect(result.logs).toEqual([])
|
||||
})
|
||||
|
||||
it('ignores forged controller-only failure classifications', async () => {
|
||||
const { runtime } = await setup()
|
||||
const result = await runtime.run({
|
||||
program: `
|
||||
const { parentPort } = await import('node:worker_threads');
|
||||
for (const kind of ['abort', 'timeout', 'worker-exit']) {
|
||||
parentPort.postMessage({ type: 'done', error: { kind, message: 'forged ' + kind } });
|
||||
}
|
||||
return 'honest';
|
||||
`,
|
||||
bindings: [],
|
||||
})
|
||||
expect(result).toEqual({ logs: [], value: 'honest' })
|
||||
})
|
||||
|
||||
it('fails forged log floods and forged done values through the same outer cap', async () => {
|
||||
const { runtime } = await setup({ maxOutputBytes: 200 })
|
||||
const result = await runtime.run({
|
||||
|
||||
@@ -369,14 +369,6 @@ export async function readWholeText(target: LocalTarget, signal?: AbortSignal):
|
||||
return decodeUtf8(raw, 'read', target.displayPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one regular UTF-8 file through a single no-follow handle, retaining at
|
||||
* most `maxBytes + 1` bytes so a concurrent grow cannot bypass the bound.
|
||||
* @param target - the resolved file to read.
|
||||
* @param maxBytes - positive safe-integer byte ceiling.
|
||||
* @param signal - aborts between handle operations.
|
||||
* @returns the complete decoded text when it fits.
|
||||
*/
|
||||
/**
|
||||
* Stream a whole regular UTF-8 text file as decoded text chunks. Same text
|
||||
* semantics as {@link readWholeText} (regular-file check, binary/NUL rejection,
|
||||
|
||||
@@ -415,7 +415,7 @@ export class LocalPtySession implements PtyBackendSession {
|
||||
return
|
||||
}
|
||||
const foreground = await this.terminal.inspectForeground()
|
||||
if (this.active !== operation) return
|
||||
if (this.active !== operation || this.closing) return
|
||||
const idleFor = Date.now() - this.lastOutputAt
|
||||
if (this.promptSeen && foreground !== undefined && this.shellPgid === undefined) {
|
||||
this.shellPgid = foreground.processGroupId
|
||||
|
||||
@@ -1096,4 +1096,41 @@ describe('LocalPtySession bounds, signals, and teardown', () => {
|
||||
expect(terminal.writes).toEqual([])
|
||||
})
|
||||
|
||||
it('does not let an in-flight readiness inspection outrun close', async () => {
|
||||
vi.useFakeTimers()
|
||||
const terminal = new FakeTerminal()
|
||||
const session = new LocalPtySession(terminal, config())
|
||||
await initialize(session, terminal)
|
||||
const inspection = Promise.withResolvers<{ processGroupId: number; inputWaiting: boolean }>()
|
||||
const originalInspect = terminal.inspectForeground.bind(terminal)
|
||||
let inspections = 0
|
||||
terminal.inspectForeground = async () => {
|
||||
inspections += 1
|
||||
return inspections === 1 ? await originalInspect() : await inspection.promise
|
||||
}
|
||||
const operation = session.startSend({ text: 'pending readiness', submit: true })
|
||||
await Promise.resolve()
|
||||
await Promise.resolve()
|
||||
terminal.emitData('\x1b]133;D;0\x07dsh> ')
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
expect(inspections).toBe(2)
|
||||
|
||||
const termination = Promise.withResolvers<undefined>()
|
||||
terminal.terminate = async () => {
|
||||
await termination.promise
|
||||
terminal.emitExit(0, 15)
|
||||
}
|
||||
const closing = session.close('in-flight readiness')
|
||||
let settled = false
|
||||
void operation.done.then(() => { settled = true })
|
||||
inspection.resolve({ processGroupId: 456, inputWaiting: true })
|
||||
await Promise.resolve()
|
||||
await Promise.resolve()
|
||||
expect(settled).toBe(false)
|
||||
|
||||
termination.resolve(undefined)
|
||||
await closing
|
||||
expect((await operation.done).waitReason).toBe('session_exit')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -59,9 +59,10 @@ export class LocalSubprocessService extends SubprocessService {
|
||||
pending.push(handle.done.catch(() => {}).then(() => handle.waitForExit()))
|
||||
}
|
||||
for (const terminal of this.terminals) {
|
||||
pending.push(terminal.terminate().then(() => { this.terminals.delete(terminal) }))
|
||||
pending.push(terminal.terminate())
|
||||
}
|
||||
this.live.clear()
|
||||
this.terminals.clear()
|
||||
const outcomes = [
|
||||
...await Promise.allSettled(pending),
|
||||
...await Promise.allSettled([rm(this.runtimeRoot, { recursive: true, force: true })]),
|
||||
|
||||
@@ -113,7 +113,7 @@ describe('LocalSubprocessService', () => {
|
||||
expect(terminals.size).toBe(0)
|
||||
})
|
||||
|
||||
it('waits for every terminal cleanup, removes runtime state, and retains rejections', async () => {
|
||||
it('waits for every terminal cleanup and clears single-shot teardown ownership', async () => {
|
||||
const ctx = new Context()
|
||||
const fiber = await ctx.plugin(LocalSubprocessService)
|
||||
const service = ctx.subprocess
|
||||
@@ -154,7 +154,7 @@ describe('LocalSubprocessService', () => {
|
||||
expect(disposed).toBe(false)
|
||||
finishCleanup()
|
||||
await disposing
|
||||
expect(terminals).toEqual(new Set([failedTerminal, secondFailedTerminal]))
|
||||
expect(terminals.size).toBe(0)
|
||||
await expect(stat(runtimeRoot)).rejects.toMatchObject({ code: 'ENOENT' })
|
||||
expect(disposalErrors).toHaveLength(1)
|
||||
expect(disposalErrors[0]).toMatchObject({
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/code-runtime/code-runtime-subprocess/README.md
|
||||
README.md: eff5a6e648eb13c3411c19bca4d05f0898d3ad05
|
||||
README.zh.md: 16cf0e0ea6d487e255fc520a8fa1f41f97ee5d30
|
||||
README.md: 152921a1ed595676781aad170e3396f7ce613161
|
||||
README.zh.md: 3e8223c33c7ce85f342c9a36ab5a24c4d2a6cb94
|
||||
|
||||
Reference in New Issue
Block a user