Gradle, js, browser: best effort for parsing karma suite names

#KT-31011
This commit is contained in:
Sergey Rostov
2019-05-15 10:46:05 +03:00
parent 236dfa98b6
commit 7e4eaa8210
5 changed files with 54 additions and 13 deletions
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
import org.slf4j.Logger
import java.text.ParseException
import java.lang.System.currentTimeMillis as currentTimeMillis1
data class TCServiceMessagesClientSettings(
val rootNodeName: String,
@@ -28,7 +27,7 @@ data class TCServiceMessagesClientSettings(
val ignoreOutOfRootNodes: Boolean = false
)
internal class TCServiceMessagesClient(
internal open class TCServiceMessagesClient(
private val results: TestResultProcessor,
val settings: TCServiceMessagesClientSettings,
val log: Logger
@@ -51,7 +50,7 @@ internal class TCServiceMessagesClient(
log.kotlinDebug { "TCSM: $message" }
when (message) {
is TestSuiteStarted -> open(message.ts, SuiteNode(requireLeafGroup(), message.suiteName))
is TestSuiteStarted -> open(message.ts, SuiteNode(requireLeafGroup(), getSuiteName(message)))
is TestStarted -> beginTest(message.ts, message.testName)
is TestStdOut -> requireLeafTest().output(StdOut, message.stdOut)
is TestStdErr -> requireLeafTest().output(StdErr, message.stdErr)
@@ -66,11 +65,13 @@ internal class TCServiceMessagesClient(
endTest(message.ts, message.testName)
}
}
is TestSuiteFinished -> close(message.ts, message.suiteName)
is TestSuiteFinished -> close(message.ts, getSuiteName(message))
else -> Unit
}
}
protected open fun getSuiteName(message: BaseTestSuiteMessage) = message.suiteName
override fun regularText(text: String) {
log.kotlinDebug { "TCSM stdout captured: $text" }
val actualText = text + "\n"
@@ -83,6 +84,9 @@ internal class TCServiceMessagesClient(
}
}
protected open val testNameSuffix: String?
get() = settings.testNameSuffix
private fun beginTest(ts: Long, testName: String, isIgnored: Boolean = false) {
val parent = requireLeafGroup()
parent.requireReportingNode()
@@ -93,8 +97,8 @@ internal class TCServiceMessagesClient(
}
val parsedName = ParsedTestName(finalTestName, parent.localId)
val fullTestName = if (settings.testNameSuffix == null) parsedName.methodName
else "${parsedName.methodName}[${settings.testNameSuffix}]"
val fullTestName = if (testNameSuffix == null) parsedName.methodName
else "${parsedName.methodName}[$testNameSuffix]"
open(
ts, TestNode(
@@ -8,17 +8,21 @@ import org.gradle.internal.operations.BuildOperationExecutor
import org.gradle.process.ProcessForkOptions
import org.gradle.process.internal.ExecHandle
import org.gradle.process.internal.ExecHandleFactory
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.PipedInputStream
import java.io.PipedOutputStream
import kotlin.concurrent.thread
data class TCServiceMessagesTestExecutionSpec(
open class TCServiceMessagesTestExecutionSpec(
val forkOptions: ProcessForkOptions,
val args: List<String>,
val checkExitCode: Boolean,
val clientSettings: TCServiceMessagesClientSettings
) : TestExecutionSpec
) : TestExecutionSpec {
internal open fun createClient(testResultProcessor: TestResultProcessor, log: Logger): TCServiceMessagesClient =
TCServiceMessagesClient(testResultProcessor, clientSettings, log)
}
private val log = LoggerFactory.getLogger("org.jetbrains.kotlin.gradle.tasks.testing")
@@ -37,7 +41,7 @@ class TCServiceMessagesTestExecutor(
outputReaderThread = thread(name = "${spec.forkOptions} output reader") {
try {
val client = TCServiceMessagesClient(testResultProcessor, spec.clientSettings, log)
val client = spec.createClient(testResultProcessor, log)
client.root(rootOperation) {
stdInPipe.reader().useLines { lines ->
@@ -69,7 +69,7 @@ abstract class KotlinJsSubTarget(
compileTask.outputFile.exists()
}
testJs.targetName = disambiguationClassifier
testJs.targetName = target.disambiguationClassifier + "," + disambiguationClassifier
testJs.nodeModulesToLoad.add(compileTask.outputFile.nameWithoutExtension)
testJs.configureConventions()
@@ -6,8 +6,11 @@
package org.jetbrains.kotlin.gradle.targets.js.testing.karma
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.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClient
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.targets.js.appendConfigsFromDir
@@ -21,6 +24,7 @@ import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KarmaConfig.CoverageReporter.Reporter
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfigWriter
import org.jetbrains.kotlin.gradle.testing.internal.reportsDir
import org.slf4j.Logger
import java.io.File
class KotlinKarma(val project: Project) : KotlinJsTestFramework {
@@ -209,12 +213,42 @@ class KotlinKarma(val project: Project) : KotlinJsTestFramework {
} +
listOf("start", karmaConfJs.absolutePath)
return TCServiceMessagesTestExecutionSpec(
return object : TCServiceMessagesTestExecutionSpec(
forkOptions,
args,
false,
clientSettings
)
) {
override fun createClient(testResultProcessor: TestResultProcessor, log: Logger) =
object : TCServiceMessagesClient(testResultProcessor, clientSettings, log) {
val baseTestNameSuffix get() = settings.testNameSuffix
override var testNameSuffix: String? = baseTestNameSuffix
override fun getSuiteName(message: BaseTestSuiteMessage): String {
val src = message.suiteName.trim()
// example: "sample.a DeepPackageTest Inner.HeadlessChrome 74.0.3729 (Mac OS X 10.14.4)"
// should be reported as "sample.a.DeepPackageTest.Inner[js,browser,HeadlessChrome74.0.3729,MacOSX10.14.4]"
// lets parse it from the end:
val os = src.substringAfterLast("(") // Mac OS X 10.14.4)
.removeSuffix(")") // Mac OS X 10.14.4
.replace(" ", "") // MacOSX10.14.4
val withoutOs = src.substringBeforeLast(" (") // sample.a DeepPackageTest Inner.HeadlessChrome 74.0.3729
val rawSuiteNameOnly = withoutOs
.substringBeforeLast(" ") // sample.a DeepPackageTest Inner.HeadlessChrome
.substringBeforeLast(".") // sample.a DeepPackageTest Inner
val browser = withoutOs.substring(rawSuiteNameOnly.length + 1) // HeadlessChrome 74.0.3729
.replace(" ", "") // HeadlessChrome74.0.3729
testNameSuffix = "$baseTestNameSuffix,$browser,$os"
return rawSuiteNameOnly.replace(" ", ".") // sample.a.DeepPackageTest.Inner
}
}
}
}
private fun Appendable.appendFromConfigDir() {
@@ -9,7 +9,6 @@ import org.gradle.api.Project
import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinGradleNpmPackage