@squiz/job-runner-lib 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/domains/job/constants/QueueBacklog.constants.d.ts +11 -0
- package/lib/domains/job/constants/RetryConfig.constants.d.ts +6 -1
- package/lib/domains/job/constants/RuntimeImage.constants.d.ts +5 -0
- package/lib/domains/job/errors/RuntimeImageTaskDefinitionError.d.ts +7 -0
- package/lib/domains/job/errors/index.d.ts +1 -0
- package/lib/domains/job/index.d.ts +1 -0
- package/lib/domains/job/manifest/JobManifestTypes.d.ts +13 -1
- package/lib/domains/job/model/Job/Job.d.ts +12 -0
- package/lib/domains/job/repository/JobExecutionRepository/JobExecutionRepository.d.ts +15 -0
- package/lib/domains/job/repository/JobManifestRepository/JobManifestRepository.d.ts +1 -1
- package/lib/domains/job/repository/JobRepository/JobRepository.d.ts +2 -2
- package/lib/domains/job/services/JobExecutionTaskService/JobExecutionTaskService.d.ts +1 -0
- package/lib/domains/job/services/JobExecutionTaskService/JobExecutionTaskService.defs.d.ts +1 -0
- package/lib/domains/job/utils/ResolveRuntimeImageTaskDefinitionArn/ResolveRuntimeImageTaskDefinitionArn.d.ts +6 -0
- package/lib/domains/job/utils/ResolveRuntimeImageTaskDefinitionArn/ResolveRuntimeImageTaskDefinitionArn.types.d.ts +9 -0
- package/lib/domains/job/utils/index.d.ts +2 -0
- package/lib/domains/manifest/index.d.ts +3 -2
- package/lib/domains/manifest/utils/defaultAutoRetry.d.ts +5 -0
- package/lib/domains/manifest/utils/defaultAutoRetry.spec.d.ts +5 -0
- package/lib/index.js +9 -9
- package/lib/index.js.map +4 -4
- package/package.json +2 -2
- package/src/domains/job/constants/QueueBacklog.constants.ts +12 -0
- package/src/domains/job/constants/RetryConfig.constants.ts +8 -2
- package/src/domains/job/constants/RuntimeImage.constants.ts +8 -2
- package/src/domains/job/errors/RuntimeImageTaskDefinitionError.ts +10 -0
- package/src/domains/job/errors/index.ts +1 -0
- package/src/domains/job/index.ts +1 -0
- package/src/domains/job/manifest/JobManifestTypes.ts +16 -1
- package/src/domains/job/manifest/mocks/JobManifest.mock.ts +1 -0
- package/src/domains/job/manifest/mocks/JobManifestDto.mock.ts +3 -0
- package/src/domains/job/manifest/mocks/JobManifestRecord.mock.ts +1 -0
- package/src/domains/job/manifest/mocks/JobManifestRequest.mock.ts +1 -0
- package/src/domains/job/model/Job/Job.ts +14 -0
- package/src/domains/job/model/Job/mocks/Job.mock.ts +2 -0
- package/src/domains/job/model/Job/mocks/JobDto.mock.ts +4 -0
- package/src/domains/job/model/Job/mocks/JobRecord.mock.ts +2 -0
- package/src/domains/job/model/Job/mocks/JobRequest.mock.ts +2 -0
- package/src/domains/job/repository/JobExecutionRepository/JobExecutionRepository.spec.ts +65 -0
- package/src/domains/job/repository/JobExecutionRepository/JobExecutionRepository.ts +53 -0
- package/src/domains/job/repository/JobManifestRepository/JobManifestRepository.spec.ts +56 -4
- package/src/domains/job/repository/JobManifestRepository/JobManifestRepository.ts +14 -4
- package/src/domains/job/repository/JobRepository/JobRepository.spec.ts +36 -4
- package/src/domains/job/repository/JobRepository/JobRepository.ts +10 -5
- package/src/domains/job/services/JobExecutionTaskService/JobExecutionTaskService.defs.ts +1 -0
- package/src/domains/job/services/JobExecutionTaskService/JobExecutionTaskService.spec.ts +53 -3
- package/src/domains/job/services/JobExecutionTaskService/JobExecutionTaskService.ts +19 -8
- package/src/domains/job/services/JobManifestService/JobManifestService.spec.ts +9 -8
- package/src/domains/job/utils/ResolveRuntimeImageTaskDefinitionArn/ResolveRuntimeImageTaskDefinitionArn.ts +39 -0
- package/src/domains/job/utils/ResolveRuntimeImageTaskDefinitionArn/ResolveRuntimeImageTaskDefinitionArn.types.ts +10 -0
- package/src/domains/job/utils/index.ts +2 -0
- package/src/domains/manifest/index.ts +3 -2
- package/src/domains/manifest/utils/defaultAutoRetry.spec.ts +16 -0
- package/src/domains/manifest/utils/defaultAutoRetry.ts +6 -0
- package/src/domains/manifest/utils/validateRuntimeImage.spec.ts +11 -12
|
@@ -11,18 +11,19 @@ import {
|
|
|
11
11
|
QueryCommandOutput,
|
|
12
12
|
} from '@aws-sdk/client-dynamodb';
|
|
13
13
|
import { inject } from 'inversify';
|
|
14
|
-
import {
|
|
15
|
-
import { Repository } from '../AbstractRepository';
|
|
14
|
+
import { InjectTokens } from '../../constants/InjectTokens';
|
|
16
15
|
import { ENTITY_TYPES } from '../../constants/Repository.constants';
|
|
17
|
-
import {
|
|
18
|
-
import { CreateJobRequest, Job, JobDto, JobSk, ListJobParameters } from '../../model/Job';
|
|
16
|
+
import { getRuntimeImageOrDefault } from '../../constants/RuntimeImage.constants';
|
|
19
17
|
import {
|
|
20
18
|
decodeTokenString,
|
|
21
19
|
PAGINATION_DIRECTION_TYPE_BEFORE,
|
|
22
20
|
PaginationInfo,
|
|
23
21
|
PaginationQueryResponse,
|
|
24
22
|
} from '../../core/pagination';
|
|
25
|
-
import {
|
|
23
|
+
import { CreateJobRequest, Job, JobDto, JobSk, ListJobParameters } from '../../model/Job';
|
|
24
|
+
import { parsePartitionKey } from '../../ParsePartitionKey';
|
|
25
|
+
import { provideTransient } from '../../transientProvider';
|
|
26
|
+
import { Repository } from '../AbstractRepository';
|
|
26
27
|
|
|
27
28
|
@provideTransient(JobRepository)
|
|
28
29
|
export class JobRepository extends Repository<Job, JobDto, JobSk> {
|
|
@@ -37,6 +38,7 @@ export class JobRepository extends Repository<Job, JobDto, JobSk> {
|
|
|
37
38
|
public async create(input: CreateJobRequest): Promise<Job> {
|
|
38
39
|
const newJob: Job = {
|
|
39
40
|
...input,
|
|
41
|
+
image: getRuntimeImageOrDefault(input.image),
|
|
40
42
|
type: ENTITY_TYPES.job,
|
|
41
43
|
};
|
|
42
44
|
|
|
@@ -157,11 +159,13 @@ export class JobRepository extends Repository<Job, JobDto, JobSk> {
|
|
|
157
159
|
name: { S: item.name },
|
|
158
160
|
description: item.description ? { S: item.description } : { NULL: true },
|
|
159
161
|
version: { S: item.version },
|
|
162
|
+
image: { S: item.image },
|
|
160
163
|
};
|
|
161
164
|
}
|
|
162
165
|
|
|
163
166
|
convertToItem(dbItem: JobDto): Job {
|
|
164
167
|
const { pk, name, version } = dbItem;
|
|
168
|
+
const image = (dbItem as Partial<JobDto>).image?.S;
|
|
165
169
|
let description;
|
|
166
170
|
// TODO https://jira.squiz.net/browse/CONN-609 remove this check if we tidy up
|
|
167
171
|
// jobs added before this field was implemented
|
|
@@ -175,6 +179,7 @@ export class JobRepository extends Repository<Job, JobDto, JobSk> {
|
|
|
175
179
|
description: description.S ? (description.S as string) : '',
|
|
176
180
|
type: parsePartitionKey(pk.S as string).entityType,
|
|
177
181
|
version: version.S as string,
|
|
182
|
+
image: getRuntimeImageOrDefault(image),
|
|
178
183
|
};
|
|
179
184
|
}
|
|
180
185
|
|
|
@@ -4,6 +4,7 @@ import { AwsClientStub, mockClient } from 'aws-sdk-client-mock';
|
|
|
4
4
|
import 'aws-sdk-client-mock-jest';
|
|
5
5
|
import { JobDetailsRepository, JobUploadsRepository } from '../../S3Repository';
|
|
6
6
|
import { JOB_EXECUTION_STATUS } from '../../constants/JobExecutionStatus.constants';
|
|
7
|
+
import { RuntimeImageTaskDefinitionError } from '../../errors';
|
|
7
8
|
import { createMockJobManifest } from '../../manifest';
|
|
8
9
|
import { createMockJobContext } from '../../model/JobContext';
|
|
9
10
|
import { createMockJobExecution } from '../../model/JobExecution';
|
|
@@ -30,7 +31,11 @@ describe('JobExecutionTaskService', () => {
|
|
|
30
31
|
shortRegion: 'au',
|
|
31
32
|
shortEnvironment: 'dev',
|
|
32
33
|
clusterArn: `clusterArn`,
|
|
33
|
-
taskDefinitionArn: `
|
|
34
|
+
taskDefinitionArn: `legacyTaskDefinitionArn`,
|
|
35
|
+
taskDefinitionArnsByRuntimeImage: {
|
|
36
|
+
'node:20': 'node20TaskDefinitionArn',
|
|
37
|
+
'node:24': 'node24TaskDefinitionArn',
|
|
38
|
+
},
|
|
34
39
|
tenantId: 'some_tenant',
|
|
35
40
|
};
|
|
36
41
|
|
|
@@ -104,7 +109,7 @@ describe('JobExecutionTaskService', () => {
|
|
|
104
109
|
const mockArn = `mock-arn`;
|
|
105
110
|
const mockTask = { taskArn: mockArn };
|
|
106
111
|
const jobContext = createMockJobContext();
|
|
107
|
-
const jobManifest = createMockJobManifest();
|
|
112
|
+
const jobManifest = createMockJobManifest({ image: 'node:24' });
|
|
108
113
|
const jobExecution = createMockJobExecution({
|
|
109
114
|
id: `20250917T005949395Z-9602417782`,
|
|
110
115
|
jobName: 'jobName',
|
|
@@ -173,7 +178,7 @@ describe('JobExecutionTaskService', () => {
|
|
|
173
178
|
{ key: 'map-migrated', value: 'migUJ1IX3DUXG' },
|
|
174
179
|
{ key: 'cmp:tenant', value: 'some_tenant' },
|
|
175
180
|
],
|
|
176
|
-
taskDefinition: defaultRunJobTaskParams.
|
|
181
|
+
taskDefinition: defaultRunJobTaskParams.taskDefinitionArnsByRuntimeImage['node:24'],
|
|
177
182
|
// sha1 of execution job name/id + tenant + retryCount.
|
|
178
183
|
clientToken: '4725755e08138edde031a177c36a269ecdbed5a3',
|
|
179
184
|
});
|
|
@@ -207,6 +212,51 @@ describe('JobExecutionTaskService', () => {
|
|
|
207
212
|
null,
|
|
208
213
|
defaultRunJobTaskParams.jobExecution,
|
|
209
214
|
);
|
|
215
|
+
expect(mockEcsClient).toHaveReceivedCommandWith(RunTaskCommand, {
|
|
216
|
+
taskDefinition: defaultRunJobTaskParams.taskDefinitionArnsByRuntimeImage['node:20'],
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should use the legacy task definition ARN when the node:20 map entry is missing', async () => {
|
|
221
|
+
const mockArn = `mock-arn`;
|
|
222
|
+
|
|
223
|
+
mockEcsClient.on(RunTaskCommand).resolves({ tasks: [{ taskArn: mockArn }] });
|
|
224
|
+
mockJobContextService.findJobContext.mockResolvedValue(createMockJobContext());
|
|
225
|
+
mockJobManifestService.findJobManifest.mockResolvedValue(createMockJobManifest({ image: 'node:20' }));
|
|
226
|
+
|
|
227
|
+
await jobExecutionTaskService.runJobExecutionTask({
|
|
228
|
+
...defaultRunJobTaskParams,
|
|
229
|
+
taskDefinitionArnsByRuntimeImage: {},
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
expect(mockEcsClient).toHaveReceivedCommandWith(RunTaskCommand, {
|
|
233
|
+
taskDefinition: defaultRunJobTaskParams.taskDefinitionArn,
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should throw before creating an ECS task when the runtime image is unsupported', async () => {
|
|
238
|
+
mockJobManifestService.findJobManifest.mockResolvedValue(createMockJobManifest({ image: 'node:26' }));
|
|
239
|
+
|
|
240
|
+
await expect(jobExecutionTaskService.runJobExecutionTask(defaultRunJobTaskParams)).rejects.toThrow(
|
|
241
|
+
RuntimeImageTaskDefinitionError,
|
|
242
|
+
);
|
|
243
|
+
expect(mockEcsClient).not.toHaveReceivedCommand(RunTaskCommand);
|
|
244
|
+
expect(mockJobDetailsRepository.createJobDetailsFile).not.toHaveBeenCalled();
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should throw before creating an ECS task when the runtime image has no task definition ARN', async () => {
|
|
248
|
+
mockJobManifestService.findJobManifest.mockResolvedValue(createMockJobManifest({ image: 'node:24' }));
|
|
249
|
+
|
|
250
|
+
await expect(
|
|
251
|
+
jobExecutionTaskService.runJobExecutionTask({
|
|
252
|
+
...defaultRunJobTaskParams,
|
|
253
|
+
taskDefinitionArnsByRuntimeImage: {
|
|
254
|
+
'node:20': 'node20TaskDefinitionArn',
|
|
255
|
+
},
|
|
256
|
+
}),
|
|
257
|
+
).rejects.toThrow(RuntimeImageTaskDefinitionError);
|
|
258
|
+
expect(mockEcsClient).not.toHaveReceivedCommand(RunTaskCommand);
|
|
259
|
+
expect(mockJobDetailsRepository.createJobDetailsFile).not.toHaveBeenCalled();
|
|
210
260
|
});
|
|
211
261
|
|
|
212
262
|
it('should handle ConflictException with a previously started task arn', async () => {
|
|
@@ -7,9 +7,10 @@ import { ConflictException, ECSClient, RunTaskCommand } from '@aws-sdk/client-ec
|
|
|
7
7
|
import { createHash } from 'node:crypto';
|
|
8
8
|
import { JobDetailsRepository, JobUploadsRepository } from '../../S3Repository';
|
|
9
9
|
import { JOB_EXECUTION_STATUS } from '../../constants/JobExecutionStatus.constants';
|
|
10
|
+
import { JobManifest } from '../../manifest';
|
|
10
11
|
import { JobExecution } from '../../model/JobExecution';
|
|
11
12
|
import { JobExecutionRepository } from '../../repository';
|
|
12
|
-
import { getAwsTags } from '../../utils';
|
|
13
|
+
import { getAwsTags, resolveRuntimeImageTaskDefinitionArn } from '../../utils';
|
|
13
14
|
import { JobContextService } from '../JobContextService/JobContextService';
|
|
14
15
|
import { JobManifestService } from '../JobManifestService/JobManifestService';
|
|
15
16
|
import { HasReachedMaxTenantConcurrencyParams, RunJobTaskParams } from './JobExecutionTaskService.defs';
|
|
@@ -56,7 +57,13 @@ export class JobExecutionTaskService {
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
public async runJobExecutionTask(params: RunJobTaskParams): Promise<string | undefined> {
|
|
59
|
-
const
|
|
60
|
+
const jobManifest = await this.findJobManifest(params.jobExecution);
|
|
61
|
+
const taskDefinitionArn = resolveRuntimeImageTaskDefinitionArn({
|
|
62
|
+
image: jobManifest?.image,
|
|
63
|
+
taskDefinitionArnsByRuntimeImage: params.taskDefinitionArnsByRuntimeImage,
|
|
64
|
+
legacyTaskDefinitionArn: params.taskDefinitionArn,
|
|
65
|
+
});
|
|
66
|
+
const jobDetailsFileUrl = await this.createJobDetailsFile(params.tenantId, params.jobExecution, jobManifest);
|
|
60
67
|
const tags = getAwsTags({
|
|
61
68
|
tenant: params.tenantId,
|
|
62
69
|
region: params.awsRegion,
|
|
@@ -104,7 +111,7 @@ export class JobExecutionTaskService {
|
|
|
104
111
|
const result = await this.ecsClient.send(
|
|
105
112
|
new RunTaskCommand({
|
|
106
113
|
cluster: params.clusterArn,
|
|
107
|
-
taskDefinition:
|
|
114
|
+
taskDefinition: taskDefinitionArn,
|
|
108
115
|
overrides: {
|
|
109
116
|
containerOverrides: [
|
|
110
117
|
{
|
|
@@ -183,11 +190,11 @@ export class JobExecutionTaskService {
|
|
|
183
190
|
return createHash('sha1').update(key).digest('hex');
|
|
184
191
|
}
|
|
185
192
|
|
|
186
|
-
private async createJobDetailsFile(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
193
|
+
private async createJobDetailsFile(
|
|
194
|
+
tenantId: string,
|
|
195
|
+
executionToStart: JobExecution,
|
|
196
|
+
jobManifest: JobManifest | null,
|
|
197
|
+
): Promise<string> {
|
|
191
198
|
const jobContext = await this.jobContextService.findJobContext(executionToStart.context);
|
|
192
199
|
|
|
193
200
|
const jobDetailsFileName = await this.jobDetailsRepository.createJobDetailsFile(
|
|
@@ -198,4 +205,8 @@ export class JobExecutionTaskService {
|
|
|
198
205
|
);
|
|
199
206
|
return await this.jobDetailsRepository.getS3SignedUrl(jobDetailsFileName);
|
|
200
207
|
}
|
|
208
|
+
|
|
209
|
+
private async findJobManifest(executionToStart: JobExecution): Promise<JobManifest | null> {
|
|
210
|
+
return await this.jobManifestService.findJobManifest(executionToStart.jobName, executionToStart.version);
|
|
211
|
+
}
|
|
201
212
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @license
|
|
3
3
|
* Copyright Squiz Australia Pty Ltd. All Rights Reserved.
|
|
4
4
|
*/
|
|
5
|
-
import { initIocContainer, iocContainer } from '../../../../mocks/mockIoc';
|
|
6
5
|
import {
|
|
7
6
|
DynamoDBClient,
|
|
8
7
|
DynamoDBClientConfig,
|
|
@@ -10,7 +9,13 @@ import {
|
|
|
10
9
|
PutItemCommandOutput,
|
|
11
10
|
ScanCommandOutput,
|
|
12
11
|
} from '@aws-sdk/client-dynamodb';
|
|
13
|
-
import {
|
|
12
|
+
import { initIocContainer, iocContainer } from '../../../../mocks/mockIoc';
|
|
13
|
+
import { ENTITY_TYPES } from '../../constants/Repository.constants';
|
|
14
|
+
import {
|
|
15
|
+
createMockClientGetResponse,
|
|
16
|
+
createMockClientPutResponse,
|
|
17
|
+
createMockClientScanResponse,
|
|
18
|
+
} from '../../core/dynamoClient.mock';
|
|
14
19
|
import {
|
|
15
20
|
createMockCreateJobManifestRequest,
|
|
16
21
|
createMockJobManifest,
|
|
@@ -19,12 +24,7 @@ import {
|
|
|
19
24
|
createMockJobManifestRecord,
|
|
20
25
|
JobManifest,
|
|
21
26
|
} from '../../manifest';
|
|
22
|
-
import {
|
|
23
|
-
createMockClientGetResponse,
|
|
24
|
-
createMockClientPutResponse,
|
|
25
|
-
createMockClientScanResponse,
|
|
26
|
-
} from '../../core/dynamoClient.mock';
|
|
27
|
-
import { ENTITY_TYPES } from '../../constants/Repository.constants';
|
|
27
|
+
import { JobManifestService } from './JobManifestService';
|
|
28
28
|
|
|
29
29
|
initIocContainer();
|
|
30
30
|
|
|
@@ -88,6 +88,7 @@ describe('JobManifestService', (): void => {
|
|
|
88
88
|
version: mockJobManifestItem.version.S as string,
|
|
89
89
|
timeoutSeconds: parseInt(mockJobManifestItem.timeoutSeconds.N as string),
|
|
90
90
|
image: mockJobManifestItem.image.S as string,
|
|
91
|
+
autoRetry: false,
|
|
91
92
|
type: `manifest`,
|
|
92
93
|
} as JobManifest);
|
|
93
94
|
expect(mockSend).toBeCalledTimes(1);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Squiz Australia Pty Ltd. All Rights Reserved.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
LEGACY_RUNTIME_IMAGE,
|
|
8
|
+
SUPPORTED_RUNTIME_IMAGES,
|
|
9
|
+
getRuntimeImageOrDefault,
|
|
10
|
+
isSupportedRuntimeImage,
|
|
11
|
+
} from '../../constants/RuntimeImage.constants';
|
|
12
|
+
import { RuntimeImageTaskDefinitionError } from '../../errors';
|
|
13
|
+
import { ResolveRuntimeImageTaskDefinitionArnParams } from './ResolveRuntimeImageTaskDefinitionArn.types';
|
|
14
|
+
|
|
15
|
+
export const resolveRuntimeImageTaskDefinitionArn = ({
|
|
16
|
+
image,
|
|
17
|
+
taskDefinitionArnsByRuntimeImage,
|
|
18
|
+
legacyTaskDefinitionArn,
|
|
19
|
+
}: ResolveRuntimeImageTaskDefinitionArnParams): string => {
|
|
20
|
+
const runtimeImage = getRuntimeImageOrDefault(image);
|
|
21
|
+
|
|
22
|
+
if (!isSupportedRuntimeImage(runtimeImage)) {
|
|
23
|
+
throw new RuntimeImageTaskDefinitionError(
|
|
24
|
+
`Unsupported runtime image "${runtimeImage}". Supported images are: ${SUPPORTED_RUNTIME_IMAGES.join(', ')}`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const taskDefinitionArn =
|
|
29
|
+
taskDefinitionArnsByRuntimeImage[runtimeImage] ||
|
|
30
|
+
(runtimeImage === LEGACY_RUNTIME_IMAGE ? legacyTaskDefinitionArn : undefined);
|
|
31
|
+
|
|
32
|
+
if (!taskDefinitionArn) {
|
|
33
|
+
throw new RuntimeImageTaskDefinitionError(
|
|
34
|
+
`No ECS task definition ARN configured for runtime image "${runtimeImage}"`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return taskDefinitionArn;
|
|
39
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Squiz Australia Pty Ltd. All Rights Reserved.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface ResolveRuntimeImageTaskDefinitionArnParams {
|
|
7
|
+
image: string | null | undefined;
|
|
8
|
+
taskDefinitionArnsByRuntimeImage: Record<string, string>;
|
|
9
|
+
legacyTaskDefinitionArn: string;
|
|
10
|
+
}
|
|
@@ -3,3 +3,5 @@ export * from './GetAwsTags/GetAwsTags.types';
|
|
|
3
3
|
export * from './SlackClient/SlackClient';
|
|
4
4
|
export * from './SlackClient/types/SlackClient.types';
|
|
5
5
|
export * from './SortByTimeQueued/SortByTimeQueued';
|
|
6
|
+
export * from './ResolveRuntimeImageTaskDefinitionArn/ResolveRuntimeImageTaskDefinitionArn';
|
|
7
|
+
export * from './ResolveRuntimeImageTaskDefinitionArn/ResolveRuntimeImageTaskDefinitionArn.types';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export * from './services/ManifestServiceForDev';
|
|
2
1
|
export * from './services/JobFunctionService';
|
|
2
|
+
export * from './services/ManifestServiceForDev';
|
|
3
3
|
|
|
4
|
+
export * from './utils/defaultAutoRetry';
|
|
4
5
|
export * from './utils/getAndAssertJobManifestVersion';
|
|
5
6
|
export * from './utils/isValidManifestVersion';
|
|
6
7
|
export * from './utils/validateRuntimeImage';
|
|
7
8
|
|
|
8
|
-
export * from './ManifestModel';
|
|
9
9
|
export * from '../job/manifest/JobManifestV1';
|
|
10
10
|
export * from './errors/ManifestValidationError';
|
|
11
|
+
export * from './ManifestModel';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Squiz Australia Pty Ltd. All Rights Reserved.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { defaultAutoRetry } from './defaultAutoRetry';
|
|
7
|
+
|
|
8
|
+
describe('defaultAutoRetry', () => {
|
|
9
|
+
it('returns true when autoRetry is true', () => {
|
|
10
|
+
expect(defaultAutoRetry(true)).toEqual(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it.each([false, null, undefined])('returns false when autoRetry is %s', (autoRetry) => {
|
|
14
|
+
expect(defaultAutoRetry(autoRetry)).toEqual(false);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
* Copyright Squiz Australia Pty Ltd. All Rights Reserved.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
DEPRECATED_RUNTIME_IMAGES,
|
|
8
|
+
RECOMMENDED_RUNTIME_IMAGE,
|
|
9
|
+
SUPPORTED_RUNTIME_IMAGES,
|
|
10
|
+
} from '../../job/constants/RuntimeImage.constants';
|
|
8
11
|
import { ManifestValidationError } from '../errors/ManifestValidationError';
|
|
9
12
|
import { validateAndDefaultRuntimeImage } from './validateRuntimeImage';
|
|
10
13
|
|
|
11
14
|
describe('validateAndDefaultRuntimeImage', () => {
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
jest.restoreAllMocks();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
15
|
it('returns the recommended runtime image when image is undefined', () => {
|
|
17
16
|
expect(validateAndDefaultRuntimeImage(undefined)).toEqual(RECOMMENDED_RUNTIME_IMAGE);
|
|
18
17
|
});
|
|
@@ -21,9 +20,12 @@ describe('validateAndDefaultRuntimeImage', () => {
|
|
|
21
20
|
expect(validateAndDefaultRuntimeImage(null)).toEqual(RECOMMENDED_RUNTIME_IMAGE);
|
|
22
21
|
});
|
|
23
22
|
|
|
24
|
-
it.each(SUPPORTED_RUNTIME_IMAGES
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
it.each(SUPPORTED_RUNTIME_IMAGES.filter((image) => !DEPRECATED_RUNTIME_IMAGES.includes(image)))(
|
|
24
|
+
'returns "%s" when it is supported and not deprecated',
|
|
25
|
+
(supportedImage) => {
|
|
26
|
+
expect(validateAndDefaultRuntimeImage(supportedImage)).toEqual(supportedImage);
|
|
27
|
+
},
|
|
28
|
+
);
|
|
27
29
|
|
|
28
30
|
it('throws ManifestValidationError when the image is not supported', () => {
|
|
29
31
|
expect(() => validateAndDefaultRuntimeImage('node:18')).toThrow(ManifestValidationError);
|
|
@@ -31,9 +33,6 @@ describe('validateAndDefaultRuntimeImage', () => {
|
|
|
31
33
|
});
|
|
32
34
|
|
|
33
35
|
it('throws ManifestValidationError when the image is deprecated', () => {
|
|
34
|
-
jest.spyOn(runtimeImageConstants, 'isSupportedRuntimeImage').mockReturnValue(true);
|
|
35
|
-
jest.spyOn(runtimeImageConstants, 'isDeprecatedRuntimeImage').mockReturnValue(true);
|
|
36
|
-
|
|
37
36
|
expect(() => validateAndDefaultRuntimeImage('node:20')).toThrow(ManifestValidationError);
|
|
38
37
|
expect(() => validateAndDefaultRuntimeImage('node:20')).toThrow(/deprecated/);
|
|
39
38
|
});
|