[Gradle] Introduce MppTestReportHelper to handle differences in internal Gradle testing API

#KT-54634 Fixed
This commit is contained in:
Alexander Likhachev
2022-12-01 19:14:44 +01:00
committed by Space Team
parent b7ebe77399
commit 6bbc577942
18 changed files with 326 additions and 46 deletions
@@ -15,6 +15,7 @@ import org.gradle.api.tasks.testing.TestResult.ResultType.*
import org.gradle.internal.operations.OperationIdentifier import org.gradle.internal.operations.OperationIdentifier
import org.gradle.process.internal.ExecHandle import org.gradle.process.internal.ExecHandle
import org.jetbrains.kotlin.gradle.internal.LogType import org.jetbrains.kotlin.gradle.internal.LogType
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
import org.jetbrains.kotlin.gradle.utils.LegacyTestDescriptorInternal import org.jetbrains.kotlin.gradle.utils.LegacyTestDescriptorInternal
@@ -35,7 +36,8 @@ data class TCServiceMessagesClientSettings(
internal open class TCServiceMessagesClient( internal open class TCServiceMessagesClient(
private val results: TestResultProcessor, private val results: TestResultProcessor,
val settings: TCServiceMessagesClientSettings, val settings: TCServiceMessagesClientSettings,
val log: Logger val log: Logger,
val testReporter: MppTestReportHelper,
) : ServiceMessageParserCallback { ) : ServiceMessageParserCallback {
lateinit var rootOperationId: OperationIdentifier lateinit var rootOperationId: OperationIdentifier
var afterMessage = false var afterMessage = false
@@ -155,7 +157,8 @@ internal open class TCServiceMessagesClient(
} }
private fun TestNode.failure( private fun TestNode.failure(
message: TestFailed message: TestFailed,
isAssertionFailure: Boolean = true,
) { ) {
hasFailures = true hasFailures = true
@@ -173,18 +176,16 @@ internal open class TCServiceMessagesClient(
val parsedStackTrace = settings.stackTraceParser(stacktrace) val parsedStackTrace = settings.stackTraceParser(stacktrace)
val failMessage = parsedStackTrace?.message ?: message.failureMessage val failMessage = parsedStackTrace?.message ?: message.failureMessage
results.failure( val exceptionClassName = failMessage?.let { extractExceptionClassName(it) } ?: "Unknown"
descriptor.id, val rawFailure = KotlinTestFailure(
KotlinTestFailure( exceptionClassName,
failMessage?.let { extractExceptionClassName(it) } failMessage,
?: "Unknown", stacktrace,
failMessage, patchStackTrace(this, parsedStackTrace?.stackTrace),
stacktrace, message.expected,
patchStackTrace(this, parsedStackTrace?.stackTrace), message.actual,
message.expected,
message.actual
)
) )
testReporter.reportFailure(results, descriptor.id, rawFailure, isAssertionFailure)
} }
private fun extractExceptionClassName(message: String): String = private fun extractExceptionClassName(message: String): String =
@@ -527,7 +528,7 @@ internal open class TCServiceMessagesClient(
if (currentLeaf is TestNode) { if (currentLeaf is TestNode) {
currentTest = currentLeaf currentTest = currentLeaf
output.append(currentLeaf.allOutput) output.append(currentLeaf.allOutput)
currentLeaf.failure(TestFailed(currentLeaf.cleanName, null as Throwable?)) currentLeaf.failure(TestFailed(currentLeaf.cleanName, null as Throwable?), false)
} }
close(ts, currentLeaf.localId) close(ts, currentLeaf.localId)
@@ -13,6 +13,7 @@ import org.gradle.process.ExecResult
import org.gradle.process.ProcessForkOptions import org.gradle.process.ProcessForkOptions
import org.gradle.process.internal.ExecHandle import org.gradle.process.internal.ExecHandle
import org.gradle.process.internal.ExecHandleFactory import org.gradle.process.internal.ExecHandleFactory
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.OutputStream import java.io.OutputStream
@@ -24,8 +25,12 @@ open class TCServiceMessagesTestExecutionSpec(
val clientSettings: TCServiceMessagesClientSettings, val clientSettings: TCServiceMessagesClientSettings,
val dryRunArgs: List<String>? = null, val dryRunArgs: List<String>? = null,
) : TestExecutionSpec { ) : TestExecutionSpec {
internal open fun createClient(testResultProcessor: TestResultProcessor, log: Logger): TCServiceMessagesClient = internal open fun createClient(
TCServiceMessagesClient(testResultProcessor, clientSettings, log) testResultProcessor: TestResultProcessor,
log: Logger,
testReporter: MppTestReportHelper,
): TCServiceMessagesClient =
TCServiceMessagesClient(testResultProcessor, clientSettings, log, testReporter)
internal open fun wrapExecute(body: () -> Unit) = body() internal open fun wrapExecute(body: () -> Unit) = body()
internal open fun showSuppressedOutput() = Unit internal open fun showSuppressedOutput() = Unit
@@ -38,7 +43,8 @@ class TCServiceMessagesTestExecutor(
val buildOperationExecutor: BuildOperationExecutor, val buildOperationExecutor: BuildOperationExecutor,
val runListeners: MutableList<KotlinTestRunnerListener>, val runListeners: MutableList<KotlinTestRunnerListener>,
val ignoreTcsmOverflow: Boolean, val ignoreTcsmOverflow: Boolean,
val ignoreRunFailures: Boolean val ignoreRunFailures: Boolean,
val testReporter: MppTestReportHelper,
) : TestExecuter<TCServiceMessagesTestExecutionSpec> { ) : TestExecuter<TCServiceMessagesTestExecutionSpec> {
private lateinit var execHandle: ExecHandle private lateinit var execHandle: ExecHandle
var outputReaderThread: Thread? = null var outputReaderThread: Thread? = null
@@ -48,7 +54,7 @@ class TCServiceMessagesTestExecutor(
spec.wrapExecute { spec.wrapExecute {
val rootOperation = buildOperationExecutor.currentOperation.parentId!! val rootOperation = buildOperationExecutor.currentOperation.parentId!!
val client = spec.createClient(testResultProcessor, log) val client = spec.createClient(testResultProcessor, log, testReporter)
if (spec.dryRunArgs != null) { if (spec.dryRunArgs != null) {
val exec = execHandleFactory.newExec() val exec = execHandleFactory.newExec()
@@ -146,6 +146,11 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class, ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class,
DefaultConfigurationTimePropertiesAccessorVariantFactory() DefaultConfigurationTimePropertiesAccessorVariantFactory()
) )
factories.putIfAbsent(
MppTestReportHelper.MppTestReportHelperVariantFactory::class,
DefaultMppTestReportHelperVariantFactory()
)
} }
protected fun setupAttributeMatchingStrategy( protected fun setupAttributeMatchingStrategy(
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin.internal
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.internal.tasks.testing.TestStartEvent
import org.gradle.api.tasks.testing.TestFailure
import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
/**
* Handles differences in internal Gradle testing API before and since Gradle 7.6
*/
interface MppTestReportHelper {
fun reportFailure(
results: TestResultProcessor,
id: Any,
failure: KotlinTestFailure,
isAssertionFailure: Boolean,
)
fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String): TestResultProcessor
interface MppTestReportHelperVariantFactory : VariantImplementationFactories.VariantImplementationFactory {
fun getInstance(): MppTestReportHelper
}
}
internal class DefaultMppTestReportHelperVariantFactory : MppTestReportHelper.MppTestReportHelperVariantFactory {
override fun getInstance(): MppTestReportHelper = DefaultMppTestReportHelper()
}
internal class DefaultMppTestReportHelper : MppTestReportHelper {
override fun reportFailure(
results: TestResultProcessor,
id: Any,
failure: KotlinTestFailure,
isAssertionFailure: Boolean,
) {
results.failure(
id,
if (isAssertionFailure) {
TestFailure.fromTestAssertionFailure(failure, failure.expected, failure.actual)
} else {
TestFailure.fromTestFrameworkFailure(failure)
}
)
}
@Suppress("DuplicatedCode") // the delegating processor implements different interfaces with the same code
override fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String) =
object : TestResultProcessor by origin {
override fun started(test: TestDescriptorInternal, event: TestStartEvent) {
val myTest = object : TestDescriptorInternal by test {
override fun getDisplayName(): String = "${test.displayName}[$targetName]"
override fun getClassName(): String? = test.className?.replace('$', '.')
override fun getClassDisplayName(): String? = test.classDisplayName?.replace('$', '.')
}
origin.started(myTest, event)
}
}
}
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.gradle.internal.LogType
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
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.slf4j.Logger import org.slf4j.Logger
internal open class JSServiceMessagesTestExecutionSpec( internal open class JSServiceMessagesTestExecutionSpec(
@@ -24,11 +25,12 @@ internal open class JSServiceMessagesTestExecutionSpec(
checkExitCode, checkExitCode,
clientSettings clientSettings
) { ) {
override fun createClient(testResultProcessor: TestResultProcessor, log: Logger): TCServiceMessagesClient { override fun createClient(testResultProcessor: TestResultProcessor, log: Logger, testReporter: MppTestReportHelper): TCServiceMessagesClient {
return JSServiceMessagesClient( return JSServiceMessagesClient(
results = testResultProcessor, results = testResultProcessor,
settings = clientSettings, settings = clientSettings,
log = log log = log,
testReporter = testReporter,
) )
} }
} }
@@ -36,8 +38,9 @@ internal open class JSServiceMessagesTestExecutionSpec(
internal open class JSServiceMessagesClient( internal open class JSServiceMessagesClient(
results: TestResultProcessor, results: TestResultProcessor,
settings: TCServiceMessagesClientSettings, settings: TCServiceMessagesClientSettings,
log: Logger log: Logger,
) : TCServiceMessagesClient(results, settings, log) { testReporter: MppTestReportHelper,
) : TCServiceMessagesClient(results, settings, log, testReporter) {
override fun printNonTestOutput(text: String, type: LogType?) { override fun printNonTestOutput(text: String, type: LogType?) {
if (log.isDebugEnabled) { if (log.isDebugEnabled) {
log.debug(text) log.debug(text)
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecuti
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.targets.js.* import org.jetbrains.kotlin.gradle.targets.js.*
import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl.Companion.webpackRulesContainer import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl.Companion.webpackRulesContainer
@@ -467,11 +468,12 @@ class KotlinKarma(
} }
} }
override fun createClient(testResultProcessor: TestResultProcessor, log: Logger) = override fun createClient(testResultProcessor: TestResultProcessor, log: Logger, testReporter: MppTestReportHelper) =
object : JSServiceMessagesClient( object : JSServiceMessagesClient(
testResultProcessor, testResultProcessor,
clientSettings, clientSettings,
log log,
testReporter,
) { ) {
val baseTestNameSuffix get() = settings.testNameSuffix val baseTestNameSuffix get() = settings.testNameSuffix
override var testNameSuffix: String? = baseTestNameSuffix override var testNameSuffix: String? = baseTestNameSuffix
@@ -10,9 +10,8 @@ import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.testing.Test import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.TestFilter import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactoryProvider
import org.jetbrains.kotlin.gradle.plugin.KotlinTestRun
@CacheableTask @CacheableTask
open class KotlinJvmTest : Test() { open class KotlinJvmTest : Test() {
@@ -20,28 +19,25 @@ open class KotlinJvmTest : Test() {
@Optional @Optional
var targetName: String? = null var targetName: String? = null
private val testReporter = project.gradle
.variantImplementationFactoryProvider<MppTestReportHelper.MppTestReportHelperVariantFactory>()
.map { it.getInstance() }
override fun createTestExecuter(): TestExecuter<JvmTestExecutionSpec> = override fun createTestExecuter(): TestExecuter<JvmTestExecutionSpec> =
if (targetName != null) Executor( if (targetName != null) Executor(
super.createTestExecuter(), super.createTestExecuter(),
targetName!! targetName!!,
testReporter.get(),
) )
else super.createTestExecuter() else super.createTestExecuter()
class Executor( class Executor(
private val delegate: TestExecuter<JvmTestExecutionSpec>, private val delegate: TestExecuter<JvmTestExecutionSpec>,
private val targetName: String private val targetName: String,
private val testReporter: MppTestReportHelper,
) : TestExecuter<JvmTestExecutionSpec> by delegate { ) : TestExecuter<JvmTestExecutionSpec> by delegate {
override fun execute(testExecutionSpec: JvmTestExecutionSpec, testResultProcessor: TestResultProcessor) { override fun execute(testExecutionSpec: JvmTestExecutionSpec, testResultProcessor: TestResultProcessor) {
delegate.execute(testExecutionSpec, object : TestResultProcessor by testResultProcessor { delegate.execute(testExecutionSpec, testReporter.createDelegatingTestReportProcessor(testResultProcessor, targetName))
override fun started(test: TestDescriptorInternal, event: TestStartEvent) {
val myTest = object : TestDescriptorInternal by test {
override fun getDisplayName(): String = "${test.displayName}[$targetName]"
override fun getClassName(): String? = test.className?.replace('$', '.')
override fun getClassDisplayName(): String? = test.classDisplayName?.replace('$', '.')
}
testResultProcessor.started(myTest, event)
}
})
} }
} }
} }
@@ -15,6 +15,8 @@ import org.gradle.process.internal.ExecHandleFactory
import org.jetbrains.kotlin.gradle.internal.testing.KotlinTestRunnerListener import org.jetbrains.kotlin.gradle.internal.testing.KotlinTestRunnerListener
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactoryProvider
import org.jetbrains.kotlin.gradle.utils.injected import org.jetbrains.kotlin.gradle.utils.injected
import javax.inject.Inject import javax.inject.Inject
@@ -62,11 +64,16 @@ abstract class KotlinTest : AbstractTestTask() {
PropertiesProvider(project).ignoreTcsmOverflow PropertiesProvider(project).ignoreTcsmOverflow
} }
private val testReporter = project.gradle
.variantImplementationFactoryProvider<MppTestReportHelper.MppTestReportHelperVariantFactory>()
.map { it.getInstance() }
override fun createTestExecuter() = TCServiceMessagesTestExecutor( override fun createTestExecuter() = TCServiceMessagesTestExecutor(
execHandleFactory, execHandleFactory,
buildOperationExecutor, buildOperationExecutor,
runListeners, runListeners,
ignoreTcsmOverflow, ignoreTcsmOverflow,
ignoreRunFailures ignoreRunFailures,
testReporter.get(),
) )
} }
@@ -9,13 +9,16 @@ import org.gradle.internal.serialize.PlaceholderException
import java.io.PrintWriter import java.io.PrintWriter
/** /**
* Class to be shown in default Gradle tests console reporter. * Class to be shown in the default Gradle tests console reporter.
* *
* Example console output: * Example console output:
* ``` * ```
* sample.SampleTests.testMe FAILED * sample.SampleTests.testMe FAILED
* AssertionError at mpplib2/src/commonTest/kotlin/sample/SampleTests.kt:9 * AssertionError at mpplib2/src/commonTest/kotlin/sample/SampleTests.kt:9
* ``` * ```
*
* Inherits [PlaceholderException] in order to override a displayed exception-class name,
* e.g. [kotlin.AssertionError] instead of [KotlinTestFailure]
*/ */
class KotlinTestFailure( class KotlinTestFailure(
className: String, className: String,
@@ -145,4 +145,6 @@ private fun Project.registerVariantImplementations() {
IdeaSyncDetectorG70.IdeaSyncDetectorVariantFactoryG70() IdeaSyncDetectorG70.IdeaSyncDetectorVariantFactoryG70()
factories[ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class] = factories[ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class] =
ConfigurationTimePropertiesAccessorG70.ConfigurationTimePropertiesAccessorVariantFactoryG70() ConfigurationTimePropertiesAccessorG70.ConfigurationTimePropertiesAccessorVariantFactoryG70()
factories[MppTestReportHelper.MppTestReportHelperVariantFactory::class] =
MppTestReportHelperG70.MppTestReportHelperVariantFactoryG70()
} }
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin.internal
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.internal.tasks.testing.TestStartEvent
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
internal class MppTestReportHelperG70 : MppTestReportHelper {
internal class MppTestReportHelperVariantFactoryG70 :
MppTestReportHelper.MppTestReportHelperVariantFactory {
override fun getInstance(): MppTestReportHelper = MppTestReportHelperG70()
}
override fun reportFailure(
results: TestResultProcessor,
id: Any,
failure: KotlinTestFailure,
isAssertionFailure: Boolean,
) {
results.failure(
id,
failure,
)
}
@Suppress("DuplicatedCode") // the delegating processor implements different interfaces with the same code
override fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String) =
object : TestResultProcessor by origin {
override fun started(test: TestDescriptorInternal, event: TestStartEvent) {
val myTest = object : TestDescriptorInternal by test {
override fun getDisplayName(): String = "${test.displayName}[$targetName]"
override fun getClassName(): String? = test.className?.replace('$', '.')
override fun getClassDisplayName(): String? = test.classDisplayName?.replace('$', '.')
}
origin.started(myTest, event)
}
}
}
@@ -12,9 +12,8 @@ import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessor import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessorG71 import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessorG71
import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetector
import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetectorG71 import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetectorG71
import javax.inject.Inject import javax.inject.Inject
@@ -147,4 +146,6 @@ private fun Project.registerVariantImplementations() {
IdeaSyncDetectorG71.IdeaSyncDetectorVariantFactoryG71() IdeaSyncDetectorG71.IdeaSyncDetectorVariantFactoryG71()
factories[ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class] = factories[ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class] =
ConfigurationTimePropertiesAccessorG71.ConfigurationTimePropertiesAccessorVariantFactoryG71() ConfigurationTimePropertiesAccessorG71.ConfigurationTimePropertiesAccessorVariantFactoryG71()
factories[MppTestReportHelper.MppTestReportHelperVariantFactory::class] =
MppTestReportHelperG71.MppTestReportHelperVariantFactoryG71()
} }
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin.internal
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.internal.tasks.testing.TestStartEvent
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
internal class MppTestReportHelperG71 : MppTestReportHelper {
internal class MppTestReportHelperVariantFactoryG71 :
MppTestReportHelper.MppTestReportHelperVariantFactory {
override fun getInstance(): MppTestReportHelper = MppTestReportHelperG71()
}
override fun reportFailure(
results: TestResultProcessor,
id: Any,
failure: KotlinTestFailure,
isAssertionFailure: Boolean,
) {
results.failure(
id,
failure,
)
}
@Suppress("DuplicatedCode") // the delegating processor implements different interfaces with the same code
override fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String) =
object : TestResultProcessor by origin {
override fun started(test: TestDescriptorInternal, event: TestStartEvent) {
val myTest = object : TestDescriptorInternal by test {
override fun getDisplayName(): String = "${test.displayName}[$targetName]"
override fun getClassName(): String? = test.className?.replace('$', '.')
override fun getClassDisplayName(): String? = test.classDisplayName?.replace('$', '.')
}
origin.started(myTest, event)
}
}
}
@@ -12,6 +12,8 @@ import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelperG75
import javax.inject.Inject import javax.inject.Inject
private const val PLUGIN_VARIANT_NAME = "gradle75" private const val PLUGIN_VARIANT_NAME = "gradle75"
@@ -137,7 +139,8 @@ open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
} }
} }
@Suppress("UnusedReceiverParameter")
private fun Project.registerVariantImplementations() { private fun Project.registerVariantImplementations() {
val factories = VariantImplementationFactories.get(gradle)
factories[MppTestReportHelper.MppTestReportHelperVariantFactory::class] =
MppTestReportHelperG75.MppTestReportHelperVariantFactoryG75()
} }
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin.internal
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.internal.tasks.testing.TestStartEvent
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
internal class MppTestReportHelperG75 : MppTestReportHelper {
internal class MppTestReportHelperVariantFactoryG75 :
MppTestReportHelper.MppTestReportHelperVariantFactory {
override fun getInstance(): MppTestReportHelper = MppTestReportHelperG75()
}
override fun reportFailure(
results: TestResultProcessor,
id: Any,
failure: KotlinTestFailure,
isAssertionFailure: Boolean,
) {
results.failure(
id,
failure,
)
}
@Suppress("DuplicatedCode") // the delegating processor implements different interfaces with the same code
override fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String) =
object : TestResultProcessor by origin {
override fun started(test: TestDescriptorInternal, event: TestStartEvent) {
val myTest = object : TestDescriptorInternal by test {
override fun getDisplayName(): String = "${test.displayName}[$targetName]"
override fun getClassName(): String? = test.className?.replace('$', '.')
override fun getClassDisplayName(): String? = test.classDisplayName?.replace('$', '.')
}
origin.started(myTest, event)
}
}
}
@@ -151,4 +151,6 @@ private fun Project.registerVariantImplementations() {
IdeaSyncDetectorG6.IdeaSyncDetectorVariantFactoryG6() IdeaSyncDetectorG6.IdeaSyncDetectorVariantFactoryG6()
factories[ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class] = factories[ConfigurationTimePropertiesAccessor.ConfigurationTimePropertiesAccessorVariantFactory::class] =
ConfigurationTimePropertiesAccessorG6.ConfigurationTimePropertiesAccessorVariantFactoryG6() ConfigurationTimePropertiesAccessorG6.ConfigurationTimePropertiesAccessorVariantFactoryG6()
factories[MppTestReportHelper.MppTestReportHelperVariantFactory::class] =
MppTestReportHelperG6.MppTestReportHelperVariantFactoryG6()
} }
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin.internal
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.internal.tasks.testing.TestStartEvent
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
internal class MppTestReportHelperG6 : MppTestReportHelper {
internal class MppTestReportHelperVariantFactoryG6 :
MppTestReportHelper.MppTestReportHelperVariantFactory {
override fun getInstance(): MppTestReportHelper = MppTestReportHelperG6()
}
override fun reportFailure(
results: TestResultProcessor,
id: Any,
failure: KotlinTestFailure,
isAssertionFailure: Boolean,
) {
results.failure(
id,
failure,
)
}
@Suppress("DuplicatedCode") // the delegating processor implements different interfaces with the same code
override fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String) =
object : TestResultProcessor by origin {
override fun started(test: TestDescriptorInternal, event: TestStartEvent) {
val myTest = object : TestDescriptorInternal by test {
override fun getDisplayName(): String = "${test.displayName}[$targetName]"
override fun getClassName(): String? = test.className?.replace('$', '.')
override fun getClassDisplayName(): String? = test.classDisplayName?.replace('$', '.')
}
origin.started(myTest, event)
}
}
}
@@ -1,10 +1,13 @@
package org.jetbrains.kotlin.gradle.internal.testing.tcsmc package org.jetbrains.kotlin.gradle.internal.testing.tcsmc
import jetbrains.buildServer.messages.serviceMessages.ServiceMessage import jetbrains.buildServer.messages.serviceMessages.ServiceMessage
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.internal.operations.OperationIdentifier import org.gradle.internal.operations.OperationIdentifier
import org.jetbrains.kotlin.gradle.internal.testing.RecordingTestResultProcessor import org.jetbrains.kotlin.gradle.internal.testing.RecordingTestResultProcessor
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.plugin.internal.MppTestReportHelper
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
import org.jetbrains.kotlin.test.util.trimTrailingWhitespaces import org.jetbrains.kotlin.test.util.trimTrailingWhitespaces
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -38,7 +41,15 @@ open class TCServiceMessagesClientTest {
rootNodeName, rootNodeName,
treatFailedTestOutputAsStacktrace = treatFailedTestOutputAsStacktrace treatFailedTestOutputAsStacktrace = treatFailedTestOutputAsStacktrace
), ),
LoggerFactory.getLogger("test") LoggerFactory.getLogger("test"),
object : MppTestReportHelper {
override fun reportFailure(results: TestResultProcessor, id: Any, failure: KotlinTestFailure, isAssertionFailure: Boolean) {
results.failure(id, failure)
}
override fun createDelegatingTestReportProcessor(origin: TestResultProcessor, targetName: String): TestResultProcessor =
origin
}
) )
} }