diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/ArtifactHandler.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/ArtifactHandler.kt index fbbfadcc99..11accfd610 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/ArtifactHandler.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/ArtifactHandler.kt @@ -39,6 +39,7 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.model.DownloadFai import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId import software.aws.toolkits.jetbrains.services.codemodernizer.model.ParseZipFailureReason import software.aws.toolkits.jetbrains.services.codemodernizer.model.UnzipFailureReason +import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeModernizerSessionState import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getPathToHilArtifactDir import software.aws.toolkits.jetbrains.services.codemodernizer.utils.isValidCodeTransformConnection import software.aws.toolkits.jetbrains.services.codemodernizer.utils.openTroubleshootingGuideNotificationAction @@ -199,6 +200,17 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G downloadedBuildLogPath[job] = path } else { downloadedArtifacts[job] = path + if (output.artifact is CodeModernizerArtifact && output.artifact.metrics != null) { + output.artifact.metrics.linesOfCodeSubmitted = CodeModernizerSessionState.getInstance(project).getLinesOfCodeSubmitted() + output.artifact.metrics.programmingLanguage = CodeModernizerSessionState.getInstance(project).getTransformationLanguage() + try { + clientAdaptor.sendTransformTelemetryEvent(job, output.artifact.metrics) + } catch (e: Exception) { + // log error, but can still show diff.patch and summary.md + LOG.error { e.message.toString() } + telemetryErrorMessage = "Unexpected error when sending telemetry with metrics ${e.localizedMessage}" + } + } } output } catch (e: RuntimeException) { diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/client/GumbyClient.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/client/GumbyClient.kt index 2d83779d9c..c4378c9077 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/client/GumbyClient.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/client/GumbyClient.kt @@ -16,6 +16,7 @@ import software.amazon.awssdk.services.codewhispererruntime.model.GetTransformat import software.amazon.awssdk.services.codewhispererruntime.model.GetTransformationPlanResponse import software.amazon.awssdk.services.codewhispererruntime.model.GetTransformationRequest import software.amazon.awssdk.services.codewhispererruntime.model.GetTransformationResponse +import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory import software.amazon.awssdk.services.codewhispererruntime.model.ResumeTransformationRequest import software.amazon.awssdk.services.codewhispererruntime.model.ResumeTransformationResponse import software.amazon.awssdk.services.codewhispererruntime.model.StartTransformationRequest @@ -46,8 +47,11 @@ import software.aws.toolkits.jetbrains.services.amazonq.CONTENT_SHA256 import software.aws.toolkits.jetbrains.services.amazonq.SERVER_SIDE_ENCRYPTION import software.aws.toolkits.jetbrains.services.amazonq.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID import software.aws.toolkits.jetbrains.services.amazonq.clients.AmazonQStreamingClient +import software.aws.toolkits.jetbrains.services.amazonq.codeWhispererUserContext +import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerMetrics import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId import software.aws.toolkits.jetbrains.services.codemodernizer.utils.calculateTotalLatency +import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getTelemetryOptOutPreference import java.io.File import java.net.HttpURLConnection import java.time.Instant @@ -210,6 +214,26 @@ class GumbyClient(private val project: Project) { } } + fun sendTransformTelemetryEvent(job: JobId, metrics: CodeModernizerMetrics) { + bearerClient().sendTelemetryEvent { requestBuilder -> + requestBuilder.telemetryEvent { telemetryEventBuilder -> + telemetryEventBuilder.transformEvent { + it.jobId(job.id) + it.timestamp(Instant.now()) + it.ideCategory(IdeCategory.JETBRAINS) + it.programmingLanguage { language -> + language.languageName(metrics.programmingLanguage) + } + it.linesOfCodeChanged(metrics.linesOfCodeChanged) + it.charsOfCodeChanged(metrics.charactersOfCodeChanged) + it.linesOfCodeSubmitted(metrics.linesOfCodeSubmitted) // currently unavailable for SQL conversions + } + } + requestBuilder.optOutPreference(getTelemetryOptOutPreference()) + requestBuilder.userContext(codeWhispererUserContext()) + } + } + companion object { private val LOG = getLogger() diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerArtifact.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerArtifact.kt index cd9f6ae8fe..ed3c0723d2 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerArtifact.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerArtifact.kt @@ -5,6 +5,7 @@ package software.aws.toolkits.jetbrains.services.codemodernizer.model import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue import com.intellij.openapi.util.io.FileUtil.createTempDirectory import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VirtualFile @@ -29,17 +30,19 @@ open class CodeModernizerArtifact( private val patches: List, val summary: TransformationSummary, val summaryMarkdownFile: File, + val metrics: CodeModernizerMetrics?, ) : CodeTransformDownloadArtifact { val patch: VirtualFile get() = patches.first() companion object { - private const val maxSupportedVersion = 1.0 + private const val MAX_SUPPORTED_VERSION = 1.0 private val tempDir = createTempDirectory("codeTransformArtifacts", null) - private const val manifestPathInZip = "manifest.json" - private const val summaryNameInZip = "summary.md" + private const val MANIFEST_FILE_NAME = "manifest.json" + private const val SUMMARY_FILE_NAME = "summary.md" + private const val METRICS_FILE_NAME = "metrics.json" val LOG = getLogger() - private val MAPPER = jacksonObjectMapper() + val MAPPER = jacksonObjectMapper() /** * Extracts the file at [zipPath] and uses its contents to produce a [CodeModernizerArtifact]. @@ -53,28 +56,29 @@ open class CodeModernizerArtifact( throw RuntimeException("Could not unzip artifact") } val manifest = loadManifest() - if (manifest.version > maxSupportedVersion) { + if (manifest.version > MAX_SUPPORTED_VERSION) { // If not supported we can still try to use it, i.e. the versions should largely be backwards compatible - LOG.warn { "Unsupported version: ${manifest.version}" } + LOG.warn { "Unsupported manifest.json version: ${manifest.version}" } } val patches = extractPatches(manifest) val summary = extractSummary(manifest) val summaryMarkdownFile = getSummaryFile(manifest) + val metrics = loadMetrics(manifest) if (patches.size != 1) throw RuntimeException("Expected 1 patch, but found ${patches.size}") - return CodeModernizerArtifact(zipPath, manifest, patches, summary, summaryMarkdownFile) + return CodeModernizerArtifact(zipPath, manifest, patches, summary, summaryMarkdownFile, metrics) } throw RuntimeException("Could not find artifact") } private fun extractSummary(manifest: CodeModernizerManifest): TransformationSummary { - val summaryFile = tempDir.toPath().resolve(manifest.summaryRoot).resolve(summaryNameInZip).toFile() + val summaryFile = tempDir.toPath().resolve(manifest.summaryRoot).resolve(SUMMARY_FILE_NAME).toFile() if (!summaryFile.exists() || summaryFile.isDirectory) { throw RuntimeException("The summary in the downloaded zip had an unknown format") } return TransformationSummary(summaryFile.readText()) } - private fun getSummaryFile(manifest: CodeModernizerManifest) = tempDir.toPath().resolve(manifest.summaryRoot).resolve(summaryNameInZip).toFile() + private fun getSummaryFile(manifest: CodeModernizerManifest) = tempDir.toPath().resolve(manifest.summaryRoot).resolve(SUMMARY_FILE_NAME).toFile() /** * Attempts to load the manifest from the zip file. Throws an exception if the manifest is not found or cannot be serialized. @@ -82,10 +86,10 @@ open class CodeModernizerArtifact( private fun loadManifest(): CodeModernizerManifest { val manifestFile = tempDir.listFiles() - ?.firstOrNull { it.name.endsWith(manifestPathInZip) } + ?.firstOrNull { it.name.endsWith(MANIFEST_FILE_NAME) } ?: throw RuntimeException("Could not find manifest") try { - val manifest = MAPPER.readValue(manifestFile, CodeModernizerManifest::class.java) + val manifest = MAPPER.readValue(manifestFile) if (manifest.version == 0.0F) { throw RuntimeException( "Unable to deserialize the manifest", @@ -97,6 +101,19 @@ open class CodeModernizerArtifact( } } + private fun loadMetrics(manifest: CodeModernizerManifest): CodeModernizerMetrics? { + try { + val metricsFile = + tempDir.resolve(manifest.metricsRoot).listFiles() + ?.firstOrNull { it.name.endsWith(METRICS_FILE_NAME) } + ?: throw RuntimeException("Could not find metrics.json") + return MAPPER.readValue(metricsFile) + } catch (exception: Exception) { + // if metrics.json not present or parsing fails, can still show diff.patch and summary.md + return null + } + } + @OptIn(ExperimentalPathApi::class) private fun extractPatches(manifest: CodeModernizerManifest): List { val fileSystem = LocalFileSystem.getInstance() diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerManifest.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerManifest.kt index a09ded600c..be4bc0303a 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerManifest.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerManifest.kt @@ -6,4 +6,4 @@ package software.aws.toolkits.jetbrains.services.codemodernizer.model import com.fasterxml.jackson.annotation.JsonIgnoreProperties @JsonIgnoreProperties(ignoreUnknown = true) -data class CodeModernizerManifest(val version: Float, val patchesRoot: String, val artifactsRoot: String, val summaryRoot: String) +data class CodeModernizerManifest(val version: Float, val patchesRoot: String, val artifactsRoot: String, val summaryRoot: String, val metricsRoot: String) diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerMetrics.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerMetrics.kt new file mode 100644 index 0000000000..748604c785 --- /dev/null +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerMetrics.kt @@ -0,0 +1,14 @@ +// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.codemodernizer.model + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties + +@JsonIgnoreProperties(ignoreUnknown = true) +data class CodeModernizerMetrics( + val linesOfCodeChanged: Int?, + val charactersOfCodeChanged: Int?, + var linesOfCodeSubmitted: Int?, + var programmingLanguage: String?, +) diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/plan/CodeModernizerPlanEditor.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/plan/CodeModernizerPlanEditor.kt index 1130d0dd76..f55ac25645 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/plan/CodeModernizerPlanEditor.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/plan/CodeModernizerPlanEditor.kt @@ -3,7 +3,6 @@ package software.aws.toolkits.jetbrains.services.codemodernizer.plan -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.intellij.ide.BrowserUtil import com.intellij.openapi.fileEditor.FileEditor @@ -22,11 +21,14 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.constants.APPENDI import software.aws.toolkits.jetbrains.services.codemodernizer.constants.CodeModernizerUIConstants import software.aws.toolkits.jetbrains.services.codemodernizer.constants.JOB_STATISTICS_TABLE_KEY import software.aws.toolkits.jetbrains.services.codemodernizer.constants.LOC_THRESHOLD +import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerArtifact.Companion.MAPPER import software.aws.toolkits.jetbrains.services.codemodernizer.model.PlanTable import software.aws.toolkits.jetbrains.services.codemodernizer.plan.CodeModernizerPlanEditorProvider.Companion.MIGRATION_PLAN_KEY import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getAuthType import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getBillingText +import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getLinesOfCodeSubmitted import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getTableMapping +import software.aws.toolkits.jetbrains.services.codemodernizer.utils.parseTableMapping import software.aws.toolkits.jetbrains.services.codewhisperer.layout.CodeWhispererLayoutConfig.addHorizontalGlue import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.CredentialSourceId @@ -59,13 +61,7 @@ import javax.swing.table.DefaultTableModel class CodeModernizerPlanEditor(val project: Project, private val virtualFile: VirtualFile) : UserDataHolderBase(), FileEditor { val plan = virtualFile.getUserData(MIGRATION_PLAN_KEY) ?: throw RuntimeException("Migration plan not found") - private val tableMapping = - if (!plan.transformationSteps()[0].progressUpdates().isNullOrEmpty()) { - getTableMapping(plan.transformationSteps()[0].progressUpdates()) - } else { - throw RuntimeException("GetPlan response missing step 0 progress updates with table data") - } - private val mapper = jacksonObjectMapper() + private val tableMapping = getTableMapping(plan.transformationSteps()[0].progressUpdates()) // to-do: convert to UI DSL private val contentPanel = @@ -79,8 +75,8 @@ class CodeModernizerPlanEditor(val project: Project, private val virtualFile: Vi // key "0" reserved for job statistics table // comes from "name" field of each progressUpdate in step zero of plan if (JOB_STATISTICS_TABLE_KEY in tableMapping) { - val planTable = mapper.readValue(tableMapping[JOB_STATISTICS_TABLE_KEY], PlanTable::class.java) - val linesOfCode = planTable.rows.find { it.name == "linesOfCode" }?.value?.toInt() + val planTable = parseTableMapping(tableMapping) + val linesOfCode = planTable?.let { getLinesOfCodeSubmitted(it) } if (linesOfCode != null && linesOfCode > LOC_THRESHOLD && getAuthType(project) == CredentialSourceId.IamIdentityCenter) { val billingText = getBillingText(linesOfCode) val billingTextComponent = @@ -102,7 +98,7 @@ class CodeModernizerPlanEditor(val project: Project, private val virtualFile: Vi add(billingTextComponent, CodeModernizerUIConstants.transformationPlanPlaneConstraint) } add( - transformationPlanInfo(planTable), + planTable?.let { transformationPlanInfo(it) }, CodeModernizerUIConstants.transformationPlanPlaneConstraint, ) } @@ -110,7 +106,7 @@ class CodeModernizerPlanEditor(val project: Project, private val virtualFile: Vi // key "-1" reserved for appendix table if (APPENDIX_TABLE_KEY in tableMapping) { add( - transformationPlanAppendix(mapper.readValue(tableMapping[APPENDIX_TABLE_KEY], PlanTable::class.java)), + tableMapping[APPENDIX_TABLE_KEY]?.let { MAPPER.readValue(it) }?.let { transformationPlanAppendix(it) }, CodeModernizerUIConstants.transformationPlanPlaneConstraint, ) } @@ -400,7 +396,7 @@ class CodeModernizerPlanEditor(val project: Project, private val virtualFile: Vi val table = tableMapping[step.id()] val parsedTable = table?.let { - mapper.readValue(it) + MAPPER.readValue(it) } val renderedStepTable = parsedTable?.let { diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/state/CodeModernizerSessionState.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/state/CodeModernizerSessionState.kt index decbda8bf2..7725a2c74d 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/state/CodeModernizerSessionState.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/state/CodeModernizerSessionState.kt @@ -12,6 +12,9 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModerni import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerSessionContext import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobHistoryItem import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId +import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getLinesOfCodeSubmitted +import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getTableMapping +import software.aws.toolkits.jetbrains.services.codemodernizer.utils.parseTableMapping import java.time.Duration import java.time.Instant import kotlin.io.path.Path @@ -55,4 +58,14 @@ class CodeModernizerSessionState { } fun getJobHistory(): Array = previousJobHistory.values.toTypedArray() + + // LOC submitted only available for Java upgrades + fun getLinesOfCodeSubmitted(): Int? { + val tableMapping = transformationPlan?.transformationSteps()?.get(0)?.let { getTableMapping(it.progressUpdates()) } + val planTable = tableMapping?.let { parseTableMapping(it) } + return planTable?.let { getLinesOfCodeSubmitted(it) } + } + + // we only create a transformationPlan for Java upgrades + fun getTransformationLanguage(): String = if (transformationPlan != null) "JAVA" else "SQL" } diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/utils/CodeTransformApiUtils.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/utils/CodeTransformApiUtils.kt index c033eec192..5e0d43d9b4 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/utils/CodeTransformApiUtils.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/utils/CodeTransformApiUtils.kt @@ -3,6 +3,7 @@ package software.aws.toolkits.jetbrains.services.codemodernizer.utils +import com.fasterxml.jackson.module.kotlin.readValue import com.intellij.openapi.project.Project import com.intellij.serviceContainer.AlreadyDisposedException import kotlinx.coroutines.delay @@ -23,7 +24,10 @@ import software.aws.toolkits.core.utils.Waiters.waitUntil import software.aws.toolkits.jetbrains.services.codemodernizer.CodeTransformTelemetryManager import software.aws.toolkits.jetbrains.services.codemodernizer.client.GumbyClient import software.aws.toolkits.jetbrains.services.codemodernizer.constants.BILLING_RATE +import software.aws.toolkits.jetbrains.services.codemodernizer.constants.JOB_STATISTICS_TABLE_KEY +import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerArtifact.Companion.MAPPER import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId +import software.aws.toolkits.jetbrains.services.codemodernizer.model.PlanTable import software.aws.toolkits.resources.message import java.time.Duration import java.util.Locale @@ -128,11 +132,23 @@ suspend fun JobId.pollTransformationStatusAndPlan( } // "name" holds the ID of the corresponding plan step (where table will go) and "description" holds the plan data -fun getTableMapping(stepZeroProgressUpdates: List) = stepZeroProgressUpdates.associate { - it.name() to it.description() +fun getTableMapping(stepZeroProgressUpdates: List): Map { + if (stepZeroProgressUpdates.isNotEmpty()) { + return stepZeroProgressUpdates.associate { + it.name() to it.description() + } + } else { + error("GetPlan response missing step 0 progress updates with table data") + } } +fun parseTableMapping(tableMapping: Map): PlanTable? = + tableMapping[JOB_STATISTICS_TABLE_KEY]?.let { MAPPER.readValue(it) } + fun getBillingText(linesOfCode: Int): String { val estimatedCost = String.format(Locale.US, "%.2f", linesOfCode.times(BILLING_RATE)) return message("codemodernizer.migration_plan.header.billing_text", linesOfCode, BILLING_RATE, estimatedCost) } + +fun getLinesOfCodeSubmitted(planTable: PlanTable) = + planTable.rows.find { it.name == "linesOfCode" }?.value?.toInt() diff --git a/plugins/amazonq/codetransform/jetbrains-community/tst-resources/codemodernizer/simple.zip b/plugins/amazonq/codetransform/jetbrains-community/tst-resources/codemodernizer/simple.zip index 88f3ae3961..0d7bc0cdef 100644 Binary files a/plugins/amazonq/codetransform/jetbrains-community/tst-resources/codemodernizer/simple.zip and b/plugins/amazonq/codetransform/jetbrains-community/tst-resources/codemodernizer/simple.zip differ diff --git a/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTest.kt b/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTest.kt index 0f657f2d27..f2c4f993b1 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTest.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTest.kt @@ -155,7 +155,7 @@ class CodeWhispererCodeModernizerTest : CodeWhispererCodeModernizerTestBase() { fun `CodeModernizerArtifact can process a valid zip file`() { val artifact = CodeModernizerArtifact.create(exampleZipPath.toAbsolutePath().toString()) assertEquals(validManifest, artifact.manifest) - assertEquals(validTransformationSummary, artifact.summary) + assertEquals(validMetrics.linesOfCodeChanged, artifact.metrics?.linesOfCodeChanged) } @Test diff --git a/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTestBase.kt b/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTestBase.kt index 8b489b74d8..5ec2dd198f 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTestBase.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerTestBase.kt @@ -52,6 +52,7 @@ import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenPr import software.aws.toolkits.jetbrains.services.codemodernizer.client.GumbyClient import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerArtifact import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerManifest +import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerMetrics import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerSessionContext import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeTransformFailureBuildLog import software.aws.toolkits.jetbrains.services.codemodernizer.model.CustomerSelection @@ -105,6 +106,7 @@ open class CodeWhispererCodeModernizerTestBase( internal val validZipSummaryPath = "summary/" internal val validZipManifestPath = "manifest.json" internal val validZipPatchFilePath = "patch/diff.patch" + internal val validZipMetricsPath = "metrics/" internal val validZipManifestVersion = 1.0F internal val validManifest = CodeModernizerManifest( @@ -112,6 +114,7 @@ open class CodeWhispererCodeModernizerTestBase( validZipPatchDirPath, validZipArtifactsPath, validZipSummaryPath, + validZipMetricsPath ) internal val validTransformationSummary = TransformationSummary( @@ -128,6 +131,14 @@ open class CodeWhispererCodeModernizerTestBase( """.trimIndent(), ) + internal val validMetrics = + CodeModernizerMetrics( + charactersOfCodeChanged = 1234, + linesOfCodeChanged = 119, + linesOfCodeSubmitted = 567, + programmingLanguage = "JAVA", + ) + internal val exampleCreateUploadUrlResponse = CreateUploadUrlResponse.builder() .uploadUrl("https://smth.com") @@ -280,6 +291,7 @@ open class CodeWhispererCodeModernizerTestBase( listOf(examplePatchVirtualFile), validTransformationSummary, summaryFileMock, + validMetrics ), ) testTransformFailureBuildLog =