Gradle: Escape TC service messages in debug logs

The MPP plugin uses TC service messages to interact with JS and
native test runs an writes received messages to a debug log. But
if a build is executed by TeamCity, these log messages may be
treated by TC as actual service messages.

This patch transforms the logged messages to avoid this issue.
This commit is contained in:
Ilya Matveev
2019-12-10 15:34:18 +07:00
parent 33df86338b
commit 6bc0fe121a
7 changed files with 29 additions and 6 deletions
@@ -1293,7 +1293,7 @@ class NewMultiplatformIT : BaseGradleIT() {
}
@Test
fun testNativeTests() = with(Project("new-mpp-native-tests", gradleVersion, minLogLevel = LogLevel.INFO)) {
fun testNativeTests() = with(Project("new-mpp-native-tests", gradleVersion)) {
val testTasks = listOf("macos64Test", "linux64Test", "mingw64Test", "iosTest")
val hostTestTask = "${nativeHostTargetName}Test"
@@ -1 +1,3 @@
# Enable escaping TC service messages in logs.
teamcity=true
kotlin.native.disableCompilerDaemon=true
@@ -25,7 +25,8 @@ data class TCServiceMessagesClientSettings(
val treatFailedTestOutputAsStacktrace: Boolean = false,
val stackTraceParser: (String) -> ParsedStackTrace? = { null },
val ignoreOutOfRootNodes: Boolean = false,
val ignoreLineEndingAfterMessage: Boolean = true
val ignoreLineEndingAfterMessage: Boolean = true,
val escapeTCMessagesInLog: Boolean = false
)
internal open class TCServiceMessagesClient(
@@ -51,7 +52,17 @@ internal open class TCServiceMessagesClient(
}
override fun serviceMessage(message: ServiceMessage) {
log.kotlinDebug { "TCSM: $message" }
// If a user uses TeamCity, this log may be treated by TC as an actual service message.
// So, escape logged messages if the corresponding setting is specified.
log.kotlinDebug {
val messageString = if (settings.escapeTCMessagesInLog) {
message.toString().replaceFirst("^##teamcity\\[".toRegex(), "##TC[")
} else {
message.toString()
}
"TCSM: $messageString"
}
when (message) {
is TestSuiteStarted -> open(message.ts, SuiteNode(requireLeafGroup(), getSuiteName(message)))
@@ -81,4 +81,8 @@ class TCServiceMessagesTestExecutor(
execHandle?.abort()
outputReaderThread?.join()
}
companion object {
const val TC_PROJECT_PROPERTY = "teamcity"
}
}
@@ -14,6 +14,7 @@ import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.operation
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor.Companion.TC_PROJECT_PROPERTY
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.targets.js.NpmPackageVersion
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
@@ -313,7 +314,8 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF
testNameSuffix = task.targetName,
prependSuiteName = true,
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
ignoreOutOfRootNodes = true
ignoreOutOfRootNodes = true,
escapeTCMessagesInLog = project.hasProperty(TC_PROJECT_PROPERTY)
)
config.basePath = npmProject.nodeModulesDir.absolutePath
@@ -9,6 +9,7 @@ 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.internal.testing.TCServiceMessagesTestExecutor.Companion.TC_PROJECT_PROPERTY
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.targets.js.KotlinGradleNpmPackage
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
@@ -50,7 +51,8 @@ class KotlinMocha(override val compilation: KotlinJsCompilation) : KotlinJsTestF
testNameSuffix = task.targetName,
prependSuiteName = true,
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
ignoreOutOfRootNodes = true
ignoreOutOfRootNodes = true,
escapeTCMessagesInLog = project.hasProperty(TC_PROJECT_PROPERTY)
)
val npmProject = compilation.npmProject
@@ -17,6 +17,7 @@ import org.gradle.process.internal.DefaultProcessForkOptions
import org.jetbrains.kotlin.compilerRunner.konanVersion
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor.Companion.TC_PROJECT_PROPERTY
import org.jetbrains.kotlin.gradle.targets.native.internal.parseKotlinNativeStackTraceAsJvm
import org.jetbrains.kotlin.gradle.tasks.KotlinTest
import org.jetbrains.kotlin.konan.CompilerVersion
@@ -117,7 +118,8 @@ abstract class KotlinNativeTest : KotlinTest() {
testNameSuffix = targetName,
prependSuiteName = targetName != null,
treatFailedTestOutputAsStacktrace = false,
stackTraceParser = ::parseKotlinNativeStackTraceAsJvm
stackTraceParser = ::parseKotlinNativeStackTraceAsJvm,
escapeTCMessagesInLog = project.hasProperty(TC_PROJECT_PROPERTY)
)
// The KotlinTest expects that the exit code is zero even if some tests failed.