Skip to content

Commit

Permalink
Implemented ability to specify instrumentation include filter
Browse files Browse the repository at this point in the history
Resolves #673

PR #681
  • Loading branch information
shanshin authored Aug 28, 2024
1 parent b8c1ddb commit 8b7d17c
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 13 deletions.
1 change: 1 addition & 0 deletions kover-gradle-plugin/api/kover-gradle-plugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverProjectInst
public abstract fun getDisabledForAll ()Lorg/gradle/api/provider/Property;
public abstract fun getDisabledForTestTasks ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getExcludedClasses ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getIncludedClasses ()Lorg/gradle/api/provider/SetProperty;
}

public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportFilter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
package kotlinx.kover.gradle.plugin.test.functional.cases

import kotlinx.kover.gradle.plugin.test.functional.framework.checker.defaultTestTaskName
import kotlinx.kover.gradle.plugin.test.functional.framework.configurator.*
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.*

Expand Down Expand Up @@ -31,6 +30,44 @@ internal class InstrumentationFilteringTests {
}
}

@SlicedGeneratedTest(all = true)
fun BuildConfigurator.testInclude() {
addProjectWithKover {
sourcesFrom("simple")

kover {
currentProject {
instrumentation {
includedClasses.add("*.ExampleClass")
}
}
}
}
}

@SlicedGeneratedTest(all = true)
fun BuildConfigurator.testMixed() {
addProjectWithKover {
sourcesFrom("simple")

kover {
currentProject {
instrumentation {
includedClasses.add("*Class")
excludedClasses.add("*.SecondClass")
}
}
}
}

run("build", "koverXmlReport") {
xmlReport {
classCounter("org.jetbrains.ExampleClass").assertCovered()
classCounter("org.jetbrains.SecondClass").assertFullyMissed()
}
}
}

