Gradle, js, karma: show output as progress

This commit is contained in:
Sergey Rostov
2019-05-15 11:37:22 +03:00
parent c7d52331f7
commit 26c2afd8d5
3 changed files with 66 additions and 33 deletions
@@ -80,10 +80,14 @@ internal open class TCServiceMessagesClient(
if (test != null) { if (test != null) {
test.output(StdOut, actualText) test.output(StdOut, actualText)
} else { } else {
print(actualText) printNonTestOutput(actualText)
} }
} }
protected open fun printNonTestOutput(actualText: String) {
print(actualText)
}
protected open val testNameSuffix: String? protected open val testNameSuffix: String?
get() = settings.testNameSuffix get() = settings.testNameSuffix
@@ -22,6 +22,9 @@ open class TCServiceMessagesTestExecutionSpec(
) : TestExecutionSpec { ) : TestExecutionSpec {
internal open fun createClient(testResultProcessor: TestResultProcessor, log: Logger): TCServiceMessagesClient = internal open fun createClient(testResultProcessor: TestResultProcessor, log: Logger): TCServiceMessagesClient =
TCServiceMessagesClient(testResultProcessor, clientSettings, log) 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") private val log = LoggerFactory.getLogger("org.jetbrains.kotlin.gradle.tasks.testing")
@@ -35,51 +38,56 @@ class TCServiceMessagesTestExecutor(
var shouldStop = false var shouldStop = false
override fun execute(spec: TCServiceMessagesTestExecutionSpec, testResultProcessor: TestResultProcessor) { 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") { outputReaderThread = thread(name = "${spec.forkOptions} output reader") {
try { try {
val client = spec.createClient(testResultProcessor, log) val client = spec.createClient(testResultProcessor, log)
client.root(rootOperation) { client.root(rootOperation) {
stdInPipe.reader().useLines { lines -> stdInPipe.reader().useLines { lines ->
lines.forEach { lines.forEach {
if (shouldStop) { if (shouldStop) {
client.closeAll() client.closeAll()
return@thread return@thread
} }
try { try {
ServiceMessage.parse(it, client) ServiceMessage.parse(it, client)
} catch (e: Exception) { } catch (e: Exception) {
log.error( spec.showSuppressedOutput()
"Error while processing test process output message \"$it\"", log.error(
e "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() val exec = execHandleFactory.newExec()
spec.forkOptions.copyTo(exec) spec.forkOptions.copyTo(exec)
exec.args = spec.args exec.args = spec.args
exec.standardOutput = PipedOutputStream(stdInPipe) exec.standardOutput = PipedOutputStream(stdInPipe)
execHandle = exec.build() execHandle = exec.build()
execHandle!!.start() execHandle!!.start()
val result = execHandle!!.waitForFinish() val result = execHandle!!.waitForFinish()
outputReaderThread!!.join() outputReaderThread!!.join()
if (spec.checkExitCode && result.exitValue != 0) { if (spec.checkExitCode && result.exitValue != 0) {
error("$execHandle exited with errors (exit code: ${result.exitValue})") spec.showSuppressedOutput()
error("$execHandle exited with errors (exit code: ${result.exitValue})")
}
} }
} }
@@ -9,7 +9,9 @@ import com.google.gson.GsonBuilder
import jetbrains.buildServer.messages.serviceMessages.BaseTestSuiteMessage import jetbrains.buildServer.messages.serviceMessages.BaseTestSuiteMessage
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.internal.tasks.testing.TestResultProcessor import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.internal.logging.progress.ProgressLogger
import org.gradle.process.ProcessForkOptions 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.TCServiceMessagesClient
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
@@ -221,8 +223,27 @@ class KotlinKarma(val project: Project) : KotlinJsTestFramework {
false, false,
clientSettings 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) = override fun createClient(testResultProcessor: TestResultProcessor, log: Logger) =
object : TCServiceMessagesClient(testResultProcessor, clientSettings, log) { object : TCServiceMessagesClient(testResultProcessor, clientSettings, log) {
override fun printNonTestOutput(actualText: String) {
suppressedOutput.appendln(actualText)
progressLogger.progress(actualText)
}
val baseTestNameSuffix get() = settings.testNameSuffix val baseTestNameSuffix get() = settings.testNameSuffix
override var testNameSuffix: String? = baseTestNameSuffix override var testNameSuffix: String? = baseTestNameSuffix