Files
wangjia 70d996110d phase3(集成测试): 真 worker 进程 spawn → 重启 re-adopt 存活 worker → ingest;死亡→回收重试
用假 worker(走 outbox 协议、不烧 SDK token)验证 daemon↔worker 真进程 seam:
- 头条: spawn 真进程→等 started→换 Store 重连 reconcile(真判活)→re-adopt(任务仍 executing 不重跑)
  →finish 哨兵→ingest 到 exec_review(四字段 + reviewer/security/executor run 就位)
- 回收: 杀进程组 + 心跳调陈旧→reconcile 回收→failTaskAttempt 退避重入队

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:07:42 +08:00

38 lines
1.8 KiB
TypeScript

// 集成测试用的「假 worker」:走完整 outbox 协议,但【不调用 SDK / 不建 worktree】,零 token。
// 用法:daemon 通过 MAESTRO_WORKER_CMD='npx tsx test/fixtures/fake-worker.ts' spawn 它,argv[2]=runId。
// 行为:emit started + 持续刷心跳;轮询 runs/<runId>/finish 哨兵文件出现后 emit result+done 退出。
// 收到 SIGTERM → emit failed+done 退出。模拟一个「在跑的真进程」,供测试验证 spawn / 心跳 / re-adopt / ingest。
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { appendOutbox, readJobSpec, touchHeartbeat, runDir } from '../../src/executor/protocol.js';
const runId = process.argv[2];
if (!runId) { process.exit(2); }
const job = readJobSpec(runId);
touchHeartbeat(runId);
appendOutbox(runId, { type: 'started', pid: process.pid, worktree: job.worktreeDir, branch: job.branch, model: 'fake' });
const hb = setInterval(() => touchHeartbeat(runId), 300);
const finishFile = join(runDir(runId), 'finish');
const poll = setInterval(() => {
if (!existsSync(finishFile)) return;
clearInterval(hb); clearInterval(poll);
appendOutbox(runId, {
type: 'result', branch: job.branch, worktree: job.worktreeDir,
diffSummary: ' demo.txt | 1 +', commits: ['abc1234 fake commit'],
executor: { transcriptRef: null, sessionId: 'sess-fake' },
code: { summary: 'code ok', verdict: 'approve', transcriptRef: null },
security: { summary: 'sec ok', verdict: 'approve', transcriptRef: null },
});
appendOutbox(runId, { type: 'done' });
process.exit(0);
}, 80);
process.on('SIGTERM', () => {
clearInterval(hb); clearInterval(poll);
appendOutbox(runId, { type: 'failed', error: 'worker 收到 SIGTERM', transcriptRef: null, sessionId: null });
appendOutbox(runId, { type: 'done' });
process.exit(0);
});