diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt index de05ccc95b8..8335a52a556 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesClient.kt @@ -80,10 +80,14 @@ internal open class TCServiceMessagesClient( if (test != null) { test.output(StdOut, actualText) } else { - print(actualText) + printNonTestOutput(actualText) } } + protected open fun printNonTestOutput(actualText: String) { + print(actualText) + } + protected open val testNameSuffix: String? get() = settings.testNameSuffix diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesTestExecutor.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesTestExecutor.kt index 67affb4dc38..2ab56f1541b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesTestExecutor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/testing/TCServiceMessagesTestExecutor.kt @@ -22,6 +22,9 @@ open class TCServiceMessagesTestExecutionSpec( ) : TestExecutionSpec { internal open fun createClient(testResultProcessor: TestResultProcessor, log: Logger): TCServiceMessagesClient = TCServiceMessagesClient(testResultProcessor, clientSettings, log) + + internal open fun wrapExecute(body: () -> Unit) = body() + internal open fun showSuppressedOutput() = Unit } private val log = LoggerFactory.getLogger("org.jetbrains.kotlin.gradle.tasks.testing") @@ -35,51 +38,56 @@ class TCServiceMessagesTestExecutor( var shouldStop = false override fun execute(spec: TCServiceMessagesTestExecutionSpec, testResultProcessor: TestResultProcessor) { - val stdInPipe = PipedInputStream() + spec.wrapExecute { + val stdInPipe = PipedInputStream() - val rootOperation = buildOperationExecutor.currentOperation.parentId + val rootOperation = buildOperationExecutor.currentOperation.parentId - outputReaderThread = thread(name = "${spec.forkOptions} output reader") { - try { - val client = spec.createClient(testResultProcessor, log) + outputReaderThread = thread(name = "${spec.forkOptions} output reader") { + try { + val client = spec.createClient(testResultProcessor, log) - client.root(rootOperation) { - stdInPipe.reader().useLines { lines -> - lines.forEach { - if (shouldStop) { - client.closeAll() - return@thread - } + client.root(rootOperation) { + stdInPipe.reader().useLines { lines -> + lines.forEach { + if (shouldStop) { + client.closeAll() + return@thread + } - try { - ServiceMessage.parse(it, client) - } catch (e: Exception) { - log.error( - "Error while processing test process output message \"$it\"", - e - ) + try { + ServiceMessage.parse(it, client) + } catch (e: Exception) { + spec.showSuppressedOutput() + log.error( + "Error while processing test process output message \"$it\"", + e + ) + } } } } + } catch (t: Throwable) { + spec.showSuppressedOutput() + log.error("Error creating TCServiceMessagesClient", t) } - } catch (t: Throwable) { - log.error("Error creating TCServiceMessagesClient", t) } - } - val exec = execHandleFactory.newExec() - spec.forkOptions.copyTo(exec) - exec.args = spec.args - exec.standardOutput = PipedOutputStream(stdInPipe) + val exec = execHandleFactory.newExec() + spec.forkOptions.copyTo(exec) + exec.args = spec.args + exec.standardOutput = PipedOutputStream(stdInPipe) - execHandle = exec.build() + execHandle = exec.build() - execHandle!!.start() - val result = execHandle!!.waitForFinish() - outputReaderThread!!.join() + execHandle!!.start() + val result = execHandle!!.waitForFinish() + outputReaderThread!!.join() - if (spec.checkExitCode && result.exitValue != 0) { - error("$execHandle exited with errors (exit code: ${result.exitValue})") + if (spec.checkExitCode && result.exitValue != 0) { + spec.showSuppressedOutput() + error("$execHandle exited with errors (exit code: ${result.exitValue})") + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt index 38a51780612..30040349878 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt @@ -9,7 +9,9 @@ import com.google.gson.GsonBuilder import jetbrains.buildServer.messages.serviceMessages.BaseTestSuiteMessage import org.gradle.api.Project import org.gradle.api.internal.tasks.testing.TestResultProcessor +import org.gradle.internal.logging.progress.ProgressLogger import org.gradle.process.ProcessForkOptions +import org.jetbrains.kotlin.gradle.internal.operation import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClient import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec @@ -221,8 +223,27 @@ class KotlinKarma(val project: Project) : KotlinJsTestFramework { false, clientSettings ) { + lateinit var progressLogger: ProgressLogger + val suppressedOutput = StringBuilder() + + override fun wrapExecute(body: () -> Unit) { + project.operation("Running and building tests with karma and webpack") { + progressLogger = this + body() + } + } + + override fun showSuppressedOutput() { + println(suppressedOutput) + } + override fun createClient(testResultProcessor: TestResultProcessor, log: Logger) = object : TCServiceMessagesClient(testResultProcessor, clientSettings, log) { + override fun printNonTestOutput(actualText: String) { + suppressedOutput.appendln(actualText) + progressLogger.progress(actualText) + } + val baseTestNameSuffix get() = settings.testNameSuffix override var testNameSuffix: String? = baseTestNameSuffix