Skip to content

Commit b165a7b

Browse files
Muzaffer AydinMuzaffer Aydin
authored andcommitted
Merge branch 'master' into muaydin/docdb-polling-bug-fix
2 parents 3ef2673 + c32c8f0 commit b165a7b

File tree

23 files changed

+191
-330
lines changed

23 files changed

+191
-330
lines changed

buildspec/linuxE2ETests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ phases:
3737
commands:
3838
- export HOME=/home/codebuild-user
3939
# Ignore failure until throttling issues are fixed.
40-
- xvfb-run npm run testE2E
40+
- xvfb-run npm run testE2E; npm run mergeReports -- "$?"
4141
- VCS_COMMIT_ID="${CODEBUILD_RESOLVED_SOURCE_VERSION}"
4242
- CI_BUILD_URL=$(echo $CODEBUILD_BUILD_URL | sed 's/#/%23/g')
4343
- CI_BUILD_ID="${CODEBUILD_BUILD_ID}"

buildspec/linuxIntegrationTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ phases:
9292
build:
9393
commands:
9494
- export HOME=/home/codebuild-user
95-
- xvfb-run npm run testInteg
95+
- xvfb-run npm run testInteg; npm run mergeReports -- "$?"
9696
- VCS_COMMIT_ID="${CODEBUILD_RESOLVED_SOURCE_VERSION}"
9797
- CI_BUILD_URL=$(echo $CODEBUILD_BUILD_URL | sed 's/#/%23/g')
9898
- CI_BUILD_ID="${CODEBUILD_BUILD_ID}"

buildspec/linuxTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ phases:
4141
# Ensure that "foo | run_and_report" fails correctly.
4242
set -o pipefail
4343
. buildspec/shared/common.sh
44-
2>&1 xvfb-run npm test --silent | run_and_report 2 \
44+
{ 2>&1 xvfb-run npm test --silent; npm run mergeReports -- "$?"; } | run_and_report 2 \
4545
'rejected promise not handled' \
4646
'This typically indicates a bug. Read https://developer.mozilla.org/docs/Web/JavaScript/Guide/Using_promises#error_handling'
4747
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"lintfix": "eslint -c .eslintrc.js --ignore-path .gitignore --ignore-pattern '**/*.json' --ignore-pattern '**/*.gen.ts' --ignore-pattern '**/types/*.d.ts' --ignore-pattern '**/src/testFixtures/**' --ignore-pattern '**/resources/js/graphStateMachine.js' --fix --ext .ts packages plugins",
3737
"clean": "npm run clean -w packages/ -w plugins/",
3838
"reset": "npm run clean && ts-node ./scripts/clean.ts node_modules && npm install",
39-
"generateNonCodeFiles": "npm run generateNonCodeFiles -w packages/ --if-present"
39+
"generateNonCodeFiles": "npm run generateNonCodeFiles -w packages/ --if-present",
40+
"mergeReports": "ts-node ./scripts/mergeReports.ts"
4041
},
4142
"devDependencies": {
4243
"@aws-toolkits/telemetry": "^1.0.289",
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Removal",
3+
"description": "Settings: No longer migrate old CodeWhisperer settings or initialize telemetry setting from AWS Toolkit."
4+
}

packages/amazonq/test/unit/codewhisperer/util/zipUtil.test.ts

