Skip to content

Commit 0a40071

Browse files
authored
ci(integ): pull SAM images in "install" phase to avoid timeouts #6179
## Problem - The SAM tests are flaky, and sometimes fail CI. - SAM file scenarios section includes a ton of copy-pasting. ## Solution The SAM build images can be pulled ahead of time to reduce risk of timeout. To see this working, see the integ test logs below, and notice in the logs that `Fetching public.ecr.aws/sam/build-... Docker container image...`, resolved immediately (likely cached from pre-fetching) whereas before this took 60-90 seconds sometimes. To reduce copy pasting, establish useful defaults, and generate the scenarios based on a few args to avoid copy pasting information.
1 parent 5f72ec9 commit 0a40071

File tree

2 files changed

+113
-243
lines changed

2 files changed

+113
-243
lines changed

buildspec/linuxIntegrationTests.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,27 @@ phases:
5151
# Ensure that "docker" group has permissions to the socket.
5252
# - chown codebuild-user /var/run/docker.sock
5353
- chmod 666 /var/run/docker.sock
54+
# Pull Docker Images for SAM tests
55+
56+
# Nodejs
57+
- |
58+
docker pull public.ecr.aws/sam/build-nodejs18.x:latest
59+
docker pull public.ecr.aws/sam/build-nodejs20.x:latest
60+
docker pull public.ecr.aws/sam/build-nodejs22.x:latest
61+
# Java
62+
- |
63+
docker pull public.ecr.aws/sam/build-java8.al2:latest
64+
docker pull public.ecr.aws/sam/build-java11:latest
65+
docker pull public.ecr.aws/sam/build-java17:latest
66+
# Python
67+
- |
68+
docker pull public.ecr.aws/sam/build-python3.10:latest
69+
docker pull public.ecr.aws/sam/build-python3.11:latest
70+
docker pull public.ecr.aws/sam/build-python3.12:latest
71+
docker pull public.ecr.aws/sam/build-python3.13:latest
72+
# Dotnet
73+
- |
74+
docker pull public.ecr.aws/sam/build-dotnet6:latest
5475
5576
pre_build:
5677
commands:

packages/core/src/testInteg/sam.test.ts

Lines changed: 92 additions & 243 deletions
Original file line numberDiff line numberDiff line change
@@ -46,262 +46,111 @@ const noDebugSessionInterval: number = 100
4646
/** Go can't handle API tests yet */
4747
const skipLanguagesOnApi = ['go']
4848

