Skip to content

Commit 4b2c971

Browse files
projediSpace Team
authored andcommitted
[K/N][tests] Enhance FirebaseCloudXCTestExecutor error reporting
* Make the exception reporting more compact: use only a single stack trace line when there is a cause * Report the full error from all subsequent invocations ^KT-81519
1 parent 7cfe91d commit 4b2c971

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

native/executors/src/main/kotlin/org/jetbrains/kotlin/native/executors/FirebaseCloudXCTestExecutor.kt

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
44
*/
55

6+
@file:OptIn(ExperimentalAtomicApi::class)
7+
68
package org.jetbrains.kotlin.native.executors
79

810
import org.jetbrains.kotlin.konan.target.AppleConfigurables
911
import org.jetbrains.kotlin.konan.target.HostManager
1012
import org.jetbrains.kotlin.konan.target.KonanTarget
1113
import org.jetbrains.kotlin.util.removeSuffixIfPresent
1214
import java.io.ByteArrayOutputStream
15+
import java.io.PrintStream
1316
import java.nio.file.*
1417
import java.util.zip.ZipEntry
1518
import java.util.zip.ZipOutputStream
19+
import kotlin.concurrent.atomics.AtomicReference
20+
import kotlin.concurrent.atomics.ExperimentalAtomicApi
1621
import kotlin.io.path.*
1722
import kotlin.time.Duration.Companion.minutes
1823
import kotlin.time.Duration.Companion.seconds
@@ -34,13 +39,7 @@ class FirebaseCloudXCTestExecutor(
3439

3540
private val target by configurables::target
3641

37-
private enum class State {
38-
NORMAL,
39-
FAILED
40-
}
41-
42-
@Volatile
43-
private var state: State = State.NORMAL
42+
private val rememberedFailure = AtomicReference<Throwable?>(null)
4443

4544
init {
4645
require(HostManager.host.family.isAppleFamily) {
@@ -51,16 +50,29 @@ class FirebaseCloudXCTestExecutor(
5150
}
5251
}
5352

54-
@Synchronized
55-
private fun checkState() {
56-
check(state == State.NORMAL) {
57-
"${this::class.java.simpleName} is in the ${state.name} state. Check the executor logs and configuration"
53+
private fun abortWithFailureIfNeeded() {
54+
rememberedFailure.load()?.let { failure ->
55+
// The usual stack trace reporting is too verbose. Produce a compact report as the message instead
56+
fun StringBuilder.appendThrowable(t: Throwable) {
57+
appendLine(t.toString())
58+
when (val cause = t.cause) {
59+
null -> append(t.stackTraceToString())
60+
else -> {
61+
t.stackTrace.firstOrNull()?.let { appendLine("\tat $it") }
62+
append("Caused by: ")
63+
appendThrowable(cause)
64+
}
65+
}
66+
}
67+
error(buildString {
68+
appendThrowable(failure)
69+
})
5870
}
5971
}
6072

6173
override fun execute(request: ExecuteRequest): ExecuteResponse {
6274
// Check the state to understand whether it is possible to build or some config/build failure happened already.
63-
checkState()
75+
abortWithFailureIfNeeded()
6476

6577
val workDir = request.workingDirectory?.toPath() ?: Paths.get(".")
6678
val projectDir = Files.createTempDirectory(workDir, "xctest-firebase-runner")
@@ -73,8 +85,14 @@ class FirebaseCloudXCTestExecutor(
7385
createZip(bundle.prepareToRun(projectDir))
7486
}
7587
} catch (throwable: Throwable) {
76-
state = State.FAILED
77-
throw IllegalStateException("Failed to prepare a XCTest bundle with Xcode. Check Xcode or project configuration", throwable)
88+
rememberedFailure.compareAndSet(
89+
null,
90+
IllegalStateException(
91+
"Failed to prepare a XCTest bundle with Xcode. Check Xcode or project configuration",
92+
throwable
93+
)
94+
)
95+
abortWithFailureIfNeeded()
7896
}
7997

8098
// Execute tests in the Firebase

0 commit comments

Comments
 (0)