@@ -153,12 +153,17 @@ class SarifReport(
153
153
val methodArguments = utExecution.stateBefore.parameters
154
154
.joinToString(prefix = " " , separator = " , " , postfix = " " ) { it.preview() }
155
155
156
+ val errorMessage = if (executionFailure is UtTimeoutException )
157
+ " Unexpected behavior: ${executionFailure.exception.message} "
158
+ else
159
+ " Unexpected exception: ${executionFailure.exception} "
160
+
156
161
val sarifResult = SarifResult (
157
162
ruleId,
158
163
Level .Error ,
159
164
Message (
160
165
text = """
161
- Unexpected exception: ${executionFailure.exception} .
166
+ $errorMessage .
162
167
Test case: `$methodName ($methodArguments )`
163
168
[Generated test for this case]($relatedLocationId )
164
169
""" .trimIndent()
@@ -229,8 +234,10 @@ class SarifReport(
229
234
val stackTraceResolved = filterStackTrace(method, utExecution, executionFailure)
230
235
.mapNotNull { findStackTraceElementLocation(it) }
231
236
.toMutableList()
232
- if (stackTraceResolved.isEmpty())
233
- return listOf () // empty stack trace is not shown
237
+
238
+ if (stackTraceResolved.isEmpty()) {
239
+ stackTraceResolved + = stackTraceFromCoverage(utExecution) // fallback logic
240
+ }
234
241
235
242
// prepending stack trace by `method` call in generated tests
236
243
val methodCallLocation: SarifPhysicalLocation ? =
@@ -279,6 +286,10 @@ class SarifReport(
279
286
if (lastMethodCallIndex != - 1 ) {
280
287
// taking all elements before the last `method` call
281
288
stackTrace = stackTrace.take(lastMethodCallIndex + 1 )
289
+ } else { // no `method` call in the stack trace
290
+ if (executionFailure.exception !is StackOverflowError ) {
291
+ stackTrace = listOf () // (likely) the stack trace contains only our internal calls
292
+ }
282
293
}
283
294
284
295
if (executionFailure.exception is StackOverflowError ) {
@@ -292,6 +303,39 @@ class SarifReport(
292
303
return stackTraceFiltered
293
304
}
294
305
306
+ /* *
307
+ * Constructs the stack trace from the list of covered instructions.
308
+ */
309
+ private fun stackTraceFromCoverage (utExecution : UtExecution ): List <SarifFlowLocationWrapper > {
310
+ val coveredInstructions = utExecution.coverage?.coveredInstructions
311
+ ? : return listOf ()
312
+
313
+ val executionTrace = coveredInstructions.groupBy { instruction ->
314
+ instruction.className to instruction.methodSignature // group by method
315
+ }.map { (_, instructionsForOneMethod) ->
316
+ instructionsForOneMethod.last() // we need only last to construct the stack trace
317
+ }
318
+
319
+ val sarifExecutionTrace = executionTrace.map { instruction ->
320
+ val classFqn = instruction.className.replace(' /' , ' .' )
321
+ val methodName = instruction.methodSignature.substringBefore(' (' )
322
+ val lineNumber = instruction.lineNumber
323
+
324
+ val sourceFilePath = sourceFinding.getSourceRelativePath(classFqn)
325
+ val sourceFileName = sourceFilePath.substringAfterLast(' /' )
326
+
327
+ SarifFlowLocationWrapper (SarifFlowLocation (
328
+ message = Message (" $classFqn .$methodName ($sourceFileName :$lineNumber )" ),
329
+ physicalLocation = SarifPhysicalLocation (
330
+ SarifArtifact (uri = sourceFilePath),
331
+ SarifRegion (startLine = lineNumber)
332
+ )
333
+ ))
334
+ }
335
+
336
+ return sarifExecutionTrace.reversed() // to stack trace
337
+ }
338
+
295
339
private fun findStackTraceElementLocation (stackTraceElement : StackTraceElement ): SarifFlowLocationWrapper ? {
296
340
val lineNumber = stackTraceElement.lineNumber
297
341
if (lineNumber < 1 )
@@ -429,6 +473,7 @@ class SarifReport(
429
473
val overflowFailure = result is UtOverflowFailure && UtSettings .treatOverflowAsError
430
474
val assertionError = result is UtExplicitlyThrownException && result.exception is AssertionError
431
475
val sandboxFailure = result is UtSandboxFailure
432
- return implicitlyThrown || overflowFailure || assertionError || sandboxFailure
476
+ val timeoutException = result is UtTimeoutException
477
+ return implicitlyThrown || overflowFailure || assertionError || sandboxFailure || timeoutException
433
478
}
434
479
}
0 commit comments