[Native][tests] Generate KLIB ABI tests twice - to run with and w/o cache

This commit is contained in:
Dmitriy Dolovov
2022-01-26 14:50:44 +03:00
parent 5d1884d8dc
commit 02022cf260
6 changed files with 182 additions and 47 deletions
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.konan.blackboxtest;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.konan.blackboxtest.support.EnforcedProperty;
import org.jetbrains.kotlin.konan.blackboxtest.support.ClassLevelProperty;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -18,7 +20,8 @@ import java.util.regex.Pattern;
@SuppressWarnings("all")
@TestMetadata("compiler/testData/klibABI")
@TestDataPath("$PROJECT_ROOT")
public class NativeKlibABITestGenerated extends AbstractNativeKlibABITest {
@EnforcedProperty(property = ClassLevelProperty.CACHE_MODE, propertyValue = "NO")
public class KlibABITestGenerated extends AbstractNativeKlibABITest {
@Test
public void testAllFilesPresentInKlibABI() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/klibABI"), Pattern.compile("^([^_](.+))$"), null, false);
@@ -0,0 +1,59 @@
/*
* 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.konan.blackboxtest;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.konan.blackboxtest.support.EnforcedProperty;
import org.jetbrains.kotlin.konan.blackboxtest.support.ClassLevelProperty;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/klibABI")
@TestDataPath("$PROJECT_ROOT")
@EnforcedProperty(property = ClassLevelProperty.CACHE_MODE, propertyValue = "STATIC_EVERYWHERE")
public class KlibABITestWithCacheGenerated extends AbstractNativeKlibABITest {
@Test
public void testAllFilesPresentInKlibABI() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/klibABI"), Pattern.compile("^([^_](.+))$"), null, false);
}
@Test
@TestMetadata("removeClassAsParameterType")
public void testRemoveClassAsParameterType() throws Exception {
runTest("compiler/testData/klibABI/removeClassAsParameterType/");
}
@Test
@TestMetadata("removeClassAsReturnType")
public void testRemoveClassAsReturnType() throws Exception {
runTest("compiler/testData/klibABI/removeClassAsReturnType/");
}
@Test
@TestMetadata("removeClassAsSuperTypeArgument")
public void testRemoveClassAsSuperTypeArgument() throws Exception {
runTest("compiler/testData/klibABI/removeClassAsSuperTypeArgument/");
}
@Test
@TestMetadata("removeClassAsTypeArgument")
public void testRemoveClassAsTypeArgument() throws Exception {
runTest("compiler/testData/klibABI/removeClassAsTypeArgument/");
}
@Test
@TestMetadata("removeFunction")
public void testRemoveFunction() throws Exception {
runTest("compiler/testData/klibABI/removeFunction/");
}
}
@@ -10,8 +10,11 @@ import org.jetbrains.kotlin.generators.model.annotation
import org.jetbrains.kotlin.konan.blackboxtest.AbstractExternalNativeBlackBoxTest
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeKlibABITest
import org.jetbrains.kotlin.konan.blackboxtest.support.ClassLevelProperty
import org.jetbrains.kotlin.konan.blackboxtest.support.EnforcedProperty
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseExtTestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UseStandardTestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.CacheMode
import org.jetbrains.kotlin.test.TargetBackend
import org.junit.jupiter.api.Tag
@@ -43,7 +46,16 @@ fun main() {
// KLIB ABI tests.
testGroup("native/native.tests/tests-gen", "compiler/testData") {
testClass<AbstractNativeKlibABITest> {
testClass<AbstractNativeKlibABITest>(
suiteTestClassName = "KlibABITestGenerated",
annotations = listOf(enforcedCacheMode(CacheMode.Alias.NO))
) {
model("klibABI/", pattern = "^([^_](.+))$", recursive = false)
}
testClass<AbstractNativeKlibABITest>(
suiteTestClassName = "KlibABITestWithCacheGenerated",
annotations = listOf(enforcedCacheMode(CacheMode.Alias.STATIC_EVERYWHERE))
) {
model("klibABI/", pattern = "^([^_](.+))$", recursive = false)
}
}
@@ -54,3 +66,9 @@ private inline fun <reified T : Annotation> provider() = annotation(T::class.jav
private fun external() = annotation(Tag::class.java, "external")
private fun infrastructure() = annotation(Tag::class.java, "infrastructure")
private fun enforcedCacheMode(alias: CacheMode.Alias) = annotation(
EnforcedProperty::class.java,
EnforcedProperty::property.name to ClassLevelProperty.CACHE_MODE,
EnforcedProperty::propertyValue.name to alias.name
)
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.konan.blackboxtest.support
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
/*************** Process-level system properties ***************/
internal enum class ProcessLevelProperty(shortName: String) {
KOTLIN_NATIVE_HOME("nativeHome"),
COMPILER_CLASSPATH("compilerClasspath");
@@ -16,6 +18,19 @@ internal enum class ProcessLevelProperty(shortName: String) {
fun readValue(): String = System.getProperty(propertyName) ?: fail { "Unspecified $propertyName system property" }
}
/*************** Class-level system properties ***************/
@Target(AnnotationTarget.CLASS)
internal annotation class EnforcedProperty(val property: ClassLevelProperty, val propertyValue: String)
internal class EnforcedProperties(testClass: Class<*>) {
private val enforcedAnnotations: Map<ClassLevelProperty, String> = testClass.annotations
.filterIsInstance<EnforcedProperty>()
.associate { it.property to it.propertyValue }
operator fun get(propertyType: ClassLevelProperty): String? = enforcedAnnotations[propertyType]
}
internal enum class ClassLevelProperty(shortName: String) {
TEST_TARGET("target"),
TEST_MODE("mode"),
@@ -28,8 +43,8 @@ internal enum class ClassLevelProperty(shortName: String) {
internal val propertyName = fullPropertyName(shortName)
fun <T> readValue(transform: (String) -> T?, default: T): T {
val propertyValue = System.getProperty(propertyName)
fun <T> readValue(enforcedProperties: EnforcedProperties, transform: (String) -> T?, default: T): T {
val propertyValue = enforcedProperties[this] ?: System.getProperty(propertyName)
return if (propertyValue != null) {
transform(propertyValue) ?: fail { "Invalid value for $propertyName system property: $propertyValue" }
} else
@@ -37,8 +52,12 @@ internal enum class ClassLevelProperty(shortName: String) {
}
}
internal inline fun <reified E : Enum<E>> ClassLevelProperty.readValue(values: Array<out E>, default: E): E {
val optionName = System.getProperty(propertyName)
internal inline fun <reified E : Enum<E>> ClassLevelProperty.readValue(
enforcedProperties: EnforcedProperties,
values: Array<out E>,
default: E
): E {
val optionName = enforcedProperties[this] ?: System.getProperty(propertyName)
return if (optionName != null) {
values.firstOrNull { it.name == optionName } ?: fail {
buildString {
@@ -53,6 +72,8 @@ internal inline fun <reified E : Enum<E>> ClassLevelProperty.readValue(values: A
private fun fullPropertyName(shortName: String) = "kotlin.internal.native.test.$shortName"
/*************** Environment variables ***************/
internal enum class EnvironmentVariable {
PROJECT_BUILD_DIR;
@@ -106,11 +106,13 @@ private object NativeTestSupport {
/*************** Test class settings (common part) ***************/
private fun ExtensionContext.addCommonTestClassSettingsTo(output: MutableCollection<Any>) {
val optimizationMode = computeOptimizationMode()
val memoryModel = computeMemoryModel()
private fun ExtensionContext.addCommonTestClassSettingsTo(enclosingTestClass: Class<*>, output: MutableCollection<Any>) {
val enforcedProperties = EnforcedProperties(enclosingTestClass)
val threadStateChecker = computeThreadStateChecker()
val optimizationMode = computeOptimizationMode(enforcedProperties)
val memoryModel = computeMemoryModel(enforcedProperties)
val threadStateChecker = computeThreadStateChecker(enforcedProperties)
if (threadStateChecker == ThreadStateChecker.ENABLED) {
assertEquals(MemoryModel.EXPERIMENTAL, memoryModel) {
"Thread state checker can be enabled only with experimental memory model"
@@ -120,7 +122,7 @@ private object NativeTestSupport {
}
}
val gcType = computeGCType()
val gcType = computeGCType(enforcedProperties)
if (gcType != GCType.UNSPECIFIED) {
assertEquals(MemoryModel.EXPERIMENTAL, memoryModel) {
"GC type can be specified only with experimental memory model"
@@ -130,40 +132,51 @@ private object NativeTestSupport {
val nativeHome = getOrCreateTestProcessSettings().get<KotlinNativeHome>()
val hostManager = HostManager(distribution = Distribution(nativeHome.dir.path), experimental = false)
val nativeTargets = computeNativeTargets(hostManager)
val nativeTargets = computeNativeTargets(enforcedProperties, hostManager)
output += optimizationMode
output += memoryModel
output += threadStateChecker
output += gcType
output += nativeTargets
output += CacheMode::class to computeCacheMode(nativeHome, nativeTargets, optimizationMode)
output += computeTestMode()
output += computeTimeouts()
output += CacheMode::class to computeCacheMode(enforcedProperties, nativeHome, nativeTargets, optimizationMode)
output += computeTestMode(enforcedProperties)
output += computeTimeouts(enforcedProperties)
}
private fun computeOptimizationMode(): OptimizationMode =
ClassLevelProperty.OPTIMIZATION_MODE.readValue(OptimizationMode.values(), default = OptimizationMode.DEBUG)
private fun computeOptimizationMode(enforcedProperties: EnforcedProperties): OptimizationMode =
ClassLevelProperty.OPTIMIZATION_MODE.readValue(
enforcedProperties,
OptimizationMode.values(),
default = OptimizationMode.DEBUG
)
private fun computeMemoryModel(): MemoryModel =
ClassLevelProperty.MEMORY_MODEL.readValue(MemoryModel.values(), default = MemoryModel.DEFAULT)
private fun computeMemoryModel(enforcedProperties: EnforcedProperties): MemoryModel =
ClassLevelProperty.MEMORY_MODEL.readValue(enforcedProperties, MemoryModel.values(), default = MemoryModel.DEFAULT)
private fun computeThreadStateChecker(): ThreadStateChecker {
val useThreadStateChecker = ClassLevelProperty.USE_THREAD_STATE_CHECKER.readValue(String::toBooleanStrictOrNull, default = false)
private fun computeThreadStateChecker(enforcedProperties: EnforcedProperties): ThreadStateChecker {
val useThreadStateChecker =
ClassLevelProperty.USE_THREAD_STATE_CHECKER.readValue(enforcedProperties, String::toBooleanStrictOrNull, default = false)
return if (useThreadStateChecker) ThreadStateChecker.ENABLED else ThreadStateChecker.DISABLED
}
private fun computeGCType(): GCType = ClassLevelProperty.GC_TYPE.readValue(GCType.values(), default = GCType.UNSPECIFIED)
private fun computeGCType(enforcedProperties: EnforcedProperties): GCType =
ClassLevelProperty.GC_TYPE.readValue(enforcedProperties, GCType.values(), default = GCType.UNSPECIFIED)
private fun computeNativeTargets(hostManager: HostManager): KotlinNativeTargets {
private fun computeNativeTargets(enforcedProperties: EnforcedProperties, hostManager: HostManager): KotlinNativeTargets {
val hostTarget = HostManager.host
return KotlinNativeTargets(
testTarget = ClassLevelProperty.TEST_TARGET.readValue(hostManager::targetByName, default = hostTarget),
testTarget = ClassLevelProperty.TEST_TARGET.readValue(
enforcedProperties,
hostManager::targetByName,
default = hostTarget
),
hostTarget = hostTarget
)
}
private fun computeCacheMode(
enforcedProperties: EnforcedProperties,
kotlinNativeHome: KotlinNativeHome,
kotlinNativeTargets: KotlinNativeTargets,
optimizationMode: OptimizationMode
@@ -177,20 +190,29 @@ private object NativeTestSupport {
CacheMode.WithoutCache
}
val staticCacheRequiredForEveryLibrary =
when (ClassLevelProperty.CACHE_MODE.readValue(CacheMode.Alias.values(), default = CacheMode.Alias.STATIC_ONLY_DIST)) {
CacheMode.Alias.NO -> return CacheMode.WithoutCache
CacheMode.Alias.STATIC_ONLY_DIST -> false
CacheMode.Alias.STATIC_EVERYWHERE -> true
}
val cacheMode = ClassLevelProperty.CACHE_MODE.readValue(
enforcedProperties,
CacheMode.Alias.values(),
default = CacheMode.Alias.STATIC_ONLY_DIST
)
val staticCacheRequiredForEveryLibrary = when (cacheMode) {
CacheMode.Alias.NO -> return CacheMode.WithoutCache
CacheMode.Alias.STATIC_ONLY_DIST -> false
CacheMode.Alias.STATIC_EVERYWHERE -> true
}
return CacheMode.WithStaticCache(kotlinNativeHome, kotlinNativeTargets, optimizationMode, staticCacheRequiredForEveryLibrary)
}
private fun computeTestMode(): TestMode = ClassLevelProperty.TEST_MODE.readValue(TestMode.values(), default = TestMode.WITH_MODULES)
private fun computeTestMode(enforcedProperties: EnforcedProperties): TestMode =
ClassLevelProperty.TEST_MODE.readValue(enforcedProperties, TestMode.values(), default = TestMode.WITH_MODULES)
private fun computeTimeouts(): Timeouts {
val executionTimeout = ClassLevelProperty.EXECUTION_TIMEOUT.readValue({ it.toLongOrNull()?.milliseconds }, default = 10.seconds)
private fun computeTimeouts(enforcedProperties: EnforcedProperties): Timeouts {
val executionTimeout = ClassLevelProperty.EXECUTION_TIMEOUT.readValue(
enforcedProperties,
{ it.toLongOrNull()?.milliseconds },
default = 10.seconds
)
return Timeouts(executionTimeout)
}
@@ -205,7 +227,7 @@ private object NativeTestSupport {
val settings = buildList {
// Put common settings:
addCommonTestClassSettingsTo(this)
addCommonTestClassSettingsTo(enclosingTestClass, this)
// Put settings that are always required:
this += computedTestConfiguration
@@ -299,6 +321,16 @@ private object NativeTestSupport {
return Binaries(testBinariesDir, sharedBinariesDir)
}
/*************** Test class settings (simplified) ***************/
private fun ExtensionContext.getOrCreateSimpleTestClassSettings(): SimpleTestClassSettings =
root.getStore(NAMESPACE).getOrComputeIfAbsent(testClassKeyFor<SimpleTestClassSettings>()) {
SimpleTestClassSettings(
parent = getOrCreateTestProcessSettings(),
buildList { addCommonTestClassSettingsTo(enclosingTestClass, this) }
)
}.cast()
/*************** Test run settings (for black box tests only) ***************/
// Note: TestRunSettings is not cached!
@@ -321,15 +353,15 @@ private object NativeTestSupport {
// Note: SimpleTestRunSettings is not cached!
fun ExtensionContext.createSimpleTestRunSettings(): SimpleTestRunSettings {
val testProcessSettings = getOrCreateTestProcessSettings()
val testClassSettings = getOrCreateSimpleTestClassSettings()
val settings = buildList {
addCommonTestClassSettingsTo(this)
this += computeSimpleTestInstances()
this += computeSimpleTestDirectories(testProcessSettings.get(), testProcessSettings.get())
}
return SimpleTestRunSettings(parent = testProcessSettings, settings)
return SimpleTestRunSettings(
parent = testClassSettings,
listOf(
computeSimpleTestInstances(),
computeSimpleTestDirectories(testClassSettings.get(), testClassSettings.get())
)
)
}
private fun ExtensionContext.computeSimpleTestInstances(): SimpleTestInstances = SimpleTestInstances(requiredTestInstances.allInstances)
@@ -44,9 +44,11 @@ internal class TestRunSettings(parent: TestClassSettings, settings: Iterable<Any
/**
* The hierarchy of settings containers for simple Native tests (e.g. KLIB tests):
*
* | Settings container | Parent | Scope |
* | ----------------------- | --------------------- | ---------------------------------------|
* | [TestProcessSettings] | `null` | The whole Gradle test executor process |
* | [SimpleTestRunSettings] | [TestProcessSettings] | The single test run of a test function |
* | Settings container | Parent | Scope |
* | ------------------------- | ------------------------- | ------------------------------------------- |
* | [TestProcessSettings] | `null` | The whole Gradle test executor process |
* | [SimpleTestClassSettings] | [TestProcessSettings] | The single top-level (enclosing) test class |
* | [SimpleTestRunSettings] | [SimpleTestClassSettings] | The single test run of a test function |
*/
internal class SimpleTestRunSettings(parent: TestProcessSettings, settings: Iterable<Any>) : Settings(parent, settings)
internal class SimpleTestClassSettings(parent: TestProcessSettings, settings: Iterable<Any>) : Settings(parent, settings)
internal class SimpleTestRunSettings(parent: SimpleTestClassSettings, settings: Iterable<Any>) : Settings(parent, settings)