Skip to content

Commit 44501e0

Browse files
authored
Refactor batch rerun tests for RequestTimeoutError
1 parent 6b080ac commit 44501e0

1 file changed

Lines changed: 116 additions & 125 deletions

File tree

src/commands/test.rerun.spec.ts

Lines changed: 116 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -4823,142 +4823,133 @@ describe('rerun --wait — dashboardUrl on terminal output', () => {
48234823
// ---------------------------------------------------------------------------
48244824
// Batch --all --wait fan-out: RequestTimeoutError must not leave stdout empty
48254825
// ---------------------------------------------------------------------------
4826-
describe(
4827-
'[finding-5] batch rerun --wait: RequestTimeoutError during fan-out poll writes JSON stdout + exit 7',
4828-
() => {
4829-
it(
4830-
'stdout contains accepted[] with runIds when member polls throw RequestTimeoutError',
4831-
async () => {
4832-
const creds = makeCreds();
4833-
const batchResp: BatchRerunResponse = {
4834-
accepted: [
4835-
{ testId: 'test_1', runId: 'run_b1', enqueuedAt: '2026-06-03T10:00:00.000Z' },
4836-
{ testId: 'test_2', runId: 'run_b2', enqueuedAt: '2026-06-03T10:00:00.000Z' },
4837-
],
4838-
deferred: [],
4839-
conflicts: [],
4840-
closure: { byProject: [] },
4841-
};
4842-
4843-
const fetchImpl = makeFetch((url) => {
4844-
if (url.includes('/tests/batch/rerun')) {
4845-
return { status: 202, body: batchResp };
4846-
}
4847-
if (url.includes('/runs/')) {
4848-
throw new RequestTimeoutError(120000, 'req_timeout_batch_rerun');
4849-
}
4850-
return errorBody('NOT_FOUND');
4851-
});
4826+
describe('[finding-5] batch rerun --wait: RequestTimeoutError during fan-out poll writes JSON stdout + exit 7', () => {
4827+
it('stdout contains accepted[] with runIds when member polls throw RequestTimeoutError', async () => {
4828+
const creds = makeCreds();
4829+
const batchResp: BatchRerunResponse = {
4830+
accepted: [
4831+
{ testId: 'test_1', runId: 'run_b1', enqueuedAt: '2026-06-03T10:00:00.000Z' },
4832+
{ testId: 'test_2', runId: 'run_b2', enqueuedAt: '2026-06-03T10:00:00.000Z' },
4833+
],
4834+
deferred: [],
4835+
conflicts: [],
4836+
closure: { byProject: [] },
4837+
};
48524838

4853-
const stdoutLines: string[] = [];
4854-
const err = await runTestRerun(
4855-
{
4856-
testIds: ['test_1', 'test_2'],
4857-
all: false,
4858-
wait: true,
4859-
timeoutSeconds: 60,
4860-
autoHeal: false,
4861-
autoHealExplicit: false,
4862-
skipDependencies: false,
4863-
maxConcurrency: 1,
4864-
profile: 'default',
4865-
output: 'json',
4866-
debug: false,
4867-
},
4868-
{
4869-
...creds,
4870-
sleep: instantSleep,
4871-
fetchImpl: fetchImpl as unknown as FetchImpl,
4872-
stdout: (line) => stdoutLines.push(line),
4873-
stderr: () => undefined,
4874-
},
4875-
).catch((e) => e);
4839+
const fetchImpl = makeFetch(url => {
4840+
if (url.includes('/tests/batch/rerun')) {
4841+
return { status: 202, body: batchResp };
4842+
}
4843+
if (url.includes('/runs/')) {
4844+
throw new RequestTimeoutError(120000, 'req_timeout_batch_rerun');
4845+
}
4846+
return errorBody('NOT_FOUND');
4847+
});
48764848

4877-
expect(err).toMatchObject({ exitCode: 7 });
4878-
const parsed = JSON.parse(stdoutLines.join('\n')) as {
4879-
accepted: Array<{ testId: string; runId: string; status: string }>;
4880-
};
4881-
expect(parsed.accepted).toHaveLength(2);
4882-
expect(parsed.accepted.map((r) => r.runId).sort()).toEqual(['run_b1', 'run_b2']);
4883-
expect(parsed.accepted.every((r) => r.status === 'timeout')).toBe(true);
4849+
const stdoutLines: string[] = [];
4850+
const err = await runTestRerun(
4851+
{
4852+
testIds: ['test_1', 'test_2'],
4853+
all: false,
4854+
wait: true,
4855+
timeoutSeconds: 60,
4856+
autoHeal: false,
4857+
autoHealExplicit: false,
4858+
skipDependencies: false,
4859+
maxConcurrency: 1,
4860+
profile: 'default',
4861+
output: 'json',
4862+
debug: false,
48844863
},
4885-
);
4886-
},
4887-
);
4864+
{
4865+
...creds,
4866+
sleep: instantSleep,
4867+
fetchImpl: fetchImpl as unknown as FetchImpl,
4868+
stdout: (line) => stdoutLines.push(line),
4869+
stderr: () => undefined,
4870+
},
4871+
).catch(e => e);
4872+
4873+
expect(err).toMatchObject({ exitCode: 7 });
4874+
const parsed = JSON.parse(stdoutLines.join('\n')) as {
4875+
accepted: Array<{ testId: string; runId: string; status: string }>;
4876+
};
4877+
expect(parsed.accepted).toHaveLength(2);
4878+
expect(parsed.accepted.map(r => r.runId).sort()).toEqual(['run_b1', 'run_b2']);
4879+
expect(parsed.accepted.every(r => r.status === 'timeout')).toBe(true);
4880+
});
4881+
});
48884882

48894883
// ---------------------------------------------------------------------------
48904884
// TimeoutError on single FE rerun --wait: partial stdout + exit 7
48914885
// ---------------------------------------------------------------------------
48924886
describe('[finding-4] single FE rerun --wait: TimeoutError writes partial JSON to stdout', () => {
4893-
it(
4894-
'exit 7 AND stdout contains {runId, status:"running"} when --timeout polling deadline is exceeded',
4895-
async () => {
4896-
const creds = makeCreds();
4897-
const rerunResp = makeFeRerunResp();
4898-
4899-
let fetchCallCount = 0;
4900-
const fetchImpl: typeof globalThis.fetch = async (input, _init) => {
4901-
const url =
4902-
typeof input === 'string'
4903-
? input
4904-
: input instanceof URL
4887+
it('exit 7 AND stdout contains {runId, status:"running"} when --timeout polling deadline is exceeded', async () => {
4888+
const creds = makeCreds();
4889+
const rerunResp = makeFeRerunResp();
4890+
4891+
let fetchCallCount = 0;
4892+
const fetchImpl: typeof globalThis.fetch = async (input, _init) => {
4893+
const url =
4894+
typeof input === 'string'
4895+
? input
4896+
: input instanceof URL
49054897
? input.toString()
49064898
: (input as { url: string }).url;
4907-
fetchCallCount++;
4908-
if (url.includes('/tests/test_fe_01/runs/rerun')) {
4909-
return new Response(JSON.stringify(rerunResp), {
4910-
status: 202,
4911-
headers: { 'content-type': 'application/json' },
4912-
});
4913-
}
4914-
if (url.includes('/runs/')) {
4915-
const runningRun: RunResponse = {
4916-
...makeTerminalRun(rerunResp.runId, 'passed'),
4917-
status: 'running',
4918-
finishedAt: null,
4919-
};
4920-
return new Response(JSON.stringify(runningRun), {
4921-
status: 200,
4922-
headers: { 'content-type': 'application/json' },
4923-
});
4924-
}
4925-
return new Response(JSON.stringify({ error: { code: 'NOT_FOUND' } }), { status: 404 });
4926-
};
4899+
fetchCallCount++;
4900+
if (url.includes('/tests/test_fe_01/runs/rerun')) {
4901+
return new Response(JSON.stringify(rerunResp), {
4902+
status: 202,
4903+
headers: { 'content-type': 'application/json' },
4904+
});
4905+
}
4906+
if (url.includes('/runs/')) {
4907+
const runningRun: RunResponse = {
4908+
...makeTerminalRun(rerunResp.runId, 'passed'),
4909+
status: 'running',
4910+
finishedAt: null,
4911+
};
4912+
return new Response(JSON.stringify(runningRun), {
4913+
status: 200,
4914+
headers: { 'content-type': 'application/json' },
4915+
});
4916+
}
4917+
return new Response(JSON.stringify({ error: { code: 'NOT_FOUND' } }), { status: 404 });
4918+
};
49274919

4928-
const stdoutLines: string[] = [];
4920+
const stdoutLines: string[] = [];
49294921

4930-
const err = await runTestRerun(
4931-
{
4932-
testIds: ['test_fe_01'],
4933-
all: false,
4934-
wait: true,
4935-
timeoutSeconds: 0,
4936-
autoHeal: false,
4937-
autoHealExplicit: false,
4938-
skipDependencies: false,
4939-
maxConcurrency: 10,
4940-
output: 'json',
4941-
profile: 'default',
4942-
dryRun: false,
4943-
debug: false,
4944-
verbose: false,
4945-
},
4946-
{
4947-
...creds,
4948-
sleep: instantSleep,
4949-
fetchImpl: fetchImpl as unknown as FetchImpl,
4950-
stdout: (line) => stdoutLines.push(line),
4951-
stderr: () => undefined,
4952-
},
4953-
).catch((e) => e);
4922+
const err = await runTestRerun(
4923+
{
4924+
testIds: ['test_fe_01'],
4925+
all: false,
4926+
wait: true,
4927+
timeoutSeconds: 0,
4928+
autoHeal: false,
4929+
autoHealExplicit: false,
4930+
skipDependencies: false,
4931+
maxConcurrency: 10,
4932+
output: 'json',
4933+
profile: 'default',
4934+
dryRun: false,
4935+
debug: false,
4936+
verbose: false,
4937+
},
4938+
{
4939+
...creds,
4940+
sleep: instantSleep,
4941+
fetchImpl: fetchImpl as unknown as FetchImpl,
4942+
stdout: line => stdoutLines.push(line),
4943+
stderr: () => undefined,
4944+
},
4945+
).catch(e => e);
49544946

4955-
expect(err).toMatchObject({ exitCode: 7 });
4956-
expect(stdoutLines.length).toBeGreaterThan(0);
4957-
const parsed = JSON.parse(stdoutLines.join('\n')) as { runId: string; status: string };
4958-
expect(parsed.runId).toBe(rerunResp.runId);
4959-
expect(parsed.status).toBe('running');
4947+
expect(err).toMatchObject({ exitCode: 7 });
4948+
expect(stdoutLines.length).toBeGreaterThan(0);
4949+
const parsed = JSON.parse(stdoutLines.join('\n')) as { runId: string; status: string };
4950+
expect(parsed.runId).toBe(rerunResp.runId);
4951+
expect(parsed.status).toBe('running');
49604952

4961-
void fetchCallCount;
4962-
},
4963-
);
4964-
});
4953+
void fetchCallCount;
4954+
});
4955+
});

0 commit comments

Comments
 (0)