[K/N][Tests] Migrate dylib-interop-exe tests

^KT-61259
This commit is contained in:
Vladimir Sukharev
2024-02-15 13:57:30 +01:00
committed by Space Team
parent 83d851dd61
commit 2b2c685827
56 changed files with 278 additions and 397 deletions
@@ -963,73 +963,6 @@ createInterop("workerSignals") {
} }
if (PlatformInfo.isAppleTarget(project)) { if (PlatformInfo.isAppleTarget(project)) {
createInterop("objcSmoke") {
it.defFile 'interop/objc/objcSmoke.def'
it.headers "$projectDir/interop/objc/smoke.h"
}
createInterop("objcTests") {
it.defFile 'interop/objc/objcTests.def'
it.headers fileTree("$projectDir/interop/objc/tests") { include '**/*.h' }
}
createInterop("objcMisc") {
it.defFile 'interop/objc_with_initializer/objc_misc.def'
it.headers "$projectDir/interop/objc_with_initializer/objc_misc.h"
}
createInterop("objcMessaging") {
it.defFile 'interop/objc/msg_send/messaging.def'
it.headers "$projectDir/interop/objc/msg_send/messaging.h"
}
createInterop("foreignException") {
it.defFile 'interop/objc/foreignException/objc_wrap.def'
it.headers "$projectDir/interop/objc/foreignException/objc_wrap.h"
}
createInterop("foreignExceptionMode_default") {
it.defFile 'interop/objc/foreignException/objcExceptionMode.def'
it.headers "$projectDir/interop/objc/foreignException/objc_wrap.h"
}
createInterop("foreignExceptionMode_wrap") {
it.defFile 'interop/objc/foreignException/objcExceptionMode.def'
it.headers "$projectDir/interop/objc/foreignException/objc_wrap.h"
it.extraOpts '-Xforeign-exception-mode', "objc-wrap"
}
createInterop("objcKt43517") {
it.defFile 'framework/kt43517/kt43517.def'
}
createInterop("objc_kt42172") {
it.defFile 'interop/objc/kt42172/objclib.def'
it.headers "$projectDir/interop/objc/kt42172/objclib.h"
}
createInterop("objc_kt55938") {
it.defFile 'interop/objc/kt55938/objclib.def'
it.headers "$projectDir/interop/objc/kt55938/objclib.h"
}
createInterop("objc_include_categories") {
it.defFile 'interop/objc/include_categories/objc_include_categories.def'
it.headers "$projectDir/interop/objc/include_categories/objc_include_categories.h"
}
createInterop("frameworkForwardDeclarations") {
it.defFile 'framework/forwardDeclarations/clib.def'
}
createInterop("objc_kt56402") {
it.defFile 'interop/objc/kt56402/objclib.def'
it.headers "$projectDir/interop/objc/kt56402/objclib.h"
}
createInterop("objc_friendly_dealloc") {
it.defFile 'interop/objc/objc_friendly_dealloc/objclib.def'
it.headers "$projectDir/interop/objc/objc_friendly_dealloc/objclib.h"
}
createInterop("objCAction") {
it.defFile 'interop/objc/objCAction/objclib.def'
it.headers "$projectDir/interop/objc/objCAction/objclib.h"
}
createInterop("kt63423_dispose_on_main_stress") { createInterop("kt63423_dispose_on_main_stress") {
it.defFile 'interop/objc/kt63423_dispose_on_main_stress/objclib.def' it.defFile 'interop/objc/kt63423_dispose_on_main_stress/objclib.def'
it.headers "$projectDir/interop/objc/kt63423_dispose_on_main_stress/objclib.h" it.headers "$projectDir/interop/objc/kt63423_dispose_on_main_stress/objclib.h"
@@ -1157,160 +1090,6 @@ if (PlatformInfo.isAppleTarget(project)) {
UtilsKt.dependsOnPlatformLibs(it) UtilsKt.dependsOnPlatformLibs(it)
} }
interopTest("interop_objc_global_initializer") {
useGoldenData = true
source = "interop/objc_with_initializer/objc_test.kt"
interop = 'objcMisc'
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjcmisc.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc_with_initializer/objc_misc.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_msg_send") {
source = "interop/objc/msg_send/main.kt"
interop = 'objcMessaging'
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjcmessaging.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/msg_send/messaging.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_foreignException") {
source = "interop/objc/foreignException/objc_wrap.kt"
interop = 'foreignException'
UtilsKt.dependsOnPlatformLibs(it)
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjcexception.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/foreignException/objc_wrap.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_foreignExceptionMode_wrap") {
source = "interop/objc/foreignException/objcExceptionMode_wrap.kt"
interop = 'foreignExceptionMode_wrap'
useGoldenData = true
UtilsKt.dependsOnPlatformLibs(it)
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjcexception.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/foreignException/objc_wrap.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_foreignExceptionMode_default") {
source = "interop/objc/foreignException/objcExceptionMode_default.kt"
interop = 'foreignExceptionMode_default'
useGoldenData = true
UtilsKt.dependsOnPlatformLibs(it)
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjcexception.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/foreignException/objc_wrap.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_kt42172") {
enabled = !isNoopGC
source = "interop/objc/kt42172/main.kt"
interop = "objc_kt42172"
flags = ['-opt-in=kotlin.native.internal.InternalForKotlinNative']
useGoldenData = true
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjc_kt42172.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/kt42172/objclib.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_kt55938") {
source = "interop/objc/kt55938/main.kt"
lib = "interop/objc/kt55938/lib.kt"
interop = "objc_kt55938"
useGoldenData = true
enabled = cacheTesting != null
flags = [
"-Xauto-cache-from=$testOutputRoot/local/objc_kt55938",
"-Xauto-cache-from=$testOutputRoot/local/interop_objc_kt55938",
"-Xauto-cache-dir=$testOutputRoot/local/interop_objc_kt55938/cache",
"-Xsuppress-version-warnings", // suppresses warning about experimental language version, otherwise test fails with K2 due to -Werror
"-Werror" // to forbid retry with auto-cache disabled
]
UtilsKt.findKonanBuildTask(project, "objc_kt55938", target).configure {
it.doFirst {
def cacheDir = new File("$testOutputRoot/local/interop_objc_kt55938/cache")
cacheDir.deleteDir()
mkdir(cacheDir)
}
}
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjc_kt55938.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/kt55938/objclib.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
standaloneTest("objc_arc_contract") { standaloneTest("objc_arc_contract") {
def bcFile = project.layout.buildDirectory.file("objc_arc_contract.bc").get().asFile def bcFile = project.layout.buildDirectory.file("objc_arc_contract.bc").get().asFile
doBeforeBuild { doBeforeBuild {
@@ -1325,24 +1104,6 @@ if (PlatformInfo.isAppleTarget(project)) {
flags = ["-native-library", bcFile.toString()] flags = ["-native-library", bcFile.toString()]
} }
interopTest("interop_objc_include_categories") {
useGoldenData = true
source = "interop/objc/include_categories/main.kt"
interop = "objc_include_categories"
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjcincludecategories.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/include_categories/objc_include_categories.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
standaloneTest("interop_kt55653") { standaloneTest("interop_kt55653") {
// 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)
@@ -1359,70 +1120,6 @@ if (PlatformInfo.isAppleTarget(project)) {
UtilsKt.dependsOnPlatformLibs(it) UtilsKt.dependsOnPlatformLibs(it)
} }
interopTest("interop_objc_kt56402") {
// Test depends on macOS-specific AppKit
enabled = (project.testTarget == 'macos_x64' || project.testTarget == 'macos_arm64' || project.testTarget == null)
&& !isNoopGC // requires some GC
source = 'interop/objc/kt56402/main.kt'
interop = "objc_kt56402"
flags = ["-tr", "-e", "runAllTests"] // Generate test suites, but use custom entrypoint.
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjc_kt56402.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/kt56402/objclib.m"
args "-g"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
args '-framework', 'AppKit'
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
}
interopTest("interop_objc_friendly_dealloc") {
enabled = !isNoopGC // requires some GC
source = 'interop/objc/objc_friendly_dealloc/main.kt'
interop = "objc_friendly_dealloc"
flags = ["-tr"]
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjc_friendly_dealloc.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/objc_friendly_dealloc/objclib.m"
args "-lobjc", '-fno-objc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
UtilsKt.dependsOnPlatformLibs(it)
}
interopTest("interop_objCAction") {
source = 'interop/objc/objCAction/main.kt'
interop = "objCAction"
flags = ["-tr"]
doBeforeBuild {
def dylibFile = project.layout.buildDirectory.file("libobjCAction.dylib").get().asFile
mkdir(dylibFile.parentFile)
project.extensions.execClang.execClangForCompilerTests(project.target) {
args "$projectDir/interop/objc/objCAction/objclib.m"
args "-lobjc", '-fobjc-arc'
args '-fPIC', '-shared', '-o', dylibFile.toString()
}
if (UtilsKt.isSimulatorTarget(project, project.target)) {
UtilsKt.codesign(project, dylibFile.toString())
}
}
UtilsKt.dependsOnPlatformLibs(it)
}
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 +0,0 @@
OK: Ends with uncaught exception handler
@@ -1 +0,0 @@
OK: ForeignException
@@ -1,10 +0,0 @@
3.0
3.14
6.0
3
6
6.0
3.0
600.0
@@ -1,4 +0,0 @@
language = Objective-C
headerFilter = **/objc_include_categories.h
linkerOpts = -lobjcincludecategories
objcClassesIncludingCategories = BaseClass DerivedClass
@@ -1 +0,0 @@
Executed finalizer
@@ -1,3 +0,0 @@
language = Objective-C
headerFilter = **/objclib.h
linkerOpts = -lobjc_kt42172
@@ -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.
*/
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
package kt55938lib
import objclib.*
inline fun foo() = ObjCClass.foo()
@@ -1,10 +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 kt55938lib.*
fun main() {
print("foo() call result is ${foo()}")
}
@@ -1 +0,0 @@
foo() call result is 42
@@ -1,3 +0,0 @@
language = Objective-C
headerFilter = **/objclib.h
linkerOpts = -lobjc_kt55938
@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface ObjCClass : NSObject
+ (int)foo;
@end
@@ -1,11 +0,0 @@
#include "objclib.h"
@implementation ObjCClass {
}
+ (int)foo {
return 42;
}
@end
@@ -1,3 +0,0 @@
language = Objective-C
headerFilter = **/objclib.h
linkerOpts = -lobjc_kt56402
@@ -1,3 +0,0 @@
language = Objective-C
headerFilter = **/objclib.h
linkerOpts = -lobjc_friendly_dealloc
@@ -1,5 +0,0 @@
language = Objective-C
headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h
headerFilter = **/objc_misc.h Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h
linkerOpts = -lobjcmisc
@@ -0,0 +1,40 @@
// TARGET_BACKEND: NATIVE
// MODULE: cinterop
// FILE: kt55938.def
language = Objective-C
headers = kt55938.h
// FILE: kt55938.h
#import <Foundation/Foundation.h>
@interface ObjCClass : NSObject
+ (int)foo;
@end
// FILE: kt55938.m
#include "kt55938.h"
@implementation ObjCClass {
}
+ (int)foo {
return 42;
}
@end
// MODULE: lib(cinterop)
// FILE: lib.kt
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
package kt55938lib
import kt55938.*
inline fun foo() = ObjCClass.foo()
// MODULE: main(lib, cinterop)
// FILE: main.kt
import kt55938lib.*
fun box(): String {
val foo = foo()
if (foo != 42) return "FAIL $foo"
return "OK"
}
@@ -1,3 +1,3 @@
language = Objective-C language = Objective-C
headerFilter = **/objc_wrap.h headerFilter = **/objc_wrap.h
linkerOpts = -lobjcexception linkerOpts = -lforeignException
@@ -1,4 +1,4 @@
language = Objective-C language = Objective-C
headerFilter = **/objc_wrap.h headerFilter = **/objc_wrap.h
linkerOpts = -lobjcexception linkerOpts = -lforeignException
foreignExceptionMode = objc-wrap foreignExceptionMode = objc-wrap
@@ -0,0 +1,3 @@
language = Objective-C
headerFilter = **/friendly_dealloc.h
linkerOpts = -lfriendly_dealloc
@@ -4,7 +4,7 @@
*/ */
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class) @file:OptIn(kotlin.experimental.ExperimentalNativeApi::class)
import objclib.* import friendly_dealloc.*
import platform.objc.* import platform.objc.*
import platform.Foundation.* import platform.Foundation.*
@@ -15,7 +15,6 @@ import kotlin.system.exitProcess
import kotlin.test.* import kotlin.test.*
import kotlin.time.* import kotlin.time.*
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import kotlin.time.Duration.Companion.minutes
import kotlinx.cinterop.* import kotlinx.cinterop.*
val timeout = 10.seconds val timeout = 10.seconds
@@ -1,4 +1,4 @@
#include "objclib.h" #include "friendly_dealloc.h"
@implementation OnDestroyHook { @implementation OnDestroyHook {
void (^_onDestroy)(uintptr_t); void (^_onDestroy)(uintptr_t);
@@ -0,0 +1,4 @@
language = Objective-C
headerFilter = **/include_categories.h
linkerOpts = -linclude_categories
objcClassesIncludingCategories = BaseClass DerivedClass
@@ -2,7 +2,7 @@
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
import objc_include_categories.* import include_categories.*
class KotlinDerived : BaseClass() { class KotlinDerived : BaseClass() {
override fun multiplyBy(value: Int): Float { override fun multiplyBy(value: Int): Float {
@@ -1,4 +1,4 @@
#include "objc_include_categories.h" #include "include_categories.h"
@implementation BaseClass @implementation BaseClass
-(id) init { -(id) init {
@@ -0,0 +1,3 @@
language = Objective-C
headerFilter = **/kt42172.h
linkerOpts = -lkt42172
@@ -1,6 +1,6 @@
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, kotlin.native.runtime.NativeRuntimeApi::class, ObsoleteWorkersApi::class) @file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, kotlin.native.runtime.NativeRuntimeApi::class, ObsoleteWorkersApi::class)
import objclib.* import kt42172.*
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
import kotlinx.cinterop.* import kotlinx.cinterop.*
@@ -1,4 +1,4 @@
#include "objclib.h" #include "kt42172.h"
@implementation WithFinalizer { @implementation WithFinalizer {
Finalizer finalizer_; Finalizer finalizer_;
@@ -0,0 +1,3 @@
language = Objective-C
headerFilter = **/kt56402.h
linkerOpts = -lkt56402
@@ -4,7 +4,7 @@
*/ */
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class) @file:OptIn(kotlin.experimental.ExperimentalNativeApi::class)
import objclib.* import kt56402.*
import kotlin.concurrent.AtomicInt import kotlin.concurrent.AtomicInt
import kotlin.native.concurrent.* import kotlin.native.concurrent.*
@@ -185,7 +185,7 @@ fun testProtocolOnSecondaryThread() {
waitDestruction(id) waitDestruction(id)
} }
fun runAllTests(args: Array<String>) = startApp { fun main(args: Array<String>) = startApp {
val exitCode = testLauncherEntryPoint(args) val exitCode = testLauncherEntryPoint(args)
if (exitCode != 0) { if (exitCode != 0) {
exitProcess(exitCode) exitProcess(exitCode)
@@ -1,4 +1,4 @@
#include "objclib.h" #include "kt56402.h"
#include <assert.h> #include <assert.h>
#include <dispatch/dispatch.h> #include <dispatch/dispatch.h>
@@ -1,3 +1,3 @@
language = Objective-C language = Objective-C
headerFilter = **/messaging.h headerFilter = **/messaging.h
linkerOpts = -lobjcmessaging linkerOpts = -lmessaging
@@ -1,3 +1,3 @@
language = Objective-C language = Objective-C
headerFilter = **/objclib.h headerFilter = **/objCAction.h
linkerOpts = -lobjCAction linkerOpts = -lobjCAction
@@ -5,7 +5,7 @@
@file:OptIn(kotlin.ExperimentalStdlibApi::class) @file:OptIn(kotlin.ExperimentalStdlibApi::class)
import objclib.* import objCAction.*
import platform.Foundation.* import platform.Foundation.*
import kotlin.test.* import kotlin.test.*
@@ -1,4 +1,4 @@
#include "objclib.h" #include "objCAction.h"
void performSelector0(id target, NSString* selectorName) { void performSelector0(id target, NSString* selectorName) {
NSLog(@"performSelector0(%@, %@)", target, selectorName); NSLog(@"performSelector0(%@, %@)", target, selectorName);
@@ -0,0 +1,5 @@
language = Objective-C
headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h
headerFilter = **/with_initializer.h Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h
linkerOpts = -lwith_initializer
@@ -1,6 +1,6 @@
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class) @file:OptIn(kotlin.experimental.ExperimentalNativeApi::class)
import objc_misc.* import with_initializer.*
import kotlin.native.Platform import kotlin.native.Platform
val a = B.giveC()!! as C val a = B.giveC()!! as C
@@ -1,5 +1,5 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#include "objc_misc.h" #include "with_initializer.h"
@implementation A @implementation A
@end @end
@@ -927,6 +927,12 @@ public class FirNativeCodegenLocalTestGenerated extends AbstractNativeCodegenBox
runTest("native/native.tests/testData/codegen/cinterop/kt54284_fmodules.kt"); runTest("native/native.tests/testData/codegen/cinterop/kt54284_fmodules.kt");
} }
@Test
@TestMetadata("kt55938.kt")
public void testKt55938() {
runTest("native/native.tests/testData/codegen/cinterop/kt55938.kt");
}
@Test @Test
@TestMetadata("kt57640.kt") @TestMetadata("kt57640.kt")
public void testKt57640() { public void testKt57640() {
@@ -905,6 +905,12 @@ public class NativeCodegenLocalTestGenerated extends AbstractNativeCodegenBoxTes
runTest("native/native.tests/testData/codegen/cinterop/kt54284_fmodules.kt"); runTest("native/native.tests/testData/codegen/cinterop/kt54284_fmodules.kt");
} }
@Test
@TestMetadata("kt55938.kt")
public void testKt55938() {
runTest("native/native.tests/testData/codegen/cinterop/kt55938.kt");
}
@Test @Test
@TestMetadata("kt57640.kt") @TestMetadata("kt57640.kt")
public void testKt57640() { public void testKt57640() {
@@ -22,12 +22,14 @@ import org.jetbrains.kotlin.konan.test.blackbox.support.settings.*
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.Timeouts import org.jetbrains.kotlin.konan.test.blackbox.support.settings.Timeouts
import org.jetbrains.kotlin.konan.test.blackbox.support.util.ClangDistribution import org.jetbrains.kotlin.konan.test.blackbox.support.util.ClangDistribution
import org.jetbrains.kotlin.konan.test.blackbox.support.util.compileWithClang import org.jetbrains.kotlin.konan.test.blackbox.support.util.compileWithClang
import org.jetbrains.kotlin.native.executors.RunProcessResult
import org.jetbrains.kotlin.native.executors.runProcess import org.jetbrains.kotlin.native.executors.runProcess
import org.jetbrains.kotlin.test.TestMetadata import org.jetbrains.kotlin.test.TestMetadata
import org.junit.jupiter.api.Assumptions import org.junit.jupiter.api.Assumptions
import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import java.io.File import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
import kotlin.time.Duration import kotlin.time.Duration
@@ -205,6 +207,192 @@ abstract class ComplexCInteropTestBase : AbstractNativeSimpleTest() {
runExecutableAndVerify(testCase, testExecutable) runExecutableAndVerify(testCase, testExecutable)
} }
@Test
@TestMetadata("with_initializer")
fun testObjCWithGlobalInitializer() {
val execResult = testDylibCinteropExe("with_initializer")
assertEquals("OK", execResult.stdout)
}
@Test
@TestMetadata("messaging")
fun testMessaging() {
testDylibCinteropExe("messaging")
}
@Test
@TestMetadata("kt42172")
fun testKt42172() {
Assumptions.assumeFalse(testRunSettings.get<GCType>() == GCType.NOOP)
val execResult = testDylibCinteropExe("kt42172")
assertEquals("Executed finalizer", execResult.stdout)
}
@Test
@TestMetadata("include_categories")
fun testInclude_categories() {
val execResult = testDylibCinteropExe("include_categories")
assertEquals("""
3.0
3.14
6.0
3
6
6.0
3.0
600.0
""".trimIndent(), execResult.stdout)
}
@Test
@TestMetadata("kt56402")
fun testKt56402() {
// Test depends on macOS-specific AppKit and some GC
Assumptions.assumeTrue(targets.testTarget.family == Family.OSX)
Assumptions.assumeFalse(testRunSettings.get<GCType>() == GCType.NOOP)
val execResult = testDylibCinteropExe(
"kt56402",
extraClangOpts = listOf("-framework", "AppKit", "-fobjc-arc"),
extraCompilerOpts = listOf("-tr"),
)
assertTrue(execResult.stdout.contains("[ PASSED ] 8 tests"))
}
@Test
@TestMetadata("friendly_dealloc")
fun testFriendly_dealloc() {
Assumptions.assumeFalse(testRunSettings.get<GCType>() == GCType.NOOP)
val execResult = testDylibCinteropExe(
"friendly_dealloc",
extraClangOpts = listOf("-fno-objc-arc"),
extraCompilerOpts = listOf("-tr", "-XXLanguage:+ImplicitSignedToUnsignedIntegerConversion"),
extras = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT),
)
assertTrue(execResult.stdout.contains("[ PASSED ] 4 tests"))
}
@Test
@TestMetadata("objCAction")
fun testObjCAction() {
val execResult = testDylibCinteropExe(
"objCAction",
extraCompilerOpts = listOf("-tr"),
extras = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT),
)
assertTrue(execResult.stdout.contains("[ PASSED ] 5 tests"))
}
@Test
@TestMetadata("foreignException")
fun testForeignException() {
val res = testDylibCinteropExe(
"foreignException",
"objc_wrap.h",
"objc_wrap.m",
"objc_wrap.def",
"objc_wrap.kt",
)
assertEquals("", res.stdout)
assertEquals("", res.stderr)
}
@Test
@TestMetadata("foreignException")
fun testForeignExceptionMode_default() {
val res = testDylibCinteropExe(
"foreignException",
"objc_wrap.h",
"objc_wrap.m",
"objcExceptionMode.def",
"objcExceptionMode_wrap.kt",
)
assertEquals("OK: Ends with uncaught exception handler", res.stdout)
assertEquals("", res.stderr)
}
@Test
@TestMetadata("foreignException")
fun testForeignExceptionMode_wrap() {
val res = testDylibCinteropExe(
"foreignException",
"objc_wrap.h",
"objc_wrap.m",
"objcExceptionMode.def",
"objcExceptionMode_wrap.kt",
extraCinteropArgs = listOf("-Xforeign-exception-mode", "objc-wrap")
)
assertEquals("OK: ForeignException", res.stdout)
assertEquals("", res.stderr)
}
private fun testDylibCinteropExe(
testName: String,
extraClangOpts: List<String> = listOf("-fobjc-arc"),
extraCompilerOpts: List<String> = emptyList(),
extras: TestCase.Extras = TestCase.NoTestRunnerExtras("main"),
): RunProcessResult {
return testDylibCinteropExe(
testName,
hFile = "$testName.h",
mFile = "$testName.m",
defFile = "$testName.def",
ktFile = "$testName.kt",
extraClangOpts = extraClangOpts,
extraCompilerOpts = extraCompilerOpts,
extras = extras,
)
}
private fun testDylibCinteropExe(
testName: String,
hFile: String,
mFile: String,
defFile: String,
ktFile: String,
extraCinteropArgs: List<String> = emptyList(),
extraClangOpts: List<String> = listOf("-fobjc-arc"),
extraCompilerOpts: List<String> = emptyList(),
extras: TestCase.Extras = TestCase.NoTestRunnerExtras("main"),
): RunProcessResult {
Assumptions.assumeTrue(targets.testTarget.family.isAppleFamily)
val srcDir = interopObjCDir.resolve(testName)
val dylib = compileDylib(testName, listOf(srcDir.resolve(mFile)), extraClangOpts)
if (testRunSettings.configurables.targetTriple.isSimulator)
codesign(dylib.resultingArtifact.path)
val cinteropKlib = cinteropToLibrary(
targets = targets,
defFile = srcDir.resolve(defFile),
outputDir = buildDir,
freeCompilerArgs = TestCompilerArgs(
compilerArgs = emptyList(),
cinteropArgs = extraCinteropArgs + listOf("-header", srcDir.resolve(hFile).absolutePath)
)
).assertSuccess().resultingArtifact
val testKind = when (extras) {
is TestCase.NoTestRunnerExtras -> TestKind.STANDALONE_NO_TR
is TestCase.WithTestRunnerExtras -> TestKind.STANDALONE
}
val testCase = generateTestCaseWithSingleFile(
sourceFile = srcDir.resolve(ktFile),
moduleName = testName,
testKind = testKind,
extras = extras,
freeCompilerArgs = TestCompilerArgs(
"-opt-in=kotlinx.cinterop.ExperimentalForeignApi",
"-opt-in=kotlin.native.internal.InternalForKotlinNative",
"-linker-option", "-L${buildDir.absolutePath}",
*extraCompilerOpts.toTypedArray()
)
)
val success = compileToExecutable(testCase, cinteropKlib.asLibraryDependency()).assertSuccess()
return testRunSettings.executor.runProcess(success.resultingArtifact.executableFile.absolutePath)
}
@Test @Test
@TestMetadata("withSpaces.kt") @TestMetadata("withSpaces.kt")
fun testWithSpaces() { fun testWithSpaces() {
@@ -255,7 +443,7 @@ abstract class ComplexCInteropTestBase : AbstractNativeSimpleTest() {
assertTrue(mapfile.exists()) assertTrue(mapfile.exists())
} }
private fun compileDylib(name: String, mSources: List<File>): TestCompilationResult.Success<out TestCompilationArtifact.Executable> { private fun compileDylib(name: String, mSources: List<File>, extraClangOpts: List<String> = listOf("-fobjc-arc")): TestCompilationResult.Success<out TestCompilationArtifact.Executable> {
val clangResult = compileWithClang( val clangResult = compileWithClang(
clangDistribution = ClangDistribution.Llvm, clangDistribution = ClangDistribution.Llvm,
sourceFiles = mSources, sourceFiles = mSources,
@@ -263,8 +451,8 @@ abstract class ComplexCInteropTestBase : AbstractNativeSimpleTest() {
outputFile = buildDir.resolve("lib$name.dylib"), outputFile = buildDir.resolve("lib$name.dylib"),
libraryDirectories = emptyList(), libraryDirectories = emptyList(),
libraries = emptyList(), libraries = emptyList(),
additionalClangFlags = listOf( additionalClangFlags = extraClangOpts + listOf(
"-DNS_FORMAT_ARGUMENT(A)=", "-lobjc", "-fobjc-arc", "-fPIC", "-shared", "-DNS_FORMAT_ARGUMENT(A)=", "-lobjc", "-fPIC", "-shared",
// Enable ARC optimizations to prevent some objects from leaking in Obj-C code due to exceptions: // Enable ARC optimizations to prevent some objects from leaking in Obj-C code due to exceptions:
"-O2" "-O2"
), ),