[Native][tests] Gradle property: OptimizationMode
This commit is contained in:
@@ -48,6 +48,7 @@ enum class TestProperty(shortName: String) {
|
|||||||
KOTLIN_NATIVE_HOME("nativeHome"),
|
KOTLIN_NATIVE_HOME("nativeHome"),
|
||||||
COMPILER_CLASSPATH("compilerClasspath"),
|
COMPILER_CLASSPATH("compilerClasspath"),
|
||||||
TEST_MODE("mode"),
|
TEST_MODE("mode"),
|
||||||
|
OPTIMIZATION_MODE("optimizationMode"),
|
||||||
USE_CACHE("useCache"),
|
USE_CACHE("useCache"),
|
||||||
EXECUTION_TIMEOUT("executionTimeout");
|
EXECUTION_TIMEOUT("executionTimeout");
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// FREE_COMPILER_ARGS: -opt -verbose
|
// FREE_COMPILER_ARGS: -Xprint-files -verbose
|
||||||
|
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
|
|||||||
+28
-34
@@ -57,6 +57,7 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
computeNativeHome(),
|
computeNativeHome(),
|
||||||
computeNativeClassLoader(),
|
computeNativeClassLoader(),
|
||||||
computeTestMode(),
|
computeTestMode(),
|
||||||
|
computeOptimizationMode(),
|
||||||
CacheKind::class to computeCacheKind(),
|
CacheKind::class to computeCacheKind(),
|
||||||
computeBaseDirs(),
|
computeBaseDirs(),
|
||||||
computeTimeouts()
|
computeTimeouts()
|
||||||
@@ -81,55 +82,47 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun computeTestMode(): TestMode = systemProperty(
|
private fun computeTestMode(): TestMode = enumSystemProperty(TEST_MODE, TestMode.values(), default = TestMode.WITH_MODULES)
|
||||||
name = TEST_MODE,
|
|
||||||
transform = { testModeName ->
|
|
||||||
TestMode.values().firstOrNull { it.name == testModeName } ?: fail {
|
|
||||||
buildString {
|
|
||||||
appendLine("Unknown test mode name $testModeName.")
|
|
||||||
appendLine("One of the following test modes should be passed through $TEST_MODE system property:")
|
|
||||||
TestMode.values().forEach { testMode ->
|
|
||||||
appendLine("- ${testMode.name}: ${testMode.description}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
private fun computeOptimizationMode(): OptimizationMode =
|
||||||
default = TestMode.WITH_MODULES
|
enumSystemProperty(OPTIMIZATION_MODE, OptimizationMode.values(), default = OptimizationMode.DEBUG)
|
||||||
)
|
|
||||||
|
|
||||||
private fun computeCacheKind(): CacheKind {
|
private fun computeCacheKind(): CacheKind {
|
||||||
val useCache = systemProperty(
|
val useCache = systemProperty(USE_CACHE, String::toBooleanStrictOrNull, default = true)
|
||||||
name = USE_CACHE,
|
|
||||||
transform = { useCacheValue ->
|
|
||||||
useCacheValue.toBooleanStrictOrNull() ?: fail { "Invalid value for $USE_CACHE system property: $useCacheValue" }
|
|
||||||
},
|
|
||||||
default = true
|
|
||||||
)
|
|
||||||
|
|
||||||
return if (useCache) CacheKind.WithStaticCache else CacheKind.WithoutCache
|
return if (useCache) CacheKind.WithStaticCache else CacheKind.WithoutCache
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeBaseDirs(): BaseDirs = BaseDirs(File(requiredEnvironmentVariable(PROJECT_BUILD_DIR)))
|
private fun computeBaseDirs(): BaseDirs = BaseDirs(File(requiredEnvironmentVariable(PROJECT_BUILD_DIR)))
|
||||||
|
|
||||||
private fun computeTimeouts(): Timeouts {
|
private fun computeTimeouts(): Timeouts {
|
||||||
val executionTimeout = systemProperty(
|
val executionTimeout = systemProperty(EXECUTION_TIMEOUT, { it.toLongOrNull()?.milliseconds }, default = 10.seconds)
|
||||||
name = EXECUTION_TIMEOUT,
|
|
||||||
transform = { executionTimeoutValue ->
|
|
||||||
executionTimeoutValue.toLongOrNull()?.milliseconds
|
|
||||||
?: fail { "Invalid value for $EXECUTION_TIMEOUT system property: $executionTimeoutValue" }
|
|
||||||
},
|
|
||||||
default = 10.seconds
|
|
||||||
)
|
|
||||||
|
|
||||||
return Timeouts(executionTimeout)
|
return Timeouts(executionTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requiredSystemProperty(name: String): String =
|
private fun requiredSystemProperty(name: String): String =
|
||||||
System.getProperty(name) ?: fail { "Unspecified $name system property" }
|
System.getProperty(name) ?: fail { "Unspecified $name system property" }
|
||||||
|
|
||||||
private fun <T> systemProperty(name: String, transform: (String) -> T, default: T): T =
|
private fun <T> systemProperty(propertyName: String, transform: (String) -> T?, default: T): T {
|
||||||
System.getProperty(name)?.let(transform) ?: default
|
val propertyValue = System.getProperty(propertyName)
|
||||||
|
return if (propertyValue != null) {
|
||||||
|
transform(propertyValue) ?: fail { "Invalid value for $propertyName system property: $propertyValue" }
|
||||||
|
} else
|
||||||
|
default
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <reified E : Enum<E>> enumSystemProperty(propertyName: String, values: Array<out E>, default: E): E {
|
||||||
|
val optionName = System.getProperty(propertyName)
|
||||||
|
return if (optionName != null) {
|
||||||
|
values.firstOrNull { it.name == optionName } ?: fail {
|
||||||
|
buildString {
|
||||||
|
appendLine("Unknown ${E::class.java.simpleName} name $optionName.")
|
||||||
|
appendLine("One of the following ${E::class.java.simpleName} should be passed through $propertyName system property:")
|
||||||
|
values.forEach { value -> appendLine("- ${value.name}: $value") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
default
|
||||||
|
}
|
||||||
|
|
||||||
private fun requiredEnvironmentVariable(name: String): String =
|
private fun requiredEnvironmentVariable(name: String): String =
|
||||||
System.getenv(name) ?: fail { "Unspecified $name environment variable" }
|
System.getenv(name) ?: fail { "Unspecified $name environment variable" }
|
||||||
@@ -139,6 +132,7 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
|
|||||||
private const val KOTLIN_NATIVE_HOME = "kotlin.internal.native.test.nativeHome"
|
private const val KOTLIN_NATIVE_HOME = "kotlin.internal.native.test.nativeHome"
|
||||||
private const val COMPILER_CLASSPATH = "kotlin.internal.native.test.compilerClasspath"
|
private const val COMPILER_CLASSPATH = "kotlin.internal.native.test.compilerClasspath"
|
||||||
private const val TEST_MODE = "kotlin.internal.native.test.mode"
|
private const val TEST_MODE = "kotlin.internal.native.test.mode"
|
||||||
|
private const val OPTIMIZATION_MODE = "kotlin.internal.native.test.optimizationMode"
|
||||||
private const val USE_CACHE = "kotlin.internal.native.test.useCache"
|
private const val USE_CACHE = "kotlin.internal.native.test.useCache"
|
||||||
private const val EXECUTION_TIMEOUT = "kotlin.internal.native.test.executionTimeout"
|
private const val EXECUTION_TIMEOUT = "kotlin.internal.native.test.executionTimeout"
|
||||||
private const val PROJECT_BUILD_DIR = "PROJECT_BUILD_DIR"
|
private const val PROJECT_BUILD_DIR = "PROJECT_BUILD_DIR"
|
||||||
|
|||||||
+5
-2
@@ -50,6 +50,7 @@ internal class TestCompilationFactory {
|
|||||||
targets = settings.get(),
|
targets = settings.get(),
|
||||||
home = settings.get(),
|
home = settings.get(),
|
||||||
classLoader = settings.get(),
|
classLoader = settings.get(),
|
||||||
|
optimizationMode = settings.get(),
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
sourceModules = rootModules,
|
sourceModules = rootModules,
|
||||||
dependencies = TestCompilationDependencies(libraries = libraries, friends = friends),
|
dependencies = TestCompilationDependencies(libraries = libraries, friends = friends),
|
||||||
@@ -67,7 +68,7 @@ internal class TestCompilationFactory {
|
|||||||
add(testRunnerArg)
|
add(testRunnerArg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.getRootCacheDirectory(debuggable = true)?.let { rootCacheDir ->
|
settings.getRootCacheDirectory()?.let { rootCacheDir ->
|
||||||
add("-Xcache-directory=$rootCacheDir")
|
add("-Xcache-directory=$rootCacheDir")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,6 +92,7 @@ internal class TestCompilationFactory {
|
|||||||
targets = settings.get(),
|
targets = settings.get(),
|
||||||
home = settings.get(),
|
home = settings.get(),
|
||||||
classLoader = settings.get(),
|
classLoader = settings.get(),
|
||||||
|
optimizationMode = settings.get(),
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
sourceModules = sourceModules,
|
sourceModules = sourceModules,
|
||||||
dependencies = TestCompilationDependencies(libraries = libraries, friends = friends),
|
dependencies = TestCompilationDependencies(libraries = libraries, friends = friends),
|
||||||
@@ -239,6 +241,7 @@ private class TestCompilationImpl(
|
|||||||
private val targets: KotlinNativeTargets,
|
private val targets: KotlinNativeTargets,
|
||||||
private val home: KotlinNativeHome,
|
private val home: KotlinNativeHome,
|
||||||
private val classLoader: KotlinNativeClassLoader,
|
private val classLoader: KotlinNativeClassLoader,
|
||||||
|
private val optimizationMode: OptimizationMode,
|
||||||
private val freeCompilerArgs: TestCompilerArgs,
|
private val freeCompilerArgs: TestCompilerArgs,
|
||||||
private val sourceModules: Collection<TestModule>,
|
private val sourceModules: Collection<TestModule>,
|
||||||
private val dependencies: TestCompilationDependencies,
|
private val dependencies: TestCompilationDependencies,
|
||||||
@@ -257,7 +260,6 @@ private class TestCompilationImpl(
|
|||||||
private fun ArgsBuilder.applyCommonArgs() {
|
private fun ArgsBuilder.applyCommonArgs() {
|
||||||
add(
|
add(
|
||||||
"-enable-assertions",
|
"-enable-assertions",
|
||||||
"-g",
|
|
||||||
"-target", targets.testTarget.name,
|
"-target", targets.testTarget.name,
|
||||||
"-repo", home.dir.resolve("klib").path,
|
"-repo", home.dir.resolve("klib").path,
|
||||||
"-output", expectedArtifactFile.path,
|
"-output", expectedArtifactFile.path,
|
||||||
@@ -265,6 +267,7 @@ private class TestCompilationImpl(
|
|||||||
"-Xverify-ir",
|
"-Xverify-ir",
|
||||||
"-Xbinary=runtimeAssertionsMode=panic"
|
"-Xbinary=runtimeAssertionsMode=panic"
|
||||||
)
|
)
|
||||||
|
optimizationMode.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
|
|
||||||
addFlattened(dependencies.libraries) { library -> listOf("-l", library.resultingArtifactPath) }
|
addFlattened(dependencies.libraries) { library -> listOf("-l", library.resultingArtifactPath) }
|
||||||
dependencies.friends.takeIf(Collection<*>::isNotEmpty)?.let { friends ->
|
dependencies.friends.takeIf(Collection<*>::isNotEmpty)?.let { friends ->
|
||||||
|
|||||||
+3
-2
@@ -113,11 +113,12 @@ internal class TestCompilerArgs(val compilerArgs: List<String>) {
|
|||||||
"-trw", "-generate-worker-test-runner",
|
"-trw", "-generate-worker-test-runner",
|
||||||
"-nomain",
|
"-nomain",
|
||||||
"-output",
|
"-output",
|
||||||
"-entry",
|
"-entry", "-e",
|
||||||
"-produce",
|
"-produce",
|
||||||
"-repo",
|
"-repo",
|
||||||
"-target",
|
"-target",
|
||||||
"-Xinclude"
|
"-Xinclude",
|
||||||
|
"-g", "-opt"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-6
@@ -30,7 +30,7 @@ internal class KotlinNativeClassLoader(private val lazyClassLoader: Lazy<ClassLo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: in fact, only WITH_MODULES mode is supported now
|
// TODO: in fact, only WITH_MODULES mode is supported now
|
||||||
internal enum class TestMode(val description: String) {
|
internal enum class TestMode(private val description: String) {
|
||||||
ONE_STAGE(
|
ONE_STAGE(
|
||||||
description = "Compile test files altogether without producing intermediate KLIBs."
|
description = "Compile test files altogether without producing intermediate KLIBs."
|
||||||
),
|
),
|
||||||
@@ -40,7 +40,17 @@ internal enum class TestMode(val description: String) {
|
|||||||
WITH_MODULES(
|
WITH_MODULES(
|
||||||
description = "Compile each test file as one or many modules (depending on MODULE directives declared in the file)." +
|
description = "Compile each test file as one or many modules (depending on MODULE directives declared in the file)." +
|
||||||
" Then link the KLIBs into the single executable file."
|
" Then link the KLIBs into the single executable file."
|
||||||
)
|
);
|
||||||
|
|
||||||
|
override fun toString() = description
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum class OptimizationMode(private val description: String, val compilerFlag: String?) {
|
||||||
|
DEBUG("Build with debug information", "-g"),
|
||||||
|
OPT("Build with optimizations applied", "-opt"),
|
||||||
|
NO("Don't use any specific optimizations", null);
|
||||||
|
|
||||||
|
override fun toString() = description + if (compilerFlag == null) "" else " ($compilerFlag)"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,10 +73,10 @@ internal sealed interface CacheKind {
|
|||||||
fun getRootCacheDirectory(
|
fun getRootCacheDirectory(
|
||||||
kotlinNativeHome: KotlinNativeHome,
|
kotlinNativeHome: KotlinNativeHome,
|
||||||
kotlinNativeTargets: KotlinNativeTargets,
|
kotlinNativeTargets: KotlinNativeTargets,
|
||||||
debuggable: Boolean
|
optimizationMode: OptimizationMode
|
||||||
): File? = kotlinNativeHome.dir
|
): File? = kotlinNativeHome.dir
|
||||||
.resolve("klib/cache")
|
.resolve("klib/cache")
|
||||||
.resolve(computeCacheDirName(kotlinNativeTargets.testTarget, CACHE_KIND, debuggable))
|
.resolve(computeCacheDirName(kotlinNativeTargets.testTarget, CACHE_KIND, optimizationMode == OptimizationMode.DEBUG))
|
||||||
.takeIf { it.exists() }
|
.takeIf { it.exists() }
|
||||||
|
|
||||||
private const val CACHE_KIND = "STATIC"
|
private const val CACHE_KIND = "STATIC"
|
||||||
@@ -78,5 +88,5 @@ internal sealed interface CacheKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Settings.getRootCacheDirectory(debuggable: Boolean): File? =
|
internal fun Settings.getRootCacheDirectory(): File? =
|
||||||
get<CacheKind>().safeAs<CacheKind.WithStaticCache>()?.getRootCacheDirectory(get(), get(), debuggable)
|
get<CacheKind>().safeAs<CacheKind.WithStaticCache>()?.getRootCacheDirectory(get(), get(), get())
|
||||||
|
|||||||
Reference in New Issue
Block a user