[K/N][Tests] Support test directive ASSERTIONS_MODE

^KT-64844 Fixed
This commit is contained in:
Vladimir Sukharev
2024-01-09 23:15:18 +01:00
committed by Space Team
parent 809d652bdf
commit fee2a20a55
9 changed files with 53 additions and 54 deletions
+2 -1
View File
@@ -1,13 +1,14 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: STDLIB_ASSERT
// KT-59059
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: JS
// ASSERTIONS_MODE: always-disable
// WITH_STDLIB
@file:Suppress("OPT_IN_USAGE_ERROR") // ExperimentalNativeApi is defined only in Native
fun checkTrue(): Boolean {
var hit = false
val l = { hit = true; true }
-1
View File
@@ -2,7 +2,6 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: JS
// IGNORE_NATIVE: optimizationMode=OPT
// ASSERTIONS_MODE: always-enable
// WITH_STDLIB
@@ -1,8 +0,0 @@
// EXIT_CODE: !0
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class)
// TODO: Test running this test with disabled assertions. This requires removing always-enabled
// -enable-assertions from `BasicCompilation`.
fun main() {
assert(false)
}
@@ -1,5 +0,0 @@
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class)
fun main() {
assert(true)
}
@@ -156,18 +156,6 @@ public class FirNativeStandaloneTestGenerated extends AbstractNativeBlackBoxTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/standalone/termination"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("assertFailed.kt")
public void testAssertFailed() throws Exception {
runTest("native/native.tests/testData/standalone/termination/assertFailed.kt");
}
@Test
@TestMetadata("assertPassed.kt")
public void testAssertPassed() throws Exception {
runTest("native/native.tests/testData/standalone/termination/assertPassed.kt");
}
@Test
@TestMetadata("exitProcess.kt")
public void testExitProcess() throws Exception {
@@ -147,18 +147,6 @@ public class NativeStandaloneTestGenerated extends AbstractNativeBlackBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/standalone/termination"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("assertFailed.kt")
public void testAssertFailed() throws Exception {
runTest("native/native.tests/testData/standalone/termination/assertFailed.kt");
}
@Test
@TestMetadata("assertPassed.kt")
public void testAssertPassed() throws Exception {
runTest("native/native.tests/testData/standalone/termination/assertPassed.kt");
}
@Test
@TestMetadata("exitProcess.kt")
public void testExitProcess() throws Exception {
@@ -196,6 +196,26 @@ internal object TestDirectives : SimpleDirectivesContainer() {
Note that this directive makes sense only in combination with // KIND: STANDALONE_NO_TR
""".trimIndent()
)
val ASSERTIONS_MODE by enumDirective<AssertionsMode>(
description = """
Force assertions mode to given value, overriding calculated mode which is derived from cacheMode and optimizationMode.
""".trimIndent()
)
}
// mimics class `JVMAssertionsMode`
internal enum class AssertionsMode(val description: String) {
ALWAYS_ENABLE("always-enable"),
ALWAYS_DISABLE("always-disable"),
JVM("jvm"),
LEGACY("legacy");
companion object {
val DEFAULT = LEGACY
fun fromStringOrNull(string: String?) = entries.find { it.description == string }
fun fromString(string: String?) = fromStringOrNull(string) ?: DEFAULT
}
}
internal enum class TestKind {
@@ -225,7 +245,11 @@ internal class TestCInteropArgs(cinteropArgs: List<String>) : TestCompilerArgs(e
constructor(vararg cinteropArgs: String) : this(cinteropArgs.asList())
}
internal open class TestCompilerArgs(val compilerArgs: List<String>, val cinteropArgs: List<String> = emptyList()) {
internal open class TestCompilerArgs(
val compilerArgs: List<String>,
val cinteropArgs: List<String> = emptyList(),
val assertionsMode: AssertionsMode = AssertionsMode.DEFAULT,
) {
constructor(vararg compilerArgs: String) : this(compilerArgs.asList())
private val uniqueCompilerArgs = compilerArgs.toSet()
@@ -236,7 +260,9 @@ internal open class TestCompilerArgs(val compilerArgs: List<String>, val cintero
operator fun plus(otherCompilerArgs: TestCompilerArgs): TestCompilerArgs = TestCompilerArgs(
this.compilerArgs + otherCompilerArgs.compilerArgs,
this.cinteropArgs + otherCompilerArgs.cinteropArgs
this.cinteropArgs + otherCompilerArgs.cinteropArgs,
if (this.assertionsMode == otherCompilerArgs.assertionsMode) this.assertionsMode
else fail { "Cannot add ${this.assertionsMode} and ${otherCompilerArgs.assertionsMode}" },
)
companion object {
@@ -55,7 +55,9 @@ internal abstract class BasicCompilation<A : TestCompilationArtifact>(
private fun ArgsBuilder.applyCommonArgs() {
add("-target", targets.testTarget.name)
optimizationMode.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
if (optimizationMode != OptimizationMode.OPT) add("-enable-assertions")
if ((freeCompilerArgs.assertionsMode != AssertionsMode.ALWAYS_DISABLE && optimizationMode != OptimizationMode.OPT) ||
freeCompilerArgs.assertionsMode == AssertionsMode.ALWAYS_ENABLE)
add("-enable-assertions")
add(
"-Xverify-ir=error"
)
@@ -218,7 +220,7 @@ internal class LibraryCompilation(
dependencies = CategorizedDependencies(dependencies),
expectedArtifact = expectedArtifact
) {
override val binaryOptions get() = BinaryOptions.RuntimeAssertionsMode.defaultForTesting(optimizationMode)
override val binaryOptions get() = BinaryOptions.RuntimeAssertionsMode.defaultForTesting(optimizationMode, freeCompilerArgs.assertionsMode)
override fun applySpecificArgs(argsBuilder: ArgsBuilder) = with(argsBuilder) {
add(
@@ -253,7 +255,7 @@ internal class ObjCFrameworkCompilation(
dependencies = CategorizedDependencies(dependencies),
expectedArtifact = expectedArtifact
) {
override val binaryOptions get() = BinaryOptions.RuntimeAssertionsMode.defaultForTesting(optimizationMode)
override val binaryOptions get() = BinaryOptions.RuntimeAssertionsMode.defaultForTesting(optimizationMode, freeCompilerArgs.assertionsMode)
override fun applySpecificArgs(argsBuilder: ArgsBuilder) = with(argsBuilder) {
add(
@@ -356,7 +358,7 @@ internal class ExecutableCompilation(
expectedArtifact = expectedArtifact
) {
private val cacheMode: CacheMode = settings.get()
override val binaryOptions = BinaryOptions.RuntimeAssertionsMode.chooseFor(cacheMode, optimizationMode)
override val binaryOptions = BinaryOptions.RuntimeAssertionsMode.chooseFor(cacheMode, optimizationMode, freeCompilerArgs.assertionsMode)
private val partialLinkageConfig: UsedPartialLinkageConfig = settings.get()
@@ -552,15 +554,19 @@ internal class CategorizedDependencies(uncategorizedDependencies: Iterable<TestC
private object BinaryOptions {
object RuntimeAssertionsMode {
// Here the 'default' is in the sense the default for testing, not the default for the compiler.
fun defaultForTesting(optimizationMode: OptimizationMode): Map<String, String> = when (optimizationMode) {
OptimizationMode.OPT -> mapOf()
else -> mapOf("runtimeAssertionsMode" to "panic")
fun defaultForTesting(optimizationMode: OptimizationMode, assertionsMode: AssertionsMode): Map<String, String> {
val panic = mapOf("runtimeAssertionsMode" to "panic")
return when (assertionsMode) {
AssertionsMode.ALWAYS_ENABLE -> panic
AssertionsMode.ALWAYS_DISABLE -> mapOf()
else -> if (optimizationMode == OptimizationMode.OPT) mapOf() else panic
}
}
val forUseWithCache: Map<String, String> = mapOf("runtimeAssertionsMode" to "ignore")
fun chooseFor(cacheMode: CacheMode, optimizationMode: OptimizationMode) =
if (cacheMode.useStaticCacheForDistributionLibraries) forUseWithCache else defaultForTesting(optimizationMode)
fun chooseFor(cacheMode: CacheMode, optimizationMode: OptimizationMode, assertionsMode: AssertionsMode) =
if (cacheMode.useStaticCacheForDistributionLibraries) forUseWithCache else defaultForTesting(optimizationMode, assertionsMode)
}
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.konan.test.blackbox.support.*
import org.jetbrains.kotlin.konan.test.blackbox.support.TestCase.WithTestRunnerExtras
import org.jetbrains.kotlin.konan.test.blackbox.support.TestDirectives.ASSERTIONS_MODE
import org.jetbrains.kotlin.konan.test.blackbox.support.TestDirectives.DISABLE_NATIVE
import org.jetbrains.kotlin.konan.test.blackbox.support.TestDirectives.DISABLE_NATIVE_K1
import org.jetbrains.kotlin.konan.test.blackbox.support.TestDirectives.DISABLE_NATIVE_K2
@@ -147,7 +148,8 @@ private class ExtTestDataFile(
nominalPackageName = computePackageName(
testDataBaseDir = testRoots.baseDir,
testDataFile = testDataFile
)
),
assertionsMode = AssertionsMode.fromString(structure.directives[ASSERTIONS_MODE.name])
)
}
@@ -172,8 +174,8 @@ private class ExtTestDataFile(
args += "-opt-in=kotlin.native.internal.InternalForKotlinNative" // for `Any.isPermanent()` and `Any.isLocal()`
args += "-opt-in=kotlin.native.internal.InternalForKotlinNativeTests" // for ReflectionPackageName
val freeCInteropArgs = structure.directives.listValues(FREE_CINTEROP_ARGS.name)
?.flatMap { it.split(" ") }
return TestCompilerArgs(args, freeCInteropArgs ?: emptyList())
.orEmpty().flatMap { it.split(" ") }
return TestCompilerArgs(args, freeCInteropArgs, testDataFileSettings.assertionsMode)
}
fun createTestCase(settings: Settings, sharedModules: ThreadSafeCache<String, TestModule.Shared?>): TestCase {
@@ -197,6 +199,7 @@ private class ExtTestDataFile(
private fun determineIfStandaloneTest(): Boolean = with(structure) {
if (directives.contains(NATIVE_STANDALONE_DIRECTIVE)) return true
if (directives.contains(FILECHECK_STAGE.name)) return true
if (directives.contains(ASSERTIONS_MODE.name)) return true
if (isExpectedFailure) return true
// To make the debug of possible failed testruns easier, it makes sense to run dodgy tests alone
if (directives.contains(IGNORE_NATIVE.name) ||
@@ -604,7 +607,8 @@ private class ExtTestDataFileSettings(
val optInsForSourceCode: Set<String>,
val optInsForCompiler: Set<String>,
val generatedSourcesDir: File,
val nominalPackageName: PackageName
val nominalPackageName: PackageName,
val assertionsMode: AssertionsMode,
)
private typealias SharedModuleGenerator = (sharedModulesDir: File) -> TestModule.Shared?