Skip to content

Commit 3921f72

Browse files
author
Vandita Patidar
committed
Review change
1 parent f5e3ce3 commit 3921f72

File tree

9 files changed

+74
-174
lines changed

9 files changed

+74
-174
lines changed

packages/core/src/awsService/appBuilder/activation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ async function registerAppBuilderCommands(context: ExtContext): Promise<void> {
202202
}
203203
}),
204204
Commands.register({ id: 'aws.toolkit.lambda.createServerlessLandProject', autoconnect: false }, async () => {
205-
await telemetry.serverlessland_createProject.run(async () => {
205+
await telemetry.lambda_createServerlessLandProject.run(async () => {
206206
await createNewServerlessLandProject(context)
207207
})
208208
})

packages/core/src/awsService/appBuilder/serverlessLand/main.ts

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import * as nls from 'vscode-nls'
77
const localize = nls.loadMessageBundle()
88
import * as path from 'path'
99
import * as vscode from 'vscode'
10-
import { getTelemetryReason, getTelemetryResult } from '../../../shared/errors'
1110
import { getLogger } from '../../../shared/logger/logger'
1211
import { checklogs } from '../../../shared/localizedText'
13-
import { Result, telemetry } from '../../../shared/telemetry/telemetry'
12+
import { telemetry } from '../../../shared/telemetry/telemetry'
1413
import { CreateServerlessLandWizardForm, CreateServerlessLandWizard } from './wizard'
1514
import { ExtContext } from '../../../shared/extensions'
1615
import { addFolderToWorkspace } from '../../../shared/utilities/workspaceUtils'
@@ -37,17 +36,13 @@ const serverlessLandRepo = 'serverless-patterns'
3736
* 6. Handles errors and emits telemetry
3837
*/
3938
export async function createNewServerlessLandProject(extContext: ExtContext): Promise<void> {
40-
let createResult: Result = 'Succeeded'
41-
let reason: string | undefined
4239
let metadataManager: MetadataManager
4340

4441
try {
4542
metadataManager = MetadataManager.getInstance()
4643
// Launch the project creation wizard
4744
const config = await launchProjectCreationWizard(extContext)
4845
if (!config) {
49-
createResult = 'Cancelled'
50-
reason = 'userCancelled'
5146
return
5247
}
5348
const assetName = metadataManager.getAssetName(config.pattern, config.runtime, config.iac)
@@ -61,9 +56,12 @@ export async function createNewServerlessLandProject(extContext: ExtContext): Pr
6156
},
6257
true
6358
)
59+
telemetry.record({
60+
runtimeString: config.runtime,
61+
templateName: assetName,
62+
result: 'Succeeded',
63+
})
6464
} catch (err) {
65-
createResult = getTelemetryResult(err)
66-
reason = getTelemetryReason(err)
6765
getLogger().error(
6866
localize(
6967
'AWS.serverlessland.initWizard.general.error',
@@ -72,11 +70,6 @@ export async function createNewServerlessLandProject(extContext: ExtContext): Pr
7270
)
7371
)
7472
getLogger().error('Error creating new Serverless Land Application: %O', err as Error)
75-
} finally {
76-
telemetry.serverlessland_createProject.emit({
77-
result: createResult,
78-
reason: reason,
79-
})
8073
}
8174
}
8275

