Skip to content

Commit 5dc5e84

Browse files
authored
Merge branch 'main' into finding-telemetry
2 parents 5c7447a + 1bd99f4 commit 5dc5e84

File tree

28 files changed

+1228
-49
lines changed

28 files changed

+1228
-49
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "/review: normalize relative file path before unzipping"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "fix Q chat request timeout"
4+
}

buildspec/linuxIntegrationTests.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ phases:
1515
install:
1616
commands:
1717
- startDocker.sh
18-
# login to DockerHub so we don't get throttled
19-
- export DOCKER_USERNAME=`echo $DOCKER_HUB_TOKEN | jq -r '.username'`
20-
- export DOCKER_PASSWORD=`echo $DOCKER_HUB_TOKEN | jq -r '.password'`
21-
- docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD || true
2218
# should probably be managed as an extension/rule in any tests that need a screen available
2319
- /usr/bin/Xvfb :22 -screen 0 1920x1080x24 &
2420

buildspec/linuxUiTests.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@ phases:
2121
commands:
2222
- dnf install -y marco mate-media e2fsprogs
2323
- startDesktop.sh
24-
25-
# login to DockerHub so we don't get throttled
26-
- export DOCKER_USERNAME=`echo $DOCKER_HUB_TOKEN | jq -r '.username'`
27-
- export DOCKER_PASSWORD=`echo $DOCKER_HUB_TOKEN | jq -r '.password'`
28-
- docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD || true
2924
- export PATH="$PATH:$HOME/.dotnet/tools"
3025
- dotnet codeartifact-creds install
3126

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ kotlin = "2.0.0"
2424
kotlinCoroutines = "1.8.0"
2525
mockito = "5.12.0"
2626
mockitoKotlin = "5.4.0"
27-
mockk = "1.13.10"
27+
mockk = "1.13.17"
2828
nimbus-jose-jwt = "9.40"
2929
node-gradle = "7.0.2"
3030
telemetryGenerator = "1.0.307"

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import software.aws.toolkits.core.utils.debug
2929
import software.aws.toolkits.core.utils.error
3030
import software.aws.toolkits.core.utils.getLogger
3131
import software.aws.toolkits.core.utils.info
32+
import software.aws.toolkits.jetbrains.core.credentials.sono.isInternalUser
3233
import software.aws.toolkits.jetbrains.services.amazonq.clients.AmazonQStreamingClient
3334
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.controller.CodeTestChatHelper
3435
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.Button
@@ -55,6 +56,7 @@ import software.aws.toolkits.jetbrains.utils.isQConnected
5556
import software.aws.toolkits.resources.message
5657
import software.aws.toolkits.telemetry.AmazonqTelemetry
5758
import software.aws.toolkits.telemetry.MetricResult
59+
import software.aws.toolkits.telemetry.Status
5860
import java.io.ByteArrayInputStream
5961
import java.io.ByteArrayOutputStream
6062
import java.io.File
@@ -558,12 +560,25 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin
558560
e is JsonParseException -> message("testgen.error.generic_technical_error_message")
559561
else -> message("testgen.error.generic_error_message")
560562
}
561-
563+
val buttonList = mutableListOf<Button>()
564+
if (isInternalUser(getStartUrl(project))) {
565+
buttonList.add(
566+
Button(
567+
"utg_feedback",
568+
message("testgen.button.feedback"),
569+
keepCardAfterClick = true,
570+
position = "outside",
571+
status = "info",
572+
icon = "comment"
573+
),
574+
)
575+
}
562576
codeTestChatHelper.addAnswer(
563577
CodeTestChatMessageContent(
564578
message = errorMessage,
565579
type = ChatMessageType.Answer,
566-
canBeVoted = false
580+
canBeVoted = false,
581+
buttons = buttonList
567582
)
568583
)
569584

