Skip to content

Commit c146b6e

Browse files
nkomonen-amazonjustinmk3
authored andcommitted
fix(ci): slow "Clone aws-sam-cli-app-templates" step
The `sam init` integration tests took an average of 7 minutes to complete. This commit reduces them to an average of 2 minutes 30 seconds. Problem: The current sam cli implementation clones the entire template repo each call of sam.test.ts#createSamApplication(). This function is called more than it needs to be for the same test coverage. Solution: Remove redundant calls to the createSamApplication() method. Test a certain scenario only once because it does not change for each iteration of SAM project type. Note: I looked in to the `sam init --location` flag and it doesn't assist in trying to test the current logic this test aims to validate. Use of `--location` is a different way to do do a `sam init`, but we are only testing Scenario 1 "Initializes a new SAM project with required parameters passed as parameters": //Scenario 1 $ sam init --runtime python3.7 --dependency-manager pip --app-template hello-world --name sam-app // Scenario 2 $ sam init --location /path/to/template/folder ref: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-init.html fix #2090 Signed-off-by: Nikolas Komonen <[email protected]>
1 parent 4014a95 commit c146b6e

File tree

2 files changed

+49
-49
lines changed

2 files changed

+49
-49
lines changed

src/integrationTest/sam.test.ts

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,30 @@ describe('SAM Integration Tests', async function () {
397397
console.log(`DebugSessions seen in this run:\n${sessionReport}`)
398398
})
399399

