From cb071028f6024475a23c309dc3a7c821bcd01a01 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Fri, 31 Mar 2023 22:58:40 +0200 Subject: [PATCH] [PL][tests] Run K/N tests (new infra) with PL enabled (where possible) #KT-57378 --- .../blackboxtest/support/NativeTestSupport.kt | 36 ++++++++++++-- .../support/compilation/TestCompilation.kt | 24 ++++++++-- .../compilation/TestCompilationFactory.kt | 4 +- .../support/group/UsePartialLinkage.kt | 11 +++++ .../support/settings/TestClassSettings.kt | 6 +++ .../support/settings/TestProcessSettings.kt | 47 ++++++++++++------- 6 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/UsePartialLinkage.kt diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NativeTestSupport.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NativeTestSupport.kt index bd018e64afd..2852f55afc4 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NativeTestSupport.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NativeTestSupport.kt @@ -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()?.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 = diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilation.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilation.kt index c206a7153e3..fc5d4c69f11 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilation.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilation.kt @@ -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.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().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 = mapOf("runtimeAssertionsMode" to "panic") val forUseWithCache: Map = 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 } } diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilationFactory.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilationFactory.kt index 429c1c3331d..266bcc74cd9 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilationFactory.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/compilation/TestCompilationFactory.kt @@ -65,10 +65,10 @@ internal class TestCompilationFactory { companion object { fun decideForRegularKlib(settings: Settings): ProduceStaticCache = - if (settings.get().staticCacheRequiredForEveryLibrary) Yes.Regular else No + if (settings.get().useStaticCacheForUserLibraries) Yes.Regular else No fun decideForIncludedKlib(settings: Settings, expectedExecutableArtifact: Executable, extras: Extras): ProduceStaticCache = - if (!settings.get().staticCacheRequiredForEveryLibrary) + if (!settings.get().useStaticCacheForUserLibraries) No else when (extras) { diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/UsePartialLinkage.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/UsePartialLinkage.kt new file mode 100644 index 00000000000..5553cdcedb8 --- /dev/null +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/UsePartialLinkage.kt @@ -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 } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestClassSettings.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestClassSettings.kt index 0dcff4f9e45..0294badf653 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestClassSettings.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestClassSettings.kt @@ -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) + +/** + * Which PL mode and PL log level to use in tests. + */ +internal class UsedPartialLinkageConfig(val config: PartialLinkageConfig) diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestProcessSettings.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestProcessSettings.kt index 8eac2e57d63..3145b244ef4 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestProcessSettings.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/settings/TestProcessSettings.kt @@ -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" } }