Skip to content

Commit aec6cfd

Browse files
committed
remove duplicate code
1 parent 0b4f0bf commit aec6cfd

File tree

5 files changed

+184
-138
lines changed

5 files changed

+184
-138
lines changed

packages/core/src/lambda/remoteDebugging/ldkClient.ts

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,30 @@ interface TunnelInfo {
3232
destinationToken: string
3333
}
3434

35+
async function callUpdateFunctionConfiguration(
36+
lambda: DefaultLambdaClient,
37+
config: Lambda.FunctionConfiguration,
38+
waitForUpdate: boolean
39+
): Promise<Lambda.FunctionConfiguration> {
40+
// Update function configuration back to original values
41+
return await lambda.updateFunctionConfiguration(
42+
{
43+
FunctionName: config.FunctionName!,
44+
Timeout: config.Timeout,
45+
Layers: config.Layers?.map((layer) => layer.Arn!).filter(Boolean) || [],
46+
Environment: {
47+
Variables: config.Environment?.Variables ?? {},
48+
},
49+
},
50+
{
51+
maxRetries: 5,
52+
initialDelayMs: 2000,
53+
backoffMultiplier: 2,
54+
waitForUpdate: waitForUpdate,
55+
}
56+
)
57+
}
58+
3559
export class LdkClient {
3660
static #instance: LdkClient
3761
private localProxy: LocalProxy | undefined
@@ -285,22 +309,18 @@ export class LdkClient {
285309
if (!config.FunctionArn || !config.FunctionName) {
286310
throw new Error('Function ARN is missing')
287311
}
288-
await lambda.updateFunctionConfiguration(
289-
{
290-
FunctionName: config.FunctionName,
291-
Timeout: lambdaTimeout ?? 900, // 15 minutes
292-
Layers: updatedLayers,
293-
Environment: {
294-
Variables: updatedEnv,
295-
},
312+
313+
// Create a temporary config for the update
314+
const updateConfig: Lambda.FunctionConfiguration = {
315+
FunctionName: config.FunctionName,
316+
Timeout: lambdaTimeout ?? 900, // 15 minutes
317+
Layers: updatedLayers.map((arn) => ({ Arn: arn })),
318+
Environment: {
319+
Variables: updatedEnv,
296320
},
297-
{
298-
maxRetries: 5,
299-
initialDelayMs: 2000,
300-
backoffMultiplier: 2,
301-
waitForUpdate: true,
302-
}
303-
)
321+
}
322+
323+
await callUpdateFunctionConfiguration(lambda, updateConfig, true)
304324

305325
// publish version
306326
let version = '$Latest'
@@ -310,26 +330,14 @@ export class LdkClient {
310330
version = versionResp.Version ?? ''
311331
// remove debug deployment in a non-blocking way
312332
void Promise.resolve(
313-
lambda
314-
.updateFunctionConfiguration(
315-
{
316-
FunctionName: config.FunctionName,
317-
Timeout: config.Timeout,
318-
Layers: config.Layers?.map((layer) => layer.Arn!).filter(Boolean) || [],
319-
Environment: {
320-
Variables: config.Environment?.Variables ?? {},
321-
},
322-
},
323-
{ waitForUpdate: false }
324-
)
325-
.then(() => {
326-
progress.report({
327-
message: localize(
328-
'AWS.lambda.ldkClient.debugDeploymentCompleted',
329-
'Debug deployment completed successfully'
330-
),
331-
})
333+
callUpdateFunctionConfiguration(lambda, config, false).then(() => {
334+
progress.report({
335+
message: localize(
336+
'AWS.lambda.ldkClient.debugDeploymentCompleted',
337+
'Debug deployment completed successfully'
338+
),
332339
})
340+
})
333341
)
334342
}
335343
return version
@@ -368,21 +376,7 @@ export class LdkClient {
368376
const lambda = this.getLambdaClient(region)
369377

370378
// Update function configuration back to original values
371-
await lambda.updateFunctionConfiguration(
372-
{
373-
FunctionName: config.FunctionName,
374-
Timeout: config.Timeout,
375-
Layers: config.Layers?.map((layer) => layer.Arn!).filter(Boolean) || [],
376-
Environment: {
377-
Variables: config.Environment?.Variables ?? {},
378-
},
379-
},
380-
{
381-
maxRetries: 5,
382-
initialDelayMs: 2000,
383-
backoffMultiplier: 2,
384-
}
385-
)
379+
await callUpdateFunctionConfiguration(lambda, config, false)
386380

387381
return true
388382
} catch (error) {

packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { LocalProxy } from '../../../lambda/remoteDebugging/localProxy'
1111
import * as utils from '../../../lambda/remoteDebugging/utils'
1212
import * as telemetryUtil from '../../../shared/telemetry/util'
1313
import globals from '../../../shared/extensionGlobals'
14+
import { createMockFunctionConfig, createMockProgress } from './testUtils'
1415

1516
describe('LdkClient', () => {
1617
let sandbox: sinon.SinonSandbox
@@ -182,15 +183,9 @@ describe('LdkClient', () => {
182183
})
183184

184185
describe('getFunctionDetail()', () => {
185-
const mockFunctionConfig: Lambda.FunctionConfiguration = {
186-
FunctionName: 'testFunction',
186+
const mockFunctionConfig: Lambda.FunctionConfiguration = createMockFunctionConfig({
187187
FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction',
188-
Runtime: 'nodejs18.x',
189-
Timeout: 30,
190-
Layers: [],
191-
Environment: { Variables: {} },
192-
Architectures: ['x86_64'],
193-
}
188+
})
194189

195190
it('should get function details successfully', async () => {
196191
mockLambdaClient.getFunction.resolves({ Configuration: mockFunctionConfig })
@@ -217,19 +212,11 @@ describe('LdkClient', () => {
217212
})
218213

219214
describe('createDebugDeployment()', () => {
220-
const mockFunctionConfig: Lambda.FunctionConfiguration = {
221-
FunctionName: 'testFunction',
215+
const mockFunctionConfig: Lambda.FunctionConfiguration = createMockFunctionConfig({
222216
FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction',
223-
Runtime: 'nodejs18.x',
224-
Timeout: 30,
225-
Layers: [],
226-
Environment: { Variables: {} },
227-
Architectures: ['x86_64'],
228-
}
217+
})
229218

230-
const mockProgress = {
231-
report: sinon.stub(),
232-
}
219+
const mockProgress = createMockProgress()
233220

234221
beforeEach(() => {
235222
mockLambdaClient.updateFunctionConfiguration.resolves({})
@@ -304,15 +291,9 @@ describe('LdkClient', () => {
304291
})
305292

306293
describe('removeDebugDeployment()', () => {
307-
const mockFunctionConfig: Lambda.FunctionConfiguration = {
308-
FunctionName: 'testFunction',
294+
const mockFunctionConfig: Lambda.FunctionConfiguration = createMockFunctionConfig({
309295
FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction',
310-
Runtime: 'nodejs18.x',
311-
Timeout: 30,
312-
Layers: [],
313-
Environment: { Variables: {} },
314-
Architectures: ['x86_64'],
315-
}
296+
})
316297

317298
beforeEach(() => {
318299
mockLambdaClient.updateFunctionConfiguration.resolves({})

packages/core/src/test/lambda/remoteDebugging/ldkController.test.ts

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import globals from '../../../shared/extensionGlobals'
1919
import * as messages from '../../../shared/utilities/messages'
2020
import { getOpenExternalStub } from '../../globalSetup.test'
2121
import { assertTelemetry } from '../../testUtil'
22+
import { createMockFunctionConfig, createMockDebugConfig } from './testUtils'
2223

2324
describe('RemoteDebugController', () => {
2425
let sandbox: sinon.SinonSandbox
@@ -200,27 +201,11 @@ describe('RemoteDebugController', () => {
200201
let mockFunctionConfig: Lambda.FunctionConfiguration
201202

202203
beforeEach(() => {
203-
mockConfig = {
204-
functionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
205-
functionName: 'testFunction',
206-
port: 9229,
207-
localRoot: '/local/path',
208-
remoteRoot: '/var/task',
209-
skipFiles: [],
210-
shouldPublishVersion: false,
211-
lambdaTimeout: 900,
204+
mockConfig = createMockDebugConfig({
212205
layerArn: 'arn:aws:lambda:us-west-2:123456789012:layer:LDKLayerX86:6',
213-
}
206+
})
214207

215-
mockFunctionConfig = {
216-
FunctionName: 'testFunction',
217-
FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
218-
Runtime: 'nodejs18.x',
219-
Timeout: 30,
220-
Layers: [],
221-
Environment: { Variables: {} },
222-
Architectures: ['x86_64'],
223-
}
208+
mockFunctionConfig = createMockFunctionConfig()
224209
})
225210

226211
it('should start debugging successfully', async () => {
@@ -437,27 +422,11 @@ describe('RemoteDebugController', () => {
437422
let mockFunctionConfig: Lambda.FunctionConfiguration
438423

439424
beforeEach(() => {
440-
mockConfig = {
441-
functionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
442-
functionName: 'testFunction',
443-
port: 9229,
444-
localRoot: '/local/path',
445-
remoteRoot: '/var/task',
446-
skipFiles: [],
447-
shouldPublishVersion: false,
448-
lambdaTimeout: 900,
425+
mockConfig = createMockDebugConfig({
449426
layerArn: 'arn:aws:lambda:us-west-2:123456789012:layer:LDKLayerX86:6',
450-
}
427+
})
451428

452-
mockFunctionConfig = {
453-
FunctionName: 'testFunction',
454-
FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
455-
Runtime: 'nodejs18.x',
456-
Timeout: 30,
457-
Layers: [],
458-
Environment: { Variables: {} },
459-
Architectures: ['x86_64'],
460-
}
429+
mockFunctionConfig = createMockFunctionConfig()
461430
})
462431

463432
it('should emit lambda_remoteDebugStart telemetry for successful debugging start', async () => {
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import sinon from 'sinon'
7+
import { Lambda } from 'aws-sdk'
8+
import { LambdaFunctionNode } from '../../../lambda/explorer/lambdaFunctionNode'
9+
import { InitialData } from '../../../lambda/vue/remoteInvoke/invokeLambda'
10+
import { DebugConfig } from '../../../lambda/remoteDebugging/ldkController'
11+
12+
/**
13+
* Creates a mock Lambda function configuration for testing
14+
*/
15+
export function createMockFunctionConfig(
16+
overrides: Partial<Lambda.FunctionConfiguration> = {}
17+
): Lambda.FunctionConfiguration {
18+
return {
19+
FunctionName: 'testFunction',
20+
FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
21+
Runtime: 'nodejs18.x',
22+
Handler: 'index.handler',
23+
Timeout: 30,
24+
Layers: [],
25+
Environment: { Variables: {} },
26+
Architectures: ['x86_64'],
27+
SnapStart: { ApplyOn: 'None' },
28+
...overrides,
29+
}
30+
}
31+
32+
/**
33+
* Creates a mock Lambda function node for testing
34+
*/
35+
export function createMockFunctionNode(overrides: Partial<LambdaFunctionNode> = {}): LambdaFunctionNode {
36+
const config = createMockFunctionConfig()
37+
return {
38+
configuration: config,
39+
regionCode: 'us-west-2',
40+
localDir: '/local/path',
41+
...overrides,
42+
} as LambdaFunctionNode
43+
}
44+
45+
/**
46+
* Creates mock initial data for RemoteInvokeWebview testing
47+
*/
48+
export function createMockInitialData(overrides: Partial<InitialData> = {}): InitialData {
49+
const mockFunctionNode = createMockFunctionNode()
50+
return {
51+
FunctionName: 'testFunction',
52+
FunctionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
53+
FunctionRegion: 'us-west-2',
54+
InputSamples: [],
55+
Runtime: 'nodejs18.x',
56+
LocalRootPath: '/local/path',
57+
LambdaFunctionNode: mockFunctionNode,
58+
supportCodeDownload: true,
59+
runtimeSupportsRemoteDebug: true,
60+
regionSupportsRemoteDebug: true,
61+
...overrides,
62+
} as InitialData
63+
}
64+
65+
/**
66+
* Creates a mock debug configuration for testing
67+
*/
68+
export function createMockDebugConfig(overrides: Partial<DebugConfig> = {}): DebugConfig {
69+
return {
70+
functionArn: 'arn:aws:lambda:us-west-2:123456789012:function:testFunction',
71+
functionName: 'testFunction',
72+
port: 9229,
73+
localRoot: '/local/path',
74+
remoteRoot: '/var/task',
75+
skipFiles: [],
76+
shouldPublishVersion: false,
77+
lambdaTimeout: 900,
78+
layerArn: 'arn:aws:lambda:us-west-2:123456789012:layer:LDKLayerX86:6',
79+
...overrides,
80+
}
81+
}
82+
83+
/**
84+
* Creates a mock global state for testing
85+
*/
86+
export function createMockGlobalState(): any {
87+
const stateStorage = new Map<string, any>()
88+
return {
89+
get: (key: string) => stateStorage.get(key),
90+
tryGet: (key: string, type?: any, defaultValue?: any) => {
91+
const value = stateStorage.get(key)
92+
return value !== undefined ? value : defaultValue
93+
},
94+
update: async (key: string, value: any) => {
95+
stateStorage.set(key, value)
96+
return Promise.resolve()
97+
},
98+
}
99+
}
100+
101+
/**
102+
* Sets up common mocks for VSCode APIs
103+
*/
104+
export function setupVSCodeMocks(sandbox: sinon.SinonSandbox) {
105+
return {
106+
startDebugging: sandbox.stub(),
107+
executeCommand: sandbox.stub(),
108+
onDidTerminateDebugSession: sandbox.stub().returns({ dispose: sandbox.stub() }),
109+
}
110+
}
111+
112+
/**
113+
* Creates a mock progress reporter for testing
114+
*/
115+
export function createMockProgress(): any {
116+
return {
117+
report: sinon.stub(),
118+
}
119+
}

0 commit comments

Comments
 (0)