Lines changed: 34 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import vscode from 'vscode'
88
import sinon from 'sinon'
99
import { join } from 'path'
1010
import { getTestWorkspaceFolder } from 'aws-core-vscode/test'
11-
import { CodeAnalysisScope, ZipUtil } from 'aws-core-vscode/codewhisperer'
11+
import { CodeAnalysisScope, CodeWhispererConstants, ZipUtil } from 'aws-core-vscode/codewhisperer'
1212
import { codeScanTruncDirPrefix } from 'aws-core-vscode/codewhisperer'
13-
import { ToolkitError } from 'aws-core-vscode/shared'
13+
import { tempDirPath, ToolkitError } from 'aws-core-vscode/shared'
1414
import { LspClient } from 'aws-core-vscode/amazonq'
1515
import { fs } from 'aws-core-vscode/shared'
1616
import path from 'path'
@@ -142,97 +142,58 @@ describe('zipUtil', function () {
142142

143143
describe('generateZipTestGen', function () {
144144
let zipUtil: ZipUtil
145-
let mockFs: sinon.SinonStubbedInstance<typeof fs>
146-
const projectPath = '/test/project'
147-
const zipDirPath = '/test/zip'
148-
const zipFilePath = '/test/zip/test.zip'
145+
let getZipDirPathStub: sinon.SinonStub
146+
let testTempDirPath: string
149147

150148
beforeEach(function () {
151149
zipUtil = new ZipUtil()
152-
mockFs = sinon.stub(fs)
153-
154-
const mockRepoMapPath = '/path/to/repoMapData.json'
155-
mockFs.exists.withArgs(mockRepoMapPath).resolves(true)
156-
sinon.stub(LspClient, 'instance').get(() => ({
157-
getRepoMapJSON: sinon.stub().resolves(mockRepoMapPath),
158-
}))
159-
160-
sinon.stub(zipUtil, 'getZipDirPath').returns(zipDirPath)
161-
sinon.stub(zipUtil as any, 'zipProject').resolves(zipFilePath)
150+
testTempDirPath = path.join(tempDirPath, CodeWhispererConstants.TestGenerationTruncDirPrefix)
151+
getZipDirPathStub = sinon.stub(zipUtil, 'getZipDirPath')
152+
getZipDirPathStub.callsFake(() => testTempDirPath)
162153
})
163154

164155
afterEach(function () {
165156
sinon.restore()
166157
})
167158

168-
it('Should generate zip for test generation successfully', async function () {
169-
mockFs.stat.resolves({
170-
type: vscode.FileType.File,
171-
size: 1000,
172-
ctime: Date.now(),
173-
mtime: Date.now(),
174-
} as vscode.FileStat)
175-
176-
mockFs.readFileBytes.resolves(Buffer.from('test content'))
159+
it('should generate zip for test generation successfully', async function () {
160+
const mkdirSpy = sinon.spy(fs, 'mkdir')
177161

178-
// Fix: Create a Set from the array
179-
zipUtil['_totalSize'] = 500
180-
zipUtil['_totalBuildSize'] = 200
181-
zipUtil['_totalLines'] = 100
182-
zipUtil['_language'] = 'typescript'
183-
zipUtil['_pickedSourceFiles'] = new Set(['file1.ts', 'file2.ts'])
162+
const result = await zipUtil.generateZipTestGen(appRoot, false)
184163

185-
const result = await zipUtil.generateZipTestGen(projectPath, false)
186-
187-
assert.ok(mockFs.mkdir.calledWith(path.join(zipDirPath, 'utgRequiredArtifactsDir')))
164+
assert.ok(mkdirSpy.calledWith(path.join(testTempDirPath, 'utgRequiredArtifactsDir')))
188165
assert.ok(
189-
mockFs.mkdir.calledWith(path.join(zipDirPath, 'utgRequiredArtifactsDir', 'buildAndExecuteLogDir'))
166+
mkdirSpy.calledWith(path.join(testTempDirPath, 'utgRequiredArtifactsDir', 'buildAndExecuteLogDir'))
190167
)
191-
assert.ok(mockFs.mkdir.calledWith(path.join(zipDirPath, 'utgRequiredArtifactsDir', 'repoMapData')))
192-
assert.ok(mockFs.mkdir.calledWith(path.join(zipDirPath, 'utgRequiredArtifactsDir', 'testCoverageDir')))
193-
194-
// assert.ok(
195-
// mockFs.copy.calledWith(
196-
// '/path/to/repoMapData.json',
197-
// path.join(zipDirPath, 'utgRequiredArtifactsDir', 'repoMapData', 'repoMapData.json')
198-
// )
199-
// )
200-
201-
assert.strictEqual(result.rootDir, zipDirPath)
202-
assert.strictEqual(result.zipFilePath, zipFilePath)
203-
assert.strictEqual(result.srcPayloadSizeInBytes, 500)
204-
assert.strictEqual(result.buildPayloadSizeInBytes, 200)
205-
assert.strictEqual(result.zipFileSizeInBytes, 1000)
206-
assert.strictEqual(result.lines, 100)
207-
assert.strictEqual(result.language, 'typescript')
208-
assert.deepStrictEqual(Array.from(result.scannedFiles), ['file1.ts', 'file2.ts'])
209-
})
210-
211-
// it('Should handle LSP client error', async function () {
212-
// // Override the default stub with one that rejects
213-
// sinon.stub(LspClient, 'instance').get(() => ({
214-
// getRepoMapJSON: sinon.stub().rejects(new Error('LSP error')),
215-
// }))
168+
assert.ok(mkdirSpy.calledWith(path.join(testTempDirPath, 'utgRequiredArtifactsDir', 'repoMapData')))
169+
assert.ok(mkdirSpy.calledWith(path.join(testTempDirPath, 'utgRequiredArtifactsDir', 'testCoverageDir')))
216170

217-
// await assert.rejects(() => zipUtil.generateZipTestGen(projectPath), /LSP error/)
218-
// })
171+
assert.strictEqual(result.rootDir, testTempDirPath)
172+
assert.strictEqual(result.zipFilePath, testTempDirPath + CodeWhispererConstants.codeScanZipExt)
173+
assert.ok(result.srcPayloadSizeInBytes > 0)
174+
assert.strictEqual(result.buildPayloadSizeInBytes, 0)
175+
assert.ok(result.zipFileSizeInBytes > 0)
176+
assert.strictEqual(result.lines, 150)
177+
assert.strictEqual(result.language, 'java')
178+
assert.strictEqual(result.scannedFiles.size, 4)
179+
})
219180

220181
it('Should handle file system errors during directory creation', async function () {
221182
sinon.stub(LspClient, 'instance').get(() => ({
222183
getRepoMapJSON: sinon.stub().resolves('{"mock": "data"}'),
223184
}))
224-
mockFs.mkdir.rejects(new Error('Directory creation failed'))
185+
sinon.stub(fs, 'mkdir').rejects(new Error('Directory creation failed'))
225186

226-
await assert.rejects(() => zipUtil.generateZipTestGen(projectPath, false), /Directory creation failed/)
187+
await assert.rejects(() => zipUtil.generateZipTestGen(appRoot, false), /Directory creation failed/)
227188
})
228189

229190
it('Should handle zip project errors', async function () {
230191
sinon.stub(LspClient, 'instance').get(() => ({
231192
getRepoMapJSON: sinon.stub().resolves('{"mock": "data"}'),
232193
}))
233-
;(zipUtil as any).zipProject.rejects(new Error('Zip failed'))
194+
sinon.stub(zipUtil, 'zipProject' as keyof ZipUtil).rejects(new Error('Zip failed'))
234195

235-
await assert.rejects(() => zipUtil.generateZipTestGen(projectPath, false), /Zip failed/)
196+
await assert.rejects(() => zipUtil.generateZipTestGen(appRoot, false), /Zip failed/)
236197
})
237198

238199
it('Should handle file copy to downloads folder error', async function () {
@@ -241,31 +202,15 @@ describe('zipUtil', function () {
241202
getRepoMapJSON: sinon.stub().resolves('{"mock": "data"}'),
242203
}))
243204

244-
// Mock file operations
245-
const mockFs = {
246-
mkdir: sinon.stub().resolves(),
247-
copy: sinon.stub().rejects(new Error('Copy failed')),
248-
exists: sinon.stub().resolves(true),
249-
stat: sinon.stub().resolves({
250-
type: vscode.FileType.File,
251-
size: 1000,
252-
ctime: Date.now(),
253-
mtime: Date.now(),
254-
} as vscode.FileStat),
255-
}
256-
257-
// Since the function now uses Promise.all for directory creation and file operations,
258-
// we need to ensure the mkdir succeeds but the copy fails
259-
fs.mkdir = mockFs.mkdir
260-
fs.copy = mockFs.copy
261-
fs.exists = mockFs.exists
262-
fs.stat = mockFs.stat
263-
264-
await assert.rejects(() => zipUtil.generateZipTestGen(projectPath, false), /Copy failed/)
205+
const mkdirSpy = sinon.spy(fs, 'mkdir')
206+
sinon.stub(fs, 'exists').resolves(true)
207+
sinon.stub(fs, 'copy').rejects(new Error('Copy failed'))
208+
209+
await assert.rejects(() => zipUtil.generateZipTestGen(appRoot, false), /Copy failed/)
265210

266211
// Verify mkdir was called for all directories
267-
assert(mockFs.mkdir.called, 'mkdir should have been called')
268-
assert.strictEqual(mockFs.mkdir.callCount, 4, 'mkdir should have been called 4 times')
212+
assert(mkdirSpy.called, 'mkdir should have been called')
213+
assert.strictEqual(mkdirSpy.callCount, 4, 'mkdir should have been called 4 times')
269214
})
270215
})
271216
})

