[PL][tests] Run K/N tests (new infra) with PL enabled (where possible)

#KT-57378
This commit is contained in:
Dmitriy Dolovov
2023-03-31 22:58:40 +02:00
parent f1a97ed4b8
commit cb071028f6
6 changed files with 102 additions and 26 deletions
@@ -5,13 +5,18 @@
package org.jetbrains.kotlin.konan.blackboxtest.support
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageConfig
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageLogLevel
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageMode
import org.jetbrains.kotlin.konan.blackboxtest.support.NativeTestSupport.createSimpleTestRunSettings
import org.jetbrains.kotlin.konan.blackboxtest.support.NativeTestSupport.createTestRunSettings
import org.jetbrains.kotlin.konan.blackboxtest.support.NativeTestSupport.getOrCreateSimpleTestRunProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.NativeTestSupport.getOrCreateTestRunProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.group.*
import org.jetbrains.kotlin.konan.blackboxtest.support.group.DisabledTests
import org.jetbrains.kotlin.konan.blackboxtest.support.group.DisabledTestsIfProperty
import org.jetbrains.kotlin.konan.blackboxtest.support.group.FirPipeline
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UsePartialLinkage
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.SimpleTestRunProvider
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunProvider
@@ -23,6 +28,7 @@ import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.test.TestMetadata
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.junit.jupiter.api.extension.BeforeAllCallback
import org.junit.jupiter.api.extension.BeforeEachCallback
import org.junit.jupiter.api.extension.ExtensionContext
@@ -199,7 +205,7 @@ private object NativeTestSupport {
output += computeTimeouts(enforcedProperties)
// Parse annotations of current class, since there's no way to put annotations to upper-level enclosing class
output += computePipelineType(testClass.get())
output += computeUsedPartialLinkageConfig(enclosingTestClass)
output += computeCompilerOutputInterceptor(enforcedProperties)
return nativeTargets
@@ -260,7 +266,7 @@ private object NativeTestSupport {
CacheMode.Alias.values(),
default = CacheMode.defaultForTestTarget(distribution, kotlinNativeTargets)
)
val staticCacheRequiredForEveryLibrary = when (cacheMode) {
val useStaticCacheForUserLibraries = when (cacheMode) {
CacheMode.Alias.NO -> return CacheMode.WithoutCache
CacheMode.Alias.STATIC_ONLY_DIST -> false
CacheMode.Alias.STATIC_EVERYWHERE -> true
@@ -268,7 +274,13 @@ private object NativeTestSupport {
}
val makePerFileCaches = cacheMode == CacheMode.Alias.STATIC_PER_FILE_EVERYWHERE
return CacheMode.WithStaticCache(distribution, kotlinNativeTargets, optimizationMode, staticCacheRequiredForEveryLibrary, makePerFileCaches)
return CacheMode.WithStaticCache(
distribution,
kotlinNativeTargets,
optimizationMode,
useStaticCacheForUserLibraries,
makePerFileCaches
)
}
private fun computeTestMode(enforcedProperties: EnforcedProperties): TestMode =
@@ -446,6 +458,24 @@ private object NativeTestSupport {
else PipelineType.K1
}
private fun computeUsedPartialLinkageConfig(enclosingTestClass: Class<*>): UsedPartialLinkageConfig {
val findPartialLinkageMode: (Class<*>) -> UsePartialLinkage.Mode? = { clazz ->
clazz.allInheritedAnnotations.firstIsInstanceOrNull<UsePartialLinkage>()?.mode
}
val mode = findPartialLinkageMode(enclosingTestClass)
?: enclosingTestClass.declaredClasses.firstNotNullOfOrNull { findPartialLinkageMode(it) }
?: UsePartialLinkage.Mode.ENABLED_WITH_ERROR // The default mode.
val config = when (mode) {
UsePartialLinkage.Mode.DISABLED -> PartialLinkageConfig(PartialLinkageMode.DISABLE, PartialLinkageLogLevel.ERROR)
UsePartialLinkage.Mode.ENABLED_WITH_WARNING -> PartialLinkageConfig(PartialLinkageMode.ENABLE, PartialLinkageLogLevel.WARNING)
UsePartialLinkage.Mode.ENABLED_WITH_ERROR -> PartialLinkageConfig(PartialLinkageMode.ENABLE, PartialLinkageLogLevel.ERROR)
}
return UsedPartialLinkageConfig(config)
}
/*************** Test class settings (simplified) ***************/
private fun ExtensionContext.getOrCreateSimpleTestClassSettings(): SimpleTestClassSettings =
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.konan.blackboxtest.support.*
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.*
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allDependsOn
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.ExecutableCompilation.Companion.applyPartialLinkageArgs
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.ExecutableCompilation.Companion.applyTestRunnerSpecificArgs
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.ExecutableCompilation.Companion.assertTestDumpFileNotEmptyIfExists
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.*
@@ -289,6 +290,8 @@ internal class ExecutableCompilation(
private val cacheMode: CacheMode = settings.get()
override val binaryOptions = BinaryOptions.RuntimeAssertionsMode.chooseFor(cacheMode)
private val partialLinkageConfig: UsedPartialLinkageConfig = settings.get()
override fun applySpecificArgs(argsBuilder: ArgsBuilder): Unit = with(argsBuilder) {
add(
"-produce", "program",
@@ -299,7 +302,7 @@ internal class ExecutableCompilation(
is WithTestRunnerExtras -> {
val testDumpFile: File? = if (sourceModules.isEmpty()
&& dependencies.includedLibraries.isNotEmpty()
&& cacheMode.staticCacheRequiredForEveryLibrary
&& cacheMode.useStaticCacheForUserLibraries
) {
// If there are no source modules passed to the compiler, but there is an included library with the static cache, then
// this should be two-stage test mode: Test functions are already stored in the included library, and they should
@@ -313,12 +316,13 @@ internal class ExecutableCompilation(
applyTestRunnerSpecificArgs(extras, testDumpFile)
}
}
applyPartialLinkageArgs(partialLinkageConfig)
super.applySpecificArgs(argsBuilder)
}
override fun applyDependencies(argsBuilder: ArgsBuilder): Unit = with(argsBuilder) {
super.applyDependencies(argsBuilder)
cacheMode.staticCacheRootDir?.let { cacheRootDir -> add("-Xcache-directory=$cacheRootDir") }
cacheMode.staticCacheForDistributionLibrariesRootDir?.let { cacheRootDir -> add("-Xcache-directory=$cacheRootDir") }
add(dependencies.uniqueCacheDirs) { libraryCacheDir -> "-Xcache-directory=${libraryCacheDir.path}" }
}
@@ -344,6 +348,14 @@ internal class ExecutableCompilation(
}
}
}
internal fun ArgsBuilder.applyPartialLinkageArgs(partialLinkageConfig: UsedPartialLinkageConfig) {
with(partialLinkageConfig.config) {
add("-Xpartial-linkage=${mode.name.lowercase()}")
if (mode.isEnabled)
add("-Xpartial-linkage-loglevel=${logLevel.name.lowercase()}")
}
}
}
}
@@ -374,11 +386,13 @@ internal class StaticCacheCompilation(
private val cacheRootDir: File = run {
val cacheMode = settings.get<CacheMode>()
cacheMode.staticCacheRootDir ?: fail { "No cache root directory found for cache mode $cacheMode" }
cacheMode.staticCacheForDistributionLibrariesRootDir ?: fail { "No cache root directory found for cache mode $cacheMode" }
}
private val makePerFileCache: Boolean = settings.get<CacheMode>().makePerFileCaches
private val partialLinkageConfig: UsedPartialLinkageConfig = settings.get()
override fun applySpecificArgs(argsBuilder: ArgsBuilder): Unit = with(argsBuilder) {
add("-produce", "static_cache")
pipelineType.compilerFlags.forEach { compilerFlag -> add(compilerFlag) }
@@ -400,6 +414,8 @@ internal class StaticCacheCompilation(
)
if (makePerFileCache)
add("-Xmake-per-file-cache")
applyPartialLinkageArgs(partialLinkageConfig)
}
override fun applyDependencies(argsBuilder: ArgsBuilder): Unit = with(argsBuilder) {
@@ -458,6 +474,6 @@ private object BinaryOptions {
val defaultForTesting: Map<String, String> = mapOf("runtimeAssertionsMode" to "panic")
val forUseWithCache: Map<String, String> = mapOf("runtimeAssertionsMode" to "ignore")
fun chooseFor(cacheMode: CacheMode) = if (cacheMode.staticCacheRootDir != null) forUseWithCache else defaultForTesting
fun chooseFor(cacheMode: CacheMode) = if (cacheMode.useStaticCacheForDistributionLibraries) forUseWithCache else defaultForTesting
}
}
@@ -65,10 +65,10 @@ internal class TestCompilationFactory {
companion object {
fun decideForRegularKlib(settings: Settings): ProduceStaticCache =
if (settings.get<CacheMode>().staticCacheRequiredForEveryLibrary) Yes.Regular else No
if (settings.get<CacheMode>().useStaticCacheForUserLibraries) Yes.Regular else No
fun decideForIncludedKlib(settings: Settings, expectedExecutableArtifact: Executable, extras: Extras): ProduceStaticCache =
if (!settings.get<CacheMode>().staticCacheRequiredForEveryLibrary)
if (!settings.get<CacheMode>().useStaticCacheForUserLibraries)
No
else
when (extras) {
@@ -0,0 +1,11 @@
/*
* 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.konan.blackboxtest.support.group
@Target(AnnotationTarget.CLASS)
internal annotation class UsePartialLinkage(val mode: Mode) {
enum class Mode { DISABLED, ENABLED_WITH_WARNING, ENABLED_WITH_ERROR }
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.konan.blackboxtest.support.settings
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageConfig
import org.jetbrains.kotlin.konan.blackboxtest.AbstractNativeBlackBoxTest
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseId
import java.io.File
@@ -37,3 +38,8 @@ internal data class ComputedTestConfiguration(val configuration: TestConfigurati
* This is applicable only to inheritors of [AbstractNativeBlackBoxTest] that use [TestCaseId.TestDataFile].
*/
internal class DisabledTestDataFiles(val filesAndDirectories: Set<File>)
/**
* Which PL mode and PL log level to use in tests.
*/
internal class UsedPartialLinkageConfig(val config: PartialLinkageConfig)
@@ -188,14 +188,16 @@ internal class Timeouts(val executionTimeout: Duration) {
/**
* Used cache mode.
*/
internal sealed interface CacheMode {
val staticCacheRootDir: File?
val staticCacheRequiredForEveryLibrary: Boolean
val makePerFileCaches: Boolean
internal sealed class CacheMode {
abstract val staticCacheForDistributionLibrariesRootDir: File?
abstract val useStaticCacheForUserLibraries: Boolean
abstract val makePerFileCaches: Boolean
object WithoutCache : CacheMode {
override val staticCacheRootDir: File? get() = null
override val staticCacheRequiredForEveryLibrary get() = false
val useStaticCacheForDistributionLibraries: Boolean get() = staticCacheForDistributionLibrariesRootDir != null
object WithoutCache : CacheMode() {
override val staticCacheForDistributionLibrariesRootDir: File? get() = null
override val useStaticCacheForUserLibraries: Boolean get() = false
override val makePerFileCaches: Boolean = false
}
@@ -203,21 +205,21 @@ internal sealed interface CacheMode {
distribution: Distribution,
kotlinNativeTargets: KotlinNativeTargets,
optimizationMode: OptimizationMode,
override val staticCacheRequiredForEveryLibrary: Boolean,
override val useStaticCacheForUserLibraries: Boolean,
override val makePerFileCaches: Boolean
) : CacheMode {
override val staticCacheRootDir: File = File(distribution.klib)
) : CacheMode() {
override val staticCacheForDistributionLibrariesRootDir: File = File(distribution.klib)
.resolve("cache")
.resolve(
computeCacheDirName(
computeDistroCacheDirName(
testTarget = kotlinNativeTargets.testTarget,
cacheKind = CACHE_KIND,
debuggable = optimizationMode == OptimizationMode.DEBUG
)
).also { rootCacheDir ->
assertTrue(rootCacheDir.exists()) { "The root cache directory is not found: $rootCacheDir" }
assertTrue(rootCacheDir.isDirectory) { "The root cache directory is not a directory: $rootCacheDir" }
assertTrue(rootCacheDir.list().orEmpty().isNotEmpty()) { "The root cache directory is empty: $rootCacheDir" }
).apply {
assertTrue(exists()) { "The distribution libraries cache directory is not found: $this" }
assertTrue(isDirectory) { "The distribution libraries cache directory is not a directory: $this" }
assertTrue(list().orEmpty().isNotEmpty()) { "The distribution libraries cache directory is empty: $this" }
}
companion object {
@@ -237,8 +239,19 @@ internal sealed interface CacheMode {
return if (kotlinNativeTargets.testTarget in cacheableTargets) Alias.STATIC_ONLY_DIST else Alias.NO
}
fun computeCacheDirName(testTarget: KonanTarget, cacheKind: String, debuggable: Boolean) =
"$testTarget${if (debuggable) "-g" else ""}$cacheKind"
fun computeCacheDirName(
testTarget: KonanTarget,
cacheKind: String,
debuggable: Boolean,
partialLinkageEnabled: Boolean
) = "$testTarget${if (debuggable) "-g" else ""}$cacheKind${if (partialLinkageEnabled) "-pl" else ""}"
// N.B. The distribution libs are always built with the partial linkage turned off.
fun computeDistroCacheDirName(
testTarget: KonanTarget,
cacheKind: String,
debuggable: Boolean,
) = "$testTarget${if (debuggable) "-g" else ""}$cacheKind"
}
}