test: share task executor cancellation fixtures

This commit is contained in:
Peter Steinberger
2026-04-20 19:16:28 +01:00
parent 7aebac697e
commit 5934a8eacc

View File

@@ -97,6 +97,56 @@ async function withTaskExecutorStateDir(run: (stateDir: string) => Promise<void>
});
}
function createRunningAcpChildTaskRun(
overrides: Partial<Parameters<typeof createRunningTaskRun>[0]> = {},
) {
return createRunningTaskRun({
runtime: "acp",
ownerKey: "agent:main:main",
scopeKind: "session",
childSessionKey: "agent:codex:acp:child",
runId: "run-acp-child",
task: "Inspect a PR",
startedAt: 10,
deliveryStatus: "pending",
...overrides,
});
}
function spyOnRuntimeCancel() {
const defaultRuntime = getDetachedTaskLifecycleRuntime();
const cancelDetachedTaskRunByIdSpy = vi.fn(
(...args: Parameters<typeof defaultRuntime.cancelDetachedTaskRunById>) =>
defaultRuntime.cancelDetachedTaskRunById(...args),
);
setDetachedTaskLifecycleRuntime({
...defaultRuntime,
cancelDetachedTaskRunById: cancelDetachedTaskRunByIdSpy,
});
return cancelDetachedTaskRunByIdSpy;
}
function expectCancelledAcpChildTask(
child: ReturnType<typeof createRunningTaskRun>,
cancelled: unknown,
) {
expect(cancelled).toMatchObject({
found: true,
cancelled: true,
});
expect(getTaskById(child.taskId)).toMatchObject({
taskId: child.taskId,
status: "cancelled",
});
expect(hoisted.cancelSessionMock).toHaveBeenCalledWith({
cfg: {} as never,
sessionKey: "agent:codex:acp:child",
reason: "task-cancel",
});
}
describe("task-executor", () => {
afterEach(() => {
if (ORIGINAL_STATE_DIR === undefined) {
@@ -587,15 +637,8 @@ describe("task-executor", () => {
await withTaskExecutorStateDir(async () => {
hoisted.cancelSessionMock.mockResolvedValue(undefined);
const child = createRunningTaskRun({
runtime: "acp",
ownerKey: "agent:main:main",
scopeKind: "session",
childSessionKey: "agent:codex:acp:child",
const child = createRunningAcpChildTaskRun({
runId: "run-linear-cancel",
task: "Inspect a PR",
startedAt: 10,
deliveryStatus: "pending",
});
const cancelled = await cancelDetachedTaskRunById({
@@ -603,19 +646,7 @@ describe("task-executor", () => {
taskId: child.taskId,
});
expect(cancelled).toMatchObject({
found: true,
cancelled: true,
});
expect(getTaskById(child.taskId)).toMatchObject({
taskId: child.taskId,
status: "cancelled",
});
expect(hoisted.cancelSessionMock).toHaveBeenCalledWith({
cfg: {} as never,
sessionKey: "agent:codex:acp:child",
reason: "task-cancel",
});
expectCancelledAcpChildTask(child, cancelled);
});
});
@@ -623,27 +654,11 @@ describe("task-executor", () => {
await withTaskExecutorStateDir(async () => {
hoisted.cancelSessionMock.mockResolvedValue(undefined);
const child = createRunningTaskRun({
runtime: "acp",
ownerKey: "agent:main:main",
scopeKind: "session",
childSessionKey: "agent:codex:acp:child",
const child = createRunningAcpChildTaskRun({
runId: "run-external-cancel",
task: "Inspect a PR",
startedAt: 10,
deliveryStatus: "pending",
});
const defaultRuntime = getDetachedTaskLifecycleRuntime();
const cancelDetachedTaskRunByIdSpy = vi.fn(
(...args: Parameters<typeof defaultRuntime.cancelDetachedTaskRunById>) =>
defaultRuntime.cancelDetachedTaskRunById(...args),
);
setDetachedTaskLifecycleRuntime({
...defaultRuntime,
cancelDetachedTaskRunById: cancelDetachedTaskRunByIdSpy,
});
const cancelDetachedTaskRunByIdSpy = spyOnRuntimeCancel();
const cancelled = await cancelDetachedTaskRunById({
cfg: {} as never,
@@ -665,15 +680,8 @@ describe("task-executor", () => {
await withTaskExecutorStateDir(async () => {
hoisted.cancelSessionMock.mockResolvedValue(undefined);
const child = createRunningTaskRun({
runtime: "acp",
ownerKey: "agent:main:main",
scopeKind: "session",
childSessionKey: "agent:codex:acp:child",
const child = createRunningAcpChildTaskRun({
runId: "run-runtime-decline-cancel",
task: "Inspect a PR",
startedAt: 10,
deliveryStatus: "pending",
});
const cancelDetachedTaskRunByIdSpy = vi.fn(async () => ({
@@ -696,19 +704,7 @@ describe("task-executor", () => {
cfg: {} as never,
taskId: child.taskId,
});
expect(cancelled).toMatchObject({
found: true,
cancelled: true,
});
expect(getTaskById(child.taskId)).toMatchObject({
taskId: child.taskId,
status: "cancelled",
});
expect(hoisted.cancelSessionMock).toHaveBeenCalledWith({
cfg: {} as never,
sessionKey: "agent:codex:acp:child",
reason: "task-cancel",
});
expectCancelledAcpChildTask(child, cancelled);
});
});
@@ -716,15 +712,8 @@ describe("task-executor", () => {
await withTaskExecutorStateDir(async () => {
hoisted.cancelSessionMock.mockResolvedValue(undefined);
const child = createRunningTaskRun({
runtime: "acp",
ownerKey: "agent:main:main",
scopeKind: "session",
childSessionKey: "agent:codex:acp:child",
const child = createRunningAcpChildTaskRun({
runId: "run-runtime-owned-cancel",
task: "Inspect a PR",
startedAt: 10,
deliveryStatus: "pending",
});
const cancelDetachedTaskRunByIdSpy = vi.fn(async () => ({
@@ -824,15 +813,7 @@ describe("task-executor", () => {
throw new Error("expected child task payload");
}
const defaultRuntime = getDetachedTaskLifecycleRuntime();
const cancelDetachedTaskRunByIdSpy = vi.fn(
(...args: Parameters<typeof defaultRuntime.cancelDetachedTaskRunById>) =>
defaultRuntime.cancelDetachedTaskRunById(...args),
);
setDetachedTaskLifecycleRuntime({
...defaultRuntime,
cancelDetachedTaskRunById: cancelDetachedTaskRunByIdSpy,
});
const cancelDetachedTaskRunByIdSpy = spyOnRuntimeCancel();
const cancelled = await cancelFlowById({
cfg: {} as never,