From 9d77c04ee98b6ac117810586956e509622160579 Mon Sep 17 00:00:00 2001 From: Tai Lai Date: Fri, 17 Jan 2025 13:04:19 -0800 Subject: [PATCH] config(amazonq): lower timeout for auto reviews --- .../service/securityScanHandler.test.ts | 56 +++++++++++++++++++ packages/core/src/codewhisperer/index.ts | 4 +- .../src/codewhisperer/models/constants.ts | 4 +- .../service/securityScanHandler.ts | 9 +-- packages/core/src/shared/index.ts | 1 + 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/amazonq/test/unit/codewhisperer/service/securityScanHandler.test.ts b/packages/amazonq/test/unit/codewhisperer/service/securityScanHandler.test.ts index b0086b2a205..173aa42cd50 100644 --- a/packages/amazonq/test/unit/codewhisperer/service/securityScanHandler.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/service/securityScanHandler.test.ts @@ -13,7 +13,10 @@ import { mapToAggregatedList, DefaultCodeWhispererClient, ListCodeScanFindingsResponse, + pollScanJobStatus, + SecurityScanTimedOutError, } from 'aws-core-vscode/codewhisperer' +import { timeoutUtils } from 'aws-core-vscode/shared' import assert from 'assert' import sinon from 'sinon' import * as vscode from 'vscode' @@ -239,4 +242,57 @@ describe('securityScanHandler', function () { assert.strictEqual(codeScanIssueMap.get('file1.ts')?.length, 1) }) }) + + describe('pollScanJobStatus', function () { + let mockClient: Stub + let clock: sinon.SinonFakeTimers + const mockJobId = 'test-job-id' + const mockStartTime = Date.now() + + beforeEach(function () { + mockClient = stub(DefaultCodeWhispererClient) + clock = sinon.useFakeTimers({ + shouldAdvanceTime: true, + }) + sinon.stub(timeoutUtils, 'sleep').resolves() + }) + + afterEach(function () { + sinon.restore() + clock.restore() + }) + + it('should return status when scan completes successfully', async function () { + mockClient.getCodeScan + .onFirstCall() + .resolves({ status: 'Pending', $response: { requestId: 'req1' } }) + .onSecondCall() + .resolves({ status: 'Completed', $response: { requestId: 'req2' } }) + + const result = await pollScanJobStatus(mockClient, mockJobId, CodeAnalysisScope.FILE_AUTO, mockStartTime) + assert.strictEqual(result, 'Completed') + }) + + it('should throw SecurityScanTimedOutError when polling exceeds timeout for express scans', async function () { + mockClient.getCodeScan.resolves({ status: 'Pending', $response: { requestId: 'req1' } }) + + const pollPromise = pollScanJobStatus(mockClient, mockJobId, CodeAnalysisScope.FILE_AUTO, mockStartTime) + + const expectedTimeoutMs = 60_000 + clock.tick(expectedTimeoutMs + 1000) + + await assert.rejects(() => pollPromise, SecurityScanTimedOutError) + }) + + it('should throw SecurityScanTimedOutError when polling exceeds timeout for standard scans', async function () { + mockClient.getCodeScan.resolves({ status: 'Pending', $response: { requestId: 'req1' } }) + + const pollPromise = pollScanJobStatus(mockClient, mockJobId, CodeAnalysisScope.PROJECT, mockStartTime) + + const expectedTimeoutMs = 600_000 + clock.tick(expectedTimeoutMs + 1000) + + await assert.rejects(() => pollPromise, SecurityScanTimedOutError) + }) + }) }) diff --git a/packages/core/src/codewhisperer/index.ts b/packages/core/src/codewhisperer/index.ts index 5484411a7ac..3aea72fb4ca 100644 --- a/packages/core/src/codewhisperer/index.ts +++ b/packages/core/src/codewhisperer/index.ts @@ -73,7 +73,7 @@ export { DocumentChangedSource, KeyStrokeHandler, DefaultDocumentChangedType } f export { ReferenceLogViewProvider } from './service/referenceLogViewProvider' export { LicenseUtil } from './util/licenseUtil' export { SecurityIssueProvider } from './service/securityIssueProvider' -export { listScanResults, mapToAggregatedList } from './service/securityScanHandler' +export { listScanResults, mapToAggregatedList, pollScanJobStatus } from './service/securityScanHandler' export { CodeWhispererCodeCoverageTracker } from './tracker/codewhispererCodeCoverageTracker' export { TelemetryHelper } from './util/telemetryHelper' export { LineSelection, LineTracker } from './tracker/lineTracker' @@ -97,7 +97,7 @@ export * as supplementalContextUtil from './util/supplementalContext/supplementa export * from './service/diagnosticsProvider' export * as diagnosticsProvider from './service/diagnosticsProvider' export * from './ui/codeWhispererNodes' -export { SecurityScanError } from '../codewhisperer/models/errors' +export { SecurityScanError, SecurityScanTimedOutError } from '../codewhisperer/models/errors' export * as CodeWhispererConstants from '../codewhisperer/models/constants' export { getSelectedCustomization, setSelectedCustomization, baseCustomization } from './util/customizationUtil' export { Container } from './service/serviceContainer' diff --git a/packages/core/src/codewhisperer/models/constants.ts b/packages/core/src/codewhisperer/models/constants.ts index 46dfc83e026..a811022ac97 100644 --- a/packages/core/src/codewhisperer/models/constants.ts +++ b/packages/core/src/codewhisperer/models/constants.ts @@ -258,9 +258,9 @@ export const codeScanZipExt = '.zip' export const contextTruncationTimeoutSeconds = 10 -export const codeScanJobTimeoutSeconds = 60 * 10 // 10 minutes +export const standardScanTimeoutMs = 600_000 // 10 minutes -export const codeFileScanJobTimeoutSeconds = 60 * 10 // 10 minutes +export const expressScanTimeoutMs = 60_000 export const codeFixJobTimeoutMs = 60_000 diff --git a/packages/core/src/codewhisperer/service/securityScanHandler.ts b/packages/core/src/codewhisperer/service/securityScanHandler.ts index ab9e637e519..22f5fa30e60 100644 --- a/packages/core/src/codewhisperer/service/securityScanHandler.ts +++ b/packages/core/src/codewhisperer/service/securityScanHandler.ts @@ -403,10 +403,7 @@ function getPollingDelayMsForScope(scope: CodeWhispererConstants.CodeAnalysisSco } function getPollingTimeoutMsForScope(scope: CodeWhispererConstants.CodeAnalysisScope) { - return ( - (scope === CodeWhispererConstants.CodeAnalysisScope.FILE_AUTO || - scope === CodeWhispererConstants.CodeAnalysisScope.FILE_ON_DEMAND - ? CodeWhispererConstants.codeFileScanJobTimeoutSeconds - : CodeWhispererConstants.codeScanJobTimeoutSeconds) * 1000 - ) + return scope === CodeWhispererConstants.CodeAnalysisScope.FILE_AUTO + ? CodeWhispererConstants.expressScanTimeoutMs + : CodeWhispererConstants.standardScanTimeoutMs } diff --git a/packages/core/src/shared/index.ts b/packages/core/src/shared/index.ts index a4f35d525c6..ea73349e817 100644 --- a/packages/core/src/shared/index.ts +++ b/packages/core/src/shared/index.ts @@ -22,6 +22,7 @@ export { getMachineId } from './vscode/env' export { getLogger } from './logger/logger' export { activateExtension, openUrl } from './utilities/vsCodeUtils' export { waitUntil, sleep, Timeout } from './utilities/timeoutUtils' +export * as timeoutUtils from './utilities/timeoutUtils' export { Prompter } from './ui/prompter' export { VirtualFileSystem } from './virtualFilesystem' export { VirtualMemoryFile } from './virtualMemoryFile'