From 8cf8226903aa7b4339cd0f594616814a9b02213f Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Mon, 20 Jun 2022 13:36:44 +0300 Subject: [PATCH 1/2] #247 Fix incorrect analysis steps in the sarif report --- .../src/main/kotlin/org/utbot/sarif/SarifReport.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt index 42e70cad2d..f977d8f22c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt @@ -254,10 +254,12 @@ class SarifReport( return null // searching needed method call + val publicMethodCall = "$methodName(" + val privateMethodCall = Regex("""$methodName.*\.invoke\(""") // using reflection val methodCallLineNumber = testsBodyLines .drop(testMethodStartsAt + 1) // for search after it .indexOfFirst { line -> - line.contains("$methodName(") + line.contains(publicMethodCall) || line.contains(privateMethodCall) } if (methodCallLineNumber == -1) return null From 736abbfa530b2543a47ef2d9c0374385dd2fa2d5 Mon Sep 17 00:00:00 2001 From: Nikita Stroganov Date: Mon, 20 Jun 2022 17:13:21 +0300 Subject: [PATCH 2/2] #247 Add unit tests --- .../kotlin/org/utbot/sarif/SarifReport.kt | 6 +- .../kotlin/org/utbot/sarif/SarifReportTest.kt | 146 ++++++++++++------ 2 files changed, 101 insertions(+), 51 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt index f977d8f22c..286476b075 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt @@ -254,12 +254,12 @@ class SarifReport( return null // searching needed method call - val publicMethodCall = "$methodName(" - val privateMethodCall = Regex("""$methodName.*\.invoke\(""") // using reflection + val publicMethodCallPattern = "$methodName(" + val privateMethodCallPattern = Regex("""$methodName.*\.invoke\(""") // using reflection val methodCallLineNumber = testsBodyLines .drop(testMethodStartsAt + 1) // for search after it .indexOfFirst { line -> - line.contains(publicMethodCall) || line.contains(privateMethodCall) + line.contains(publicMethodCallPattern) || line.contains(privateMethodCallPattern) } if (methodCallLineNumber == -1) return null diff --git a/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt b/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt index dc9e0bacab..fad4ff0334 100644 --- a/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt +++ b/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt @@ -17,7 +17,7 @@ class SarifReportTest { val actualReport = SarifReport( testCases = listOf(), generatedTestsCode = "", - SourceFindingStrategyDefault("", "", "", "") + sourceFindingEmpty ).createReport() assert(actualReport.isNotEmpty()) @@ -28,7 +28,7 @@ class SarifReportTest { val sarif = SarifReport( testCases = listOf(testCase), generatedTestsCode = "", - SourceFindingStrategyDefault("", "", "", "") + sourceFindingEmpty ).createReport().toSarif() assert(sarif.runs.first().results.isEmpty()) @@ -58,7 +58,7 @@ class SarifReportTest { val report = SarifReport( testCases = testCases, generatedTestsCode = "", - SourceFindingStrategyDefault("", "", "", "") + sourceFindingEmpty ).createReport().toSarif() assert(report.runs.first().results[0].message.text.contains("NullPointerException")) @@ -74,23 +74,9 @@ class SarifReportTest { ) Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf()) Mockito.`when`(mockUtExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(1337) - Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain") + Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException") - val report = SarifReport( - testCases = listOf(testCase), - generatedTestsCode = """ - // comment for `startLine == 2` in related location - public void testMain() throws Throwable { - Main.main(); - } - """.trimIndent(), - SourceFindingStrategyDefault( - sourceClassFqn = "Main", - sourceFilePath = "src/Main.java", - testsFilePath = "test/MainTest.java", - projectRootPath = "." - ) - ).createReport().toSarif() + val report = sarifReportMain.createReport().toSarif() val result = report.runs.first().results.first() val location = result.locations.first().physicalLocation @@ -99,7 +85,7 @@ class SarifReportTest { assert(location.artifactLocation.uri.contains("Main.java")) assert(location.region.startLine == 1337) assert(relatedLocation.artifactLocation.uri.contains("MainTest.java")) - assert(relatedLocation.region.startLine == 2) + assert(relatedLocation.region.startLine == 1) } @Test @@ -117,16 +103,7 @@ class SarifReportTest { ) ) - val report = SarifReport( - testCases = listOf(testCase), - generatedTestsCode = "", - SourceFindingStrategyDefault( - sourceClassFqn = "Main", - sourceFilePath = "src/Main.java", - testsFilePath = "test/MainTest.java", - projectRootPath = "." - ) - ).createReport().toSarif() + val report = sarifReportMain.createReport().toSarif() val result = report.runs.first().results.first() assert(result.message.text.contains("227")) @@ -135,14 +112,13 @@ class SarifReportTest { } @Test - fun testCorrectCodeFlow() { + fun testCorrectCodeFlows() { mockUtMethodNames() val uncheckedException = Mockito.mock(NullPointerException::class.java) + val stackTraceElement = StackTraceElement("Main", "main", "Main.java", 17) Mockito.`when`(uncheckedException.stackTrace).thenReturn( - Array(2) { - StackTraceElement("Main", "main", "Main.java", 17) - } + Array(2) { stackTraceElement } ) Mockito.`when`(mockUtExecution.result).thenReturn( @@ -150,24 +126,61 @@ class SarifReportTest { ) Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf()) - val report = SarifReport( - testCases = listOf(testCase), - generatedTestsCode = "", - SourceFindingStrategyDefault( - sourceClassFqn = "Main", - sourceFilePath = "src/Main.java", - testsFilePath = "test/MainTest.java", - projectRootPath = "." - ) - ).createReport().toSarif() + val report = sarifReportMain.createReport().toSarif() val result = report.runs.first().results.first().codeFlows.first().threadFlows.first().locations.map { it.location.physicalLocation } - assert(result[0].artifactLocation.uri.contains("Main.java")) - assert(result[0].region.startLine == 17) - assert(result[1].artifactLocation.uri.contains("Main.java")) - assert(result[1].region.startLine == 17) + for (index in 0..1) { + assert(result[index].artifactLocation.uri.contains("Main.java")) + assert(result[index].region.startLine == 17) + } + } + + @Test + fun testCodeFlowsStartsWithMethodCall() { + mockUtMethodNames() + + val uncheckedException = Mockito.mock(NullPointerException::class.java) + val stackTraceElement = StackTraceElement("Main", "main", "Main.java", 3) + Mockito.`when`(uncheckedException.stackTrace).thenReturn(arrayOf(stackTraceElement)) + + Mockito.`when`(mockUtExecution.result).thenReturn( + UtImplicitlyThrownException(uncheckedException, false) + ) + Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf()) + Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException") + + val report = sarifReportMain.createReport().toSarif() + + val codeFlowPhysicalLocations = report.runs[0].results[0].codeFlows[0].threadFlows[0].locations.map { + it.location.physicalLocation + } + assert(codeFlowPhysicalLocations[0].artifactLocation.uri.contains("MainTest.java")) + assert(codeFlowPhysicalLocations[0].region.startLine == 3) + } + + @Test + fun testCodeFlowsStartsWithPrivateMethodCall() { + mockUtMethodNames() + + val uncheckedException = Mockito.mock(NullPointerException::class.java) + val stackTraceElement = StackTraceElement("Main", "main", "Main.java", 3) + Mockito.`when`(uncheckedException.stackTrace).thenReturn(arrayOf(stackTraceElement)) + + Mockito.`when`(mockUtExecution.result).thenReturn( + UtImplicitlyThrownException(uncheckedException, false) + ) + Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf()) + Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException") + + val report = sarifReportPrivateMain.createReport().toSarif() + + val codeFlowPhysicalLocations = report.runs[0].results[0].codeFlows[0].threadFlows[0].locations.map { + it.location.physicalLocation + } + assert(codeFlowPhysicalLocations[0].artifactLocation.uri.contains("MainTest.java")) + assert(codeFlowPhysicalLocations[0].region.startLine == 4) } // internal @@ -184,4 +197,41 @@ class SarifReportTest { } private fun String.toSarif(): Sarif = jacksonObjectMapper().readValue(this) + + // constants + + private val sourceFindingEmpty = SourceFindingStrategyDefault( + sourceClassFqn = "", + sourceFilePath = "", + testsFilePath = "", + projectRootPath = "" + ) + + private val sourceFindingMain = SourceFindingStrategyDefault( + sourceClassFqn = "Main", + sourceFilePath = "src/Main.java", + testsFilePath = "test/MainTest.java", + projectRootPath = "." + ) + + private val generatedTestsCodeMain = """ + public void testMain_ThrowArithmeticException() { + Main main = new Main(); + main.main(0); + } + """.trimIndent() + + private val generatedTestsCodePrivateMain = """ + public void testMain_ThrowArithmeticException() { + Main main = new Main(); + // ... + mainMethod.invoke(main, mainMethodArguments); + } + """.trimIndent() + + private val sarifReportMain = + SarifReport(listOf(testCase), generatedTestsCodeMain, sourceFindingMain) + + private val sarifReportPrivateMain = + SarifReport(listOf(testCase), generatedTestsCodePrivateMain, sourceFindingMain) } \ No newline at end of file