49-
interface TestScenario {
50-
displayName: string
51-
runtime: Runtime
52-
baseImage?: string
49+
interface TestScenarioDefaults {
5350
path: string
5451
debugSessionType: string
5552
language: Language
5653
dependencyManager: DependencyManager
5754
/** Minimum vscode version required by the relevant third-party extension. */
5855
vscodeMinimum: string
5956
}
57+
type TestScenario = {
58+
displayName: string
59+
runtime: Runtime
60+
baseImage?: string
61+
} & TestScenarioDefaults
62+
63+
const nodeDefaults = {
64+
path: 'hello-world/app.mjs',
65+
debugSessionType: 'pwa-node',
66+
dependencyManager: 'npm' as DependencyManager,
67+
language: 'javascript' as Language,
68+
vscodeMinimum: '1.50.0',
69+
}
70+
// https://github.com/microsoft/vscode-python/blob/main/package.json
71+
const pythonDefaults = {
72+
path: 'hello_world/app.py',
73+
debugSessionType: 'python',
74+
dependencyManager: 'pip' as DependencyManager,
75+
language: 'python' as Language,
76+
vscodeMinimum: '1.77.0',
77+
}
78+
79+
const javaDefaults = {
80+
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
81+
debugSessionType: 'java',
82+
dependencyManager: 'gradle' as DependencyManager,
83+
language: 'java' as Language,
84+
vscodeMinimum: '1.50.0',
85+
}
6086

87+
const dotnetDefaults = {
88+
path: 'src/HelloWorld/Function.cs',
89+
debugSessionType: 'coreclr',
90+
language: 'csharp' as Language,
91+
dependencyManager: 'cli-package' as DependencyManager,
92+
vscodeMinimum: '1.80.0',
93+
}
94+
95+
const defaults: Record<Runtime, TestScenarioDefaults> = {
96+
nodejs: nodeDefaults,
97+
java: javaDefaults,
98+
python: pythonDefaults,
99+
dotnet: dotnetDefaults,
100+
}
101+
102+
function generateScenario(
103+
runtime: Runtime,
104+
version: string,
105+
options: Partial<TestScenario & { sourceTag: string }> = {},
106+
fromImage: boolean = false
107+
): TestScenario {
108+
if (fromImage && !options.baseImage) {
109+
throw new Error('baseImage property must be specified when testing from image')
110+
}
111+
const { sourceTag, ...defaultOverride } = options
112+
const source = `(${options.sourceTag ? `${options.sourceTag} ` : ''}${fromImage ? 'Image' : 'ZIP'})`
113+
const fullName = `${runtime}${version}`
114+
return {
115+
runtime: fullName,
116+
displayName: `${fullName} ${source}`,
117+
...defaults[runtime],
118+
...defaultOverride,
119+
}
120+
}
61121
// When testing additional runtimes, consider pulling the docker container in buildspec\linuxIntegrationTests.yml
62122
// to reduce the chance of automated tests timing out.
123+
63124
const scenarios: TestScenario[] = [
64125
// zips
65-
{
66-
runtime: 'nodejs18.x',
67-
displayName: 'nodejs18.x (ZIP)',
68-
path: 'hello-world/app.mjs',
69-
debugSessionType: 'pwa-node',
70-
language: 'javascript',
71-
dependencyManager: 'npm',
72-
vscodeMinimum: '1.50.0',
73-
},
74-
{
75-
runtime: 'nodejs20.x',
76-
displayName: 'nodejs20.x (ZIP)',
77-
path: 'hello-world/app.mjs',
78-
debugSessionType: 'pwa-node',
79-
language: 'javascript',
80-
dependencyManager: 'npm',
81-
vscodeMinimum: '1.50.0',
82-
},
83-
{
84-
runtime: 'nodejs22.x',
85-
displayName: 'nodejs22.x (ZIP)',
86-
path: 'hello-world/app.mjs',
87-
debugSessionType: 'pwa-node',
88-
language: 'javascript',
89-
dependencyManager: 'npm',
90-
vscodeMinimum: '1.78.0',
91-
},
92-
{
93-
runtime: 'python3.10',
94-
displayName: 'python 3.10 (ZIP)',
95-
path: 'hello_world/app.py',
96-
debugSessionType: 'python',
97-
language: 'python',
98-
dependencyManager: 'pip',
99-
// https://github.com/microsoft/vscode-python/blob/main/package.json
100-
vscodeMinimum: '1.77.0',
101-
},
102-
{
103-
runtime: 'python3.11',
104-
displayName: 'python 3.11 (ZIP)',
105-
path: 'hello_world/app.py',
106-
debugSessionType: 'python',
107-
language: 'python',
108-
dependencyManager: 'pip',
109-
// https://github.com/microsoft/vscode-python/blob/main/package.json
110-
vscodeMinimum: '1.78.0',
111-
},
112-
{
113-
runtime: 'python3.12',
114-
displayName: 'python 3.12 (ZIP)',
115-
path: 'hello_world/app.py',
116-
debugSessionType: 'python',
117-
language: 'python',
118-
dependencyManager: 'pip',
119-
// https://github.com/microsoft/vscode-python/blob/main/package.json
120-
vscodeMinimum: '1.78.0',
121-
},
122-
{
123-
runtime: 'python3.13',
124-
displayName: 'python 3.13 (ZIP)',
125-
path: 'hello_world/app.py',
126-
debugSessionType: 'python',
127-
language: 'python',
128-
dependencyManager: 'pip',
129-
// https://github.com/microsoft/vscode-python/blob/main/package.json
130-
vscodeMinimum: '1.78.0',
131-
},
132-
{
133-
runtime: 'dotnet6',
134-
displayName: 'dotnet6 (ZIP)',
135-
path: 'src/HelloWorld/Function.cs',
136-
debugSessionType: 'coreclr',
137-
language: 'csharp',
138-
dependencyManager: 'cli-package',
139-
vscodeMinimum: '1.80.0',
140-
},
141-
{
142-
runtime: 'java8.al2',
143-
displayName: 'java8.al2 (Maven ZIP)',
144-
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
145-
debugSessionType: 'java',
146-
language: 'java',
147-
dependencyManager: 'maven',
148-
vscodeMinimum: '1.50.0',
149-
},
150-
{
151-
runtime: 'java11',
152-
displayName: 'java11 (Gradle ZIP)',
153-
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
154-
debugSessionType: 'java',
155-
language: 'java',
156-
dependencyManager: 'gradle',
157-
vscodeMinimum: '1.50.0',
158-
},
159-
{
160-
runtime: 'java17',
161-
displayName: 'java11 (Gradle ZIP)',
162-
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
163-
debugSessionType: 'java',
164-
language: 'java',
165-
dependencyManager: 'gradle',
166-
vscodeMinimum: '1.50.0',
167-
},
168-
// {
169-
// runtime: 'go1.x',
170-
// displayName: 'go1.x (ZIP)',
171-
// path: 'hello-world/main.go',
172-
// debugSessionType: 'delve',
173-
// language: 'go',
174-
// dependencyManager: 'mod',
175-
// // https://github.com/golang/vscode-go/blob/master/package.json
176-
// vscodeMinimum: '1.67.0',
177-
// },
178-
126+
generateScenario('nodejs', '18.x'),
127+
generateScenario('nodejs', '20.x'),
128+
generateScenario('nodejs', '22.x', { vscodeMinimum: '1.78.0' }),
129+
generateScenario('python', '3.10'),
130+
generateScenario('python', '3.11', { vscodeMinimum: '1.78.0' }),
131+
generateScenario('python', '3.12', { vscodeMinimum: '1.78.0' }),
132+
generateScenario('python', '3.13', { vscodeMinimum: '1.78.0' }),
133+
generateScenario('dotnet', '6'),
134+
generateScenario('java', '8.al2', { sourceTag: 'Maven', dependencyManager: 'maven' }),
135+
generateScenario('java', '11', { sourceTag: 'Gradle' }),
136+
generateScenario('java', '17', { sourceTag: 'Gradle' }),
179137
// images
180-
{
181-
runtime: 'nodejs18.x',
182-
displayName: 'nodejs18.x (Image)',
183-
baseImage: 'amazon/nodejs18.x-base',
184-
path: 'hello-world/app.mjs',
185-
debugSessionType: 'pwa-node',
186-
language: 'javascript',
187-
dependencyManager: 'npm',
188-
vscodeMinimum: '1.50.0',
189-
},
190-
{
191-
runtime: 'nodejs20.x',
192-
displayName: 'nodejs20.x (Image)',
193-
baseImage: 'amazon/nodejs20.x-base',
194-
path: 'hello-world/app.mjs',
195-
debugSessionType: 'pwa-node',
196-
language: 'javascript',
197-
dependencyManager: 'npm',
198-
vscodeMinimum: '1.50.0',
199-
},
200-
{
201-
runtime: 'nodejs22.x',
202-
displayName: 'nodejs22.x (Image)',
203-
baseImage: 'amazon/nodejs22.x-base',
204-
path: 'hello-world/app.mjs',
205-
debugSessionType: 'pwa-node',
206-
language: 'javascript',
207-
dependencyManager: 'npm',
208-
vscodeMinimum: '1.78.0',
209-
},
210-
{
211-
runtime: 'python3.10',
212-
displayName: 'python 3.10 (ZIP)',
213-
baseImage: 'amazon/python3.10-base',
214-
path: 'hello_world/app.py',
215-
debugSessionType: 'python',
216-
language: 'python',
217-
dependencyManager: 'pip',
218-
// https://github.com/microsoft/vscode-python/blob/main/package.json
219-
vscodeMinimum: '1.77.0',
220-
},
221-
{
222-
runtime: 'python3.11',
223-
displayName: 'python 3.11 (ZIP)',
224-
baseImage: 'amazon/python3.11-base',
225-
path: 'hello_world/app.py',
226-
debugSessionType: 'python',
227-
language: 'python',
228-
dependencyManager: 'pip',
229-
// https://github.com/microsoft/vscode-python/blob/main/package.json
230-
vscodeMinimum: '1.78.0',
231-
},
232-
{
233-
runtime: 'python3.12',
234-
displayName: 'python 3.12 (ZIP)',
235-
baseImage: 'amazon/python3.12-base',
236-
path: 'hello_world/app.py',
237-
debugSessionType: 'python',
238-
language: 'python',
239-
dependencyManager: 'pip',
240-
// https://github.com/microsoft/vscode-python/blob/main/package.json
241-
vscodeMinimum: '1.78.0',
242-
},
243-
{
244-
runtime: 'python3.13',
245-
displayName: 'python 3.13 (ZIP)',
246-
baseImage: 'amazon/python3.13-base',
247-
path: 'hello_world/app.py',
248-
debugSessionType: 'python',
249-
language: 'python',
250-
dependencyManager: 'pip',
251-
// https://github.com/microsoft/vscode-python/blob/main/package.json
252-
vscodeMinimum: '1.78.0',
253-
},
254-
// {
255-
// runtime: 'go1.x',
256-
// displayName: 'go1.x (Image)',
257-
// baseImage: 'amazon/go1.x-base',
258-
// path: 'hello-world/main.go',
259-
// debugSessionType: 'delve',
260-
// language: 'go',
261-
// dependencyManager: 'mod',
262-
// // https://github.com/golang/vscode-go/blob/master/package.json
263-
// vscodeMinimum: '1.67.0',
264-
// },
265-
{
266-
runtime: 'java8.al2',
267-
displayName: 'java8.al2 (Gradle Image)',
268-
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
269-
baseImage: 'amazon/java8.al2-base',
270-
debugSessionType: 'java',
271-
language: 'java',
272-
dependencyManager: 'gradle',
273-
vscodeMinimum: '1.50.0',
274-
},
275-
{
276-
runtime: 'java11',
277-
displayName: 'java11 (Maven Image)',
278-
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
279-
baseImage: 'amazon/java11-base',
280-
debugSessionType: 'java',
281-
language: 'java',
282-
dependencyManager: 'maven',
283-
vscodeMinimum: '1.50.0',
284-
},
285-
{
286-
runtime: 'java17',
287-
displayName: 'java17 (Maven Image)',
288-
path: 'HelloWorldFunction/src/main/java/helloworld/App.java',
289-
baseImage: 'amazon/java17-base',
290-
debugSessionType: 'java',
291-
language: 'java',
292-
dependencyManager: 'maven',
293-
vscodeMinimum: '1.50.0',
294-
},
295-
{
296-
runtime: 'dotnet6',
297-
displayName: 'dotnet6 (Image)',
298-
path: 'src/HelloWorld/Function.cs',
299-
baseImage: 'amazon/dotnet6-base',
300-
debugSessionType: 'coreclr',
301-
language: 'csharp',
302-
dependencyManager: 'cli-package',
303-
vscodeMinimum: '1.80.0',
304-
},
138+
generateScenario('nodejs', '18.x', { baseImage: 'amazon/nodejs18.x-base' }, true),
139+
generateScenario('nodejs', '20.x', { baseImage: 'amazon/nodejs20.x-base' }, true),
140+
generateScenario('nodejs', '22.x', { baseImage: 'amazon/nodejs22.x-base', vscodeMinimum: '1.78.0' }, true),
141+
generateScenario('python', '3.10', { baseImage: 'amazon/python3.10-base' }, true),
142+
generateScenario('python', '3.11', { baseImage: 'amazon/python3.11-base', vscodeMinimum: '1.78.0' }, true),
143+
generateScenario('python', '3.12', { baseImage: 'amazon/python3.12-base', vscodeMinimum: '1.78.0' }, true),
144+
generateScenario('python', '3.13', { baseImage: 'amazon/python3.13-base', vscodeMinimum: '1.78.0' }, true),
145+
generateScenario('dotnet', '6', { baseImage: 'amazon/dotnet6-base' }, true),
146+
generateScenario(
147+
'java',
148+
'.al2',
149+
{ baseImage: 'amazon/java8.al2-base', sourceTag: 'Maven', dependencyManager: 'maven' },
150+
true
151+
),
152+
generateScenario('java', '11', { baseImage: 'amazon/java11-base', sourceTag: 'Gradle' }, true),
153+
generateScenario('java', '17', { baseImage: 'amazon/java17-base', sourceTag: 'Gradle' }, true),
305154
]
306155

307156
async function openSamAppFile(applicationPath: string): Promise<vscode.Uri> {

0 commit comments

Comments
 (0)