Add @GradleWithJdkTest annotation.
Adding this annotation to the test will provide requested JDKs + Gradle versions matrix as test parameter. It is also possible to filter out supported by Gradle version JDKs. ^KT-45745 In Progress
This commit is contained in:
@@ -85,6 +85,23 @@ plugins {
|
|||||||
A bunch of additional useful assertions available to use, such as file assertions, output assertions and task assertions. If you want to
|
A bunch of additional useful assertions available to use, such as file assertions, output assertions and task assertions. If you want to
|
||||||
add a new assertion, add as a reviewer someone from Kotlin build tools team.
|
add a new assertion, add as a reviewer someone from Kotlin build tools team.
|
||||||
|
|
||||||
|
##### Additional test helpers
|
||||||
|
|
||||||
|
Whenever you need to test combination of different JDKs and Gradle versions - you could use `@GradleWithJdkTest` instead of `@GradleTest`.
|
||||||
|
Then test method will receive requires JDKs as a second parameter:
|
||||||
|
```kotlin
|
||||||
|
@JdkVersions(version = [JavaVersion.VERSION_11, JavaVersion.VERSION_17])
|
||||||
|
@GradleWithJdkTest
|
||||||
|
fun someTest(
|
||||||
|
gradleVersion: GradleVersion,
|
||||||
|
providedJdk: JdkVersions.ProvidedJdk
|
||||||
|
) {
|
||||||
|
project("simple", gradleVersion, buildJdk = providedJdk.location) {
|
||||||
|
build("assemble")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
##### Deprecated tests setup
|
##### Deprecated tests setup
|
||||||
|
|
||||||
When you create a new test, figure out which Gradle versions it is supposed to run on. Then, when you instantiate a test project, specify one of:
|
When you create a new test, figure out which Gradle versions it is supposed to run on. Then, when you instantiate a test project, specify one of:
|
||||||
|
|||||||
+2
-2
@@ -17,8 +17,8 @@ import java.lang.annotation.Target;
|
|||||||
// Workaround for https://youtrack.jetbrains.com/issue/IDEA-265284
|
// Workaround for https://youtrack.jetbrains.com/issue/IDEA-265284
|
||||||
@Target({ElementType.METHOD})
|
@Target({ElementType.METHOD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@KGPBaseTest.GradleTestVersions
|
@GradleTestVersions
|
||||||
@ParameterizedTest(name = "{0}: {displayName}")
|
@ParameterizedTest(name = "{0}: {displayName}")
|
||||||
@ArgumentsSource(KGPBaseTest.GradleArgumentsProvider.class)
|
@ArgumentsSource(GradleArgumentsProvider.class)
|
||||||
public @interface GradleTest {
|
public @interface GradleTest {
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.testbase;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
// Has to be java annotation
|
||||||
|
// Workaround for https://youtrack.jetbrains.com/issue/IDEA-265284
|
||||||
|
@Target({ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@GradleTestVersions
|
||||||
|
@JdkVersions
|
||||||
|
@ParameterizedTest(name = "{1} with {0}: {displayName}")
|
||||||
|
@ArgumentsSource(GradleAndJdkArgumentsProvider.class)
|
||||||
|
public @interface GradleWithJdkTest {
|
||||||
|
}
|
||||||
-62
@@ -5,17 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.testbase
|
package org.jetbrains.kotlin.gradle.testbase
|
||||||
|
|
||||||
import org.gradle.util.GradleVersion
|
|
||||||
import org.jetbrains.kotlin.test.WithMuteInDatabase
|
import org.jetbrains.kotlin.test.WithMuteInDatabase
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext
|
|
||||||
import org.junit.jupiter.api.io.TempDir
|
import org.junit.jupiter.api.io.TempDir
|
||||||
import org.junit.jupiter.params.provider.Arguments
|
|
||||||
import org.junit.jupiter.params.provider.ArgumentsProvider
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.stream.Stream
|
|
||||||
import kotlin.streams.asStream
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all Kotlin Gradle plugin integration tests.
|
* Base class for all Kotlin Gradle plugin integration tests.
|
||||||
@@ -28,60 +22,4 @@ abstract class KGPBaseTest {
|
|||||||
|
|
||||||
@TempDir
|
@TempDir
|
||||||
lateinit var workingDir: Path
|
lateinit var workingDir: Path
|
||||||
|
|
||||||
class GradleArgumentsProvider : ArgumentsProvider {
|
|
||||||
override fun provideArguments(
|
|
||||||
context: ExtensionContext
|
|
||||||
): Stream<out Arguments> {
|
|
||||||
var nextSuperclass: Class<*>? = context.testClass.get().superclass
|
|
||||||
val superClassSequence = if (nextSuperclass != null) {
|
|
||||||
generateSequence {
|
|
||||||
val currentSuperclass = nextSuperclass
|
|
||||||
nextSuperclass = nextSuperclass?.superclass
|
|
||||||
currentSuperclass
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emptySequence()
|
|
||||||
}
|
|
||||||
|
|
||||||
val versionsAnnotation = sequenceOf(
|
|
||||||
context.testMethod.get(),
|
|
||||||
context.testClass.get()
|
|
||||||
)
|
|
||||||
.plus(superClassSequence)
|
|
||||||
.mapNotNull { declaration ->
|
|
||||||
declaration.annotations.firstOrNull { it is GradleTestVersions }
|
|
||||||
}
|
|
||||||
.firstOrNull() as GradleTestVersions?
|
|
||||||
?: context.testMethod.get().annotations
|
|
||||||
.mapNotNull { annotation ->
|
|
||||||
annotation.annotationClass.annotations.firstOrNull { it is GradleTestVersions }
|
|
||||||
}
|
|
||||||
.first() as GradleTestVersions
|
|
||||||
|
|
||||||
val minGradleVersion = GradleVersion.version(versionsAnnotation.minVersion)
|
|
||||||
val maxGradleVersion = GradleVersion.version(versionsAnnotation.maxVersion)
|
|
||||||
val additionalGradleVersions = versionsAnnotation
|
|
||||||
.additionalVersions
|
|
||||||
.map(GradleVersion::version)
|
|
||||||
additionalGradleVersions.forEach {
|
|
||||||
assert(it in minGradleVersion..maxGradleVersion) {
|
|
||||||
"Additional Gradle version ${it.version} should be between ${minGradleVersion.version} and ${maxGradleVersion.version}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return setOf(minGradleVersion, *additionalGradleVersions.toTypedArray(), maxGradleVersion)
|
|
||||||
.asSequence()
|
|
||||||
.map { Arguments.of(it) }
|
|
||||||
.asStream()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS)
|
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
|
||||||
annotation class GradleTestVersions(
|
|
||||||
val minVersion: String = TestVersions.Gradle.MIN_SUPPORTED,
|
|
||||||
val maxVersion: String = TestVersions.Gradle.MAX_SUPPORTED,
|
|
||||||
val additionalVersions: Array<String> = []
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
+142
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.testbase
|
||||||
|
|
||||||
|
import org.gradle.api.JavaVersion
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
|
import org.junit.jupiter.params.provider.Arguments
|
||||||
|
import org.junit.jupiter.params.provider.ArgumentsProvider
|
||||||
|
import java.io.File
|
||||||
|
import java.util.stream.Stream
|
||||||
|
import kotlin.streams.asStream
|
||||||
|
import kotlin.streams.toList
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class GradleTestVersions(
|
||||||
|
val minVersion: String = TestVersions.Gradle.MIN_SUPPORTED,
|
||||||
|
val maxVersion: String = TestVersions.Gradle.MAX_SUPPORTED,
|
||||||
|
val additionalVersions: Array<String> = []
|
||||||
|
)
|
||||||
|
|
||||||
|
open class GradleArgumentsProvider : ArgumentsProvider {
|
||||||
|
override fun provideArguments(
|
||||||
|
context: ExtensionContext
|
||||||
|
): Stream<out Arguments> {
|
||||||
|
val versionsAnnotation = findAnnotation<GradleTestVersions>(context)
|
||||||
|
|
||||||
|
val minGradleVersion = GradleVersion.version(versionsAnnotation.minVersion)
|
||||||
|
val maxGradleVersion = GradleVersion.version(versionsAnnotation.maxVersion)
|
||||||
|
val additionalGradleVersions = versionsAnnotation
|
||||||
|
.additionalVersions
|
||||||
|
.map(GradleVersion::version)
|
||||||
|
additionalGradleVersions.forEach {
|
||||||
|
assert(it in minGradleVersion..maxGradleVersion) {
|
||||||
|
"Additional Gradle version ${it.version} should be between ${minGradleVersion.version} and ${maxGradleVersion.version}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return setOf(minGradleVersion, *additionalGradleVersions.toTypedArray(), maxGradleVersion)
|
||||||
|
.asSequence()
|
||||||
|
.map { Arguments.of(it) }
|
||||||
|
.asStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Annotation> findAnnotation(context: ExtensionContext): T {
|
||||||
|
var nextSuperclass: Class<*>? = context.testClass.get().superclass
|
||||||
|
val superClassSequence = if (nextSuperclass != null) {
|
||||||
|
generateSequence {
|
||||||
|
val currentSuperclass = nextSuperclass
|
||||||
|
nextSuperclass = nextSuperclass?.superclass
|
||||||
|
currentSuperclass
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emptySequence()
|
||||||
|
}
|
||||||
|
|
||||||
|
return sequenceOf(
|
||||||
|
context.testMethod.get(),
|
||||||
|
context.testClass.get()
|
||||||
|
)
|
||||||
|
.plus(superClassSequence)
|
||||||
|
.mapNotNull { declaration ->
|
||||||
|
declaration.annotations.firstOrNull { it is T }
|
||||||
|
}
|
||||||
|
.firstOrNull() as T?
|
||||||
|
?: context.testMethod.get().annotations
|
||||||
|
.mapNotNull { annotation ->
|
||||||
|
annotation.annotationClass.annotations.firstOrNull { it is T }
|
||||||
|
}
|
||||||
|
.first() as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class JdkVersions(
|
||||||
|
val versions: Array<JavaVersion> = [JavaVersion.VERSION_1_8, JavaVersion.VERSION_17],
|
||||||
|
val compatibleWithGradle: Boolean = true
|
||||||
|
) {
|
||||||
|
class ProvidedJdk(
|
||||||
|
val version: JavaVersion,
|
||||||
|
val location: File
|
||||||
|
) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "JDK $version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GradleAndJdkArgumentsProvider : GradleArgumentsProvider() {
|
||||||
|
override fun provideArguments(
|
||||||
|
context: ExtensionContext
|
||||||
|
): Stream<out Arguments> {
|
||||||
|
val jdkAnnotation = findAnnotation<JdkVersions>(context)
|
||||||
|
val providedJdks = jdkAnnotation
|
||||||
|
.versions
|
||||||
|
.map {
|
||||||
|
JdkVersions.ProvidedJdk(
|
||||||
|
it,
|
||||||
|
File(System.getProperty("jdk${it.majorVersion}Home"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val gradleVersions = super.provideArguments(context).map { it.get().first() as GradleVersion }.toList()
|
||||||
|
|
||||||
|
return providedJdks
|
||||||
|
.flatMap { providedJdk ->
|
||||||
|
val minSupportedGradleVersion = jdkGradleCompatibilityMatrix[providedJdk.version]
|
||||||
|
gradleVersions
|
||||||
|
.run {
|
||||||
|
if (jdkAnnotation.compatibleWithGradle && minSupportedGradleVersion != null) {
|
||||||
|
val initialVersionsCount = count()
|
||||||
|
val filteredVersions = filter { it >= minSupportedGradleVersion }
|
||||||
|
if (initialVersionsCount > filteredVersions.count()) {
|
||||||
|
(filteredVersions + minSupportedGradleVersion).toSet()
|
||||||
|
} else {
|
||||||
|
filteredVersions
|
||||||
|
}
|
||||||
|
} else this
|
||||||
|
}
|
||||||
|
.map { it to providedJdk }
|
||||||
|
}
|
||||||
|
.asSequence()
|
||||||
|
.map {
|
||||||
|
Arguments.of(it.first, it.second)
|
||||||
|
}
|
||||||
|
.asStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val jdkGradleCompatibilityMatrix = mapOf(
|
||||||
|
JavaVersion.VERSION_14 to GradleVersion.version(TestVersions.Gradle.G_6_3),
|
||||||
|
JavaVersion.VERSION_15 to GradleVersion.version(TestVersions.Gradle.G_6_7),
|
||||||
|
JavaVersion.VERSION_16 to GradleVersion.version(TestVersions.Gradle.G_7_0),
|
||||||
|
JavaVersion.VERSION_17 to GradleVersion.version(TestVersions.Gradle.G_7_3)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user