Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions packages/core/src/job.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,45 @@ describe('waitForJobToComplete', () => {
expect(mockGetInstance).toHaveBeenCalledTimes(1);
});

test('resolves when job health is SuccessCriteriaMet (status field absent)', async () => {
const completedJob = { name: 'myjob', health: 'SuccessCriteriaMet' };
mockGetInstance.mockResolvedValue(completedJob);
const result = await waitForJobToComplete(
ctx,
'eyevinn-ffmpeg-s3',
'myjob',
'token'
);
expect(result).toEqual(completedJob);
expect(mockGetInstance).toHaveBeenCalledTimes(1);
});

test('resolves when job health is Complete (status field absent)', async () => {
const completedJob = { name: 'myjob', health: 'Complete' };
mockGetInstance.mockResolvedValue(completedJob);
const result = await waitForJobToComplete(
ctx,
'eyevinn-ffmpeg-s3',
'myjob',
'token'
);
expect(result).toEqual(completedJob);
});

test('throws when job health is Failed (status field absent)', async () => {
mockGetInstance.mockResolvedValue({ health: 'Failed' });
await expect(
waitForJobToComplete(ctx, 'eyevinn-ffmpeg-s3', 'myjob', 'token')
).rejects.toThrow("Job 'myjob' failed with status: Failed");
});

test('throws when job health is FailureTarget (status field absent)', async () => {
mockGetInstance.mockResolvedValue({ health: 'FailureTarget' });
await expect(
waitForJobToComplete(ctx, 'eyevinn-ffmpeg-s3', 'myjob', 'token')
).rejects.toThrow("Job 'myjob' failed with status: FailureTarget");
});

test('polls until job reaches terminal status', async () => {
const completedJob = { name: 'myjob', status: 'SuccessCriteriaMet' };
mockGetInstance
Expand Down
13 changes: 8 additions & 5 deletions packages/core/src/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ export interface WaitForJobOptions {
* @throws {Error} If the job reaches a terminal failure state ('Failed' or 'FailureTarget')
* @throws {Error} If timeoutMs is set and the job does not complete within the given time
*
* Terminal success statuses: 'Complete', 'SuccessCriteriaMet'
* Terminal failure statuses: 'Failed', 'FailureTarget'
* Terminal success statuses (status or health field): 'Complete', 'SuccessCriteriaMet'
* Terminal failure statuses (status or health field): 'Failed', 'FailureTarget'
*/
export async function waitForJobToComplete(
context: Context,
Expand All @@ -162,11 +162,14 @@ export async function waitForJobToComplete(
throw new Error(`Job '${name}' timed out after ${options!.timeoutMs}ms`);
}
const job = await getJob(context, serviceId, name, token);
if (job.status === 'Complete' || job.status === 'SuccessCriteriaMet') {
const terminalSuccess = new Set(['Complete', 'SuccessCriteriaMet']);
const terminalFailure = new Set(['Failed', 'FailureTarget']);
if (terminalSuccess.has(job.status) || terminalSuccess.has(job.health)) {
return job;
}
if (job.status === 'Failed' || job.status === 'FailureTarget') {
throw new Error(`Job '${name}' failed with status: ${job.status}`);
if (terminalFailure.has(job.status) || terminalFailure.has(job.health)) {
const signal = terminalFailure.has(job.status) ? job.status : job.health;
throw new Error(`Job '${name}' failed with status: ${signal}`);
}
await delay(1000);
}
Expand Down
Loading