From a03e43a269ca92480cc81069200988f8171b0cbc Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Fri, 14 Oct 2022 10:36:38 +0300 Subject: [PATCH 1/5] Rebase onto master --- .gitignore | 2 +- .../org/utbot/framework/process/EngineMain.kt | 14 +-- .../generator/CodeGenerationController.kt | 38 +++++- .../plugin/inspection/AnalyzeStackTraceFix.kt | 45 +++++++ .../inspection/UTBotInspectionContext.kt | 62 ++++++++++ .../inspection/UTBotInspectionManager.kt | 39 ++++++ .../plugin/inspection/UTBotInspectionTool.kt | 115 ++++++++++++++++++ .../UTBotInspectionToolPresentation.kt | 24 ++++ .../plugin/inspection/ViewGeneratedTestFix.kt | 46 +++++++ .../intellij/plugin/process/EngineProcess.kt | 2 +- .../intellij/plugin/sarif/SarifReportIdea.kt | 7 +- .../src/main/resources/META-INF/plugin.xml | 11 ++ .../UnitTestBotInspectionTool.html | 11 ++ .../org/utbot/rd/models/EngineProcessModel.kt | 2 +- 14 files changed, 402 insertions(+), 16 deletions(-) create mode 100644 utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/AnalyzeStackTraceFix.kt create mode 100644 utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt create mode 100644 utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt create mode 100644 utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt create mode 100644 utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt create mode 100644 utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/ViewGeneratedTestFix.kt create mode 100644 utbot-intellij/src/main/resources/inspectionDescriptions/UnitTestBotInspectionTool.html diff --git a/.gitignore b/.gitignore index 011d499004..47b6b875b5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ target/ .idea/ .gradle/ *.log -*.rdgen \ No newline at end of file +*.rdgen diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineMain.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineMain.kt index fe51663852..17c8ea2a92 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineMain.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineMain.kt @@ -176,13 +176,13 @@ private fun EngineProcessModel.setup( synchronizer.measureExecutionForTermination(writeSarifReport) { params -> val reportFilePath = Paths.get(params.reportFilePath) reportFilePath.parent.toFile().mkdirs() - reportFilePath.toFile().writeText( - SarifReport( - testSets[params.testSetsId]!!, - params.generatedTestsCode, - RdSourceFindingStrategyFacade(realProtocol.rdSourceFindingStrategy) - ).createReport().toJson() - ) + val sarifReport = SarifReport( + testSets[params.testSetsId]!!, + params.generatedTestsCode, + RdSourceFindingStrategyFacade(realProtocol.rdSourceFindingStrategy) + ).createReport().toJson() + reportFilePath.toFile().writeText(sarifReport) + sarifReport } synchronizer.measureExecutionForTermination(generateTestReport) { params -> val eventLogMessage = params.eventLogMessage diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt index f651d568e1..bddd4e099e 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt @@ -1,5 +1,6 @@ package org.utbot.intellij.plugin.generator +import com.intellij.analysis.AnalysisScope import com.intellij.codeInsight.CodeInsightUtil import com.intellij.codeInsight.FileModificationService import com.intellij.ide.fileTemplates.FileTemplateManager @@ -51,6 +52,7 @@ import org.utbot.framework.codegen.model.UtilClassKind import org.utbot.framework.codegen.model.UtilClassKind.Companion.UT_UTILS_CLASS_NAME import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.CodegenLanguage +import org.utbot.intellij.plugin.inspection.UTBotInspectionManager import org.utbot.intellij.plugin.models.GenerateTestsModel import org.utbot.intellij.plugin.models.packageName import org.utbot.intellij.plugin.process.EngineProcess @@ -65,6 +67,7 @@ import org.utbot.intellij.plugin.util.IntelliJApiHelper.Target.* import org.utbot.intellij.plugin.util.IntelliJApiHelper.run import org.utbot.intellij.plugin.util.RunConfigurationHelper import org.utbot.intellij.plugin.util.extractClassMethodsIncludingNested +import org.utbot.sarif.Sarif import org.utbot.sarif.SarifReport import java.nio.file.Path import java.util.concurrent.CancellationException @@ -94,6 +97,7 @@ object CodeGenerationController { val allTestPackages = getPackageDirectories(baseTestDirectory) val latch = CountDownLatch(classesWithTests.size) val testFilesPointers = mutableListOf>() + val srcClassPathToSarifReport = mutableMapOf() val utilClassListener = UtilClassListener() var index = 0 for ((srcClass, generateResult) in classesWithTests) { @@ -119,6 +123,7 @@ object CodeGenerationController { cut, testClass, testFilePointer, + srcClassPathToSarifReport, model, latch, utilClassListener, @@ -151,6 +156,7 @@ object CodeGenerationController { UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Start tests with coverage", 0.95) RunConfigurationHelper.runTestsWithCoverage(model, testFilesPointers) } + runInspectionsIfNeeded(model.project, srcClassPathToSarifReport) // TODO proc.forceTermination() UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Start tests with coverage", 1.0) } @@ -161,6 +167,25 @@ object CodeGenerationController { } } + /** + * Runs the UTBot inspection if there are detected errors. + */ + private fun runInspectionsIfNeeded( + project: Project, + srcClassPathToSarifReport: MutableMap + ) { + val sarifHasResults = srcClassPathToSarifReport.any { (_, sarif) -> + sarif.getAllResults().isNotEmpty() + } + if (!sarifHasResults) { + return + } + UTBotInspectionManager + .getInstance(project, srcClassPathToSarifReport) + .createNewGlobalContext() + .doInspections(AnalysisScope(project)) + } + private fun proceedTestReport(proc: EngineProcess, model: GenerateTestsModel) { try { // Parametrized tests are not supported in tests report yet @@ -583,6 +608,7 @@ object CodeGenerationController { classUnderTest: ClassId, testClass: PsiClass, filePointer: SmartPsiElementPointer, + srcClassPathToSarifReport: MutableMap, model: GenerateTestsModel, reportsCountDown: CountDownLatch, utilClassListener: UtilClassListener, @@ -661,7 +687,7 @@ object CodeGenerationController { // uploading formatted code val file = filePointer.containingFile - saveSarifReport( + val sarifReport = saveSarifReport( proc, testSetsId, testClassUpdated, @@ -671,6 +697,9 @@ object CodeGenerationController { file?.text ?: generatedTestsCode, indicator ) + val srcClassPath = srcClass.containingFile.virtualFile.toNioPath() + srcClassPathToSarifReport[srcClassPath] = sarifReport + unblockDocument(testClassUpdated.project, editor.document) } } @@ -707,12 +736,12 @@ object CodeGenerationController { reportsCountDown: CountDownLatch, generatedTestsCode: String, indicator: ProgressIndicator - ) { + ): Sarif { val project = model.project - try { + return try { // saving sarif report - SarifReportIdea.createAndSave(proc, testSetsId, testClassId, model, generatedTestsCode, testClass, reportsCountDown, indicator) + SarifReportIdea.createAndSave(proc, testSetsId, testClassId, model, generatedTestsCode, testClass, reportsCountDown, indicator) } catch (e: Exception) { logger.error(e) { "error in saving sarif report"} showErrorDialogLater( @@ -720,6 +749,7 @@ object CodeGenerationController { message = "Cannot save Sarif report via generated tests: error occurred '${e.message}'", title = "Failed to save Sarif report" ) + Sarif.empty() } } diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/AnalyzeStackTraceFix.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/AnalyzeStackTraceFix.kt new file mode 100644 index 0000000000..0ebb9a5c8e --- /dev/null +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/AnalyzeStackTraceFix.kt @@ -0,0 +1,45 @@ +package org.utbot.intellij.plugin.inspection + +import com.intellij.codeInspection.LocalQuickFix +import com.intellij.codeInspection.ProblemDescriptor +import com.intellij.icons.AllIcons +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.unscramble.AnalyzeStacktraceUtil + +/** + * Button that launches the built-in "Analyze Stack Trace" action. Displayed as a quick fix. + * + * @param exceptionMessage short description of the detected exception. + * @param stackTraceLines list of strings of the form "className.methodName(fileName:lineNumber)". + */ +class AnalyzeStackTraceFix( + private val exceptionMessage: String, + private val stackTraceLines: List +) : LocalQuickFix { + + /** + * Without `invokeLater` the [com.intellij.execution.impl.ConsoleViewImpl.myPredefinedFilters] will not be filled. + * + * See [com.intellij.execution.impl.ConsoleViewImpl.createCompositeFilter] for more details. + */ + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val stackTraceContent = stackTraceLines.joinToString("\n") { "at $it" } + ApplicationManager.getApplication().invokeLater { + AnalyzeStacktraceUtil.addConsole( + /* project = */ project, + /* consoleFactory = */ null, + /* tabTitle = */ "StackTrace", + /* text = */ "$exceptionMessage\n\n$stackTraceContent", + /* icon = */ AllIcons.Actions.Lightning + ) + } + } + + /** + * This text is displayed on the quick fix button. + */ + override fun getName() = "Analyze stack trace" + + override fun getFamilyName() = name +} \ No newline at end of file diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt new file mode 100644 index 0000000000..674b69271d --- /dev/null +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt @@ -0,0 +1,62 @@ +package org.utbot.intellij.plugin.inspection + +import com.intellij.codeInspection.ex.* +import com.intellij.codeInspection.ui.InspectionToolPresentation +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.NotNullLazyValue +import com.intellij.ui.content.ContentManager +import org.utbot.sarif.Sarif +import java.nio.file.Path +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentMap + +/** + * Overrides some methods of [GlobalInspectionContextImpl] to satisfy the logic of [UTBotInspectionTool]. + */ +class UTBotInspectionContext( + project: Project, + contentManager: NotNullLazyValue, + val srcClassPathToSarifReport: MutableMap +) : GlobalInspectionContextImpl(project, contentManager) { + + /** + * See [GlobalInspectionContextImpl.myPresentationMap] for more details. + */ + private val myPresentationMap: ConcurrentMap, InspectionToolPresentation> = + ConcurrentHashMap() + + private val globalInspectionToolWrapper by lazy { + val utbotInspectionTool = UTBotInspectionTool.getInstance(srcClassPathToSarifReport) + GlobalInspectionToolWrapper(utbotInspectionTool).also { + it.initialize(/* context = */ this) + } + } + + /** + * Returns [InspectionProfileImpl] with only one inspection tool - [UTBotInspectionTool]. + */ + override fun getCurrentProfile(): InspectionProfileImpl { + val supplier = InspectionToolsSupplier.Simple(listOf(globalInspectionToolWrapper)) + return InspectionProfileImpl("UTBotInspectionToolProfile", supplier, BASE_PROFILE) + } + + override fun close(noSuspiciousCodeFound: Boolean) { + myPresentationMap.clear() + super.close(noSuspiciousCodeFound) + } + + override fun cleanup() { + myPresentationMap.clear() + super.cleanup() + } + + /** + * Overriding is needed to provide [UTBotInspectionToolPresentation] + * instead of the standard implementation of the [InspectionToolPresentation]. + */ + override fun getPresentation(toolWrapper: InspectionToolWrapper<*, *>): InspectionToolPresentation { + return myPresentationMap.computeIfAbsent(toolWrapper) { + UTBotInspectionToolPresentation(globalInspectionToolWrapper, context = this) + } + } +} diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt new file mode 100644 index 0000000000..813e6d3b65 --- /dev/null +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt @@ -0,0 +1,39 @@ +package org.utbot.intellij.plugin.inspection + +import com.intellij.codeInspection.ex.GlobalInspectionContextImpl +import com.intellij.codeInspection.ex.InspectionManagerEx +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.NotNullLazyValue +import com.intellij.ui.content.ContentManager +import org.utbot.sarif.Sarif +import java.nio.file.Path + +/** + * Overrides some methods of [InspectionManagerEx] to satisfy the logic of [UTBotInspectionTool]. + */ +class UTBotInspectionManager(project: Project) : InspectionManagerEx(project) { + + private var srcClassPathToSarifReport: MutableMap = mutableMapOf() + + companion object { + fun getInstance(project: Project, srcClassPathToSarifReport: MutableMap) = + UTBotInspectionManager(project).also { + it.srcClassPathToSarifReport = srcClassPathToSarifReport + } + } + + /** + * See [InspectionManagerEx.myContentManager] for more details. + */ + private val myContentManager: NotNullLazyValue by lazy { + NotNullLazyValue.createValue { + getProblemsViewContentManager(project) + } + } + + /** + * Overriding is needed to provide [UTBotInspectionContext] instead of [GlobalInspectionContextImpl]. + */ + override fun createNewGlobalContext(): GlobalInspectionContextImpl = + UTBotInspectionContext(project, myContentManager, srcClassPathToSarifReport) +} diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt new file mode 100644 index 0000000000..2777dd08bc --- /dev/null +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt @@ -0,0 +1,115 @@ +package org.utbot.intellij.plugin.inspection + +import com.intellij.codeInspection.* +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiFile +import org.utbot.sarif.Sarif +import org.utbot.sarif.SarifRegion +import org.utbot.sarif.SarifResult +import java.nio.file.Path + +/** + * Global inspection tool that displays detected errors from the SARIF report. + */ +class UTBotInspectionTool : GlobalSimpleInspectionTool() { + + /** + * Map from the path to the class under test to [Sarif] for it. + */ + private var srcClassPathToSarifReport: MutableMap = mutableMapOf() + + companion object { + fun getInstance(srcClassPathToSarifReport: MutableMap) = + UTBotInspectionTool().also { + it.srcClassPathToSarifReport = srcClassPathToSarifReport + } + } + + override fun getShortName() = "UnitTestBotInspectionTool" + + override fun getDisplayName() = "Unchecked exceptions" + + override fun getGroupDisplayName() = "Errors detected by UnitTestBot" + + /** + * Appends all the errors from the SARIF report for [psiFile] to the [problemDescriptionsProcessor]. + */ + override fun checkFile( + psiFile: PsiFile, + manager: InspectionManager, + problemsHolder: ProblemsHolder, + globalContext: GlobalInspectionContext, + problemDescriptionsProcessor: ProblemDescriptionsProcessor + ) { + val sarifReport = srcClassPathToSarifReport[psiFile.virtualFile.toNioPath()] + ?: return // no results for this file + + for (sarifResult in sarifReport.getAllResults()) { + val srcFileLocation = sarifResult.locations.firstOrNull() + ?: continue + + val errorRegion = srcFileLocation.physicalLocation.region + val errorTextRange = getTextRange(problemsHolder.project, psiFile, errorRegion) + + // see `org.utbot.sarif.SarifReport.processUncheckedException` for the message template + val (exceptionMessage, testCaseMessage) = + sarifResult.message.text.split('\n').take(2) + val sarifResultMessage = "$exceptionMessage $testCaseMessage" + + val testFileLocation = sarifResult.relatedLocations.firstOrNull()?.physicalLocation + val viewGeneratedTestFix = testFileLocation?.let { + ViewGeneratedTestFix( + testFileRelativePath = it.artifactLocation.uri, + lineNumber = it.region.startLine, + columnNumber = it.region.startColumn ?: 1 + ) + } + + val stackTraceLines = sarifResult.extractStackTraceLines() + val analyzeStackTraceFix = AnalyzeStackTraceFix(exceptionMessage, stackTraceLines) + + val problemDescriptor = problemsHolder.manager.createProblemDescriptor( + psiFile, + errorTextRange, + sarifResultMessage, + ProblemHighlightType.ERROR, + /* onTheFly = */ true, + viewGeneratedTestFix, + analyzeStackTraceFix + ) + problemDescriptionsProcessor.addProblemElement( + globalContext.refManager.getReference(psiFile), + problemDescriptor + ) + } + } + + // internal + + /** + * Converts [SarifRegion] to the [TextRange] of the given [file]. + */ + private fun getTextRange(project: Project, file: PsiFile, region: SarifRegion): TextRange { + val documentManager = PsiDocumentManager.getInstance(project) + val document = documentManager.getDocument(file.containingFile) + ?: return TextRange.EMPTY_RANGE + + val lineNumber = region.startLine - 1 // to 0-based + val columnNumber = region.startColumn ?: 1 + + val lineStartOffset = document.getLineStartOffset(lineNumber) + columnNumber - 1 + val lineEndOffset = document.getLineEndOffset(lineNumber) + return TextRange(lineStartOffset, lineEndOffset) + } + + private fun SarifResult.extractStackTraceLines(): List = + this.codeFlows.flatMap { sarifCodeFlow -> + sarifCodeFlow.threadFlows.flatMap { sarifThreadFlow -> + sarifThreadFlow.locations.map { sarifFlowLocationWrapper -> + sarifFlowLocationWrapper.location.message.text + } + } + }.reversed() +} diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt new file mode 100644 index 0000000000..7d1d5a69a7 --- /dev/null +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt @@ -0,0 +1,24 @@ +package org.utbot.intellij.plugin.inspection + +import com.intellij.codeInspection.CommonProblemDescriptor +import com.intellij.codeInspection.ex.InspectionToolWrapper +import com.intellij.codeInspection.ui.DefaultInspectionToolPresentation + +/** + * Overrides [resolveProblem] to avoid suppressing quick fix buttons. + */ +class UTBotInspectionToolPresentation( + toolWrapper: InspectionToolWrapper<*, *>, + context: UTBotInspectionContext +) : DefaultInspectionToolPresentation(toolWrapper, context) { + + /** + * This method is called when the user clicks on the quick fix button. + * In the case of [UTBotInspectionTool] we do not want to remove the button after applying the fix. + * + * See [DefaultInspectionToolPresentation.resolveProblem] for more details. + */ + override fun resolveProblem(descriptor: CommonProblemDescriptor) { + // nothing + } +} \ No newline at end of file diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/ViewGeneratedTestFix.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/ViewGeneratedTestFix.kt new file mode 100644 index 0000000000..d0c4605e76 --- /dev/null +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/ViewGeneratedTestFix.kt @@ -0,0 +1,46 @@ +package org.utbot.intellij.plugin.inspection + +import com.intellij.codeInspection.LocalQuickFix +import com.intellij.codeInspection.ProblemDescriptor +import com.intellij.openapi.editor.LogicalPosition +import com.intellij.openapi.fileEditor.FileEditorManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VfsUtil +import org.utbot.common.PathUtil.toPath + +/** + * Button with a link to the [testFileRelativePath]. Displayed as a quick fix. + * + * @param testFileRelativePath path to the generated test file. + * Should be relative to the project root + * @param lineNumber one-based line number + * @param columnNumber one-based column number + */ +class ViewGeneratedTestFix( + val testFileRelativePath: String, + val lineNumber: Int, + val columnNumber: Int +) : LocalQuickFix { + + /** + * Navigates the user to the [lineNumber] line of the [testFileRelativePath] file. + */ + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val testFileAbsolutePath = project.basePath?.toPath()?.resolve(testFileRelativePath) ?: return + val virtualFile = VfsUtil.findFile(testFileAbsolutePath, /* refreshIfNeeded = */ true) ?: return + val editor = FileEditorManager.getInstance(project) + editor.openFile(virtualFile, /* focusEditor = */ true) + val caretModel = editor.selectedTextEditor?.caretModel ?: return + val zeroBasedPosition = LogicalPosition(lineNumber - 1, columnNumber - 1) + caretModel.moveToLogicalPosition(zeroBasedPosition) + val selectionModel = editor.selectedTextEditor?.selectionModel ?: return + selectionModel.selectLineAtCaret() + } + + /** + * This text is displayed on the quick fix button. + */ + override fun getName() = "View generated test" + + override fun getFamilyName() = name +} \ No newline at end of file diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt index 9b8c814108..92c912d7c8 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt @@ -325,7 +325,7 @@ class EngineProcess(parent: Lifetime, val project: Project) { testSetsId: Long, generatedTestsCode: String, sourceFindingStrategy: SourceFindingStrategy - ) = runBlocking { + ): String = runBlocking { current!!.protocol.rdSourceFindingStrategy.let { it.getSourceFile.set { params -> DumbService.getInstance(project).runReadActionInSmartMode { diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt index cd46beff64..25bc27de72 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt @@ -12,6 +12,8 @@ import org.utbot.framework.plugin.api.ClassId import org.utbot.intellij.plugin.generator.UtTestsDialogProcessor import org.utbot.intellij.plugin.models.GenerateTestsModel import org.utbot.intellij.plugin.process.EngineProcess +import org.utbot.sarif.Sarif +import org.utbot.intellij.plugin.ui.utils.getOrCreateSarifReportsPath import org.utbot.intellij.plugin.util.IntelliJApiHelper import java.nio.file.Path @@ -30,7 +32,7 @@ object SarifReportIdea { psiClass: PsiClass, reportsCountDown: CountDownLatch, indicator: ProgressIndicator - ) { + ): Sarif { UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Generate SARIF report for ${classId.name}", .5) // building the path to the report file val classFqn = classId.name @@ -39,7 +41,8 @@ object SarifReportIdea { IntelliJApiHelper.run(IntelliJApiHelper.Target.THREAD_POOL, indicator) { try { - proc.writeSarif(reportFilePath, testSetsId, generatedTestsCode, sourceFinding) + val sarifReportAsJson = proc.writeSarif(reportFilePath, testSetsId, generatedTestsCode, sourceFinding) + return Sarif.fromJson(sarifReportAsJson) } catch (e: Exception) { logger.error { e } } finally { diff --git a/utbot-intellij/src/main/resources/META-INF/plugin.xml b/utbot-intellij/src/main/resources/META-INF/plugin.xml index 81f3409165..2d3969c2a3 100644 --- a/utbot-intellij/src/main/resources/META-INF/plugin.xml +++ b/utbot-intellij/src/main/resources/META-INF/plugin.xml @@ -88,4 +88,15 @@ ]]> + + + + diff --git a/utbot-intellij/src/main/resources/inspectionDescriptions/UnitTestBotInspectionTool.html b/utbot-intellij/src/main/resources/inspectionDescriptions/UnitTestBotInspectionTool.html new file mode 100644 index 0000000000..a01f16e673 --- /dev/null +++ b/utbot-intellij/src/main/resources/inspectionDescriptions/UnitTestBotInspectionTool.html @@ -0,0 +1,11 @@ + + +

Reports unchecked exceptions detected by UnitTestBot.

+

Example:

+
+void foo(int a) {
+    return 1 / a; // throws ArithmeticException when `a == 0`
+}
+
+ + \ No newline at end of file diff --git a/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt b/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt index 3dc39406cf..b10382b545 100644 --- a/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt +++ b/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt @@ -132,7 +132,7 @@ object EngineProcessModel : Ext(EngineProcessProtocolRoot) { call("obtainClassId", PredefinedType.string, array(PredefinedType.byte)).async call("findMethodsInClassMatchingSelected", findMethodsInClassMatchingSelectedArguments, findMethodsInClassMatchingSelectedResult).async call("findMethodParamNames", findMethodParamNamesArguments, findMethodParamNamesResult).async - call("writeSarifReport", writeSarifReportArguments, PredefinedType.void).async + call("writeSarifReport", writeSarifReportArguments, PredefinedType.string).async call("generateTestReport", generateTestReportArgs, generateTestReportResult).async } } \ No newline at end of file From f0e08a57c575a7fa5021dc705756f52c89d931fb Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Mon, 17 Oct 2022 06:35:38 +0300 Subject: [PATCH 2/5] Rebase onto main --- .../generated/EngineProcessModel.Generated.kt | 8 ++++---- .../plugin/generator/CodeGenerationController.kt | 5 ++--- ...nContext.kt => UnitTestBotInspectionContext.kt} | 14 +++++++------- ...nManager.kt => UnitTestBotInspectionManager.kt} | 10 +++++----- ...pectionTool.kt => UnitTestBotInspectionTool.kt} | 4 ++-- ...kt => UnitTestBotInspectionToolPresentation.kt} | 6 +++--- .../utbot/intellij/plugin/process/EngineProcess.kt | 6 +++++- .../utbot/intellij/plugin/sarif/SarifReportIdea.kt | 4 +++- .../src/main/resources/META-INF/plugin.xml | 2 +- 9 files changed, 32 insertions(+), 27 deletions(-) rename utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/{UTBotInspectionContext.kt => UnitTestBotInspectionContext.kt} (80%) rename utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/{UTBotInspectionManager.kt => UnitTestBotInspectionManager.kt} (73%) rename utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/{UTBotInspectionTool.kt => UnitTestBotInspectionTool.kt} (97%) rename utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/{UTBotInspectionToolPresentation.kt => UnitTestBotInspectionToolPresentation.kt} (78%) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt index bda4112811..92abf930d4 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt @@ -27,7 +27,7 @@ class EngineProcessModel private constructor( private val _obtainClassId: RdCall, private val _findMethodsInClassMatchingSelected: RdCall, private val _findMethodParamNames: RdCall, - private val _writeSarifReport: RdCall, + private val _writeSarifReport: RdCall, private val _generateTestReport: RdCall ) : RdExtBase() { //companion @@ -73,7 +73,7 @@ class EngineProcessModel private constructor( } - const val serializationHash = 3907671513584285891L + const val serializationHash = -621732450296355904L } override val serializersOwner: ISerializersOwner get() = EngineProcessModel @@ -89,7 +89,7 @@ class EngineProcessModel private constructor( val obtainClassId: RdCall get() = _obtainClassId val findMethodsInClassMatchingSelected: RdCall get() = _findMethodsInClassMatchingSelected val findMethodParamNames: RdCall get() = _findMethodParamNames - val writeSarifReport: RdCall get() = _writeSarifReport + val writeSarifReport: RdCall get() = _writeSarifReport val generateTestReport: RdCall get() = _generateTestReport //methods //initializer @@ -133,7 +133,7 @@ class EngineProcessModel private constructor( RdCall(FrameworkMarshallers.String, FrameworkMarshallers.ByteArray), RdCall(FindMethodsInClassMatchingSelectedArguments, FindMethodsInClassMatchingSelectedResult), RdCall(FindMethodParamNamesArguments, FindMethodParamNamesResult), - RdCall(WriteSarifReportArguments, FrameworkMarshallers.Void), + RdCall(WriteSarifReportArguments, FrameworkMarshallers.String), RdCall(GenerateTestReportArgs, GenerateTestReportResult) ) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt index bddd4e099e..169065e75d 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt @@ -52,13 +52,12 @@ import org.utbot.framework.codegen.model.UtilClassKind import org.utbot.framework.codegen.model.UtilClassKind.Companion.UT_UTILS_CLASS_NAME import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.CodegenLanguage -import org.utbot.intellij.plugin.inspection.UTBotInspectionManager +import org.utbot.intellij.plugin.inspection.UnitTestBotInspectionManager import org.utbot.intellij.plugin.models.GenerateTestsModel import org.utbot.intellij.plugin.models.packageName import org.utbot.intellij.plugin.process.EngineProcess import org.utbot.intellij.plugin.process.RdTestGenerationResult import org.utbot.intellij.plugin.sarif.SarifReportIdea -import org.utbot.intellij.plugin.sarif.SourceFindingStrategyIdea import org.utbot.intellij.plugin.ui.* import org.utbot.intellij.plugin.ui.utils.getOrCreateSarifReportsPath import org.utbot.intellij.plugin.ui.utils.showErrorDialogLater @@ -180,7 +179,7 @@ object CodeGenerationController { if (!sarifHasResults) { return } - UTBotInspectionManager + UnitTestBotInspectionManager .getInstance(project, srcClassPathToSarifReport) .createNewGlobalContext() .doInspections(AnalysisScope(project)) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt similarity index 80% rename from utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt rename to utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt index 674b69271d..ebf2b84690 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionContext.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt @@ -11,12 +11,12 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap /** - * Overrides some methods of [GlobalInspectionContextImpl] to satisfy the logic of [UTBotInspectionTool]. + * Overrides some methods of [GlobalInspectionContextImpl] to satisfy the logic of [UnitTestBotInspectionTool]. */ -class UTBotInspectionContext( +class UnitTestBotInspectionContext( project: Project, contentManager: NotNullLazyValue, - val srcClassPathToSarifReport: MutableMap + private val srcClassPathToSarifReport: MutableMap ) : GlobalInspectionContextImpl(project, contentManager) { /** @@ -26,14 +26,14 @@ class UTBotInspectionContext( ConcurrentHashMap() private val globalInspectionToolWrapper by lazy { - val utbotInspectionTool = UTBotInspectionTool.getInstance(srcClassPathToSarifReport) + val utbotInspectionTool = UnitTestBotInspectionTool.getInstance(srcClassPathToSarifReport) GlobalInspectionToolWrapper(utbotInspectionTool).also { it.initialize(/* context = */ this) } } /** - * Returns [InspectionProfileImpl] with only one inspection tool - [UTBotInspectionTool]. + * Returns [InspectionProfileImpl] with only one inspection tool - [UnitTestBotInspectionTool]. */ override fun getCurrentProfile(): InspectionProfileImpl { val supplier = InspectionToolsSupplier.Simple(listOf(globalInspectionToolWrapper)) @@ -51,12 +51,12 @@ class UTBotInspectionContext( } /** - * Overriding is needed to provide [UTBotInspectionToolPresentation] + * Overriding is needed to provide [UnitTestBotInspectionToolPresentation] * instead of the standard implementation of the [InspectionToolPresentation]. */ override fun getPresentation(toolWrapper: InspectionToolWrapper<*, *>): InspectionToolPresentation { return myPresentationMap.computeIfAbsent(toolWrapper) { - UTBotInspectionToolPresentation(globalInspectionToolWrapper, context = this) + UnitTestBotInspectionToolPresentation(globalInspectionToolWrapper, context = this) } } } diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionManager.kt similarity index 73% rename from utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt rename to utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionManager.kt index 813e6d3b65..82ed4e87f8 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionManager.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionManager.kt @@ -9,15 +9,15 @@ import org.utbot.sarif.Sarif import java.nio.file.Path /** - * Overrides some methods of [InspectionManagerEx] to satisfy the logic of [UTBotInspectionTool]. + * Overrides some methods of [InspectionManagerEx] to satisfy the logic of [UnitTestBotInspectionTool]. */ -class UTBotInspectionManager(project: Project) : InspectionManagerEx(project) { +class UnitTestBotInspectionManager(project: Project) : InspectionManagerEx(project) { private var srcClassPathToSarifReport: MutableMap = mutableMapOf() companion object { fun getInstance(project: Project, srcClassPathToSarifReport: MutableMap) = - UTBotInspectionManager(project).also { + UnitTestBotInspectionManager(project).also { it.srcClassPathToSarifReport = srcClassPathToSarifReport } } @@ -32,8 +32,8 @@ class UTBotInspectionManager(project: Project) : InspectionManagerEx(project) { } /** - * Overriding is needed to provide [UTBotInspectionContext] instead of [GlobalInspectionContextImpl]. + * Overriding is needed to provide [UnitTestBotInspectionContext] instead of [GlobalInspectionContextImpl]. */ override fun createNewGlobalContext(): GlobalInspectionContextImpl = - UTBotInspectionContext(project, myContentManager, srcClassPathToSarifReport) + UnitTestBotInspectionContext(project, myContentManager, srcClassPathToSarifReport) } diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionTool.kt similarity index 97% rename from utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt rename to utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionTool.kt index 2777dd08bc..469d0527fb 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionTool.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionTool.kt @@ -13,7 +13,7 @@ import java.nio.file.Path /** * Global inspection tool that displays detected errors from the SARIF report. */ -class UTBotInspectionTool : GlobalSimpleInspectionTool() { +class UnitTestBotInspectionTool : GlobalSimpleInspectionTool() { /** * Map from the path to the class under test to [Sarif] for it. @@ -22,7 +22,7 @@ class UTBotInspectionTool : GlobalSimpleInspectionTool() { companion object { fun getInstance(srcClassPathToSarifReport: MutableMap) = - UTBotInspectionTool().also { + UnitTestBotInspectionTool().also { it.srcClassPathToSarifReport = srcClassPathToSarifReport } } diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionToolPresentation.kt similarity index 78% rename from utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt rename to utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionToolPresentation.kt index 7d1d5a69a7..264a37f32e 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UTBotInspectionToolPresentation.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionToolPresentation.kt @@ -7,14 +7,14 @@ import com.intellij.codeInspection.ui.DefaultInspectionToolPresentation /** * Overrides [resolveProblem] to avoid suppressing quick fix buttons. */ -class UTBotInspectionToolPresentation( +class UnitTestBotInspectionToolPresentation( toolWrapper: InspectionToolWrapper<*, *>, - context: UTBotInspectionContext + context: UnitTestBotInspectionContext ) : DefaultInspectionToolPresentation(toolWrapper, context) { /** * This method is called when the user clicks on the quick fix button. - * In the case of [UTBotInspectionTool] we do not want to remove the button after applying the fix. + * In the case of [UnitTestBotInspectionTool] we do not want to remove the button after applying the fix. * * See [DefaultInspectionToolPresentation.resolveProblem] for more details. */ diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt index 92c912d7c8..b27680ff42 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt @@ -7,6 +7,7 @@ import com.intellij.psi.PsiMethod import com.intellij.psi.impl.file.impl.JavaFileManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.refactoring.util.classMembers.MemberInfo +import com.jetbrains.rd.framework.util.asCompletableFuture import com.jetbrains.rd.util.Logger import com.jetbrains.rd.util.lifetime.Lifetime import com.jetbrains.rd.util.lifetime.throwIfNotAlive @@ -37,6 +38,7 @@ import org.utbot.rd.ProcessWithRdServer import org.utbot.rd.loggers.UtRdKLoggerFactory import org.utbot.rd.rdPortArgument import org.utbot.rd.startUtProcessWithRdServer +import org.utbot.sarif.Sarif import org.utbot.sarif.SourceFindingStrategy import java.io.File import java.nio.file.Path @@ -349,7 +351,9 @@ class EngineProcess(parent: Lifetime, val project: Project) { } } } - engineModel().writeSarifReport.start(WriteSarifReportArguments(testSetsId, reportFilePath.pathString, generatedTestsCode)) + engineModel().writeSarifReport.startSuspending( + WriteSarifReportArguments(testSetsId, reportFilePath.pathString, generatedTestsCode) + ) } fun generateTestsReport(model: GenerateTestsModel, eventLogMessage: String?): Triple = runBlocking { diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt index 25bc27de72..dab4655ad2 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt @@ -36,7 +36,9 @@ object SarifReportIdea { UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Generate SARIF report for ${classId.name}", .5) // building the path to the report file val classFqn = classId.name - val (sarifReportsPath, sourceFinding) = WriteAction.computeAndWait, Exception> { model.testModule.getOrCreateSarifReportsPath(model.testSourceRoot) to SourceFindingStrategyIdea(psiClass) } + val (sarifReportsPath, sourceFinding) = WriteAction.computeAndWait, Exception> { + model.testModule.getOrCreateSarifReportsPath(model.testSourceRoot) to SourceFindingStrategyIdea(psiClass) + } val reportFilePath = sarifReportsPath.resolve("${classFqnToPath(classFqn)}Report.sarif") IntelliJApiHelper.run(IntelliJApiHelper.Target.THREAD_POOL, indicator) { diff --git a/utbot-intellij/src/main/resources/META-INF/plugin.xml b/utbot-intellij/src/main/resources/META-INF/plugin.xml index 2d3969c2a3..a809967b5b 100644 --- a/utbot-intellij/src/main/resources/META-INF/plugin.xml +++ b/utbot-intellij/src/main/resources/META-INF/plugin.xml @@ -96,7 +96,7 @@ groupKey="group.names.probable.bugs" enabledByDefault="true" level="ERROR" - implementationClass="org.utbot.intellij.plugin.inspection.UTBotInspectionTool"/> + implementationClass="org.utbot.intellij.plugin.inspection.UnitTestBotInspectionTool"/> From 9a17fad0864c70058d5e17fa2d95f69d238f1faf Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Mon, 17 Oct 2022 08:35:13 +0300 Subject: [PATCH 3/5] Rename inspection profile --- .../intellij/plugin/inspection/UnitTestBotInspectionContext.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt index ebf2b84690..a5c6714bd2 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt @@ -37,7 +37,7 @@ class UnitTestBotInspectionContext( */ override fun getCurrentProfile(): InspectionProfileImpl { val supplier = InspectionToolsSupplier.Simple(listOf(globalInspectionToolWrapper)) - return InspectionProfileImpl("UTBotInspectionToolProfile", supplier, BASE_PROFILE) + return InspectionProfileImpl("UnitTestBotProfile", supplier, BASE_PROFILE) } override fun close(noSuspiciousCodeFound: Boolean) { From 357035ea7303f68c1724bebbb0432e662a5b2425 Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Wed, 19 Oct 2022 09:29:29 +0300 Subject: [PATCH 4/5] Change profile name --- .../intellij/plugin/generator/CodeGenerationController.kt | 2 +- .../plugin/inspection/UnitTestBotInspectionContext.kt | 2 +- .../kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt index 169065e75d..2266485ccb 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt @@ -155,9 +155,9 @@ object CodeGenerationController { UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Start tests with coverage", 0.95) RunConfigurationHelper.runTestsWithCoverage(model, testFilesPointers) } - runInspectionsIfNeeded(model.project, srcClassPathToSarifReport) // TODO proc.forceTermination() UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Start tests with coverage", 1.0) + runInspectionsIfNeeded(model.project, srcClassPathToSarifReport) } } } diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt index a5c6714bd2..e44cdb5de0 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/inspection/UnitTestBotInspectionContext.kt @@ -37,7 +37,7 @@ class UnitTestBotInspectionContext( */ override fun getCurrentProfile(): InspectionProfileImpl { val supplier = InspectionToolsSupplier.Simple(listOf(globalInspectionToolWrapper)) - return InspectionProfileImpl("UnitTestBotProfile", supplier, BASE_PROFILE) + return InspectionProfileImpl("UnitTestBot", supplier, BASE_PROFILE) } override fun close(noSuspiciousCodeFound: Boolean) { diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt index dab4655ad2..84ef9b4468 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt @@ -41,16 +41,18 @@ object SarifReportIdea { } val reportFilePath = sarifReportsPath.resolve("${classFqnToPath(classFqn)}Report.sarif") + var resultSarifReport = Sarif.empty() IntelliJApiHelper.run(IntelliJApiHelper.Target.THREAD_POOL, indicator) { try { val sarifReportAsJson = proc.writeSarif(reportFilePath, testSetsId, generatedTestsCode, sourceFinding) - return Sarif.fromJson(sarifReportAsJson) + resultSarifReport = Sarif.fromJson(sarifReportAsJson) } catch (e: Exception) { logger.error { e } } finally { reportsCountDown.countDown() } } + return resultSarifReport } } From bbc1766e54f2b61f9471b479d95a5b909bc10fd4 Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Wed, 19 Oct 2022 10:55:35 +0300 Subject: [PATCH 5/5] Fix thread execution --- .../generator/CodeGenerationController.kt | 31 ++++++++++++++----- .../intellij/plugin/sarif/SarifReportIdea.kt | 9 +++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt index 2266485ccb..75ffbe0a6e 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt @@ -8,6 +8,7 @@ import com.intellij.ide.fileTemplates.FileTemplateUtil import com.intellij.ide.fileTemplates.JavaTemplateUtil import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.invokeLater import com.intellij.openapi.application.runReadAction import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.command.WriteCommandAction.runWriteCommandAction @@ -157,7 +158,10 @@ object CodeGenerationController { } proc.forceTermination() UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Start tests with coverage", 1.0) - runInspectionsIfNeeded(model.project, srcClassPathToSarifReport) + + invokeLater { + runInspectionsIfNeeded(model.project, srcClassPathToSarifReport) + } } } } @@ -686,6 +690,7 @@ object CodeGenerationController { // uploading formatted code val file = filePointer.containingFile + val srcClassPath = srcClass.containingFile.virtualFile.toNioPath() val sarifReport = saveSarifReport( proc, testSetsId, @@ -694,10 +699,10 @@ object CodeGenerationController { model, reportsCountDown, file?.text ?: generatedTestsCode, + srcClassPathToSarifReport, + srcClassPath, indicator ) - val srcClassPath = srcClass.containingFile.virtualFile.toNioPath() - srcClassPathToSarifReport[srcClassPath] = sarifReport unblockDocument(testClassUpdated.project, editor.document) } @@ -734,13 +739,26 @@ object CodeGenerationController { model: GenerateTestsModel, reportsCountDown: CountDownLatch, generatedTestsCode: String, + srcClassPathToSarifReport: MutableMap, + srcClassPath: Path, indicator: ProgressIndicator - ): Sarif { + ) { val project = model.project - return try { + try { // saving sarif report - SarifReportIdea.createAndSave(proc, testSetsId, testClassId, model, generatedTestsCode, testClass, reportsCountDown, indicator) + SarifReportIdea.createAndSave( + proc, + testSetsId, + testClassId, + model, + generatedTestsCode, + testClass, + reportsCountDown, + srcClassPathToSarifReport, + srcClassPath, + indicator + ) } catch (e: Exception) { logger.error(e) { "error in saving sarif report"} showErrorDialogLater( @@ -748,7 +766,6 @@ object CodeGenerationController { message = "Cannot save Sarif report via generated tests: error occurred '${e.message}'", title = "Failed to save Sarif report" ) - Sarif.empty() } } diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt index 84ef9b4468..8939abcdf4 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/sarif/SarifReportIdea.kt @@ -31,8 +31,10 @@ object SarifReportIdea { generatedTestsCode: String, psiClass: PsiClass, reportsCountDown: CountDownLatch, + srcClassPathToSarifReport: MutableMap, + srcClassPath: Path, indicator: ProgressIndicator - ): Sarif { + ) { UtTestsDialogProcessor.updateIndicator(indicator, UtTestsDialogProcessor.ProgressRange.SARIF, "Generate SARIF report for ${classId.name}", .5) // building the path to the report file val classFqn = classId.name @@ -41,18 +43,17 @@ object SarifReportIdea { } val reportFilePath = sarifReportsPath.resolve("${classFqnToPath(classFqn)}Report.sarif") - var resultSarifReport = Sarif.empty() IntelliJApiHelper.run(IntelliJApiHelper.Target.THREAD_POOL, indicator) { try { val sarifReportAsJson = proc.writeSarif(reportFilePath, testSetsId, generatedTestsCode, sourceFinding) - resultSarifReport = Sarif.fromJson(sarifReportAsJson) + val sarifReport = Sarif.fromJson(sarifReportAsJson) + srcClassPathToSarifReport[srcClassPath] = sarifReport } catch (e: Exception) { logger.error { e } } finally { reportsCountDown.countDown() } } - return resultSarifReport } }