Skip to content

Commit 9cb14de

Browse files
committed
test: consume protected child pipe resets
1 parent 812c079 commit 9cb14de

3 files changed

Lines changed: 8 additions & 1 deletion

File tree

tests/helpers/run-child.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export function runChild(command, args, options = {}) {
2525
child.stdout?.on('data', (chunk) => capture('stdout', chunk));
2626
child.stderr?.on('data', (chunk) => capture('stderr', chunk));
2727
if (protectedInput) {
28+
child.stdio[3]?.on('error', consumePipeError); child.stdio[4]?.on('error', consumePipeError);
2829
child.stdio[4]?.on('data', (chunk) => capture('internal', chunk));
2930
child.stdio[3]?.end(`${JSON.stringify(options.input ?? {})}\n`);
3031
} else if (options.ordinaryInput) child.stdin?.end(JSON.stringify(options.input));
@@ -39,3 +40,5 @@ export function runChild(command, args, options = {}) {
3940
child.once('exit', (code, signal) => { if (!terminating) finish(null, { code, signal, stdout, stderr, internal, spawnargs: child.spawnargs, pid: child.pid }); });
4041
});
4142
}
43+
44+
function consumePipeError() {}

tests/integration/companion.test.mjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ function run(command, args, options = {}) {
4141
let stdout = ''; let stderr = ''; let internal = '';
4242
child.stdout?.on('data', (chunk) => { stdout += chunk; }); child.stderr?.on('data', (chunk) => { stderr += chunk; });
4343
child.stdio[4]?.on('data', (chunk) => { internal += chunk; });
44+
child.stdio[3]?.on('error', consumePipeError); child.stdio[4]?.on('error', consumePipeError);
4445
/** @type {import('node:stream').Writable} */ (child.stdio[3]).end(options.rawInput ?? `${JSON.stringify(options.input ?? {})}\n`);
4546
child.once('error', reject); child.once('exit', (code) => resolvePromise({ code, stdout, stderr, internal }));
4647
});
4748
}
4849

50+
function consumePipeError() {}
51+
4952
/** @param {any} context @param {string[]} args @param {NodeJS.ProcessEnv} [extraEnv] @param {Record<string,unknown>} [authorization] */
5053
async function companion(context, args, extraEnv = {}, authorization = { callerContext: context.caller }) {
5154
const result = await run(process.execPath, [cli, ...args], { cwd: context.workspace, env: { ...context.env, ...extraEnv }, input: authorization });
@@ -141,7 +144,7 @@ test('caller authorization is absent from the running process command line and p
141144
const context = await fixture(); const reserved = await companion(context, ['review', '--background']);
142145
const caller = await context.identity.createCallerContext({ sessionId: 'codex-session', turnId: 'turn-ps', workspace: context.workspace, permissionMode: 'workspace-write' });
143146
const child = spawn(process.execPath, [cli, 'status', reserved.json.job.id, '--wait', '--timeout-ms', '500'], { cwd: context.workspace, env: context.env, stdio: ['ignore', 'pipe', 'pipe', 'pipe', 'pipe'], shell: false });
144-
let stdout = ''; let stderr = ''; let internal = ''; child.stdout?.on('data', (chunk) => { stdout += chunk; }); child.stderr?.on('data', (chunk) => { stderr += chunk; }); child.stdio[4]?.on('data', (chunk) => { internal += chunk; }); /** @type {import('node:stream').Writable} */ (child.stdio[3]).end(`${JSON.stringify({ callerContext: caller })}\n`);
147+
let stdout = ''; let stderr = ''; let internal = ''; child.stdout?.on('data', (chunk) => { stdout += chunk; }); child.stderr?.on('data', (chunk) => { stderr += chunk; }); child.stdio[3]?.on('error', consumePipeError); child.stdio[4]?.on('error', consumePipeError); child.stdio[4]?.on('data', (chunk) => { internal += chunk; }); /** @type {import('node:stream').Writable} */ (child.stdio[3]).end(`${JSON.stringify({ callerContext: caller })}\n`);
145148
const inspected = await run('ps', ['-p', String(child.pid), '-o', 'command=']);
146149
assert.equal(inspected.code, 0); assert.doesNotMatch(inspected.stdout, new RegExp(caller));
147150
const code = await new Promise((resolvePromise, reject) => { child.once('error', reject); child.once('exit', resolvePromise); });

tests/recovery.test.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ test('real CLI fd4 delivery failure revokes capability and releases the writable
327327
const fixture = await context();
328328
const child = spawn(process.execPath, [companionCli, 'rescue', '--background', '--fresh', 'repair'], { cwd: fixture.workspace, env: fixture.env, stdio: ['ignore', 'pipe', 'pipe', 'pipe', 'pipe'] });
329329
/** @type {import('node:stream').Writable} */ (child.stdio[3]).end(`${JSON.stringify({ callerContext: fixture.callerContext })}\n`);
330+
child.stdio[4].on('error', () => {});
330331
child.stdio[4].destroy();
331332
const code = await new Promise((resolve, reject) => { const timer = setTimeout(() => { child.kill('SIGKILL'); reject(new Error('companion delivery failure timed out')); }, 2_000); child.once('error', reject); child.once('exit', (value) => { clearTimeout(timer); resolve(value); }); });
332333
assert.notEqual(code, 0);

0 commit comments

Comments
 (0)