Skip to content

Commit 65c5e55

Browse files
committed
The first version of the utbot inspection tool (#972)
1 parent 0d2c65b commit 65c5e55

File tree

13 files changed

+361
-133
lines changed

13 files changed

+361
-133
lines changed

utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsCommand.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class GenerateTestsCommand :
149149
else -> {
150150
val sourceFinding =
151151
SourceFindingStrategyDefault(classFqn, sourceCodeFile, testsFilePath, projectRootPath)
152-
val report = SarifReport(testSets, testClassBody, sourceFinding).createReport()
152+
val report = SarifReport(testSets, testClassBody, sourceFinding).createReport().toJson()
153153
saveToFile(report, sarifReport)
154154
println("The report was saved to \"$sarifReport\".")
155155
}

utbot-framework-test/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt

+12-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.utbot.sarif
22

3-
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
4-
import com.fasterxml.jackson.module.kotlin.readValue
53
import org.junit.Test
64
import org.mockito.Mockito
75
import org.utbot.framework.plugin.api.ExecutableId
@@ -19,7 +17,7 @@ class SarifReportTest {
1917
testSets = listOf(),
2018
generatedTestsCode = "",
2119
sourceFindingEmpty
22-
).createReport()
20+
).createReport().toJson()
2321

2422
assert(actualReport.isNotEmpty())
2523
}
@@ -30,7 +28,7 @@ class SarifReportTest {
3028
testSets = listOf(testSet),
3129
generatedTestsCode = "",
3230
sourceFindingEmpty
33-
).createReport().toSarif()
31+
).createReport()
3432

3533
assert(sarif.runs.first().results.isEmpty())
3634
}
@@ -60,7 +58,7 @@ class SarifReportTest {
6058
testSets = testSets,
6159
generatedTestsCode = "",
6260
sourceFindingEmpty
63-
).createReport().toSarif()
61+
).createReport()
6462

6563
assert(report.runs.first().results[0].message.text.contains("NullPointerException"))
6664
assert(report.runs.first().results[1].message.text.contains("ArrayIndexOutOfBoundsException"))
@@ -77,7 +75,7 @@ class SarifReportTest {
7775
Mockito.`when`(mockUtExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(1337)
7876
Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException")
7977

80-
val report = sarifReportMain.createReport().toSarif()
78+
val report = sarifReportMain.createReport()
8179

8280
val result = report.runs.first().results.first()
8381
val location = result.locations.first().physicalLocation
@@ -105,7 +103,7 @@ class SarifReportTest {
105103
)
106104
)
107105

108-
val report = sarifReportMain.createReport().toSarif()
106+
val report = sarifReportMain.createReport()
109107

110108
val result = report.runs.first().results.first()
111109
assert(result.message.text.contains("227"))
@@ -128,7 +126,7 @@ class SarifReportTest {
128126
)
129127
Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf())
130128

131-
val report = sarifReportMain.createReport().toSarif()
129+
val report = sarifReportMain.createReport()
132130

133131
val result = report.runs.first().results.first().codeFlows.first().threadFlows.first().locations.map {
134132
it.location.physicalLocation
@@ -153,7 +151,7 @@ class SarifReportTest {
153151
Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf())
154152
Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException")
155153

156-
val report = sarifReportMain.createReport().toSarif()
154+
val report = sarifReportMain.createReport()
157155

158156
val codeFlowPhysicalLocations = report.runs[0].results[0].codeFlows[0].threadFlows[0].locations.map {
159157
it.location.physicalLocation
@@ -177,7 +175,7 @@ class SarifReportTest {
177175
Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf())
178176
Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException")
179177

180-
val report = sarifReportPrivateMain.createReport().toSarif()
178+
val report = sarifReportPrivateMain.createReport()
181179

182180
val codeFlowPhysicalLocations = report.runs[0].results[0].codeFlows[0].threadFlows[0].locations.map {
183181
it.location.physicalLocation
@@ -203,7 +201,7 @@ class SarifReportTest {
203201
testSets = testSets,
204202
generatedTestsCode = "",
205203
sourceFindingMain
206-
).createReport().toSarif()
204+
).createReport()
207205

208206
assert(report.runs.first().results.size == 1) // no duplicates
209207
}
@@ -228,7 +226,7 @@ class SarifReportTest {
228226
testSets = testSets,
229227
generatedTestsCode = "",
230228
sourceFindingMain
231-
).createReport().toSarif()
229+
).createReport()
232230

233231
assert(report.runs.first().results.size == 2) // no results have been removed
234232
}
@@ -257,7 +255,7 @@ class SarifReportTest {
257255
testSets = testSets,
258256
generatedTestsCode = "",
259257
sourceFindingMain
260-
).createReport().toSarif()
258+
).createReport()
261259

262260
assert(report.runs.first().results.size == 2) // no results have been removed
263261
}
@@ -291,7 +289,7 @@ class SarifReportTest {
291289
testSets = testSets,
292290
generatedTestsCode = "",
293291
sourceFindingMain
294-
).createReport().toSarif()
292+
).createReport()
295293

296294
assert(report.runs.first().results.size == 1) // no duplicates
297295
assert(report.runs.first().results.first().totalCodeFlowLocations() == 1) // with a shorter stack trace
@@ -310,8 +308,6 @@ class SarifReportTest {
310308
Mockito.`when`(mockExecutableId.classId.name).thenReturn("Main")
311309
}
312310

