Skip to content

Commit

Permalink
Add configuration cache tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
TadeasKriz committed Apr 14, 2024
1 parent f06170e commit b7ec023
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package co.touchlab.skie.plugin.configuration

import co.touchlab.skie.plugin.util.SkieTarget
import co.touchlab.skie.plugin.configuration.SkieExtension.Companion.buildConfiguration
import co.touchlab.skie.plugin.configuration.util.GradleSkieConfiguration
import co.touchlab.skie.plugin.configuration.util.GradleSkieConfigurationData
import co.touchlab.skie.plugin.directory.createSkieBuildDirectoryTask
import co.touchlab.skie.plugin.util.registerSkieTargetBasedTask
import co.touchlab.skie.plugin.util.skieBuildDirectory
Expand All @@ -20,7 +20,7 @@ import java.io.File
internal abstract class CreateSkieConfigurationTask : DefaultTask() {

@get:Input
abstract val configuration: Property<GradleSkieConfiguration>
abstract val configuration: Property<GradleSkieConfigurationData>

@get:OutputFile
abstract val configurationFile: Property<File>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package co.touchlab.skie.test.annotation.filter

import kotlin.reflect.KClass

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
annotation class FilterMatrixWith(
val value: KClass<out MatrixFilter>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package co.touchlab.skie.test.annotation.filter

import co.touchlab.skie.test.runner.SkieTestMatrixSource
import org.junit.jupiter.api.extension.ExtensionContext

interface MatrixFilter {
fun apply(context: ExtensionContext, source: SkieTestMatrixSource)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package co.touchlab.skie.test.annotation.filter

import co.touchlab.skie.test.filter.OnlyConfigurationCacheMatrixFilter

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
@FilterMatrixWith(OnlyConfigurationCacheMatrixFilter::class)
annotation class OnlyConfigurationCache
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package co.touchlab.skie.test.annotation.filter

import co.touchlab.skie.test.filter.OnlyForMatrixFilter
import co.touchlab.skie.test.runner.BuildConfiguration
import co.touchlab.skie.test.util.LinkMode
import co.touchlab.skie.test.util.RawKotlinTarget
import org.intellij.lang.annotations.Language

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
@FilterMatrixWith(OnlyForMatrixFilter::class)
annotation class OnlyFor(
val targets: Array<RawKotlinTarget> = [],
val configurations: Array<BuildConfiguration> = [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import co.touchlab.skie.test.trait.TestUtilsTrait
import co.touchlab.skie.test.trait.gradle.GradleBuildFileBuilderTrait
import co.touchlab.skie.test.util.CommandResult
import co.touchlab.skie.test.util.KotlinTarget
import co.touchlab.skie.test.util.StringBuilderScope
import co.touchlab.skie.test.util.execute
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
Expand Down Expand Up @@ -58,9 +59,10 @@ abstract class BaseGradleTests: TestUtilsTrait, GradleBuildFileBuilderTrait {

@BeforeEach
fun createGradlePropertiesFile() {
gradlePropertiesFile("""
org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=1g -XX:+UseParallelGC
""".trimIndent())
gradlePropertiesFile {
+"org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=1g -XX:+UseParallelGC\n"
appendAdditionalGradleProperties()
}
}

fun runGradle(
Expand Down Expand Up @@ -144,4 +146,6 @@ abstract class BaseGradleTests: TestUtilsTrait, GradleBuildFileBuilderTrait {
"build/bin/${target.id}/${configuration.name.lowercase()}Framework"
}
}

protected open fun StringBuilderScope.appendAdditionalGradleProperties() { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package co.touchlab.skie.test.filter

import co.touchlab.skie.test.annotation.filter.MatrixFilter
import co.touchlab.skie.test.runner.SkieTestMatrixSource
import org.junit.jupiter.api.extension.ExtensionContext

object OnlyConfigurationCacheMatrixFilter : MatrixFilter {
override fun apply(context: ExtensionContext, source: SkieTestMatrixSource) {
source.kotlinVersions.removeAll { kotlinVersion ->
kotlinVersion.value.startsWith("1.8.") ||
kotlinVersion.value.startsWith("1.9.0") ||
kotlinVersion.value.startsWith("1.9.1")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package co.touchlab.skie.test.filter

import co.touchlab.skie.test.annotation.filter.MatrixFilter
import co.touchlab.skie.test.annotation.filter.OnlyFor
import co.touchlab.skie.test.runner.SkieTestMatrixSource
import co.touchlab.skie.test.util.KotlinVersion
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.platform.commons.util.AnnotationUtils

object OnlyForMatrixFilter: MatrixFilter {

override fun apply(context: ExtensionContext, source: SkieTestMatrixSource) {
val parentClassFilterAnnotations = AnnotationUtils.findRepeatableAnnotations(
context.requiredTestClass,
OnlyFor::class.java,
)
val methodFilterAnnotations = AnnotationUtils.findRepeatableAnnotations(
context.requiredTestMethod,
OnlyFor::class.java,
)

(parentClassFilterAnnotations + methodFilterAnnotations).forEach { filter ->
filter.targets.map { it.target }.applyTo(source.targets)
filter.linkModes.toList().applyTo(source.linkModes)
filter.configurations.toList().applyTo(source.configurations)
filter.kotlinVersions.map(::KotlinVersion).applyTo(source.kotlinVersions)
}
}

private inline fun <reified T> Collection<T>.applyTo(source: MutableList<T>) {
if (this.isNotEmpty()) {
val thisSet = this.toSet()
source.removeAll {
it !in thisSet
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,13 @@
package co.touchlab.skie.test.runner

import co.touchlab.skie.test.annotation.filter.OnlyFor
import co.touchlab.skie.test.util.KotlinTarget
import co.touchlab.skie.test.util.KotlinVersion
import co.touchlab.skie.test.util.LinkMode

data class MatrixFilter(
val targets: Set<KotlinTarget>,
val configurations: Set<BuildConfiguration>,
val linkModes: Set<LinkMode>,
val kotlinVersions: Set<String>,
) {
fun apply(onlyFor: OnlyFor): MatrixFilter = MatrixFilter(
targets = targets.intersectOrChoose(onlyFor.targets.map { it.target }),
configurations = configurations.intersectOrChoose(onlyFor.configurations.toList()),
linkModes = linkModes.intersectOrChoose(onlyFor.linkModes.toList()),
kotlinVersions = kotlinVersions.intersectOrChoose(onlyFor.kotlinVersions.toList()),
)

companion object {
val empty = MatrixFilter(
targets = emptySet(),
configurations = emptySet(),
linkModes = emptySet(),
kotlinVersions = emptySet(),
)

private inline fun <reified T> Set<T>.intersectOrChoose(other: Collection<T>): Set<T> {
return when {
this.isEmpty() -> other.toSet()
other.isEmpty() -> this
else -> intersect(other.toSet())
}
}
}
}
data class SkieTestMatrixSource(
val targets: MutableList<KotlinTarget>,
val presets: MutableList<KotlinTarget.Preset>,
val configurations: MutableList<BuildConfiguration>,
val linkModes: MutableList<LinkMode>,
val kotlinVersions: MutableList<KotlinVersion>,
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package co.touchlab.skie.test.runner

import co.touchlab.skie.test.annotation.MatrixTest
import co.touchlab.skie.test.annotation.filter.OnlyFor
import co.touchlab.skie.test.annotation.filter.FilterMatrixWith
import io.kotest.mpp.newInstanceNoArgConstructorOrObjectInstance
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.TestTemplateInvocationContext
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider
Expand All @@ -15,13 +16,27 @@ class SkieTestRunner: TestTemplateInvocationContextProvider {

override fun provideTestTemplateInvocationContexts(context: ExtensionContext): Stream<TestTemplateInvocationContext> {
val testMethod = context.requiredTestMethod
val parentClassFilterAnnotations =
AnnotationUtils.findRepeatableAnnotations(context.requiredTestClass, OnlyFor::class.java)
val methodFilterAnnotations = AnnotationUtils.findRepeatableAnnotations(testMethod, OnlyFor::class.java)
val matrixFilter = (parentClassFilterAnnotations + methodFilterAnnotations).fold(MatrixFilter.empty) { acc, onlyFor ->
acc.apply(onlyFor)
val parentClassFilterAnnotations = AnnotationUtils.findRepeatableAnnotations(
context.requiredTestClass,
FilterMatrixWith::class.java
)
val methodFilterAnnotations = AnnotationUtils.findRepeatableAnnotations(
testMethod,
FilterMatrixWith::class.java
)
val uniqueMatrixFilterClasses = (parentClassFilterAnnotations + methodFilterAnnotations).map {
it.value
}.toSet()

val uniqueMatrixFilters = uniqueMatrixFilterClasses.map {
it.newInstanceNoArgConstructorOrObjectInstance()
}

val matrixSource = SkieTestRunnerConfiguration.buildMatrixSource()
uniqueMatrixFilters.forEach { filter ->
filter.apply(context, matrixSource)
}
val filteredAxes = SkieTestRunnerConfiguration.filteredMatrixAxes(matrixFilter)
val filteredAxes = SkieTestRunnerConfiguration.buildMatrixAxes(matrixSource)

val matrixAxes = testMethod.parameterTypes.mapNotNull { requestedAxisType ->
filteredAxes[requestedAxisType]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,34 @@ object SkieTestRunnerConfiguration {
val kotlinVersions = list("matrix.kotlinVersions", ::KotlinVersion) ?: listOf("1.8.0", "1.8.20", "1.9.20").map(::KotlinVersion)
val gradleVersions = list("matrix.gradleVersions", ::GradleVersion) ?: listOf("8.6").map(::GradleVersion)

fun filteredMatrixAxes(filter: MatrixFilter) = buildList<SkieTestMatrix.Axis<*>> {
this += SkieTestMatrix.Axis<BuildConfiguration>(
"Configuration",
configurations.intersectOrKeepIfEmpty(filter.configurations.toList())
)
this += SkieTestMatrix.Axis<LinkMode>("Linkage", linkModes.intersectOrKeepIfEmpty(filter.linkModes.toList()))
this += SkieTestMatrix.Axis<KotlinVersion>(
"Kotlin",
kotlinVersions.intersectOrKeepIfEmpty(filter.kotlinVersions.map(::KotlinVersion))
fun buildMatrixSource(): SkieTestMatrixSource {
val allTargets = targets.targets
return SkieTestMatrixSource(
targets = allTargets.toMutableList(),
presets = targets.presets.takeIf { it.isNotEmpty() }?.toMutableList()
?: KotlinTarget.Preset.Root.children.presets.filter { preset ->
allTargets.toSet().intersect(preset.targets.toSet()).isNotEmpty()
}.toMutableList(),
configurations = configurations.toMutableList(),
linkModes = linkModes.toMutableList(),
kotlinVersions = kotlinVersions.toMutableList(),
)
}

val filteredTargets = if (filter.targets.isNotEmpty()) {
targets.targets.filter(filter.targets::contains)
} else {
targets.targets
}
this += SkieTestMatrix.Axis("Target", filteredTargets)
this += SkieTestMatrix.Axis("Target", filteredTargets.filterIsInstance<KotlinTarget.Native>())
this += SkieTestMatrix.Axis("Target", filteredTargets.filterIsInstance<KotlinTarget.Native.Darwin>())
this += SkieTestMatrix.Axis("Target", filteredTargets.filterIsInstance<KotlinTarget.Native.Ios>())
this += SkieTestMatrix.Axis("Target", filteredTargets.filterIsInstance<KotlinTarget.Native.MacOS>())

// TODO: Add filtering
val presets = targets.presets.takeIf { it.isNotEmpty() } ?: KotlinTarget.Preset.Root.children.presets.filter { preset ->
targets.targets.toSet().intersect(preset.targets.toSet()).isNotEmpty()
}
this += SkieTestMatrix.Axis("Preset", presets)
this += SkieTestMatrix.Axis("Preset", presets.filterIsInstance<KotlinTarget.Preset.Native>())
this += SkieTestMatrix.Axis("Preset", presets.filterIsInstance<KotlinTarget.Preset.Native.Darwin>())
fun buildMatrixAxes(source: SkieTestMatrixSource) = buildList<SkieTestMatrix.Axis<*>> {
this += SkieTestMatrix.Axis<BuildConfiguration>("Configuration", source.configurations)
this += SkieTestMatrix.Axis<LinkMode>("Linkage", source.linkModes)
this += SkieTestMatrix.Axis<KotlinVersion>("Kotlin", source.kotlinVersions)

this += SkieTestMatrix.Axis("Target", source.targets)
this += SkieTestMatrix.Axis("Target", source.targets.filterIsInstance<KotlinTarget.Native>())
this += SkieTestMatrix.Axis("Target", source.targets.filterIsInstance<KotlinTarget.Native.Darwin>())
this += SkieTestMatrix.Axis("Target", source.targets.filterIsInstance<KotlinTarget.Native.Ios>())
this += SkieTestMatrix.Axis("Target", source.targets.filterIsInstance<KotlinTarget.Native.MacOS>())

this += SkieTestMatrix.Axis("Preset", source.presets)
this += SkieTestMatrix.Axis("Preset", source.presets.filterIsInstance<KotlinTarget.Preset.Native>())
this += SkieTestMatrix.Axis("Preset", source.presets.filterIsInstance<KotlinTarget.Preset.Native.Darwin>())
}.associateBy { it.type }

private fun <T: Any> value(property: String, deserialize: (String) -> T?): T? {
Expand Down
Loading

0 comments on commit b7ec023

Please sign in to comment.