@@ -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} "
0 commit comments