mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-11 04:00:38 +00:00
test(code-runtime-python): drive the inherited SIGXCPU path with a wrapper; fix the zh outer wire sentence
The review's two follow-ups on the inherited-SIGXCPU fix: (1) a discriminating case — pythonBin points at a wrapper that ignores SIGXCPU before exec'ing python3, so the child genuinely inherits the ignore; with cpuSeconds: 1 the busy loop must end as timeout (the bootstrap reset restored SIG_DFL), and reverting the reset leaves it running to the wall — verified red. (2) The zh README's OUTER wire section now carries the truncation-exception sentence (the previous commit had duplicated it in the inner section instead); the duplicate is removed, and the settlement note registers the inherited-SIGXCPU reset.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { existsSync, readdirSync, realpathSync, statSync } from 'node:fs'
|
||||
import { existsSync, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from 'node:fs'
|
||||
import { mkdtemp, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { basename, dirname, join } from 'node:path'
|
||||
@@ -638,6 +638,26 @@ describe('PythonCodeRuntime — inherited resource limits', () => {
|
||||
expect(result.value).toBeUndefined()
|
||||
}, 20_000)
|
||||
|
||||
it('reports a timeout when the interpreter was started with SIGXCPU ignored (inherited state)', async () => {
|
||||
// The child inherits the host's SIGXCPU disposition: a wrapper that
|
||||
// ignores SIGXCPU before exec'ing python3 hands the child a soft
|
||||
// RLIMIT_CPU that cannot stop it. The bootstrap resets SIGXCPU to SIG_DFL
|
||||
// before model code runs, so a busy loop still ends as a timeout rather
|
||||
// than running to the hard limit and being misclassified as worker-exit.
|
||||
const wrapper = join(tmpdir(), `dsh-xcpu-ignore-${process.pid}.sh`)
|
||||
writeFileSync(wrapper, '#!/bin/sh\ntrap "" XCPU\nexec python3 "$@"\n', { mode: 0o755 })
|
||||
try {
|
||||
const { runtime } = await setup({ maxWallMs: 30_000, cpuSeconds: 1, pythonBin: wrapper })
|
||||
const result = await runtime.run({
|
||||
program: ['while True: pass'].join('\n'),
|
||||
bindings: [],
|
||||
})
|
||||
expect(result.error?.kind).toBe('timeout')
|
||||
} finally {
|
||||
rmSync(wrapper, { force: true })
|
||||
}
|
||||
}, 20_000)
|
||||
|
||||
it('reports a timeout when a program traps AND masks SIGXCPU and returns past the soft limit', async () => {
|
||||
// The mask-only case exercises the unblock; the trap+mask combination is
|
||||
// the harder one: a program that installed a custom handler AND masked the
|
||||
|
||||
Reference in New Issue
Block a user