Skip to content

Commit 9cf1786

Browse files
committed
fix the bug which might cause user can not execute the build command & add telemetry for build&execute
1 parent b5de261 commit 9cf1786

File tree

5 files changed

+168
-68
lines changed

5 files changed

+168
-68
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mockitoKotlin = "5.4.0"
2727
mockk = "1.13.10"
2828
nimbus-jose-jwt = "9.40"
2929
node-gradle = "7.0.2"
30-
telemetryGenerator = "1.0.297"
30+
telemetryGenerator = "1.0.299"
3131
testLogger = "4.0.0"
3232
testRetry = "1.5.10"
3333
# test-only; platform provides slf4j transitively at runtime

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

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -589,25 +589,46 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin
589589
canBeVoted = false
590590
)
591591
)
592+
if(session.iteration == 1){
593+
AmazonqTelemetry.utgGenerateTests(
594+
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
595+
hasUserPromptSupplied = session.hasUserPromptSupplied,
596+
isFileInWorkspace = true,
597+
isSupportedLanguage = true,
598+
credentialStartUrl = getStartUrl(project),
599+
jobGroup = session.testGenerationJobGroupName,
600+
jobId = session.testGenerationJob,
601+
result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed,
602+
reason = (e as CodeTestException).code ?: "DefaultError",
603+
reasonDesc = if (e.message == message("testgen.message.cancelled")) "${e.code}: ${e.message}" else e.message,
604+
perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration),
605+
isCodeBlockSelected = session.isCodeBlockSelected,
606+
artifactsUploadDuration = session.artifactUploadDuration,
607+
buildPayloadBytes = session.srcPayloadSize,
608+
buildZipFileBytes = session.srcZipFileSize,
609+
requestId = session.startTestGenerationRequestId
610+
)
611+
612+
}else{
613+
AmazonqTelemetry.unitTestGeneration(
614+
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
615+
hasUserPromptSupplied = session.hasUserPromptSupplied,
616+
isSupportedLanguage = true,
617+
credentialStartUrl = getStartUrl(project),
618+
jobGroup = session.testGenerationJobGroupName,
619+
jobId = session.testGenerationJob,
620+
result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed,
621+
reason = (e as CodeTestException).code ?: "DefaultError",
622+
reasonDesc = if (e.message == message("testgen.message.cancelled")) "${e.code}: ${e.message}" else e.message,
623+
perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration),
624+
isCodeBlockSelected = session.isCodeBlockSelected,
625+
artifactsUploadDuration = session.artifactUploadDuration,
626+
buildZipFileBytes = session.srcZipFileSize,
627+
requestId = session.startTestGenerationRequestId
628+
)
629+
}
630+
592631

