From 66c5778da806888829db0ddc8223df384001b3a7 Mon Sep 17 00:00:00 2001 From: "Sergey.Shanshin" Date: Thu, 20 Jan 2022 14:02:12 +0300 Subject: [PATCH] Added support of parallel tests execution Fixes #113 --- src/main/kotlin/kotlinx/kover/KoverPlugin.kt | 36 ++++++++++++++++--- .../kover/engines/intellij/IntellijAgent.kt | 2 +- .../kover/engines/jacoco/JacocoAgent.kt | 2 +- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/kotlinx/kover/KoverPlugin.kt b/src/main/kotlin/kotlinx/kover/KoverPlugin.kt index e2f1895f..c1b6c129 100644 --- a/src/main/kotlin/kotlinx/kover/KoverPlugin.kt +++ b/src/main/kotlin/kotlinx/kover/KoverPlugin.kt @@ -102,7 +102,7 @@ class KoverPlugin : Plugin { } tasks.withType(Test::class.java).configureEach { t -> - t.configTest(providers, agents) + t.configTestTask(providers, agents) } } @@ -238,7 +238,7 @@ class KoverPlugin : Plugin { return extension } - private fun Test.configTest( + private fun Test.configTestTask( providers: AllProviders, agents: Map ) { @@ -263,7 +263,8 @@ class KoverPlugin : Plugin { ) ) - doLast(IntellijErrorLogChecker(taskExtension)) + doFirst(BinaryReportCleanupAction(providers.koverExtension, taskExtension)) + doLast(IntellijErrorLogCopyAction(taskExtension)) } private fun Project.checkAlreadyApplied() { @@ -278,7 +279,34 @@ class KoverPlugin : Plugin { } } -private class IntellijErrorLogChecker(private val taskExtension: KoverTaskExtension) : Action { +/* + To support parallel tests, both Coverage Engines work in append to data file mode. + For this reason, before starting the tests, it is necessary to clear the file from the results of previous runs. +*/ +private class BinaryReportCleanupAction( + private val koverExtensionProvider: Provider, + private val taskExtension: KoverTaskExtension +) : Action { + override fun execute(task: Task) { + val koverExtension = koverExtensionProvider.get() + val file = taskExtension.binaryReportFile.get() + + // always delete previous data file + file.delete() + + if (!taskExtension.isDisabled + && !koverExtension.isDisabled + && !koverExtension.disabledProjects.contains(task.project.name) + && koverExtension.coverageEngine.get() == CoverageEngine.INTELLIJ + ) { + // IntelliJ engine expected empty file for parallel test execution. + // Since it is impossible to know in advance whether the tests will be run in parallel, we always create an empty file. + file.createNewFile() + } + } +} + +private class IntellijErrorLogCopyAction(private val taskExtension: KoverTaskExtension) : Action { override fun execute(task: Task) { task.project.copyIntellijErrorLog( task.project.layout.buildDirectory.get().file("kover/errors/${task.name}.log").asFile, diff --git a/src/main/kotlin/kotlinx/kover/engines/intellij/IntellijAgent.kt b/src/main/kotlin/kotlinx/kover/engines/intellij/IntellijAgent.kt index 0ec50149..bc88d76f 100644 --- a/src/main/kotlin/kotlinx/kover/engines/intellij/IntellijAgent.kt +++ b/src/main/kotlin/kotlinx/kover/engines/intellij/IntellijAgent.kt @@ -21,7 +21,7 @@ internal fun Project.createIntellijAgent(koverExtension: KoverExtension): Covera private class IntellijAgent(private val config: Configuration): CoverageAgent { private val trackingPerTest = false // a flag to enable tracking per test coverage private val calculateForUnloadedClasses = false // a flag to calculate coverage for unloaded classes - private val appendToDataFile = false // a flag to use data file as initial coverage + private val appendToDataFile = true // a flag to use data file as initial coverage private val samplingMode = false //a flag to run coverage in sampling mode or in tracing mode otherwise override val engine: CoverageEngine = CoverageEngine.INTELLIJ diff --git a/src/main/kotlin/kotlinx/kover/engines/jacoco/JacocoAgent.kt b/src/main/kotlin/kotlinx/kover/engines/jacoco/JacocoAgent.kt index 71988042..9ea7fe88 100644 --- a/src/main/kotlin/kotlinx/kover/engines/jacoco/JacocoAgent.kt +++ b/src/main/kotlin/kotlinx/kover/engines/jacoco/JacocoAgent.kt @@ -37,7 +37,7 @@ private class JacocoAgent(private val config: Configuration, private val project return listOfNotNull( "destfile=${binary.canonicalPath}", - "append=false", // Kover don't support parallel execution of one task + "append=true", "inclnolocationclasses=false", "dumponexit=true", "output=file",