[Native][tests] Generate KLIB ABI tests twice - to run with and w/o cache
This commit is contained in:
+4
-1
@@ -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);
|
||||
+59
@@ -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/");
|
||||
}
|
||||
}
|
||||
+19
-1
@@ -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
|
||||
)
|
||||
|
||||
+25
-4
@@ -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;
|
||||
|
||||
|
||||
+68
-36
@@ -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)
|
||||
|
||||
+7
-5
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user