593-
AmazonqTelemetry.utgGenerateTests(
594-
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
595-
hasUserPromptSupplied = session.hasUserPromptSupplied,
596-
isFileInWorkspace = true,
597-
isSupportedLanguage = true,
598-
credentialStartUrl = getStartUrl(project),
599-
jobGroup = session.testGenerationJobGroupName,
600-
jobId = session.testGenerationJob,
601-
result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed,
602-
reason = (e as CodeTestException).code ?: "DefaultError",
603-
reasonDesc = if (e.message == message("testgen.message.cancelled")) "${e.code}: ${e.message}" else e.message,
604-
perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration),
605-
isCodeBlockSelected = session.isCodeBlockSelected,
606-
artifactsUploadDuration = session.artifactUploadDuration,
607-
buildPayloadBytes = session.srcPayloadSize,
608-
buildZipFileBytes = session.srcZipFileSize,
609-
requestId = session.startTestGenerationRequestId
610-
)
611632
session.isGeneratingTests = false
612633
} finally {
613634
// Reset the flow if there is any error

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

Lines changed: 110 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class CodeTestChatController(
116116
private val authController: AuthController = AuthController(),
117117
private val cs: CoroutineScope,
118118
) : InboundAppMessagesHandler {
119+
var buildResult = false
119120
val messenger = context.messagesFromAppToUi
120121
private val codeTestChatHelper = CodeTestChatHelper(context.messagesFromAppToUi, chatSessionStorage)
121122
private val supportedLanguage = setOf("python", "java")
@@ -666,28 +667,59 @@ class CodeTestChatController(
666667

667668
UiTelemetry.click(null as Project?, "unitTestGeneration_acceptDiff")
668669

669-
AmazonqTelemetry.utgGenerateTests(
670-
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
671-
hasUserPromptSupplied = session.hasUserPromptSupplied,
672-
isFileInWorkspace = true,
673-
isSupportedLanguage = true,
674-
credentialStartUrl = getStartUrl(project = context.project),
675-
jobGroup = session.testGenerationJobGroupName,
676-
jobId = session.testGenerationJob,
677-
acceptedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
678-
generatedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
679-
acceptedLinesCount = session.linesOfCodeGenerated?.toLong(),
680-
generatedLinesCount = session.linesOfCodeGenerated?.toLong(),
681-
acceptedCharactersCount = session.charsOfCodeGenerated?.toLong(),
682-
generatedCharactersCount = session.charsOfCodeGenerated?.toLong(),
683-
result = MetricResult.Succeeded,
684-
perfClientLatency = session.latencyOfTestGeneration,
685-
isCodeBlockSelected = session.isCodeBlockSelected,
686-
artifactsUploadDuration = session.artifactUploadDuration,
687-
buildPayloadBytes = session.srcPayloadSize,
688-
buildZipFileBytes = session.srcZipFileSize,
689-
requestId = session.startTestGenerationRequestId
690-
)
670+
if(session.iteration == 1){
671+
AmazonqTelemetry.utgGenerateTests(
672+
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
673+
hasUserPromptSupplied = session.hasUserPromptSupplied,
674+
isFileInWorkspace = true,
675+
isSupportedLanguage = true,
676+
credentialStartUrl = getStartUrl(project = context.project),
677+
jobGroup = session.testGenerationJobGroupName,
678+
jobId = session.testGenerationJob,
679+
acceptedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
680+
generatedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
681+
acceptedLinesCount = session.linesOfCodeGenerated?.toLong(),
682+
generatedLinesCount = session.linesOfCodeGenerated?.toLong(),
683+
acceptedCharactersCount = session.charsOfCodeGenerated?.toLong(),
684+
generatedCharactersCount = session.charsOfCodeGenerated?.toLong(),
685+
result = MetricResult.Succeeded,
686+
perfClientLatency = session.latencyOfTestGeneration,
687+
isCodeBlockSelected = session.isCodeBlockSelected,
688+
artifactsUploadDuration = session.artifactUploadDuration,
689+
buildPayloadBytes = session.srcPayloadSize,
690+
buildZipFileBytes = session.srcZipFileSize,
691+
requestId = session.startTestGenerationRequestId
692+
)
693+
}else{
694+
AmazonqTelemetry.unitTestGeneration(
695+
count = session.iteration.toLong() - 1,
696+
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
697+
hasUserPromptSupplied = session.hasUserPromptSupplied,
698+
isSupportedLanguage = true,
699+
credentialStartUrl = getStartUrl(project = context.project),
700+
jobGroup = session.testGenerationJobGroupName,
701+
jobId = session.testGenerationJob,
702+
acceptedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
703+
generatedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
704+
acceptedLinesCount = session.linesOfCodeGenerated?.toLong(),
705+
generatedLinesCount = session.linesOfCodeGenerated?.toLong(),
706+
acceptedCharactersCount = session.charsOfCodeGenerated?.toLong(),
707+
generatedCharactersCount = session.charsOfCodeGenerated?.toLong(),
708+
result = if(buildResult){
709+
MetricResult.Succeeded
710+
}else{
711+
MetricResult.Failed
712+
},
713+
perfClientLatency = session.latencyOfTestGeneration,
714+
isCodeBlockSelected = session.isCodeBlockSelected,
715+
artifactsUploadDuration = session.artifactUploadDuration,
716+
buildZipFileBytes = session.srcZipFileSize,
717+
requestId = session.startTestGenerationRequestId,
718+
update = session.updateBuildCommands,
719+
)
720+
}
721+
722+
691723
codeTestChatHelper.addAnswer(
692724
CodeTestChatMessageContent(
693725
message = message("testgen.message.success"),
@@ -784,11 +816,10 @@ class CodeTestChatController(
784816
)
785817
} else {
786818
// TODO: change this hardcoded string
787-
val monthlyLimitString = "25 out of 30"
788819
codeTestChatHelper.addAnswer(
789820
CodeTestChatMessageContent(
790821
message = """
791-
You have gone through all three iterations and this unit test generation workflow is complete. You have $monthlyLimitString Amazon Q Developer Agent invocations left this month.
822+
You have gone through both iterations and this unit test generation workflow is complete.
792823
""".trimIndent(),
793824
type = ChatMessageType.Answer,
794825
)
@@ -863,28 +894,58 @@ class CodeTestChatController(
863894
}
864895

865896
UiTelemetry.click(null as Project?, "unitTestGeneration_rejectDiff")
866-
AmazonqTelemetry.utgGenerateTests(
867-
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
868-
hasUserPromptSupplied = session.hasUserPromptSupplied,
869-
isFileInWorkspace = true,
870-
isSupportedLanguage = true,
871-
credentialStartUrl = getStartUrl(project = context.project),
872-
jobGroup = session.testGenerationJobGroupName,
873-
jobId = session.testGenerationJob,
874-
acceptedCount = 0,
875-
generatedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
876-
acceptedLinesCount = 0,
877-
generatedLinesCount = session.linesOfCodeGenerated?.toLong(),
878-
acceptedCharactersCount = 0,
879-
generatedCharactersCount = session.charsOfCodeGenerated?.toLong(),
880-
result = MetricResult.Succeeded,
881-
perfClientLatency = session.latencyOfTestGeneration,
882-
isCodeBlockSelected = session.isCodeBlockSelected,
883-
artifactsUploadDuration = session.artifactUploadDuration,
884-
buildPayloadBytes = session.srcPayloadSize,
885-
buildZipFileBytes = session.srcZipFileSize,
886-
requestId = session.startTestGenerationRequestId
887-
)
897+
if(session.iteration == 1){
898+
AmazonqTelemetry.utgGenerateTests(
899+
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
900+
hasUserPromptSupplied = session.hasUserPromptSupplied,
901+
isFileInWorkspace = true,
902+
isSupportedLanguage = true,
903+
credentialStartUrl = getStartUrl(project = context.project),
904+
jobGroup = session.testGenerationJobGroupName,
905+
jobId = session.testGenerationJob,
906+
acceptedCount = 0,
907+
generatedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
908+
acceptedLinesCount = 0,
909+
generatedLinesCount = session.linesOfCodeGenerated?.toLong(),
910+
acceptedCharactersCount = 0,
911+
generatedCharactersCount = session.charsOfCodeGenerated?.toLong(),
912+
result = MetricResult.Succeeded,
913+
perfClientLatency = session.latencyOfTestGeneration,
914+
isCodeBlockSelected = session.isCodeBlockSelected,
915+
artifactsUploadDuration = session.artifactUploadDuration,
916+
buildPayloadBytes = session.srcPayloadSize,
917+
buildZipFileBytes = session.srcZipFileSize,
918+
requestId = session.startTestGenerationRequestId
919+
)
920+
}else{
921+
AmazonqTelemetry.unitTestGeneration(
922+
count = session.iteration.toLong() - 1,
923+
cwsprChatProgrammingLanguage = session.programmingLanguage.languageId,
924+
hasUserPromptSupplied = session.hasUserPromptSupplied,
925+
isSupportedLanguage = true,
926+
credentialStartUrl = getStartUrl(project = context.project),
927+
jobGroup = session.testGenerationJobGroupName,
928+
jobId = session.testGenerationJob,
929+
acceptedCount = 0,
930+
generatedCount = session.numberOfUnitTestCasesGenerated?.toLong(),
931+
acceptedLinesCount = 0,
932+
generatedLinesCount = session.linesOfCodeGenerated?.toLong(),
933+
acceptedCharactersCount = 0,
934+
generatedCharactersCount = session.charsOfCodeGenerated?.toLong(),
935+
result = if(buildResult){
936+
MetricResult.Succeeded
937+
}else{
938+
MetricResult.Failed
939+
},
940+
perfClientLatency = session.latencyOfTestGeneration,
941+
isCodeBlockSelected = session.isCodeBlockSelected,
942+
artifactsUploadDuration = session.artifactUploadDuration,
943+
buildZipFileBytes = session.srcZipFileSize,
944+
requestId = session.startTestGenerationRequestId,
945+
update = session.updateBuildCommands,
946+
)
947+
}
948+
888949
sessionCleanUp(message.tabId)
889950
}
890951
"utg_skip_and_finish" -> {
@@ -922,7 +983,7 @@ class CodeTestChatController(
922983
"tmpFile for build logs:\n ${buildLogsFile.path}"
923984
}
924985

925-
runBuildOrTestCommand(taskContext.buildCommand, buildLogsFile, context.project, isBuildCommand = true, taskContext, session.projectRoot)
986+
runBuildOrTestCommand(taskContext.buildCommand, buildLogsFile, context.project, isBuildCommand = true, taskContext, session.testFileRelativePathToProjectRoot)
926987
while (taskContext.buildExitCode < 0) {
927988
// wait until build command finished
928989
delay(1000)
@@ -938,6 +999,7 @@ class CodeTestChatController(
938999
canBeVoted = false
9391000
)
9401001
)
1002+
buildResult = true
9411003
sessionCleanUp(message.tabId)
9421004
return
9431005
}
@@ -1029,6 +1091,7 @@ class CodeTestChatController(
10291091
}
10301092
"utg_modify_command" -> {
10311093
// TODO allow user input to modify the command
1094+
session.updateBuildCommands = true
10321095
codeTestChatHelper.addAnswer(
10331096
CodeTestChatMessageContent(
10341097
message = """

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ data class Session(val tabId: String) {
3333
var srcPayloadSize: Long = 0
3434
var srcZipFileSize: Long = 0
3535
var artifactUploadDuration: Long = 0
36+
var updateBuildCommands : Boolean = false
3637

3738
// First iteration will have a value of 1
3839
var userPrompt: String = ""

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,27 @@ fun runBuildOrTestCommand(
9090
project: Project,
9191
isBuildCommand: Boolean,
9292
buildAndExecuteTaskContext: BuildAndExecuteTaskContext,
93-
projectRoot: String,
93+
testFileRelativePathToProjectRoot: String,
9494
) {
9595
if (localCommand.isEmpty()) {
9696
buildAndExecuteTaskContext.testExitCode = 0
9797
return
9898
}
99+
val projectRoot = File(project.basePath ?: return)
100+
val testFileAbsolutePath = File(projectRoot, testFileRelativePathToProjectRoot)
101+
102+
// Find the nearest Gradle root directory
103+
var packageRoot: File? = testFileAbsolutePath.parentFile
104+
while (packageRoot != null && packageRoot != projectRoot) {
105+
if (File(packageRoot, "settings.gradle.kts").exists() || File(packageRoot, "build.gradle.kts").exists()) {
106+
break // top when we find a valid Gradle project root
107+
}
108+
packageRoot = packageRoot.parentFile
109+
}
110+
111+
// If no valid Gradle directory is found, fallback to the project root
112+
val workingDir = packageRoot ?: projectRoot
113+
println("Running command in directory: ${workingDir.absolutePath}")
99114
// val repositoryPath = project.basePath ?: return
100115
val commandParts = localCommand.split(" ")
101116
val command = commandParts.first()
@@ -116,7 +131,7 @@ fun runBuildOrTestCommand(
116131

117132
val processBuilder = ProcessBuilder()
118133
.command(listOf("zsh", "-c", "source ~/.zshrc && $command ${args.joinToString(" ")}"))
119-
.directory(File(projectRoot))
134+
.directory(packageRoot)
120135
.redirectErrorStream(true)
121136

122137
val env = processBuilder.environment()

0 commit comments

Comments
 (0)