Skip to content

Commit 9bb96f7

Browse files
amandelpieonewhl
authored andcommitted
Reordered the test clusters (UnitTestBot#991)
* Reordered the test clusters * Renamed clusters * Fixed tests * Fixed tests Co-authored-by: Zarina Kurbatova <[email protected]>
1 parent 258d962 commit 9bb96f7

File tree

4 files changed

+119
-95
lines changed

4 files changed

+119
-95
lines changed

utbot-summary-tests/src/test/kotlin/math/SummaryIntMathTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class SummaryIntMathTest : SummaryTestCaseGeneratorTest(
137137
)
138138

139139
val clusterInfo = listOf(
140-
Pair(UtClusterInfo("SYMBOLIC EXECUTION ENGINE: SUCCESSFUL EXECUTIONS for method pow(int, int)", null), 14)
140+
Pair(UtClusterInfo("SYMBOLIC EXECUTION: SUCCESSFUL EXECUTIONS for method pow(int, int)", null), 14)
141141
)
142142

143143
val method = IntMath::pow

utbot-summary-tests/src/test/kotlin/math/SummaryOfMathTest.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ class SummaryOfMathTest : SummaryTestCaseGeneratorTest(
219219
)
220220

221221
val clusterInfo = listOf(
222-
Pair(UtClusterInfo("SYMBOLIC EXECUTION ENGINE: SUCCESSFUL EXECUTIONS #0 for method ofDoubles(double[])", null), 3),
222+
Pair(UtClusterInfo("SYMBOLIC EXECUTION: SUCCESSFUL EXECUTIONS #0 for method ofDoubles(double[])", null), 3),
223223
Pair(
224224
UtClusterInfo(
225-
"SYMBOLIC EXECUTION ENGINE: SUCCESSFUL EXECUTIONS #1 for method ofDoubles(double[])", "\n" +
225+
"SYMBOLIC EXECUTION: SUCCESSFUL EXECUTIONS #1 for method ofDoubles(double[])", "\n" +
226226
"Common steps:\n" +
227227
"<pre>\n" +
228228
"Tests execute conditions:\n" +
@@ -246,7 +246,7 @@ class SummaryOfMathTest : SummaryTestCaseGeneratorTest(
246246
"</pre>"
247247
), 3
248248
),
249-
Pair(UtClusterInfo("SYMBOLIC EXECUTION ENGINE: ERROR SUITE for method ofDoubles(double[])", null), 1)
249+
Pair(UtClusterInfo("SYMBOLIC EXECUTION: ERROR SUITE for method ofDoubles(double[])", null), 1)
250250
)
251251

252252
summaryCheck(method, mockStrategy, coverage, summaryKeys, methodNames, displayNames, clusterInfo)

utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt

+112-88
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
7777
private val jimpleBodyAnalysis = ExecutionStructureAnalysis()
7878

7979
fun fillSummaries(testSet: UtMethodTestSet): List<UtExecutionCluster> {
80-
val namesCounter = mutableMapOf<String, Int>()
81-
8280
if (testSet.executions.isEmpty()) {
8381
logger.info {
8482
"No execution traces found in test case " +
@@ -87,98 +85,29 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
8785
return listOf(UtExecutionCluster(UtClusterInfo(), testSet.executions))
8886
}
8987

90-
// init
91-
val sootToAST = sootToAST(testSet)
92-
val jimpleBody = testSet.jimpleBody
93-
val updatedExecutions = mutableListOf<UtSymbolicExecution>()
9488
val clustersToReturn = mutableListOf<UtExecutionCluster>()
9589

96-
// handles tests produced by fuzzing
97-
val executionsProducedByFuzzer = testSet.executions.filterIsInstance<UtFuzzedExecution>()
98-
val successfulFuzzerExecutions = mutableListOf<UtFuzzedExecution>()
99-
val unsuccessfulFuzzerExecutions = mutableListOf<UtFuzzedExecution>()
100-
101-
if (executionsProducedByFuzzer.isNotEmpty()) {
102-
executionsProducedByFuzzer.forEach { utExecution ->
103-
104-
val nameSuggester = sequenceOf(ModelBasedNameSuggester(), MethodBasedNameSuggester())
105-
val testMethodName = try {
106-
nameSuggester.flatMap {
107-
it.suggest(
108-
utExecution.fuzzedMethodDescription as FuzzedMethodDescription,
109-
utExecution.fuzzingValues as List<FuzzedValue>,
110-
utExecution.result
111-
)
112-
}.firstOrNull()
113-
} catch (t: Throwable) {
114-
logger.error(t) { "Cannot create suggested test name for $utExecution" } // TODO: add better explanation or default behavoiur
115-
null
116-
}
117-
118-
utExecution.testMethodName = testMethodName?.testName
119-
utExecution.displayName = testMethodName?.displayName
120-
121-
when (utExecution.result) {
122-
is UtConcreteExecutionFailure -> unsuccessfulFuzzerExecutions.add(utExecution)
123-
is UtExplicitlyThrownException -> unsuccessfulFuzzerExecutions.add(utExecution)
124-
is UtImplicitlyThrownException -> unsuccessfulFuzzerExecutions.add(utExecution)
125-
is UtOverflowFailure -> unsuccessfulFuzzerExecutions.add(utExecution)
126-
is UtSandboxFailure -> unsuccessfulFuzzerExecutions.add(utExecution)
127-
is UtTimeoutException -> unsuccessfulFuzzerExecutions.add(utExecution)
128-
is UtExecutionSuccess -> successfulFuzzerExecutions.add(utExecution)
129-
}
130-
}
131-
132-
if (successfulFuzzerExecutions.isNotEmpty()) {
133-
val clusterHeader = buildFuzzerClusterHeaderForSuccessfulExecutions(testSet)
134-
135-
clustersToReturn.add(
136-
UtExecutionCluster(
137-
UtClusterInfo(clusterHeader, null),
138-
successfulFuzzerExecutions
139-
)
140-
)
141-
}
142-
143-
if (unsuccessfulFuzzerExecutions.isNotEmpty()) {
144-
val clusterHeader = buildFuzzerClusterHeaderForUnsuccessfulExecutions(testSet)
145-
146-
clustersToReturn.add(
147-
UtExecutionCluster(
148-
UtClusterInfo(clusterHeader, null),
149-
unsuccessfulFuzzerExecutions
150-
)
151-
)
152-
}
153-
}
154-
155-
// handles tests produced by symbolic engine, but with empty paths
156-
val testSetWithEmptyPaths = prepareTestSetWithEmptyPaths(testSet)
157-
158-
val executionsWithEmptyPaths = testSetWithEmptyPaths.executions
159-
160-
if (executionsWithEmptyPaths.isNotEmpty()) {
161-
executionsWithEmptyPaths.forEach {
162-
logger.info {
163-
"The path for test ${it.testMethodName} " +
164-
"for method ${testSet.method.classId.name} is empty and summaries could not be generated."
165-
}
166-
}
167-
168-
val clusteredExecutions = groupExecutionsWithEmptyPaths(testSetWithEmptyPaths)
90+
clustersToReturn += generateSummariesForTestsWithNonEmptyPathsProducedBySymbolicExecutor(testSet)
91+
clustersToReturn += generateSummariesForTestsProducedByFuzzer(testSet)
92+
clustersToReturn += generateSummariesForTestsWithEmptyPathsProducedBySymbolicExecutor(testSet)
16993

170-
clusteredExecutions.forEach {
171-
clustersToReturn.add(
172-
UtExecutionCluster(
173-
UtClusterInfo(it.header),
174-
it.executions
175-
)
176-
)
177-
}
178-
}
94+
return if (clustersToReturn.size > 0)
95+
clustersToReturn
96+
else
97+
listOf(UtExecutionCluster(UtClusterInfo(), testSet.executions))
98+
}
17999

100+
private fun generateSummariesForTestsWithNonEmptyPathsProducedBySymbolicExecutor(
101+
testSet: UtMethodTestSet
102+
): List<UtExecutionCluster> {
103+
val clustersToReturn: MutableList<UtExecutionCluster> = mutableListOf()
180104
val testSetWithNonEmptyPaths = prepareTestSetForByteCodeAnalysis(testSet)
181105

106+
val sootToAST = sootToAST(testSetWithNonEmptyPaths)
107+
val jimpleBody = testSet.jimpleBody
108+
val updatedExecutions = mutableListOf<UtSymbolicExecution>()
109+
val namesCounter = mutableMapOf<String, Int>()
110+
182111
// analyze
183112
if (jimpleBody != null && sootToAST != null) {
184113
val methodUnderTest = jimpleBody.method
@@ -255,6 +184,101 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
255184
return listOf(UtExecutionCluster(UtClusterInfo(), testSet.executions))
256185
}
257186

187+
private fun generateSummariesForTestsWithEmptyPathsProducedBySymbolicExecutor(
188+
testSet: UtMethodTestSet,
189+
): List<UtExecutionCluster> {
190+
val clustersToReturn: MutableList<UtExecutionCluster> = mutableListOf()
191+
val testSetWithEmptyPaths = prepareTestSetWithEmptyPaths(testSet)
192+
193+
val executionsWithEmptyPaths = testSetWithEmptyPaths.executions
194+
195+
if (executionsWithEmptyPaths.isNotEmpty()) {
196+
executionsWithEmptyPaths.forEach {
197+
logger.info {
198+
"The path for test ${it.testMethodName} " +
199+
"for method ${testSet.method.classId.name} is empty and summaries could not be generated."
200+
}
201+
}
202+
203+
val clusteredExecutions = groupExecutionsWithEmptyPaths(testSetWithEmptyPaths)
204+
205+
clusteredExecutions.forEach {
206+
clustersToReturn.add(
207+
UtExecutionCluster(
208+
UtClusterInfo(it.header),
209+
it.executions
210+
)
211+
)
212+
}
213+
}
214+
return clustersToReturn.toList()
215+
}
216+
217+
private fun generateSummariesForTestsProducedByFuzzer(
218+
testSet: UtMethodTestSet
219+
): List<UtExecutionCluster> {
220+
val clustersToReturn: MutableList<UtExecutionCluster> = mutableListOf()
221+
val executionsProducedByFuzzer = testSet.executions.filterIsInstance<UtFuzzedExecution>()
222+
val successfulFuzzerExecutions = mutableListOf<UtFuzzedExecution>()
223+
val unsuccessfulFuzzerExecutions = mutableListOf<UtFuzzedExecution>()
224+
225+
if (executionsProducedByFuzzer.isNotEmpty()) {
226+
executionsProducedByFuzzer.forEach { utExecution ->
227+
228+
val nameSuggester = sequenceOf(ModelBasedNameSuggester(), MethodBasedNameSuggester())
229+
val testMethodName = try {
230+
nameSuggester.flatMap {
231+
it.suggest(
232+
utExecution.fuzzedMethodDescription as FuzzedMethodDescription,
233+
utExecution.fuzzingValues as List<FuzzedValue>,
234+
utExecution.result
235+
)
236+
}.firstOrNull()
237+
} catch (t: Throwable) {
238+
logger.error(t) { "Cannot create suggested test name for $utExecution" } // TODO: add better explanation or default behavoiur
239+
null
240+
}
241+
242+
utExecution.testMethodName = testMethodName?.testName
243+
utExecution.displayName = testMethodName?.displayName
244+
245+
when (utExecution.result) {
246+
is UtConcreteExecutionFailure -> unsuccessfulFuzzerExecutions.add(utExecution)
247+
is UtExplicitlyThrownException -> unsuccessfulFuzzerExecutions.add(utExecution)
248+
is UtImplicitlyThrownException -> unsuccessfulFuzzerExecutions.add(utExecution)
249+
is UtOverflowFailure -> unsuccessfulFuzzerExecutions.add(utExecution)
250+
is UtSandboxFailure -> unsuccessfulFuzzerExecutions.add(utExecution)
251+
is UtTimeoutException -> unsuccessfulFuzzerExecutions.add(utExecution)
252+
is UtExecutionSuccess -> successfulFuzzerExecutions.add(utExecution)
253+
}
254+
}
255+
256+
if (successfulFuzzerExecutions.isNotEmpty()) {
257+
val clusterHeader = buildFuzzerClusterHeaderForSuccessfulExecutions(testSet)
258+
259+
clustersToReturn.add(
260+
UtExecutionCluster(
261+
UtClusterInfo(clusterHeader, null),
262+
successfulFuzzerExecutions
263+
)
264+
)
265+
}
266+
267+
if (unsuccessfulFuzzerExecutions.isNotEmpty()) {
268+
val clusterHeader = buildFuzzerClusterHeaderForUnsuccessfulExecutions(testSet)
269+
270+
clustersToReturn.add(
271+
UtExecutionCluster(
272+
UtClusterInfo(clusterHeader, null),
273+
unsuccessfulFuzzerExecutions
274+
)
275+
)
276+
}
277+
}
278+
279+
return clustersToReturn.toList()
280+
}
281+
258282
private fun buildFuzzerClusterHeaderForSuccessfulExecutions(testSet: UtMethodTestSet): String {
259283
val commentPrefix = "FUZZER:"
260284
val commentPostfix = "for method ${testSet.method.humanReadableName}"

utbot-summary/src/main/kotlin/org/utbot/summary/TagGenerator.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ private fun generateExecutionTags(executions: List<UtSymbolicExecution>, splitSt
9797
fun groupExecutionsWithEmptyPaths(testSet: UtMethodTestSet): List<ExecutionCluster> {
9898
val methodExecutions = testSet.executions.filterIsInstance<UtSymbolicExecution>()
9999
val clusters = mutableListOf<ExecutionCluster>()
100-
val commentPrefix = "CONCRETE EXECUTION ENGINE:"
100+
val commentPrefix = "OTHER:"
101101
val commentPostfix = "for method ${testSet.method.humanReadableName}"
102102

103103
val grouped = methodExecutions.groupBy { it.result.clusterKind() }
@@ -118,7 +118,7 @@ fun groupExecutionsWithEmptyPaths(testSet: UtMethodTestSet): List<ExecutionClust
118118
}
119119

120120
/**
121-
* Splits executions into clusters
121+
* Splits executions produced by symbolic execution engine into clusters
122122
* By default there is 5 types of clusters:
123123
* Success, UnexpectedFail, ExpectedCheckedThrow, ExpectedUncheckedThrow, UnexpectedUncheckedThrow
124124
* These are split by the type of execution result
@@ -131,7 +131,7 @@ fun groupExecutionsWithEmptyPaths(testSet: UtMethodTestSet): List<ExecutionClust
131131
private fun toClusterExecutions(testSet: UtMethodTestSet): List<ExecutionCluster> {
132132
val methodExecutions = testSet.executions.filterIsInstance<UtSymbolicExecution>()
133133
val clusters = mutableListOf<ExecutionCluster>()
134-
val commentPrefix = "SYMBOLIC EXECUTION ENGINE:"
134+
val commentPrefix = "SYMBOLIC EXECUTION:"
135135
val commentPostfix = "for method ${testSet.method.humanReadableName}"
136136

137137
val grouped = methodExecutions.groupBy { it.result.clusterKind() }

0 commit comments

Comments
 (0)