@@ -77,8 +77,6 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
77
77
private val jimpleBodyAnalysis = ExecutionStructureAnalysis ()
78
78
79
79
fun fillSummaries (testSet : UtMethodTestSet ): List <UtExecutionCluster > {
80
- val namesCounter = mutableMapOf<String , Int >()
81
-
82
80
if (testSet.executions.isEmpty()) {
83
81
logger.info {
84
82
" No execution traces found in test case " +
@@ -87,98 +85,29 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
87
85
return listOf (UtExecutionCluster (UtClusterInfo (), testSet.executions))
88
86
}
89
87
90
- // init
91
- val sootToAST = sootToAST(testSet)
92
- val jimpleBody = testSet.jimpleBody
93
- val updatedExecutions = mutableListOf<UtSymbolicExecution >()
94
88
val clustersToReturn = mutableListOf<UtExecutionCluster >()
95
89
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)
169
93
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
+ }
179
99
100
+ private fun generateSummariesForTestsWithNonEmptyPathsProducedBySymbolicExecutor (
101
+ testSet : UtMethodTestSet
102
+ ): List <UtExecutionCluster > {
103
+ val clustersToReturn: MutableList <UtExecutionCluster > = mutableListOf ()
180
104
val testSetWithNonEmptyPaths = prepareTestSetForByteCodeAnalysis(testSet)
181
105
106
+ val sootToAST = sootToAST(testSetWithNonEmptyPaths)
107
+ val jimpleBody = testSet.jimpleBody
108
+ val updatedExecutions = mutableListOf<UtSymbolicExecution >()
109
+ val namesCounter = mutableMapOf<String , Int >()
110
+
182
111
// analyze
183
112
if (jimpleBody != null && sootToAST != null ) {
184
113
val methodUnderTest = jimpleBody.method
@@ -255,6 +184,101 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List<InvokeDe
255
184
return listOf (UtExecutionCluster (UtClusterInfo (), testSet.executions))
256
185
}
257
186
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
+
258
282
private fun buildFuzzerClusterHeaderForSuccessfulExecutions (testSet : UtMethodTestSet ): String {
259
283
val commentPrefix = " FUZZER:"
260
284
val commentPostfix = " for method ${testSet.method.humanReadableName} "
0 commit comments