@@ -583,7 +598,8 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin
583598
artifactsUploadDuration = session.artifactUploadDuration,
584599
buildPayloadBytes = session.srcPayloadSize,
585600
buildZipFileBytes = session.srcZipFileSize,
586-
requestId = session.startTestGenerationRequestId
601+
requestId = session.startTestGenerationRequestId,
602+
status = if (e.message == message("testgen.message.cancelled")) Status.CANCELLED else Status.FAILED,
587603
)
588604
session.isGeneratingTests = false
589605
} finally {

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.intellij.diff.DiffManagerEx
99
import com.intellij.diff.requests.SimpleDiffRequest
1010
import com.intellij.ide.BrowserUtil
1111
import com.intellij.openapi.application.ApplicationManager
12+
import com.intellij.openapi.application.runInEdt
1213
import com.intellij.openapi.fileEditor.FileEditorManager
1314
import com.intellij.openapi.project.Project
1415
import com.intellij.openapi.project.guessProjectDir
@@ -53,6 +54,7 @@ import software.aws.toolkits.jetbrains.core.AwsClientManager
5354
import software.aws.toolkits.jetbrains.core.coroutines.EDT
5455
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
5556
import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
57+
import software.aws.toolkits.jetbrains.core.credentials.sono.isInternalUser
5658
import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext
5759
import software.aws.toolkits.jetbrains.services.amazonq.auth.AuthController
5860
import software.aws.toolkits.jetbrains.services.amazonq.project.RelevantDocument
@@ -92,12 +94,14 @@ import software.aws.toolkits.jetbrains.services.cwc.editor.context.ExtractionTri
9294
import software.aws.toolkits.jetbrains.services.cwc.editor.context.file.FileContext
9395
import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessageType
9496
import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService
97+
import software.aws.toolkits.jetbrains.ui.feedback.TestGenFeedbackDialog
9598
import software.aws.toolkits.jetbrains.utils.notifyError
9699
import software.aws.toolkits.resources.message
97100
import software.aws.toolkits.telemetry.AmazonqTelemetry
98101
import software.aws.toolkits.telemetry.FeatureId
99102
import software.aws.toolkits.telemetry.InteractionType
100103
import software.aws.toolkits.telemetry.MetricResult
104+
import software.aws.toolkits.telemetry.Status
101105
import software.aws.toolkits.telemetry.UiTelemetry
102106
import java.io.File
103107
import java.nio.file.Files
@@ -167,13 +171,14 @@ class CodeTestChatController(
167171
override suspend fun processStartTestGen(message: IncomingCodeTestMessage.StartTestGen) {
168172
codeTestChatHelper.setActiveCodeTestTabId(message.tabId)
169173
val session = codeTestChatHelper.getActiveSession()
174+
if (session.isGeneratingTests) {
175+
return
176+
}
177+
sessionCleanUp(session.tabId)
170178
// check if IDE has active file open, yes return (fileName and filePath) else return null
171179
val project = context.project
172180
val fileInfo = checkActiveFileInIDE(project, message) ?: return
173181
session.programmingLanguage = fileInfo.fileLanguage
174-
if (session.isGeneratingTests === true) {
175-
return
176-
}
177182
session.startTimeOfTestGeneration = Instant.now().toEpochMilli().toDouble()
178183
session.isGeneratingTests = true
179184

@@ -310,7 +315,8 @@ class CodeTestChatController(
310315
credentialStartUrl = getStartUrl(project),
311316
result = MetricResult.Succeeded,
312317
perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration),
313-
requestId = id
318+
requestId = id,
319+
status = Status.ACCEPTED,
314320
)
315321
}
316322
session.isGeneratingTests = false
@@ -563,7 +569,7 @@ class CodeTestChatController(
563569
session.linesOfCodeGenerated = lineDifference.coerceAtLeast(0)
564570
session.charsOfCodeGenerated = charDifference.coerceAtLeast(0)
565571
session.latencyOfTestGeneration = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration)
566-
UiTelemetry.click(null as Project?, "unitTestGeneration_viewDiff")
572+
UiTelemetry.click(context.project, "unitTestGeneration_viewDiff")
567573

568574
val buttonList = mutableListOf<Button>()
569575
buttonList.add(
@@ -660,7 +666,7 @@ class CodeTestChatController(
660666
testGenerationEventResponse.responseMetadata().requestId()}"
661667
}
662668

663-
UiTelemetry.click(null as Project?, "unitTestGeneration_acceptDiff")
669+
UiTelemetry.click(context.project, "unitTestGeneration_acceptDiff")
664670

665671
AmazonqTelemetry.utgGenerateTests(
666672
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
@@ -682,16 +688,17 @@ class CodeTestChatController(
682688
artifactsUploadDuration = session.artifactUploadDuration,
683689
buildPayloadBytes = session.srcPayloadSize,
684690
buildZipFileBytes = session.srcZipFileSize,
685-
requestId = session.startTestGenerationRequestId
691+
requestId = session.startTestGenerationRequestId,
692+
status = Status.ACCEPTED,
686693
)
687694
codeTestChatHelper.addAnswer(
688695
CodeTestChatMessageContent(
689696
message = message("testgen.message.success"),
690697
type = ChatMessageType.Answer,
691-
canBeVoted = false
698+
canBeVoted = false,
699+
buttons = this.showFeedbackButton()
692700
)
693701
)
694-
sessionCleanUp(session.tabId)
695702
codeTestChatHelper.updateUI(
696703
promptInputDisabledState = false,
697704
promptInputPlaceholder = message("testgen.placeholder.enter_slash_quick_actions"),
@@ -837,7 +844,8 @@ class CodeTestChatController(
837844
CodeTestChatMessageContent(
838845
message = message("testgen.message.success"),
839846
type = ChatMessageType.Answer,
840-
canBeVoted = false
847+
canBeVoted = false,
848+
buttons = this.showFeedbackButton()
841849
)
842850
)
843851
val testGenerationEventResponse = client.sendTestGenerationEvent(
@@ -878,9 +886,13 @@ class CodeTestChatController(
878886
artifactsUploadDuration = session.artifactUploadDuration,
879887
buildPayloadBytes = session.srcPayloadSize,
880888
buildZipFileBytes = session.srcZipFileSize,
881-
requestId = session.startTestGenerationRequestId
889+
requestId = session.startTestGenerationRequestId,
890+
status = Status.REJECTED,
882891
)
883-
sessionCleanUp(message.tabId)
892+
}
893+
"utg_feedback" -> {
894+
sendFeedback()
895+
UiTelemetry.click(context.project, "unitTestGeneration_provideFeedback")
884896
}
885897
"utg_skip_and_finish" -> {
886898
codeTestChatHelper.addAnswer(
@@ -1369,6 +1381,33 @@ class CodeTestChatController(
13691381
println(message)
13701382
}
13711383

1384+
private fun sendFeedback() {
1385+
runInEdt {
1386+
TestGenFeedbackDialog(
1387+
context.project,
1388+
codeTestChatHelper.getActiveSession().startTestGenerationRequestId,
1389+
codeTestChatHelper.getActiveSession().testGenerationJob
1390+
).show()
1391+
}
1392+
}
1393+
1394+
private fun showFeedbackButton(): MutableList<Button> {
1395+
val buttonList = mutableListOf<Button>()
1396+
if (isInternalUser(getStartUrl(context.project))) {
1397+
buttonList.add(
1398+
Button(
1399+
"utg_feedback",
1400+
message("testgen.button.feedback"),
1401+
keepCardAfterClick = true,
1402+
position = "outside",
1403+
status = "info",
1404+
icon = "comment"
1405+
),
1406+
)
1407+
}
1408+
return buttonList
1409+
}
1410+
13721411
companion object {
13731412
private val LOG = getLogger<CodeTestChatController>()
13741413

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/ChatConstants.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
package software.aws.toolkits.jetbrains.services.cwc
55

66
object ChatConstants {
7-
const val REQUEST_TIMEOUT_MS = 60_000 // 60 seconds
7+
const val REQUEST_TIMEOUT_MS = 180_000 // 180 seconds
88

99
// API Constraints
1010
const val FILE_PATH_SIZE_LIMIT = 4_000 // Maximum length of file paths in characters (actual API limit: 4096)

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.utils.Ama
3030
import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
3131
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererUnknownLanguage
3232
import software.aws.toolkits.jetbrains.services.codewhisperer.language.programmingLanguage
33-
import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeWhispererTelemetryService
3433
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.CODE_SCAN_CREATE_PAYLOAD_TIMEOUT_IN_SECONDS
3534
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.CodeAnalysisScope
3635
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_CODE_SCAN_TIMEOUT_IN_SECONDS
3736
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_PAYLOAD_LIMIT_IN_BYTES
3837
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.EXPRESS_SCAN_TIMEOUT_IN_SECONDS
3938
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.FILE_SCAN_PAYLOAD_SIZE_LIMIT_IN_BYTES
39+
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getNormalizedRelativePath
4040
import software.aws.toolkits.jetbrains.services.codewhisperer.util.GitIgnoreFilteringUtil
4141
import software.aws.toolkits.jetbrains.services.codewhisperer.util.isWithin
4242
import software.aws.toolkits.resources.message
@@ -196,12 +196,9 @@ class CodeScanSessionConfig(
196196
private fun zipFiles(files: List<Path>, codeDiff: String? = null): File = createTemporaryZipFile {
197197
files.forEach { file ->
198198
try {
199-
val relativePath = "${project.name}/${file.relativeTo(projectRoot.toNioPath())}"
200-
if (relativePath.contains("../") || relativePath.contains("..\\")) {
201-
CodeWhispererTelemetryService.getInstance().sendInvalidZipEvent(file, projectRoot.toNioPath(), relativePath)
202-
}
199+
val relativePath = getNormalizedRelativePath(project.name, file.relativeTo(projectRoot.toNioPath()))
203200
LOG.debug { "Selected file for truncation: $file" }
204-
it.putNextEntry(relativePath.toString(), file)
201+
it.putNextEntry(relativePath, file)
205202
} catch (e: Exception) {
206203
cannotFindFile("Zipping error: ${e.message}", file.pathString)
207204
}

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererUtil.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ import software.aws.toolkits.resources.message
5656
import software.aws.toolkits.telemetry.CodewhispererCompletionType
5757
import software.aws.toolkits.telemetry.CodewhispererGettingStartedTask
5858
import software.aws.toolkits.telemetry.CredentialSourceId
59+
import java.nio.file.Path
60+
import java.nio.file.Paths
5961

6062
// Controls the condition to send telemetry event to CodeWhisperer service, currently:
6163
// 1. It will be sent for Builder ID users, only if they have optin telemetry sharing.
@@ -329,6 +331,9 @@ object CodeWhispererUtil {
329331
WindowManager.getInstance().setAlphaModeRatio(it, alpha)
330332
}
331333
}
334+
335+
fun getNormalizedRelativePath(projectName: String, relativePath: Path): String =
336+
Paths.get(projectName).resolve(relativePath).normalize().toString()
332337
}
333338

334339
enum class CaretMovement {

0 commit comments

Comments
 (0)