packages/core/src/amazonq/explorer/amazonQTreeNode.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as vscode from 'vscode'
77
import { ResourceTreeDataProvider, TreeNode } from '../../shared/treeview/resourceTreeDataProvider'
8-
import { AuthState, isPreviousQUser } from '../../codewhisperer/util/authUtil'
8+
import { AuthState } from '../../codewhisperer/util/authUtil'
99
import { createLearnMoreNode, createInstallQNode, createDismissNode } from './amazonQChildrenNodes'
1010
import { Commands } from '../../shared/vscode/commands2'
1111

@@ -40,10 +40,7 @@ export class AmazonQNode implements TreeNode {
4040
}
4141

4242
public getChildren() {
43-
const children = [createInstallQNode(), createLearnMoreNode()]
44-
if (!isPreviousQUser()) {
45-
children.push(createDismissNode())
46-
}
43+
const children = [createInstallQNode(), createLearnMoreNode(), createDismissNode()]
4744
return children
4845
}
4946

packages/core/src/amazonqGumby/chat/controller/controller.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ import {
5050
CodeTransformJavaTargetVersionsAllowed,
5151
CodeTransformJavaSourceVersionsAllowed,
5252
} from '../../../shared/telemetry/telemetry'
53-
import { MetadataResult } from '../../../shared/telemetry/telemetryClient'
5453
import { CodeTransformTelemetryState } from '../../telemetry/codeTransformTelemetryState'
5554
import DependencyVersions from '../../models/dependencies'
5655
import { getStringHash } from '../../../shared/utilities/textUtilities'
@@ -364,15 +363,16 @@ export class GumbyController {
364363
await this.handleUserLanguageUpgradeProjectChoice(message)
365364
break
366365
case ButtonActions.CANCEL_TRANSFORMATION_FORM:
367-
telemetry.codeTransform_submitSelection.emit({
368-
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
369-
userChoice: 'Cancel',
370-
result: MetadataResult.Pass,
371-
})
372-
this.transformationFinished({
373-
message: CodeWhispererConstants.jobCancelledChatMessage,
374-
tabID: message.tabID,
375-
includeStartNewTransformationButton: true,
366+
telemetry.codeTransform_submitSelection.run(() => {
367+
telemetry.record({
368+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
369+
userChoice: 'Cancel',
370+
})
371+
this.transformationFinished({
372+
message: CodeWhispererConstants.jobCancelledChatMessage,
373+
tabID: message.tabID,
374+
includeStartNewTransformationButton: true,
375+
})
376376
})
377377
break
378378
case ButtonActions.CONFIRM_SKIP_TESTS_FORM:

packages/core/src/auth/auth.ts

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,6 @@ export class Auth implements AuthService, ConnectionManager {
339339
metadata: { connectionState: 'unauthenticated' },
340340
})
341341

342-
// Remove the split session logout prompt, if it exists.
343-
if (!isAmazonQ()) {
344-
await globals.globalState.update('aws.toolkit.separationPromptDismissed', true)
345-
}
346-
347342
try {
348343
;(await tokenProvider.getToken()) ?? (await tokenProvider.createToken())
349344
const storedProfile = await this.store.addProfile(id, profile)
@@ -1136,71 +1131,3 @@ export function hasVendedIamCredentials(isC9?: boolean, isSM?: boolean) {
11361131
isSM ??= isSageMaker()
11371132
return isSM || isC9
11381133
}
1139-
1140-
type LoginCommand = 'aws.toolkit.auth.manageConnections' | 'aws.codecatalyst.manageConnections'
1141-
/**
1142-
* Temporary class that handles notifiting users who were logged out as part of
1143-
* splitting auth sessions between extensions.
1144-
*
1145-
* TODO: Remove after some time.
1146-
*/
1147-
export class SessionSeparationPrompt {
1148-
// Local variable handles per session displays, e.g. we forgot a CodeCatalyst connection AND
1149-
// an Explorer only connection. We only want to display once in this case.
1150-
// However, we don't want to set this at the global state level until a user interacts with the
1151-
// notification in case they miss it the first time.
1152-
#separationPromptDisplayed = false
1153-
1154-
/**
1155-
* Open a prompt for that last used command name (or do nothing if no command name has ever been passed),
1156-
* which is useful to redisplay the prompt after reloads in case a user misses it.
1157-
*/
1158-
public async showAnyPreviousPrompt() {
1159-
const cmd = globals.globalState.tryGet('aws.toolkit.separationPromptCommand', String)
1160-
return cmd ? await this.showForCommand(cmd as LoginCommand) : undefined
1161-
}
1162-
1163-
/**
1164-
* Displays a sign in prompt to the user if they have been logged out of the Toolkit as part of
1165-
* separating auth sessions between extensions. It will executed the passed command for sign in,
1166-
* (e.g. codecatalyst sign in vs explorer)
1167-
*/
1168-
public async showForCommand(cmd: LoginCommand) {
1169-
if (
1170-
this.#separationPromptDisplayed ||
1171-
globals.globalState.get<boolean>('aws.toolkit.separationPromptDismissed')
1172-
) {
1173-
return
1174-
}
1175-
1176-
await globals.globalState.update('aws.toolkit.separationPromptCommand', cmd)
1177-
1178-
await telemetry.toolkit_showNotification.run(async () => {
1179-
telemetry.record({ id: 'sessionSeparation' })
1180-
this.#separationPromptDisplayed = true
1181-
void vscode.window
1182-
.showWarningMessage(
1183-
'Amazon Q and AWS Toolkit no longer share connections. Please sign in again to use AWS Toolkit.',
1184-
'Sign In'
1185-
)
1186-
.then(async (resp) => {
1187-
await telemetry.toolkit_invokeAction.run(async () => {
1188-
telemetry.record({ source: 'sessionSeparationNotification' })
1189-
if (resp === 'Sign In') {
1190-
telemetry.record({ action: 'signIn' })
1191-
await vscode.commands.executeCommand(cmd)
1192-
} else {
1193-
telemetry.record({ action: 'dismiss' })
1194-
}
1195-
1196-
await globals.globalState.update('aws.toolkit.separationPromptDismissed', true)
1197-
})
1198-
})
1199-
})
1200-
}
1201-
1202-
static #instance: SessionSeparationPrompt
1203-
public static get instance() {
1204-
return (this.#instance ??= new SessionSeparationPrompt())
1205-
}
1206-
}

packages/core/src/codecatalyst/activation.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { DevEnvActivityStarter } from './devEnv'
2626
import { learnMoreCommand, onboardCommand, reauth } from './explorer'
2727
import { isInDevEnv } from '../shared/vscode/env'
2828
import { hasScopes, scopesCodeWhispererCore, getTelemetryMetadataForConn } from '../auth/connection'
29-
import { SessionSeparationPrompt } from '../auth/auth'
3029
import { telemetry } from '../shared/telemetry/telemetry'
3130
import { asStringifiedStack } from '../shared/telemetry/spans'
3231

@@ -64,7 +63,6 @@ export async function activate(ctx: ExtContext): Promise<void> {
6463
})
6564

6665
await authProvider.secondaryAuth.forgetConnection()
67-
await SessionSeparationPrompt.instance.showForCommand('aws.codecatalyst.manageConnections')
6866
})
6967
},
7068
{ emit: false, functionId: { name: 'activate', class: 'CodeCatalyst' } }

0 commit comments

Comments
 (0)