diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt index fcd61892058..62cfec0df4c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.testing.internal.configureConventions import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.testing.testTaskName +import org.jetbrains.kotlin.gradle.utils.Xcode import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget @@ -668,12 +669,8 @@ class KotlinNativeTargetWithSimulatorTestsConfigurator : override fun configureTestTask(target: KotlinNativeTargetWithSimulatorTests, testTask: KotlinNativeSimulatorTest) { super.configureTestTask(target, testTask) - testTask.deviceId = when (target.konanTarget) { - KonanTarget.IOS_X64, KonanTarget.IOS_SIMULATOR_ARM64 -> "iPhone 12" - KonanTarget.WATCHOS_X86, KonanTarget.WATCHOS_X64, KonanTarget.WATCHOS_SIMULATOR_ARM64 -> "Apple Watch Series 5 - 44mm" - KonanTarget.TVOS_X64, KonanTarget.TVOS_SIMULATOR_ARM64 -> "Apple TV" - else -> error("Simulator tests are not supported for platform ${target.konanTarget.name}") - } + testTask.deviceId = Xcode.getDefaultTestDeviceId(target.konanTarget) + ?: error("Xcode does not support simulator tests for ${target.konanTarget.name}. Check that requested SDK is installed.") } override fun createTestRun( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Xcode.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Xcode.kt index ee4dd97e76d..179103a7e06 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Xcode.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Xcode.kt @@ -9,8 +9,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.konan.target.Architecture.ARM32 import org.jetbrains.kotlin.konan.target.Architecture.ARM64 +import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.Family.* import org.jetbrains.kotlin.konan.target.KonanTarget +import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly internal object Xcode { val currentVersion: String by lazy { @@ -18,6 +20,37 @@ internal object Xcode { out.lines()[0].removePrefix("Xcode ") } + private val defaultTestDevices: Map by lazy { + val osRegex = "-- .* --".toRegex() + val deviceRegex = """[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}""".toRegex() + + val out = runCommand(listOf("/usr/bin/xcrun", "simctl", "list")) + + val result = mutableMapOf() + var os: String? = null + out.lines().forEach { s -> + val osFound = osRegex.find(s)?.value + if (osFound != null) { + os = osFound.split(" ")[1] + } else { + val currentOs = os + if (currentOs != null) { + val deviceFound = deviceRegex.find(s)?.value + if (deviceFound != null) { + result[currentOs] = deviceFound + os = null + } + } + } + } + + result.entries.associate { (osName, deviceId) -> + Family.valueOf(osName.toUpperCaseAsciiOnly()) to deviceId + } + } + + fun getDefaultTestDeviceId(target: KonanTarget): String? = defaultTestDevices[target.family] + fun defaultBitcodeEmbeddingMode(target: KonanTarget, buildType: NativeBuildType): BitcodeEmbeddingMode { if (currentVersion.split(".")[0].toInt() < 14) { if (target.family in listOf(IOS, WATCHOS, TVOS) && target.architecture in listOf(ARM32, ARM64)) {