[K/N][Tests] Migrate first Apple-specific test
^KT-61259
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// DISABLE_NATIVE: isAppleTarget=false
|
||||||
|
// There is no GameController on watchOS.
|
||||||
|
// DISABLE_NATIVE: targetFamily=WATCHOS
|
||||||
|
// MODULE: cinterop
|
||||||
|
// FILE: kt59167.def
|
||||||
|
language=Objective-C
|
||||||
|
---
|
||||||
|
#import <GameController/GCDevice.h>
|
||||||
|
|
||||||
|
// We only need to touch the problematic header to trigger the problem,
|
||||||
|
// so actual code does not matter.
|
||||||
|
id<GCDevice> dummy() {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(cinterop)
|
||||||
|
// FILE: main.kt
|
||||||
|
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||||
|
import kotlin.test.*
|
||||||
|
import kt59167.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertNull(dummy())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -1231,9 +1231,6 @@ if (PlatformInfo.isAppleTarget(project)) {
|
|||||||
it.defFile 'interop/objc/objCAction/objclib.def'
|
it.defFile 'interop/objc/objCAction/objclib.def'
|
||||||
it.headers "$projectDir/interop/objc/objCAction/objclib.h"
|
it.headers "$projectDir/interop/objc/objCAction/objclib.h"
|
||||||
}
|
}
|
||||||
createInterop("kt59167") {
|
|
||||||
it.defFile 'interop/kt59167/kt59167.def'
|
|
||||||
}
|
|
||||||
createInterop("overridabilityCondition") {
|
createInterop("overridabilityCondition") {
|
||||||
it.defFile 'interop/objc/overridabilityCondition/lib.def'
|
it.defFile 'interop/objc/overridabilityCondition/lib.def'
|
||||||
it.headers "$projectDir/interop/objc/overridabilityCondition/lib.h"
|
it.headers "$projectDir/interop/objc/overridabilityCondition/lib.h"
|
||||||
@@ -1850,13 +1847,6 @@ if (PlatformInfo.isAppleTarget(project)) {
|
|||||||
UtilsKt.dependsOnPlatformLibs(it)
|
UtilsKt.dependsOnPlatformLibs(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
interopTest("interop_kt59167") {
|
|
||||||
// There is no GameController on watchOS.
|
|
||||||
enabled = target.family != Family.WATCHOS
|
|
||||||
source = 'interop/kt59167/main.kt'
|
|
||||||
interop = 'kt59167'
|
|
||||||
}
|
|
||||||
|
|
||||||
interopTest("interop_objc_kt63423_dispose_on_main_stress") {
|
interopTest("interop_objc_kt63423_dispose_on_main_stress") {
|
||||||
// Test depends on macOS-specific AppKit
|
// Test depends on macOS-specific AppKit
|
||||||
enabled = (project.testTarget == 'macos_x64' || project.testTarget == 'macos_arm64' || project.testTarget == null)
|
enabled = (project.testTarget == 'macos_x64' || project.testTarget == 'macos_arm64' || project.testTarget == null)
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
language=Objective-C
|
|
||||||
---
|
|
||||||
#import <GameController/GCDevice.h>
|
|
||||||
|
|
||||||
// We only need to touch the problematic header to trigger the problem,
|
|
||||||
// so actual code does not matter.
|
|
||||||
id<GCDevice> dummy() {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import kotlin.test.*
|
|
||||||
import kt59167.*
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
assertNull(dummy())
|
|
||||||
}
|
|
||||||
+6
@@ -4856,6 +4856,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
|
|||||||
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt59167.kt")
|
||||||
|
public void testKt59167() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/cinterop/kt59167.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt63048.kt")
|
@TestMetadata("kt63048.kt")
|
||||||
public void testKt63048() throws Exception {
|
public void testKt63048() throws Exception {
|
||||||
|
|||||||
+6
@@ -4966,6 +4966,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
|
|||||||
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt59167.kt")
|
||||||
|
public void testKt59167() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/cinterop/kt59167.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt63048.kt")
|
@TestMetadata("kt63048.kt")
|
||||||
public void testKt63048() throws Exception {
|
public void testKt63048() throws Exception {
|
||||||
|
|||||||
+6
@@ -4746,6 +4746,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
|||||||
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt59167.kt")
|
||||||
|
public void testKt59167() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/cinterop/kt59167.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt63048.kt")
|
@TestMetadata("kt63048.kt")
|
||||||
public void testKt63048() throws Exception {
|
public void testKt63048() throws Exception {
|
||||||
|
|||||||
+6
@@ -4857,6 +4857,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
|
|||||||
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
runTest("compiler/testData/codegen/box/cinterop/kt57640.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt59167.kt")
|
||||||
|
public void testKt59167() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/cinterop/kt59167.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt63048.kt")
|
@TestMetadata("kt63048.kt")
|
||||||
public void testKt63048() throws Exception {
|
public void testKt63048() throws Exception {
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ internal sealed interface TestCompilationResult<A : TestCompilationArtifact> {
|
|||||||
companion object {
|
companion object {
|
||||||
fun <A : TestCompilationArtifact> TestCompilationResult<A>.assertSuccess(): Success<A> = when (this) {
|
fun <A : TestCompilationArtifact> TestCompilationResult<A>.assertSuccess(): Success<A> = when (this) {
|
||||||
is Success -> this
|
is Success -> this
|
||||||
is UnexpectedFailure -> fail { describeFailure() }
|
is UnexpectedFailure -> throw CompilationToolException(describeFailure())
|
||||||
is CompilationToolFailure -> throw CompilationToolException(describeFailure())
|
is CompilationToolFailure -> throw CompilationToolException(describeFailure())
|
||||||
is DependencyFailures -> fail { describeDependencyFailures() }
|
is DependencyFailures -> fail { describeDependencyFailures() }
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.konan.test.blackbox.support.group
|
|||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.ClassLevelProperty
|
import org.jetbrains.kotlin.konan.test.blackbox.support.ClassLevelProperty
|
||||||
|
|
||||||
// Deprecated: Use test directives instead:
|
// Deprecated: Use test directives instead:
|
||||||
// `IGNORE_BACKEND: NATIVE`, `IGNORE_BACKEND_K1: NATIVE`, `IGNORE_BACKEND_K2: NATIVE` if test fails in any tets config
|
// `IGNORE_BACKEND: NATIVE`, `IGNORE_BACKEND_K1: NATIVE`, `IGNORE_BACKEND_K2: NATIVE` if test fails in any test config
|
||||||
// `IGNORE_NATIVE`, `IGNORE_NATIVE_K1`, `IGNORE_NATIVE_K2` with a property matcher, for usual easy fails
|
// `IGNORE_NATIVE`, `IGNORE_NATIVE_K1`, `IGNORE_NATIVE_K2` with/without a property matcher, for usual easy fails (please provide issue link)
|
||||||
// `DISABLE_NATIVE`, `DISABLE_NATIVE_K1`, `DISABLE_NATIVE_K2` in case compiler crashes within JVM
|
// `DISABLE_NATIVE`, `DISABLE_NATIVE_K1`, `DISABLE_NATIVE_K2` with/without a property matcher, in case compiler crashes within JVM, or compilation/execution would be a resource waste
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
internal annotation class DisabledTests(
|
internal annotation class DisabledTests(
|
||||||
val sourceLocations: Array<String>
|
val sourceLocations: Array<String>
|
||||||
@@ -17,8 +17,8 @@ internal annotation class DisabledTests(
|
|||||||
|
|
||||||
// @DisabledTestsIfProperty(...) is intended primarily to turn off tests in bulk to reduce pressure on CI infrastructure for certain targets
|
// @DisabledTestsIfProperty(...) is intended primarily to turn off tests in bulk to reduce pressure on CI infrastructure for certain targets
|
||||||
// To mark failed tests, please use the following test directives instead:
|
// To mark failed tests, please use the following test directives instead:
|
||||||
// `IGNORE_NATIVE`, `IGNORE_NATIVE_K1`, `IGNORE_NATIVE_K2` with a property matcher, for usual easy fails
|
// `IGNORE_NATIVE`, `IGNORE_NATIVE_K1`, `IGNORE_NATIVE_K2` with/without a property matcher, for usual easy fails (please provide issue link)
|
||||||
// `DISABLE_NATIVE`, `DISABLE_NATIVE_K1`, `DISABLE_NATIVE_K2` for overcomplicated property combinations, or in case compiler crashes within JVM
|
// `DISABLE_NATIVE`, `DISABLE_NATIVE_K1`, `DISABLE_NATIVE_K2` with/without a property matcher, in case compiler crashes within JVM, or compilation/execution would be a resource waste
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
internal annotation class DisabledTestsIfProperty(
|
internal annotation class DisabledTestsIfProperty(
|
||||||
val sourceLocations: Array<String>,
|
val sourceLocations: Array<String>,
|
||||||
|
|||||||
+40
-21
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.*
|
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.TestCase.WithTestRunnerExtras
|
||||||
import org.jetbrains.kotlin.konan.test.blackbox.support.TestDirectives.ASSERTIONS_MODE
|
import org.jetbrains.kotlin.konan.test.blackbox.support.TestDirectives.ASSERTIONS_MODE
|
||||||
@@ -47,6 +48,7 @@ import org.jetbrains.kotlin.test.InTextDirectivesUtils.*
|
|||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_K1
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_K1
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_K2
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_K2
|
||||||
|
import org.jetbrains.kotlin.test.directives.model.StringDirective
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
@@ -155,7 +157,7 @@ private class ExtTestDataFile(
|
|||||||
|
|
||||||
val isRelevant: Boolean =
|
val isRelevant: Boolean =
|
||||||
isCompatibleTarget(TargetBackend.NATIVE, testDataFile) // Checks TARGET_BACKEND/DONT_TARGET_EXACT_BACKEND directives.
|
isCompatibleTarget(TargetBackend.NATIVE, testDataFile) // Checks TARGET_BACKEND/DONT_TARGET_EXACT_BACKEND directives.
|
||||||
&& !isDisabledNative(pipelineType, structure.directives)
|
&& !settings.isDisabledNative(structure.directives)
|
||||||
&& testDataFileSettings.languageSettings.none { it in INCOMPATIBLE_LANGUAGE_SETTINGS }
|
&& testDataFileSettings.languageSettings.none { it in INCOMPATIBLE_LANGUAGE_SETTINGS }
|
||||||
&& INCOMPATIBLE_DIRECTIVES.none { it in structure.directives }
|
&& INCOMPATIBLE_DIRECTIVES.none { it in structure.directives }
|
||||||
&& structure.directives[API_VERSION_DIRECTIVE] !in INCOMPATIBLE_API_VERSIONS
|
&& structure.directives[API_VERSION_DIRECTIVE] !in INCOMPATIBLE_API_VERSIONS
|
||||||
@@ -893,14 +895,6 @@ private class ExtTestDataFileStructureFactory(parentDisposable: Disposable) : Te
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isDisabledNative(pipelineType: PipelineType, directives: Directives): Boolean {
|
|
||||||
return when (pipelineType) {
|
|
||||||
PipelineType.K1 -> directives.contains(DISABLE_NATIVE.name) || directives.contains(DISABLE_NATIVE_K1.name)
|
|
||||||
PipelineType.K2 -> directives.contains(DISABLE_NATIVE.name) || directives.contains(DISABLE_NATIVE_K2.name)
|
|
||||||
PipelineType.DEFAULT -> directives.contains(DISABLE_NATIVE.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun Settings.isIgnoredTarget(testDataFile: File): Boolean {
|
internal fun Settings.isIgnoredTarget(testDataFile: File): Boolean {
|
||||||
val disposable = Disposer.newDisposable("Disposable for ExtTestCaseGroupProvider.isIgnoredTarget")
|
val disposable = Disposer.newDisposable("Disposable for ExtTestCaseGroupProvider.isIgnoredTarget")
|
||||||
try {
|
try {
|
||||||
@@ -934,24 +928,27 @@ private fun Settings.isIgnoredWithIGNORE_BACKEND(directives: Directives): Boolea
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val TARGET_FAMILY = "targetFamily"
|
||||||
|
private val IS_APPLE_TARGET = "isAppleTarget"
|
||||||
private val CACHE_MODE_NAMES = CacheMode.Alias.entries.map { it.name }
|
private val CACHE_MODE_NAMES = CacheMode.Alias.entries.map { it.name }
|
||||||
private val TEST_MODE_NAMES = TestMode.entries.map { it.name }
|
private val TEST_MODE_NAMES = TestMode.entries.map { it.name }
|
||||||
private val OPTIMIZATION_MODE_NAMES = OptimizationMode.entries.map { it.name }
|
private val OPTIMIZATION_MODE_NAMES = OptimizationMode.entries.map { it.name }
|
||||||
private val GC_TYPE_NAMES = GCType.entries.map { it.name }
|
private val GC_TYPE_NAMES = GCType.entries.map { it.name }
|
||||||
|
private val FAMILY_NAMES = Family.entries.map { it.name }
|
||||||
|
private val BOOLEAN_NAMES = listOf(true.toString(), false.toString())
|
||||||
|
|
||||||
private fun Settings.isIgnoredWithIGNORE_NATIVE(
|
private fun Settings.isDisabledNative(directives: Directives) =
|
||||||
directives: Directives,
|
evaluate(getDirectiveValues(directives, DISABLE_NATIVE, DISABLE_NATIVE_K1, DISABLE_NATIVE_K2))
|
||||||
): Boolean {
|
|
||||||
val directiveValues = buildList {
|
private fun Settings.isIgnoredWithIGNORE_NATIVE(directives: Directives) =
|
||||||
directives.listValues(IGNORE_NATIVE.name)?.let { addAll(it) }
|
evaluate(getDirectiveValues(directives, IGNORE_NATIVE, IGNORE_NATIVE_K1, IGNORE_NATIVE_K2))
|
||||||
when (get<PipelineType>()) {
|
|
||||||
PipelineType.K1 -> directives.listValues(IGNORE_NATIVE_K1.name)?.let { addAll(it) }
|
// Evaluation of conjunction of boolean expressions like `property1=value1 && property2=value2`.
|
||||||
PipelineType.K2 -> directives.listValues(IGNORE_NATIVE_K2.name)?.let { addAll(it) }
|
// Any null element makes whole result as `true`.
|
||||||
else -> {}
|
private fun Settings.evaluate(directiveValues: List<String?>): Boolean {
|
||||||
}
|
|
||||||
}
|
|
||||||
// Boolean evaluation of expressions like `property1=value1 && property2=value2`
|
|
||||||
directiveValues.forEach {
|
directiveValues.forEach {
|
||||||
|
if (it == null)
|
||||||
|
return true // Directive without value is treated as unconditional
|
||||||
val split = it.split("&&")
|
val split = it.split("&&")
|
||||||
val booleanList = split.map {
|
val booleanList = split.map {
|
||||||
val matchResult = "(.+)=(.+)".toRegex().find(it.trim())
|
val matchResult = "(.+)=(.+)".toRegex().find(it.trim())
|
||||||
@@ -963,6 +960,8 @@ private fun Settings.isIgnoredWithIGNORE_NATIVE(
|
|||||||
ClassLevelProperty.OPTIMIZATION_MODE.shortName -> get<OptimizationMode>().name to OPTIMIZATION_MODE_NAMES
|
ClassLevelProperty.OPTIMIZATION_MODE.shortName -> get<OptimizationMode>().name to OPTIMIZATION_MODE_NAMES
|
||||||
ClassLevelProperty.TEST_TARGET.shortName -> get<KotlinNativeTargets>().testTarget.name to null
|
ClassLevelProperty.TEST_TARGET.shortName -> get<KotlinNativeTargets>().testTarget.name to null
|
||||||
ClassLevelProperty.GC_TYPE.shortName -> get<GCType>().name to GC_TYPE_NAMES
|
ClassLevelProperty.GC_TYPE.shortName -> get<GCType>().name to GC_TYPE_NAMES
|
||||||
|
TARGET_FAMILY -> get<KotlinNativeTargets>().testTarget.family.name to FAMILY_NAMES
|
||||||
|
IS_APPLE_TARGET -> get<KotlinNativeTargets>().testTarget.family.isAppleFamily.toString() to BOOLEAN_NAMES
|
||||||
else -> throw AssertionError("ClassLevelProperty name: $propName is not yet supported in IGNORE_NATIVE* test directives.")
|
else -> throw AssertionError("ClassLevelProperty name: $propName is not yet supported in IGNORE_NATIVE* test directives.")
|
||||||
}
|
}
|
||||||
val valueFromTestDirective = matchResult.groups[2]?.value!!
|
val valueFromTestDirective = matchResult.groups[2]?.value!!
|
||||||
@@ -981,6 +980,26 @@ private fun Settings.isIgnoredWithIGNORE_NATIVE(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns list of relevant directive values.
|
||||||
|
// Null is added to result list in case the directive given without value.
|
||||||
|
private fun Settings.getDirectiveValues(
|
||||||
|
directives: Directives,
|
||||||
|
directiveAllPipelineTypes: StringDirective,
|
||||||
|
directiveK1: StringDirective,
|
||||||
|
directiveK2: StringDirective
|
||||||
|
): List<String?> = buildList {
|
||||||
|
fun extract(directives: Directives, directive: StringDirective) {
|
||||||
|
if (directives.contains(directive.name))
|
||||||
|
directives.listValues(directive.name)?.let { addAll(it) } ?: add(null)
|
||||||
|
}
|
||||||
|
extract(directives, directiveAllPipelineTypes)
|
||||||
|
when (get<PipelineType>()) {
|
||||||
|
PipelineType.K1 -> extract(directives, directiveK1)
|
||||||
|
PipelineType.K2 -> extract(directives, directiveK2)
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val KtFile.packageFqNameForKLib: FqName
|
private val KtFile.packageFqNameForKLib: FqName
|
||||||
get() = when (name.substringAfterLast(".")) {
|
get() = when (name.substringAfterLast(".")) {
|
||||||
"kt" -> packageFqName
|
"kt" -> packageFqName
|
||||||
|
|||||||
Reference in New Issue
Block a user