@@ -98,15 +91,7 @@ export async function downloadPatternCode(config: CreateServerlessLandWizardForm
9891
const location = vscode.Uri.joinPath(config.location, config.name)
9992
try {
10093
await getPattern(serverlessLandOwner, serverlessLandRepo, fullAssetName, location, true)
101-
telemetry.record({
102-
action: fullAssetName + config.iac + config.runtime,
103-
result: 'Succeeded',
104-
})
10594
} catch (error) {
106-
telemetry.serverlessland_downloadPattern.emit({
107-
result: 'Failed',
108-
reason: getTelemetryReason(error),
109-
})
11095
if (error instanceof ToolkitError) {
11196
throw error
11297
}
@@ -119,22 +104,11 @@ export async function openReadmeFile(config: CreateServerlessLandWizardForm): Pr
119104
const readmeUri = await getProjectUri(config, readmeFile)
120105
if (!readmeUri) {
121106
getLogger().warn('README.md file not found in the project directory')
122-
telemetry.serverlessland_readme.emit({
123-
result: 'Failed',
124-
reason: 'FileNotFound',
125-
})
126107
return
127108
}
128109
await vscode.commands.executeCommand('workbench.action.focusFirstEditorGroup')
129110
await vscode.commands.executeCommand('markdown.showPreview', readmeUri)
130-
telemetry.serverlessland_readme.emit({
131-
result: 'Succeeded',
132-
})
133111
} catch (err) {
134-
telemetry.serverlessland_readme.emit({
135-
result: 'Failed',
136-
reason: getTelemetryReason(err),
137-
})
138112
getLogger().error(`Error in openReadmeFile: ${err}`)
139113
throw new ToolkitError('Error processing README file')
140114
}

packages/core/src/awsService/appBuilder/serverlessLand/metadataManager.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports
6+
import * as path from 'path'
67
import { ToolkitError } from '../../../shared/errors'
78
import globals from '../../../shared/extensionGlobals'
89
import { telemetry } from '../../../shared/telemetry/telemetry'
@@ -49,7 +50,7 @@ export class MetadataManager {
4950
}
5051

5152
public getMetadataPath(): string {
52-
return globals.context.asAbsolutePath('dist/src/serverlessLand/metadata.json')
53+
return globals.context.asAbsolutePath(path.join('dist', 'src', 'serverlessLand', 'metadata.json'))
5354
}
5455

5556
/**

packages/core/src/awsService/appBuilder/serverlessLand/wizard.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export interface CreateServerlessLandWizardForm {
2222
pattern: string
2323
runtime: string
2424
iac: string
25-
assetName: string
2625
}
2726

2827
function promptPattern(metadataManager: MetadataManager) {

packages/core/src/shared/telemetry/vscodeTelemetry.json

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -645,21 +645,9 @@
645645
"description": "Records a call to remove a region from the explorer"
646646
},
647647
{
648-
"name": "serverlessland_createProject",
648+
"name": "lambda_createServerlessLandProject",
649649
"description": "Called when creating a new Serverless Project"
650650
},
651-
{
652-
"name": "serverlessland_downloadPattern",
653-
"description": "Called when downloading a Serverless Pattern"
654-
},
655-
{
656-
"name": "serverlessland_readme",
657-
"description": "Called when opening the Serverless Pattern Readme"
658-
},
659-
{
660-
"name": "serverlessland_wizard",
661-
"description": "Called when opening the Serverless Pattern Wizard"
662-
},
663651
{
664652
"name": "sam_detect",
665653
"description": "Called when detecting the location of the SAM CLI",

packages/core/src/test/awsService/appBuilder/serverlessLand/main.test.ts

Lines changed: 47 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -11,146 +11,89 @@ import * as vscode from 'vscode'
1111
import assert from 'assert'
1212
import * as sinon from 'sinon'
1313
import * as path from 'path'
14+
import { MetadataManager } from '../../../../awsService/appBuilder/serverlessLand/metadataManager'
1415
import * as main from '../../../../awsService/appBuilder/serverlessLand/main'
1516
import {
1617
createNewServerlessLandProject,
17-
launchProjectCreationWizard,
1818
openReadmeFile,
1919
getProjectUri,
2020
downloadPatternCode,
2121
} from '../../../../awsService/appBuilder/serverlessLand/main'
22-
import * as workspaceUtils from '../../../../shared/utilities/workspaceUtils'
2322
import { fs } from '../../../../shared/fs/fs'
2423
import * as downloadPatterns from '../../../../shared/utilities/downloadPatterns'
25-
import { assertTelemetryCurried } from '../../../testUtil'
26-
import { CreateServerlessLandWizard } from '../../../../awsService/appBuilder/serverlessLand/wizard'
27-
import { MetadataManager } from '../../../../awsService/appBuilder/serverlessLand/metadataManager'
2824
import { ExtContext } from '../../../../shared/extensions'
25+
import { workspaceUtils } from '../../../../shared'
26+
import * as downloadPattern from '../../../../shared/utilities/downloadPatterns'
27+
import * as wizardModule from '../../../../awsService/appBuilder/serverlessLand/wizard'
2928

3029
describe('createNewServerlessLandProject', () => {
3130
let sandbox: sinon.SinonSandbox
32-
const mockExtContext = {
33-
awsContext: {
34-
getCredentials: () => Promise.resolve({}),
35-
getCredentialDefaultRegion: () => 'us-west-2',
36-
},
37-
} as unknown as ExtContext
38-
const assertTelemetry = assertTelemetryCurried('serverlessland_createProject')
39-
const mockWizardResponse = {
40-
name: 'test-project',
41-
location: vscode.Uri.file('/test'),
42-
pattern: 'test-pattern',
43-
runtime: 'nodejs',
44-
iac: 'sam',
45-
assetName: 'test-asset',
46-
}
31+
let mockExtContext: ExtContext
32+
let mockMetadataManager: sinon.SinonStubbedInstance<MetadataManager>
33+
let mockWizard: { run: sinon.SinonStub }
4734

4835
beforeEach(() => {
4936
sandbox = sinon.createSandbox()
50-
})
51-
52-
afterEach(() => {
53-
sandbox.restore()
54-
})
55-
56-
it('successfully creates a new serverless land project', async () => {
57-
const wizardStub = sandbox.stub(main, 'launchProjectCreationWizard').resolves(mockWizardResponse)
58-
const metadataStub = sandbox
59-
.stub(MetadataManager.prototype, 'getAssetName')
60-
.withArgs('test-pattern', 'node.js', 'sam')
61-
.returns('test-asset')
62-
const downloadStub = sandbox.stub(main, 'downloadPatternCode').resolves()
63-
const readmeStub = sandbox.stub(main, 'openReadmeFile').resolves()
64-
const addFolderStub = sandbox.stub(workspaceUtils, 'addFolderToWorkspace').resolves()
65-
66-
await main.createNewServerlessLandProject(mockExtContext)
67-
68-
sandbox.assert.calledOnce(wizardStub)
69-
sandbox.assert.calledOnce(metadataStub)
70-
sandbox.assert.calledWith(downloadStub, mockWizardResponse, 'test-asset')
71-
sandbox.assert.calledOnce(readmeStub)
72-
sandbox.assert.calledWith(readmeStub, mockWizardResponse)
73-
sandbox.assert.calledOnce(addFolderStub)
74-
assertTelemetry({
75-
result: 'Succeeded',
76-
})
77-
})
37+
mockExtContext = {
38+
awsContext: {
39+
getCredentials: sandbox.stub().resolves({}),
40+
getCredentialDefaultRegion: () => 'us-west-2',
41+
},
42+
} as unknown as ExtContext
7843

79-
it('handles wizard cancellation', async () => {
80-
sandbox.stub(main, 'launchProjectCreationWizard').resolves(undefined)
81-
await createNewServerlessLandProject(mockExtContext)
82-
assertTelemetry({
83-
result: 'Failed',
84-
reason: 'Error',
85-
})
86-
})
44+
mockMetadataManager = sandbox.createStubInstance(MetadataManager)
45+
mockMetadataManager.getAssetName.returns('test-asset-name')
46+
sandbox.stub(MetadataManager, 'getInstance').returns(mockMetadataManager as unknown as MetadataManager)
8747

88-
it('handles errors during project creation', async () => {
89-
sandbox.stub(main, 'launchProjectCreationWizard').resolves(mockWizardResponse)
90-
sandbox.stub(main, 'downloadPatternCode').rejects(new Error('Download failed'))
91-
await createNewServerlessLandProject(mockExtContext)
92-
assertTelemetry({
93-
result: 'Failed',
94-
reason: 'Error',
95-
})
96-
})
97-
})
48+
mockWizard = { run: sandbox.stub() }
49+
sandbox.stub(wizardModule, 'CreateServerlessLandWizard').returns(mockWizard)
9850

99-
describe('launchProjectCreationWizard', () => {
100-
let sandbox: sinon.SinonSandbox
101-
const mockWizardResponse = {
102-
name: 'test-project',
103-
location: 'test-location',
104-
pattern: 'test-pattern',
105-
runtime: 'nodejs',
106-
iac: 'sam',
107-
}
108-
const mockExtContext = {
109-
awsContext: {
110-
getCredentials: () => Promise.resolve({}),
111-
getCredentialDefaultRegion: () => 'us-west-2',
112-
},
113-
} as unknown as ExtContext
51+
sandbox.stub(vscode.Uri, 'joinPath').returns(vscode.Uri.file('/test'))
52+
sandbox.stub(vscode.commands, 'executeCommand').resolves()
11453

115-
beforeEach(() => {
116-
sandbox = sinon.createSandbox()
54+
sandbox.stub(workspaceUtils, 'addFolderToWorkspace').resolves()
55+
sandbox.stub(downloadPattern, 'getPattern').resolves()
11756
})
11857
afterEach(() => {
11958
sandbox.restore()
12059
})
121-
it('should launch wizard and return form data', async () => {
122-
const wizardRunStub = sandbox.stub().resolves(mockWizardResponse)
123-
sandbox.stub(CreateServerlessLandWizard.prototype, 'run').get(() => wizardRunStub)
124-
125-
const result = await launchProjectCreationWizard(mockExtContext)
126-
127-
sinon.assert.calledOnce(wizardRunStub)
128-
assert.deepStrictEqual(result, mockWizardResponse)
60+
it('should complete project creation successfully', async () => {
61+
const mockConfig = {
62+
pattern: 'testPattern',
63+
runtime: 'nodejs',
64+
iac: 'sam',
65+
location: vscode.Uri.file('/test'),
66+
name: 'testProject',
67+
}
68+
mockWizard.run.resolves(mockConfig)
69+
await createNewServerlessLandProject(mockExtContext)
70+
assert.strictEqual(mockWizard.run.calledOnce, true)
71+
assert.strictEqual(mockMetadataManager.getAssetName.calledOnce, true)
72+
assert.strictEqual((downloadPattern.getPattern as sinon.SinonStub).calledOnce, true)
12973
})
130-
it('should return undefined when wizard is cancelled', async () => {
131-
const wizardRunStub = sandbox.stub().resolves(undefined)
132-
sandbox.stub(CreateServerlessLandWizard.prototype, 'run').get(() => wizardRunStub)
133-
134-
const result = await launchProjectCreationWizard(mockExtContext)
135-
136-
sinon.assert.calledOnce(wizardRunStub)
137-
assert.strictEqual(result, undefined)
74+
it('should handle wizard cancellation', async () => {
75+
mockWizard.run.resolves(undefined)
76+
await createNewServerlessLandProject(mockExtContext)
77+
assert.strictEqual(mockWizard.run.calledOnce, true)
78+
assert.strictEqual(mockMetadataManager.getAssetName.called, false)
79+
assert.strictEqual((downloadPattern.getPattern as sinon.SinonStub).called, false)
13880
})
13981
})
14082

14183
describe('downloadPatternCode', () => {
84+
let sandbox: sinon.SinonSandbox
14285
let getPatternStub: sinon.SinonStub
143-
const assertTelemetry = assertTelemetryCurried('serverlessland_downloadPattern')
14486

14587
beforeEach(function () {
146-
getPatternStub = sinon.stub(downloadPatterns, 'getPattern')
88+
sandbox = sinon.createSandbox()
89+
getPatternStub = sandbox.stub(downloadPatterns, 'getPattern')
14790
})
14891
afterEach(function () {
149-
sinon.restore()
92+
sandbox.restore()
15093
})
15194
const mockConfig = {
15295
name: 'test-project',
153-
location: vscode.Uri.file('./test'),
96+
location: vscode.Uri.file('/test'),
15497
pattern: 'test-project-sam-python',
15598
runtime: 'python',
15699
iac: 'sam',
@@ -178,10 +121,6 @@ describe('downloadPatternCode', () => {
178121
await downloadPatternCode(mockConfig, mockAssetName)
179122
assert.fail('Expected an error to be thrown')
180123
} catch (err: any) {
181-
assertTelemetry({
182-
result: 'Failed',
183-
reason: 'Error',
184-
})
185124
assert.strictEqual(err.message, 'Failed to download pattern: Error: Download failed')
186125
}
187126
})
@@ -273,7 +212,7 @@ describe('getProjectUri', () => {
273212
} as vscode.Uri)
274213

275214
const result = await getProjectUri(mockConfig, testFile)
276-
sinon.assert.calledWith(uriFileStub, expectedPath)
215+
sandbox.assert.calledWith(uriFileStub, expectedPath)
277216
assert.strictEqual(result?.fsPath, expectedPath)
278217
})
279218
it('handles missing project directory', async () => {

0 commit comments

Comments
 (0)