From 2d6bb3b7447ef2cc26a06b244f70a9b365ff79a4 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Thu, 13 Jul 2023 21:35:26 +0200 Subject: [PATCH] [Gradle] Add tags count validator for Gradle integration tests Our current test tasks setup relies on filtering tests by tags. When a test accidentally has more than one tag, it will never run on CI because every test task will filter it out. Validator will check test method tags count and fail the test if they are more than one. ^KT-59799 In Progress --- .../kotlin/gradle/testbase/KGPBaseTest.kt | 1 + .../kotlin/gradle/testbase/tagsValidator.kt | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/KGPBaseTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/KGPBaseTest.kt index 0cfb2c8e68b..6fb92e88b5e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/KGPBaseTest.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/KGPBaseTest.kt @@ -27,6 +27,7 @@ import java.nio.file.Path @Tag("JUnit5") @TestInstance(TestInstance.Lifecycle.PER_CLASS) @WithMuteInDatabase +@TagsCountValidator @TestDataPath("\$CONTENT_ROOT/resources/testProject") @OsCondition abstract class KGPBaseTest { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt new file mode 100644 index 00000000000..758aa53ee79 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2023 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.api.extension.* +import java.lang.reflect.Method + +/** + * Extension for JUnit 5 tests checking that only one test tag is applied to the test method. + * + * Just add it to the test class. + */ +@Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +@ExtendWith(TagsCountValidatorInterceptor::class) +annotation class TagsCountValidator + +class TagsCountValidatorInterceptor : InvocationInterceptor { + override fun interceptTestTemplateMethod( + invocation: InvocationInterceptor.Invocation, + invocationContext: ReflectiveInvocationContext, + extensionContext: ExtensionContext + ) { + val testTags = invocationContext.targetClass.classTags().toSet() + + invocationContext.executable.annotations.filterTestTags() + if (testTags.isEmpty()) { + invocation.skip() + throw IllegalStateException( + """ + Test method either does not have test tag annotation (for example @JvmGradlePluginTests) + or test tag is not known to this validator. + """.trimIndent() + ) + } else if (testTags.size > 1) { + invocation.skip() + throw IllegalStateException( + """ + Test method should not have more then one test tag annotated on method and class combined! + Current test has ${testTags.joinToString()} test tags. + """.trimIndent() + ) + } else { + invocation.proceed() + } + } + + private fun Class<*>.classTags(): List { + return annotations.filterTestTags() + (superclass?.classTags() ?: emptyList()) + } + + private fun Array.filterTestTags() = filter { + it is JvmGradlePluginTests || + it is DaemonsGradlePluginTests || + it is JsGradlePluginTests || + it is NativeGradlePluginTests || + it is MppGradlePluginTests || + it is AndroidGradlePluginTests || + it is OtherGradlePluginTests + } +} \ No newline at end of file