Skip to content

Commit 331f65d

Browse files
committed
fix: correctly handle test failures and display full error details
- Add fromTestExitCode() to treat exit code 3 as TEST_FAILED for test commands - Add isTestCommand parameter to BazelProcess.waitAndGetResult() - Pass isTestCommand=true in ExecuteService for test runs - Extract fullOutput and errorType in FallbackTestXmlParser for Jest tests
1 parent 3b4147d commit 331f65d

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

server/bazelrunner/src/main/kotlin/org/jetbrains/bsp/bazel/bazelrunner/BazelProcess.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ class BazelProcess internal constructor(
1818
private val serverPidFuture: CompletableFuture<Long>?,
1919
private val finishCallback: () -> Unit = {},
2020
) {
21-
fun waitAndGetResult(cancelChecker: CancelChecker, ensureAllOutputRead: Boolean = false): BazelProcessResult {
21+
fun waitAndGetResult(
22+
cancelChecker: CancelChecker,
23+
ensureAllOutputRead: Boolean = false,
24+
isTestCommand: Boolean = false,
25+
): BazelProcessResult {
2226
return try {
2327
val stopwatch = Stopwatch.start()
2428
val outputProcessor: OutputProcessor =
@@ -39,7 +43,8 @@ class BazelProcess internal constructor(
3943
val exitCode = outputProcessor.waitForExit(cancelChecker, serverPidFuture, logger)
4044
val duration = stopwatch.stop()
4145
logCompletion(exitCode, duration)
42-
return BazelProcessResult(outputProcessor.stdoutCollector, outputProcessor.stderrCollector, BazelStatus.fromExitCode(exitCode))
46+
val bazelStatus = if (isTestCommand) BazelStatus.fromTestExitCode(exitCode) else BazelStatus.fromExitCode(exitCode)
47+
return BazelProcessResult(outputProcessor.stdoutCollector, outputProcessor.stderrCollector, bazelStatus)
4348
} finally {
4449
finishCallback()
4550
}

server/commons/src/main/kotlin/org/jetbrains/bsp/bazel/commons/BazelStatus.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ch.epfl.scala.bsp4j.StatusCode
66
private const val SUCCESS_EXIT_CODE = 0
77
private const val BUILD_ERROR_EXIT_CODE = 1
88
private const val BAD_COMMAND_LINE_ARGUMENTS_EXIT_CODE = 2
9+
private const val TEST_FAILED_EXIT_CODE = 3
910
private const val CANCEL_EXIT_CODE = 8
1011
private const val OOM_EXIT_CODE = 33
1112

@@ -16,6 +17,7 @@ enum class BazelStatus {
1617
SUCCESS,
1718
BAD_COMMAND_LINE_ARGUMENTS,
1819
BUILD_ERROR,
20+
TEST_FAILED,
1921
CANCEL,
2022
OOM_ERROR,
2123
FATAL_ERROR, // for other non-categorized errors
@@ -46,5 +48,16 @@ enum class BazelStatus {
4648
OOM_EXIT_CODE -> OOM_ERROR
4749
else -> FATAL_ERROR
4850
}
51+
52+
fun fromTestExitCode(exitCode: Int): BazelStatus =
53+
when (exitCode) {
54+
SUCCESS_EXIT_CODE -> SUCCESS
55+
BUILD_ERROR_EXIT_CODE -> BUILD_ERROR
56+
BAD_COMMAND_LINE_ARGUMENTS_EXIT_CODE -> BAD_COMMAND_LINE_ARGUMENTS
57+
TEST_FAILED_EXIT_CODE -> TEST_FAILED
58+
CANCEL_EXIT_CODE -> CANCEL
59+
OOM_EXIT_CODE -> OOM_ERROR
60+
else -> FATAL_ERROR
61+
}
4962
}
5063
}

server/server/src/main/kotlin/org/jetbrains/bsp/bazel/server/bep/TestXmlParser.kt

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ private class FallbackTestXmlParser(private var bspClientTestNotifier: BspClient
254254
data class IncompleteTestCase(
255255
@JacksonXmlProperty(isAttribute = true)
256256
val name: String,
257+
@JacksonXmlProperty(isAttribute = true)
258+
val classname: String? = null,
257259
@JacksonXmlProperty(localName = "error")
258260
val error: TestResultDetail? = null,
259261
@JacksonXmlProperty(localName = "failure")
@@ -288,7 +290,7 @@ private class FallbackTestXmlParser(private var bspClientTestNotifier: BspClient
288290

289291
bspClientTestNotifier.startTest(suite.name, suiteTaskId)
290292
suite.testcase.forEach { testCase ->
291-
processIncompleteInfoCase(testCase, suiteTaskId.id, suiteStatus)
293+
processIncompleteInfoCase(testCase, suiteTaskId.id)
292294
}
293295
bspClientTestNotifier.finishTest(
294296
suite.name,
@@ -300,15 +302,7 @@ private class FallbackTestXmlParser(private var bspClientTestNotifier: BspClient
300302
)
301303
}
302304

303-
/**
304-
* Converts a TestCase into a testStart and a testFinish events.
305-
* @param testSuiteStatus - using test suite's status as test case status, because the xml one is not correct
306-
*/
307-
private fun processIncompleteInfoCase(
308-
testCase: IncompleteTestCase,
309-
parentId: String,
310-
testSuiteStatus: TestStatus,
311-
) {
305+
private fun processIncompleteInfoCase(testCase: IncompleteTestCase, parentId: String) {
312306
val testCaseTaskId = TaskId(UUID.randomUUID().toString())
313307
testCaseTaskId.parents = listOf(parentId)
314308

@@ -321,7 +315,33 @@ private class FallbackTestXmlParser(private var bspClientTestNotifier: BspClient
321315
else -> null
322316
}
323317

324-
val testCaseData = JUnitStyleTestCaseData(testCase.time, null, outcomeMessage, null, null)
318+
// Extract the full error message content.
319+
val fullOutput =
320+
when {
321+
testCase.error != null -> testCase.error.content
322+
testCase.failure != null -> testCase.failure.content
323+
testCase.skipped != null -> testCase.skipped.content
324+
else -> ""
325+
}
326+
327+
// Map the outcome into a TestStatus value.
328+
val testStatusOutcome =
329+
when {
330+
testCase.error != null -> TestStatus.FAILED
331+
testCase.failure != null -> TestStatus.FAILED
332+
testCase.skipped != null -> TestStatus.SKIPPED
333+
else -> TestStatus.PASSED
334+
}
335+
336+
// Extract error type information if provided.
337+
val errorType =
338+
when {
339+
testCase.error != null -> testCase.error.type
340+
testCase.failure != null -> testCase.failure.type
341+
else -> null
342+
}
343+
344+
val testCaseData = JUnitStyleTestCaseData(testCase.time, testCase.classname, outcomeMessage, fullOutput, errorType)
325345

326346
// In the generated xml, suite name and test case name are the same, but in the Test Console test names have
327347
// to be unique
@@ -330,7 +350,7 @@ private class FallbackTestXmlParser(private var bspClientTestNotifier: BspClient
330350
bspClientTestNotifier.finishTest(
331351
testCaseName,
332352
testCaseTaskId,
333-
testSuiteStatus,
353+
testStatusOutcome,
334354
null,
335355
JUnitStyleTestCaseData.DATA_KIND,
336356
testCaseData,

server/server/src/main/kotlin/org/jetbrains/bsp/bazel/server/sync/ExecuteService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class ExecuteService(
226226
command,
227227
originId = params.originId,
228228
serverPidFuture = bepReader.serverPid,
229-
).waitAndGetResult(cancelChecker, true)
229+
).waitAndGetResult(cancelChecker, ensureAllOutputRead = true, isTestCommand = true)
230230
}
231231

232232
return TestResult(result.bspStatusCode).apply {

0 commit comments

Comments
 (0)