diff --git a/packages/core/src/lambda/remoteDebugging/ldkClient.ts b/packages/core/src/lambda/remoteDebugging/ldkClient.ts index 1c33217c08c..020d13d5ef2 100644 --- a/packages/core/src/lambda/remoteDebugging/ldkClient.ts +++ b/packages/core/src/lambda/remoteDebugging/ldkClient.ts @@ -17,7 +17,7 @@ import { DefaultLambdaClient } from '../../shared/clients/lambdaClient' import { LocalProxy } from './localProxy' import globals from '../../shared/extensionGlobals' import { getLogger } from '../../shared/logger/logger' -import { getIoTSTClientWithAgent, getLambdaClientWithAgent } from './utils' +import { getIoTSTClientWithAgent, getLambdaClientWithAgent, getLambdaDebugUserAgent } from './utils' import { ToolkitError } from '../../shared/errors' import * as nls from 'vscode-nls' @@ -99,7 +99,7 @@ export class LdkClient { */ private getLambdaClient(region: string): DefaultLambdaClient { if (!this.lambdaClientCache.has(region)) { - this.lambdaClientCache.set(region, getLambdaClientWithAgent(region)) + this.lambdaClientCache.set(region, getLambdaClientWithAgent(region, getLambdaDebugUserAgent())) } return this.lambdaClientCache.get(region)! } diff --git a/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts b/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts index c91be446753..98734e51833 100644 --- a/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts +++ b/packages/core/src/test/lambda/remoteDebugging/ldkClient.test.ts @@ -423,6 +423,92 @@ describe('LdkClient', () => { assert.strictEqual(result, true, 'Should return true when no proxy to stop') }) }) + + describe('Client User-Agent', () => { + it('should create Lambda client with correct user-agent', async () => { + // Restore the existing stub and create a new one to track calls + const existingStub = (utils.getLambdaClientWithAgent as any).restore + ? (utils.getLambdaClientWithAgent as sinon.SinonStub) + : undefined + if (existingStub) { + existingStub.restore() + } + + // Stub getUserAgent at the telemetryUtil level to return a known value + const getUserAgentStub = sandbox.stub(telemetryUtil, 'getUserAgent') + getUserAgentStub.returns('test-user-agent') + + // Stub the sdkClientBuilderV3 to capture the client options + let capturedClientOptions: any + const createAwsServiceStub = sandbox.stub(globals.sdkClientBuilderV3, 'createAwsService') + createAwsServiceStub.callsFake((options: any) => { + capturedClientOptions = options + // Return a mock Lambda client that has the required methods + return { + send: async () => ({ + Configuration: createMockFunctionConfig({ + FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction', + }), + }), + middlewareStack: {} as any, + destroy: () => {}, + } as any + }) + + const mockFunctionConfig: FunctionConfiguration = createMockFunctionConfig({ + FunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:testFunction', + }) + + await ldkClient.getFunctionDetail(mockFunctionConfig.FunctionArn!) + + assert(createAwsServiceStub.called, 'Should call createAwsService') + assert.strictEqual(capturedClientOptions.clientOptions.region, 'us-east-1', 'Should use correct region') + assert.deepStrictEqual( + capturedClientOptions.clientOptions.userAgent, + [['LAMBDA-DEBUG/1.0.0 test-user-agent']], + 'Should include correct user-agent with LAMBDA-DEBUG prefix in Lambda API calls' + ) + }) + + it('should create IoT client with correct user-agent', async () => { + // Restore the existing stub and create a new one to track calls + const existingStub = (utils.getIoTSTClientWithAgent as any).restore + ? (utils.getIoTSTClientWithAgent as sinon.SinonStub) + : undefined + if (existingStub) { + existingStub.restore() + } + + // Stub getUserAgent to return a known value + const getUserAgentStub = sandbox.stub(telemetryUtil, 'getUserAgent') + getUserAgentStub.returns('test-user-agent') + + // Stub the sdkClientBuilderV3 to capture the client options + let capturedClientOptions: any + const createAwsServiceStub = sandbox.stub(globals.sdkClientBuilderV3, 'createAwsService') + createAwsServiceStub.callsFake((options: any) => { + capturedClientOptions = options + return mockIoTSTClient as any + }) + + mockIoTSTClient.on(ListTunnelsCommand).resolves({ tunnelSummaries: [] }) + mockIoTSTClient.on(OpenTunnelCommand).resolves({ + tunnelId: 'tunnel-123', + sourceAccessToken: 'source-token', + destinationAccessToken: 'dest-token', + }) + + await ldkClient.createOrReuseTunnel('us-east-1') + + assert(createAwsServiceStub.calledOnce, 'Should call createAwsService once') + assert.strictEqual(capturedClientOptions.clientOptions.region, 'us-east-1', 'Should use correct region') + assert.deepStrictEqual( + capturedClientOptions.clientOptions.userAgent, + [['LAMBDA-DEBUG/1.0.0 test-user-agent']], + 'Should include correct user-agent with LAMBDA-DEBUG prefix' + ) + }) + }) }) describe('Helper Functions', () => {