From 0dd329d3d4c6ad7c07be1233d400445f3944fa14 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Tue, 3 Nov 2020 01:02:34 +0300 Subject: [PATCH] Gradle IT: Intercept and log Gradle process output on import failures --- .../kotlin/gradle/ImportAndCheckNavigation.kt | 12 +++----- .../gradle/GradleImportingTestCase.kt | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt index ab678eedc6a..1614084d97c 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/ImportAndCheckNavigation.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.gradle import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.* +import com.intellij.psi.PsiComment +import com.intellij.psi.PsiReference +import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.util.PsiTreeUtil import com.intellij.testFramework.runInEdtAndGet import org.jetbrains.kotlin.idea.codeInsight.gradle.MasterPluginVersionGradleImportingTestCase @@ -23,7 +25,7 @@ class ImportAndCheckNavigation : MasterPluginVersionGradleImportingTestCase() { @Test @PluginTargetVersions(gradleVersion = "6.0+", pluginVersion = "1.4+", gradleVersionForLatestPlugin = mppImportTestMinVersionForMaster) fun testNavigationToCommonizedLibrary() { - val files = configureAndImportProject() + val files = importProjectFromTestData() files.forEach { vFile -> val referencesToTest = vFile.collectReferencesToTest() @@ -48,12 +50,6 @@ class ImportAndCheckNavigation : MasterPluginVersionGradleImportingTestCase() { override fun testDataDirName() = "importAndCheckNavigation" - private fun configureAndImportProject(): List { - val files = configureByFiles() - importProject() - return files - } - private fun VirtualFile.collectReferencesToTest(): Map { if (extension != "kt") return emptyMap() diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt index 4179d76989f..bba25d064bf 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt @@ -54,6 +54,7 @@ import org.gradle.wrapper.GradleWrapperMain import org.gradle.wrapper.PathAssembler import org.intellij.lang.annotations.Language import org.jetbrains.annotations.NonNls +import org.jetbrains.kotlin.idea.test.GradleProcessOutputInterceptor import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe @@ -162,6 +163,8 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() { "${jvmHeapArgsByGradleVersion(gradleVersion)} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}" sdkCreationChecker = KotlinSdkCreationChecker() + + GradleProcessOutputInterceptor.install(testRootDisposable) } override fun tearDown() { @@ -243,6 +246,32 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() { super.importProject(config) } + override fun handleImportFailure(errorMessage: String, errorDetails: String?) { + val gradleOutput = GradleProcessOutputInterceptor.getInstance()?.getOutput().orEmpty() + + // Typically Gradle error message consists of a line with the description of the error followed by + // a multi-line stacktrace. The idea is to cut off the stacktrace if it is already contained in + // the intercepted Gradle process output to avoid unnecessary verbosity. + val compactErrorMessage = when (val indexOfNewLine = errorMessage.indexOf('\n')) { + -1 -> errorMessage + else -> { + val compactErrorMessage = errorMessage.substring(0, indexOfNewLine) + val theRest = errorMessage.substring(indexOfNewLine + 1) + if (theRest in gradleOutput) compactErrorMessage else errorMessage + } + } + + val failureMessage = buildString { + append("Gradle import failed: ").append(compactErrorMessage).append('\n') + if (!errorDetails.isNullOrBlank()) append("Error details: ").append(errorDetails).append('\n') + append("Gradle process output (BEGIN):\n") + append(gradleOutput) + if (!gradleOutput.endsWith('\n')) append('\n') + append("Gradle process output (END)") + } + fail(failureMessage) + } + protected open fun injectRepo(@NonNls @Language("Groovy") config: String?): String { var config = config ?: "" config = """allprojects {