400+
describe('SAM install test', async () => {
401+
let runtimeTestRoot: string
402+
let randomTestScenario: TestScenario
403+
404+
before(async function () {
405+
if (scenarios.length == 0) {
406+
throw new Error('There are no scenarios available.')
407+
}
408+
randomTestScenario = scenarios[0]
409+
410+
runtimeTestRoot = path.join(testSuiteRoot, 'randomScenario')
411+
mkdirpSync(runtimeTestRoot)
412+
})
413+
414+
after(async function () {
415+
await tryRemoveFolder(runtimeTestRoot)
416+
})
417+
418+
it('produces an error when creating a SAM Application to the same location', async function () {
419+
await createSamApplication(runtimeTestRoot, randomTestScenario)
420+
await assert.rejects(createSamApplication(runtimeTestRoot, randomTestScenario), 'Promise was not rejected')
421+
})
422+
})
423+
400424
for (let scenarioIndex = 0; scenarioIndex < scenarios.length; scenarioIndex++) {
401425
const scenario = scenarios[scenarioIndex]
402426

@@ -420,33 +444,6 @@ describe('SAM Integration Tests', async function () {
420444
console.log(`sam.test.ts: scenario ${scenarioIndex} (${scenario.displayName}): ${o}`)
421445
}
422446

423-
/**
424-
* This suite cleans up at the end of each test.
425-
*/
426-
describe('Starting from scratch', async function () {
427-
let testDir: string
428-
429-
beforeEach(async function () {
430-
testDir = await mkdtemp(path.join(runtimeTestRoot, 'test-'))
431-
log(`testDir: ${testDir}`)
432-
})
433-
434-
afterEach(async function () {
435-
// don't clean up after java tests so the java language server doesn't freak out
436-
if (scenario.language !== 'java') {
437-
await tryRemoveFolder(testDir)
438-
}
439-
})
440-
441-
it('creates a new SAM Application (happy path)', async function () {
442-
await createSamApplication(testDir)
443-
444-
// Check for readme file
445-
const readmePath = path.join(testDir, samApplicationName, 'README.md')
446-
assert.ok(await fileExists(readmePath), `Expected SAM App readme to exist at ${readmePath}`)
447-
})
448-
})
449-
450447
/**
451448
* This suite makes a sam app that all tests operate on.
452449
* Cleanup happens at the end of the suite.
@@ -463,10 +460,13 @@ describe('SAM Integration Tests', async function () {
463460
testDir = await mkdtemp(path.join(runtimeTestRoot, 'samapp-'))
464461
log(`testDir: ${testDir}`)
465462

466-
await createSamApplication(testDir)
463+
await createSamApplication(testDir, scenario)
467464
appPath = path.join(testDir, samApplicationName, scenario.path)
465+
468466
cfnTemplatePath = path.join(testDir, samApplicationName, 'template.yaml')
467+
const readmePath = path.join(testDir, samApplicationName, 'README.md')
469468
assert.ok(await fileExists(cfnTemplatePath), `Expected SAM template to exist at ${cfnTemplatePath}`)
469+
assert.ok(await fileExists(readmePath), `Expected SAM App readme to exist at ${readmePath}`)
470470

471471
samAppCodeUri = await openSamAppFile(appPath)
472472
})
@@ -488,10 +488,6 @@ describe('SAM Integration Tests', async function () {
488488
}
489489
})
490490

491-
it('produces an error when creating a SAM Application to the same location', async function () {
492-
await assert.rejects(createSamApplication(testDir), 'Promise was not rejected')
493-
})
494-
495491
it('produces an Add Debug Configuration codelens', async function () {
496492
if (semver.lt(vscode.version, scenario.vscodeMinimum)) {
497493
this.skip()
@@ -622,22 +618,6 @@ describe('SAM Integration Tests', async function () {
622618
})
623619
})
624620

625-
async function createSamApplication(location: string): Promise<void> {
626-
const initArguments: SamCliInitArgs = {
627-
name: samApplicationName,
628-
location: location,
629-
dependencyManager: scenario.dependencyManager,
630-
}
631-
if (scenario.baseImage) {
632-
initArguments.baseImage = scenario.baseImage
633-
} else {
634-
initArguments.runtime = scenario.runtime
635-
initArguments.template = helloWorldTemplate
636-
}
637-
const samCliContext = getSamCliContext()
638-
await runSamCliInit(initArguments, samCliContext)
639-
}
640-
641621
function assertCodeLensReferencesHasSameRoot(codeLens: vscode.CodeLens, expectedUri: vscode.Uri) {
642622
assert.ok(codeLens.command, 'CodeLens did not have a command')
643623
const command = codeLens.command!
@@ -652,4 +632,24 @@ describe('SAM Integration Tests', async function () {
652632
assert.strictEqual(path.dirname(params.rootUri.fsPath), path.dirname(expectedUri.fsPath))
653633
}
654634
}
635+
636+
async function createSamApplication(location: string, scenario: TestScenario): Promise<void> {
637+
const initArguments: SamCliInitArgs = {
638+
name: samApplicationName,
639+
location: location,
640+
dependencyManager: scenario.dependencyManager,
641+
}
642+
if (scenario.baseImage) {
643+
initArguments.baseImage = scenario.baseImage
644+
} else {
645+
initArguments.runtime = scenario.runtime
646+
initArguments.template = helloWorldTemplate
647+
}
648+
const samCliContext = getSamCliContext()
649+
await runSamCliInit(initArguments, samCliContext)
650+
// XXX: Fixes flakiness. Ensures the files from creation of sam
651+
// app are processed by code lens file watcher. Otherwise, potential
652+
// issues of file not in registry before it is found.
653+
await globals.codelensRootRegistry.rebuild()
654+
}
655655
})

src/shared/fs/watchedFiles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export abstract class WatchedFiles<T> implements vscode.Disposable {
221221
* Rebuilds registry using current glob and exclusion patterns.
222222
* All functionality is currently internal to class, but can be made public if we want a manual "refresh" button
223223
*/
224-
private async rebuild(): Promise<void> {
224+
public async rebuild(): Promise<void> {
225225
this.reset()
226226
for (const glob of this.globs) {
227227
const itemUris = await vscode.workspace.findFiles(glob)

0 commit comments

Comments
 (0)