313-
private fun String.toSarif(): Sarif = jacksonObjectMapper().readValue(this)
314-
315311
// constants
316312

317313
private val sourceFindingEmpty = SourceFindingStrategyDefault(

utbot-framework/src/main/kotlin/org/utbot/framework/plugin/sarif/GenerateTestsAndSarifReportFacade.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class GenerateTestsAndSarifReportFacade(
9191
testClassBody: String,
9292
sourceFinding: SourceFindingStrategy
9393
) {
94-
val sarifReport = SarifReport(testSets, testClassBody, sourceFinding).createReport()
94+
val sarifReport = SarifReport(testSets, testClassBody, sourceFinding).createReport().toJson()
9595
targetClass.sarifReportFile.writeText(sarifReport)
9696
}
9797
}

utbot-framework/src/main/kotlin/org/utbot/sarif/DataClasses.kt

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package org.utbot.sarif
22

3+
import com.fasterxml.jackson.annotation.JsonInclude
34
import com.fasterxml.jackson.annotation.JsonProperty
45
import com.fasterxml.jackson.annotation.JsonValue
6+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
7+
import com.fasterxml.jackson.module.kotlin.readValue
58

69
/**
710
* Useful links:
@@ -24,7 +27,19 @@ data class Sarif(
2427

2528
fun fromRun(run: SarifRun) =
2629
Sarif(defaultSchema, defaultVersion, listOf(run))
30+
31+
fun fromJson(reportInJson: String): Sarif =
32+
jacksonObjectMapper().readValue(reportInJson)
2733
}
34+
35+
fun toJson(): String =
36+
jacksonObjectMapper()
37+
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
38+
.writerWithDefaultPrettyPrinter()
39+
.writeValueAsString(this)
40+
41+
fun getAllResults(): List<SarifResult> =
42+
runs.flatMap { it.results }
2843
}
2944

3045
/**
@@ -104,8 +119,8 @@ data class SarifResult(
104119
* Returns the total number of locations in all [codeFlows].
105120
*/
106121
fun totalCodeFlowLocations() =
107-
codeFlows.sumBy { codeFlow ->
108-
codeFlow.threadFlows.sumBy { threadFlow ->
122+
codeFlows.sumOf { codeFlow ->
123+
codeFlow.threadFlows.sumOf { threadFlow ->
109124
threadFlow.locations.size
110125
}
111126
}

utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt

+13-32
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package org.utbot.sarif
22

3-
import com.fasterxml.jackson.annotation.JsonInclude
4-
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
5-
import com.fasterxml.jackson.module.kotlin.readValue
63
import org.utbot.common.PathUtil.fileExtension
74
import org.utbot.common.PathUtil.toPath
85
import org.utbot.framework.UtSettings
@@ -29,45 +26,20 @@ class SarifReport(
2926
private val generatedTestsCode: String,
3027
private val sourceFinding: SourceFindingStrategy
3128
) {
32-
3329
companion object {
34-
3530
/**
3631
* Merges several SARIF reports given as JSON-strings into one
3732
*/
3833
fun mergeReports(reports: List<String>): String =
3934
reports.fold(Sarif.empty()) { sarif: Sarif, report: String ->
40-
sarif.copy(runs = sarif.runs + report.jsonToSarif().runs)
41-
}.sarifToJson()
42-
43-
// internal
44-
45-
private fun String.jsonToSarif(): Sarif =
46-
jacksonObjectMapper().readValue(this)
47-
48-
private fun Sarif.sarifToJson(): String =
49-
jacksonObjectMapper()
50-
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
51-
.writerWithDefaultPrettyPrinter()
52-
.writeValueAsString(this)
35+
sarif.copy(runs = sarif.runs + Sarif.fromJson(report).runs)
36+
}.toJson()
5337
}
5438

5539
/**
56-
* Creates a SARIF report and returns it as string
57-
*/
58-
fun createReport(): String =
59-
constructSarif().sarifToJson()
60-
61-
// internal
62-
63-
private val defaultLineNumber = 1 // if the line in the source code where the exception is thrown is unknown
64-
65-
/**
66-
* [Read more about links to locations](https://github.com/microsoft/sarif-tutorials/blob/main/docs/3-Beyond-basics.md#msg-links-location)
40+
* Creates a SARIF report.
6741
*/
68-
private val relatedLocationId = 1 // for attaching link to generated test in related locations
69-
70-
private fun constructSarif(): Sarif {
42+
fun createReport(): Sarif {
7143
val sarifResults = mutableListOf<SarifResult>()
7244
val sarifRules = mutableSetOf<SarifRule>()
7345

@@ -93,6 +65,15 @@ class SarifReport(
9365
)
9466
}
9567

68+
// internal
69+
70+
private val defaultLineNumber = 1 // if the line in the source code where the exception is thrown is unknown
71+
72+
/**
73+
* [Read more about links to locations](https://github.com/microsoft/sarif-tutorials/blob/main/docs/3-Beyond-basics.md#msg-links-location)
74+
*/
75+
private val relatedLocationId = 1 // for attaching link to generated test in related locations
76+
9677
/**
9778
* Minimizes detected errors and removes duplicates.
9879
*

0 commit comments

Comments
 (0)