@SlicedGeneratedTest(allLanguages = true)
fun BuildConfigurator.testDisableAll() {
addProjectWithKover {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ private fun KoverProjectInstrumentation.wrap(project: Project): KoverMergingInst
override val disabledForAll: Property<Boolean> = this@wrap.disabledForAll
override val disabledForTestTasks: SetProperty<String> = this@wrap.disabledForTestTasks
override val excludedClasses: SetProperty<String> = this@wrap.excludedClasses
override val includedClasses: SetProperty<String> = this@wrap.includedClasses
override val project: Project = project
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ internal fun TaskCollection<Test>.instrument(
koverContext.findAgentJarTask.map { it.agentJar.get().asFile },
taskInstrumentationDisabled,
excludedClassesWithAndroid,
current.instrumentation.includedClasses,
binReportProvider
)
}
Expand All @@ -87,6 +88,9 @@ private class JvmTestTaskArgumentProvider(
@get:Input
val excludedClasses: Provider<Set<String>>,

@get:Input
val includedClasses: Provider<Set<String>>,

@get:OutputFile
val reportProvider: Provider<RegularFile>
) : CommandLineArgumentProvider, Named {
Expand All @@ -103,8 +107,13 @@ private class JvmTestTaskArgumentProvider(
override fun asArguments(): MutableIterable<String> {
return if (!instrumentationDisabled.get()) {
toolProvider.get()
.jvmAgentArgs(agentJar.get(), tempDir, reportProvider.get().asFile, excludedClasses.get())
.toMutableList()
.jvmAgentArgs(
agentJar.get(),
tempDir,
reportProvider.get().asFile,
excludedClasses.get(),
includedClasses.get()
).toMutableList()
} else {
mutableListOf()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,18 @@ public interface KoverProjectInstrumentation {

/**
* Disable instrumentation in test tasks of specified classes
*
* Classes in [excludedClasses] have priority over classes from [includedClasses].
*/
public val excludedClasses: SetProperty<String>

/**
* Enable instrumentation in test tasks only of specified classes.
* All other classes will not be instrumented.
*
* Classes in [excludedClasses] have priority over classes from [includedClasses].
*/
public val includedClasses: SetProperty<String>
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal abstract class KoverCurrentProjectVariantsConfigImpl @Inject constructo

instrumentation.disabledForAll.convention(false)
instrumentation.excludedClasses.convention(emptySet())
instrumentation.includedClasses.convention(emptySet())
instrumentation.disabledForTestTasks.convention(emptySet())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,13 @@ internal interface CoverageTool {
/**
* Generate additional JVM argument for test task.
*/
fun jvmAgentArgs(jarFile: File, tempDir: File, binReportFile: File, excludedClasses: Set<String>): List<String>
fun jvmAgentArgs(
jarFile: File,
tempDir: File,
binReportFile: File,
excludedClasses: Set<String>,
includedClasses: Set<String>
): List<String>

/**
* Generate XML report.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ package kotlinx.kover.gradle.plugin.tools.jacoco

import java.io.*

internal fun buildJvmAgentArgs(jarFile: File, binReportFile: File, excludedClasses: Set<String>): List<String> {
internal fun buildJvmAgentArgs(
jarFile: File,
binReportFile: File,
excludedClasses: Set<String>,
includedClasses: Set<String>
): List<String> {
val agentArgs = listOfNotNull(
"destfile=${binReportFile.canonicalPath},append=true,inclnolocationclasses=true,dumponexit=true,output=file,jmx=false",
excludedClasses.joinToFilterString("excludes")
excludedClasses.joinToFilterString("excludes"), includedClasses.joinToFilterString("includes"),
).joinToString(",")

return listOf("-javaagent:${jarFile.canonicalPath}=$agentArgs")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ internal class JacocoTool(override val variant: CoverageToolVariant) : CoverageT
jarFile: File,
tempDir: File,
binReportFile: File,
excludedClasses: Set<String>
excludedClasses: Set<String>,
includedClasses: Set<String>
): List<String> {
return buildJvmAgentArgs(jarFile, binReportFile, excludedClasses)
return buildJvmAgentArgs(jarFile, binReportFile, excludedClasses, includedClasses)
}

override fun xmlReport(xmlFile: File, title: String, context: ReportContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ internal fun buildJvmAgentArgs(
jarFile: File,
tempDir: File,
binReportFile: File,
excludedClasses: Set<String>
excludedClasses: Set<String>,
includedClasses: Set<String>
): List<String> {
val argsFile = tempDir.resolve("kover-agent.args")
argsFile.writeAgentArgs(binReportFile, excludedClasses)
argsFile.writeAgentArgs(binReportFile, excludedClasses, includedClasses)

return mutableListOf("-javaagent:${jarFile.canonicalPath}=file:${argsFile.canonicalPath}")
}

private fun File.writeAgentArgs(binReportFile: File, excludedClasses: Set<String>) {
private fun File.writeAgentArgs(binReportFile: File, excludedClasses: Set<String>, includedClasses: Set<String>) {
binReportFile.parentFile.mkdirs()
val binReportPath = binReportFile.canonicalPath

Expand All @@ -27,5 +28,8 @@ private fun File.writeAgentArgs(binReportFile: File, excludedClasses: Set<String
excludedClasses.forEach { e ->
pw.append("exclude=").appendLine(e)
}
includedClasses.forEach { e ->
pw.append("include=").appendLine(e)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ internal class KoverTool(override val variant: CoverageToolVariant) : CoverageTo
jarFile: File,
tempDir: File,
binReportFile: File,
excludedClasses: Set<String>
excludedClasses: Set<String>,
includedClasses: Set<String>
): List<String> {
return buildJvmAgentArgs(jarFile, tempDir, binReportFile, excludedClasses)
return buildJvmAgentArgs(jarFile, tempDir, binReportFile, excludedClasses, includedClasses)
}

override fun xmlReport(xmlFile: File, title: String, context: ReportContext) {
Expand Down

0 comments on commit 8b7d17c

Please sign in to comment.