[Gradle, K/N] Improve message when a simulator for test is not booted

If a simulator test task is configured to disable standalone mode and the simulator isn't booted, the default error message might sound cryptic, so we can give a more user-friendly error message
#KT-38317 Fixed
This commit is contained in:
Alexander.Likhachev
2023-04-06 11:51:04 +02:00
parent 5486b39d04
commit f439d4d147
3 changed files with 92 additions and 8 deletions
@@ -21,6 +21,32 @@ import kotlin.test.assertEquals
@NativeGradlePluginTests
@EnabledOnOs(OS.MAC)
class NativeXcodeSimulatorTestsIT : KGPBaseTest() {
private val defaultIosSimulator by lazy {
val xcode = Xcode ?: error("XCode is expected to be defined")
xcode.getDefaultTestDeviceId(KonanTarget.IOS_SIMULATOR_ARM64) ?: error("No simulator found for iOS ARM64")
}
@DisplayName("A user-friendly error message is produced when the standalone mode is disabled and no simulator has booted")
@GradleTest
fun checkNoSimulatorErrorMessage(gradleVersion: GradleVersion) {
shutDownSimulators() // based on the tests order there no simulator should be booted, but anyway to be sure
// Note the test still may fail if you have booted the required simulator manually before running the test
// We don't shut down such simulators in the tests
project("native-test-ios-https-request", gradleVersion) {
buildGradleKts.append(
"""
tasks.withType<org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest> {
device.set("$defaultIosSimulator")
standalone.set(false)
}
""".trimIndent()
)
buildAndFail("check") {
assertOutputContains("The problem can be that you have not booted the required device or have configured the task to a different simulator. Please check the task output and its device configuration.")
}
}
}
@DisplayName("iOS simulator test with an https request fails with default settings")
@GradleTest
fun checkSimulatorTestFailsInStandaloneMode(gradleVersion: GradleVersion) {
@@ -36,13 +62,11 @@ class NativeXcodeSimulatorTestsIT : KGPBaseTest() {
@GradleTest
fun checkSimulatorTestFailsInNonStandaloneMode(gradleVersion: GradleVersion) {
project("native-test-ios-https-request", gradleVersion) {
val xcode = Xcode ?: error("XCode is expected to be defined")
val device = xcode.getDefaultTestDeviceId(KonanTarget.IOS_SIMULATOR_ARM64) ?: error("No simulator found for iOS ARM64")
bootXcodeSimulator(device)
bootXcodeSimulator(defaultIosSimulator)
buildGradleKts.append(
"""
tasks.withType<org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest> {
device.set("$device")
device.set("$defaultIosSimulator")
standalone.set(false)
}
""".trimIndent()
@@ -0,0 +1,50 @@
/*
* 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.gradle.targets.native.internal
import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions
import org.gradle.process.internal.ExecHandle
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClient
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.plugin.internal.MppTestReportHelper
import org.slf4j.Logger
internal class NativeAppleSimulatorTCServiceMessagesTestExecutionSpec(
forkOptions: ProcessForkOptions,
args: List<String>,
checkExitCode: Boolean,
clientSettings: TCServiceMessagesClientSettings,
dryRunArgs: List<String>?,
private val standaloneMode: Provider<Boolean>,
) : TCServiceMessagesTestExecutionSpec(forkOptions, args, checkExitCode, clientSettings, dryRunArgs) {
override fun createClient(
testResultProcessor: TestResultProcessor,
log: Logger,
testReporter: MppTestReportHelper
): TCServiceMessagesClient {
return NativeAppleSimulatorTCServiceMessagesClient(testResultProcessor, clientSettings, log, testReporter, standaloneMode)
}
}
internal class NativeAppleSimulatorTCServiceMessagesClient(
results: TestResultProcessor,
settings: TCServiceMessagesClientSettings,
log: Logger,
testReporter: MppTestReportHelper,
private val standaloneMode: Provider<Boolean>
) : TCServiceMessagesClient(results, settings, log, testReporter) {
override fun testFailedMessage(execHandle: ExecHandle, exitValue: Int) = when {
!standaloneMode.get() && exitValue == 149 -> """
You have standalone simulator tests run mode disabled and tests have failed to run.
The problem can be that you have not booted the required device or have configured the task to a different simulator. Please check the task output and its device configuration.
If you are sure that your setup is correct, please file an issue: https://kotl.in/issue
""".trimIndent()
else -> super.testFailedMessage(execHandle, exitValue)
}
}
@@ -16,17 +16,17 @@ import org.gradle.api.tasks.options.Option
import org.gradle.process.ProcessForkOptions
import org.gradle.process.internal.DefaultProcessForkOptions
import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.compilerRunner.konanVersion
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor.Companion.TC_PROJECT_PROPERTY
import org.jetbrains.kotlin.gradle.targets.native.internal.NativeAppleSimulatorTCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.targets.native.internal.parseKotlinNativeStackTraceAsJvm
import org.jetbrains.kotlin.gradle.tasks.KotlinTest
import java.io.File
import java.util.concurrent.Callable
import javax.inject.Inject
abstract class KotlinNativeTest: KotlinTest() {
abstract class KotlinNativeTest : KotlinTest() {
@get:Inject
abstract val providerFactory: ProviderFactory
@@ -80,8 +80,6 @@ abstract class KotlinNativeTest: KotlinTest() {
private val trackedEnvironmentVariablesKeys = mutableSetOf<String>()
private val konanVersion = project.konanVersion
@Suppress("unused")
@get:Input
val trackedEnvironment
@@ -261,4 +259,16 @@ abstract class KotlinNativeSimulatorTest : KotlinNativeTest() {
) +
testArgs(testLogger, checkExitCode, testGradleFilter, testNegativeGradleFilter, userArgs)
}
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
val origin = super.createTestExecutionSpec()
return NativeAppleSimulatorTCServiceMessagesTestExecutionSpec(
origin.forkOptions,
origin.args,
origin.checkExitCode,
origin.clientSettings,
origin.dryRunArgs,
standalone,
)
}
}