-
Notifications
You must be signed in to change notification settings - Fork 269
feat(amazonq): Adding UTG build and execute logic back for internal Amazon customers. #5396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(amazonq): Adding UTG build and execute logic back for internal Amazon customers. #5396
Conversation
.../src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt
Fixed
Show fixed
Hide fixed
@@ -25,15 +28,19 @@ | |||
BuildAndExecuteStatusIcon.WAIT.icon | |||
} else if (progressStatus == BuildAndExecuteProgressStatus.RUN_EXECUTION_TESTS) { | |||
BuildAndExecuteStatusIcon.CURRENT.icon | |||
} else if (progressStatus == BuildAndExecuteProgressStatus.BUILD_FAILED || progressStatus == BuildAndExecuteProgressStatus.FIXING_TEST_CASES) { |
Check warning
Code scanning / QDJVMC
Constant conditions
val buildLogFilePath = Path.of(utgDir, buildAndExecuteLogDir, "buildAndExecuteLog") | ||
.toString().replace("\\", "/") // Ensures consistent path format | ||
|
||
LOG.debug { "Adding build logs to ZIP at: $buildLogFilePath" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this log?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this log to make sure the build log is added to the currect folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but we should not print this out for the customers. So, we can remove this.
|
||
return | ||
} | ||
// taskContext.progressStatus = BuildAndExecuteProgressStatus.RUN_EXECUTION_TESTS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this commented code? as this is being added as part of this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this commented code is for execution loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like a bad practice to leave commented out code as future TODO. Can you put it in a different branch and PR when ready? lets not add clutter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this code, anyway we will have git history to track.
@@ -821,13 +828,12 @@ class CodeTestChatController( | |||
"Successfully sent test generation telemetry. RequestId: ${ | |||
testGenerationEventResponse.responseMetadata().requestId()}" | |||
} | |||
sessionCleanUp(session.tabId) | |||
// sessionCleanUp(session.tabId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented code.
@@ -691,24 +695,27 @@ class CodeTestChatController( | |||
canBeVoted = false | |||
) | |||
) | |||
sessionCleanUp(session.tabId) | |||
if (!isInternalUser) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you test this by login with Builder Id vs internal user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
.../src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt
Show resolved
Hide resolved
@@ -175,7 +179,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin | |||
var shortAnswer = ShortAnswer() | |||
LOG.debug { | |||
"Q TestGen session: ${codeTestChatHelper.getActiveCodeTestTabId()}: " + | |||
"polling result for id: ${job.testGenerationJobId()}, group name: ${job.testGenerationJobGroupName()}, " + | |||
"polling result for id: ${job.testGenerationJobId()}, group name: ${session.testGenerationJobGroupName}, " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: not required as both job.testGenerationJobGroupName()
and session.testGenerationJobGroupName
will be same
@@ -250,10 +255,9 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin | |||
if (shortAnswer.stopIteration == "true") { | |||
throw CodeTestException("TestGenFailedError: ${shortAnswer.planSummary}", "TestGenFailedError", shortAnswer.planSummary) | |||
} | |||
val fileName = shortAnswer.sourceFilePath?.let { Path.of(it).fileName.toString() } ?: path.fileName.toString() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did we remove this check? Any reason?
codeTestChatHelper.updateAnswer( | ||
CodeTestChatMessageContent( | ||
message = generateSummaryMessage(fileName) + shortAnswer.planSummary, | ||
message = generateSummaryMessage(path.fileName.toString()) + shortAnswer.planSummary, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if user opens test file and run /test
. This says Generating unit test for Test file but this should be Source file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when user opens test file and run /test there, if this says Generating unit test for Test file, that's expected right? Because utg is generating unit test for opening files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this code change is from me, I rebased from main and the code change is there. Maybe @ashishrp-aws or @chungjac has more info about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add this back?
Looks like it was removed as part of this PR
@@ -297,7 +301,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin | |||
// TODO: Modify text according to FnF | |||
codeTestChatHelper.addAnswer( | |||
CodeTestChatMessageContent( | |||
message = message("testgen.error.generic_technical_error_message"), | |||
message = message("testgen.message.failed"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this necessary?
We should show users
I am experiencing technical difficulties at the moment. Please try again …
instead of Test generation failed
previousIterationContext?.buildLogFile, | ||
previousIterationContext?.testLogFile | ||
) | ||
val combinedBuildAndExecuteLogFile = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
variable declaration is not needed here, if required can we change variable name to buildLogFile etc..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I keeped this in case we need excute in the future, will do it in the next pr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
...-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/utils/UTGChatUtil.kt
Show resolved
Hide resolved
bfac8e6
to
24a0832
Compare
taskContext.progressStatus = BuildAndExecuteProgressStatus.FIXING_TEST_CASES | ||
val buildAndExecuteMessageId = updateBuildAndExecuteProgressCard(taskContext.progressStatus, messageId, session.iteration) | ||
// TODO: only go to future iterations when buildExitCode or testExitCode > 0, right now iterate regardless | ||
if (taskContext.buildExitCode > 0) { |
Check warning
Code scanning / QDJVMC
Constant conditions
83095f6
to
b5de261
Compare
…& add telemetry for build&execute
.../src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt
Fixed
Show fixed
Hide fixed
...oftware/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt
Fixed
Show fixed
Hide fixed
requestId = session.startTestGenerationRequestId | ||
) | ||
if (session.iteration == 1) { | ||
AmazonqTelemetry.utgGenerateTests( |
Check warning
Code scanning / QDJVMC
Usage of redundant or deprecated syntax or deprecated symbols
|
||
// Find the nearest Gradle root directory | ||
var packageRoot: File? = testFileAbsolutePath.parentFile | ||
while (packageRoot != null && packageRoot != projectRoot) { |
Check warning
Code scanning / QDJVMC
File.equals() usage
c14981b
to
84062da
Compare
84062da
to
b5792bc
Compare
@@ -469,10 +473,8 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin | |||
previousIterationContext.selectedFile | |||
} | |||
|
|||
val combinedBuildAndExecuteLogFile = combineBuildAndExecuteLogFiles( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove combineBuildAndExecuteLogFiles
function as this is not being used
val buildLogFilePath = Path.of(utgDir, buildAndExecuteLogDir, "buildAndExecuteLog") | ||
.toString().replace("\\", "/") // Ensures consistent path format | ||
|
||
LOG.debug { "Adding build logs to ZIP at: $buildLogFilePath" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but we should not print this out for the customers. So, we can remove this.
|
||
return | ||
} | ||
// taskContext.progressStatus = BuildAndExecuteProgressStatus.RUN_EXECUTION_TESTS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this code, anyway we will have git history to track.
.../src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt
Show resolved
Hide resolved
codeTestChatHelper.updateAnswer( | ||
CodeTestChatMessageContent( | ||
message = generateSummaryMessage(fileName) + shortAnswer.planSummary, | ||
message = generateSummaryMessage(path.fileName.toString()) + shortAnswer.planSummary, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add this back?
Looks like it was removed as part of this PR
promptInputDisabledState = true, | ||
promptInputProgress = buildAndExecuteProgrogressField, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can optimize this!
codeTestChatHelper.updateUI(
promptInputDisabledState = true,
promptInputProgress = if (session.iteration == 1) {
testGenProgressField(0)
} else {
buildAndExecuteProgrogressField
}
)
...-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/utils/UTGChatUtil.kt
Show resolved
Hide resolved
...oftware/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt
Show resolved
Hide resolved
.../src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt
Show resolved
Hide resolved
// Find the nearest Gradle root directory | ||
var packageRoot: File? = testFileAbsolutePath.parentFile | ||
while (packageRoot != null && packageRoot != projectRoot) { | ||
if (File(packageRoot, "settings.gradle.kts").exists() || File(packageRoot, "build.gradle.kts").exists()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if you're using the groovy version of the gradle build script?
...-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/utils/UTGChatUtil.kt
Outdated
Show resolved
Hide resolved
packageRoot = packageRoot.parentFile | ||
} | ||
|
||
// If no valid Gradle directory is found, fallback to the project root |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? does that actually make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just in case no gradle files are found.
@@ -109,10 +130,14 @@ fun runBuildOrTestCommand( | |||
} | |||
|
|||
val processBuilder = ProcessBuilder() | |||
.command(listOf(command) + args) | |||
.directory(File(repositoryPath)) | |||
.command(listOf("zsh", "-c", "source ~/.zshrc && $command ${args.joinToString(" ")}")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if they are on windows? or don't use zsh?
...-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/utils/UTGChatUtil.kt
Outdated
Show resolved
Hide resolved
78d4edf
to
9e323fe
Compare
5ddf101
to
3601d49
Compare
) { | ||
val brazilPath = "${System.getProperty("user.home")}/.toolbox/bin:/usr/local/bin:/usr/bin:/bin:/sbin" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we hardcoding internal user paths
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rli
I think this is to get the path to access the bb
, else it always throws an error saying bb command not found
while running build and execute commands.
credentialStartUrl = getStartUrl(project), | ||
jobGroup = session.testGenerationJobGroupName, | ||
jobId = session.testGenerationJob, | ||
result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed, |
Check warning
Code scanning / QDJVMC
Usage of redundant or deprecated syntax or deprecated symbols
jobId = session.testGenerationJob, | ||
result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed, | ||
reason = (e as CodeTestException).code ?: "DefaultError", | ||
reasonDesc = if (e.message == message("testgen.message.cancelled")) "${e.code}: ${e.message}" else e.message, |
Check warning
Code scanning / QDJVMC
Usage of redundant or deprecated syntax or deprecated symbols
@@ -114,6 +116,7 @@ | |||
private val authController: AuthController = AuthController(), | |||
private val cs: CoroutineScope, | |||
) : InboundAppMessagesHandler { | |||
var buildResult = false |
Check warning
Code scanning / QDJVMC
Unused symbol
"utg_skip_and_finish" -> { | ||
codeTestChatHelper.addAnswer( | ||
CodeTestChatMessageContent( | ||
message = message("testgen.message.success"), |
Check warning
Code scanning / QDJVMC
Usage of redundant or deprecated syntax or deprecated symbols
2c3ddba
to
b5f6ce1
Compare
// If no valid Gradle directory is found, fallback to the project root | ||
val gradleWrapper = File(packageRoot, "gradlew") | ||
val workingDir = if (gradleWrapper.exists()) packageRoot else projectRoot | ||
val gradleWrapper = File(packageRoot ?: projectRoot, "gradlew") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where we are using this gradleWrapper?
Types of changes
Description
This PR introduces a build-exec loop for internal Amazon users, allowing them to run a customized build command after Amazon Q generates unit tests. The goal is to ensure that the newly generated unit tests do not break the initial build.
Solution
Adding back build and execute logic for internal amazon users to fix the errors when generating unit tests. Allow users to run 3 iterations to fix the codes if there are any issues cause build failure.

TO-DO
Checklist
License
I confirm that my contribution is made under the terms of the Apache 2.0 license.