@@ -18,7 +18,6 @@ import org.utbot.python.newtyping.PythonTypeStorage
1818import org.utbot.python.newtyping.general.Type
1919import org.utbot.python.newtyping.pythonModules
2020import org.utbot.python.newtyping.pythonTypeRepresentation
21- import org.utbot.python.utils.TestGenerationLimitManager
2221import org.utbot.python.utils.camelToSnakeCase
2322import org.utbot.summary.fuzzer.names.TestSuggestedInfo
2423import java.net.ServerSocket
@@ -143,30 +142,30 @@ class PythonEngine(
143142 )
144143 }
145144
146- fun fuzzing (parameters : List <Type >, isCancelled : () -> Boolean , limitManager : TestGenerationLimitManager ): Flow <FuzzingExecutionFeedback > = flow {
145+ fun fuzzing (parameters : List <Type >, isCancelled : () -> Boolean , until : Long ): Flow <FuzzingExecutionFeedback > = flow {
147146 val additionalModules = parameters.flatMap { it.pythonModules() }
148147
149148 ServerSocket (0 ).use { serverSocket ->
150- logger.debug { " Server port: ${serverSocket.localPort} " }
149+ logger.info { " Server port: ${serverSocket.localPort} " }
151150 val manager = try {
152151 PythonWorkerManager (
153152 serverSocket,
154153 pythonPath,
155- limitManager. until,
154+ until,
156155 { constructEvaluationInput(it) },
157156 timeoutForRun.toInt()
158157 )
159158 } catch (_: TimeoutException ) {
160- logger.info { " Cannot connect to python executor" }
161159 return @flow
162160 }
163161 logger.info { " Executor manager was created successfully" }
164162
165- fun runWithFuzzedValues (
166- arguments : List <PythonFuzzedValue >,
167- ): PythonEvaluationResult ? {
163+ fun fuzzingResultHandler (
164+ description : PythonMethodDescription ,
165+ arguments : List <PythonFuzzedValue >
166+ ): PythonExecutionResult ? {
168167 val argumentValues = arguments.map { PythonTreeModel (it.tree, it.tree.type) }
169- logger.debug(argumentValues.map { it.tree }.toString())
168+ logger.debug(argumentValues.map { it.tree } .toString())
170169 val argumentModules = argumentValues
171170 .flatMap { it.allContainingClassIds }
172171 .map { it.moduleName }
@@ -184,83 +183,52 @@ class PythonEngine(
184183 modelList,
185184 methodUnderTest.argumentsNames
186185 )
187- return try {
188- manager.run (functionArguments, localAdditionalModules)
189- } catch (_: TimeoutException ) {
190- logger.info { " Fuzzing process was interrupted by timeout" }
191- null
192- }
193- }
194-
195- fun handleExecutionResult (
196- result : PythonEvaluationResult ,
197- arguments : List <PythonFuzzedValue >,
198- description : PythonMethodDescription ,
199- ): Pair <PythonExecutionResult , Boolean > {
200- val executionFeedback: FuzzingExecutionFeedback
201- val fuzzingFeedback: PythonFeedback
202-
203- when (result) {
204- is PythonEvaluationError -> {
205- val utError = UtError (
206- " Error evaluation: ${result.status} , ${result.message} " ,
207- Throwable (result.stackTrace.joinToString(" \n " ))
208- )
209- logger.debug(result.stackTrace.joinToString(" \n " ))
210-
211- limitManager.addSuccessExecution()
212- executionFeedback = InvalidExecution (utError)
213- fuzzingFeedback = PythonFeedback (control = Control .PASS )
214- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), true )
215- }
216-
217- is PythonEvaluationTimeout -> {
218- val utError = UtError (result.message, Throwable ())
219- limitManager.addInvalidExecution()
220- executionFeedback = InvalidExecution (utError)
221- fuzzingFeedback = PythonFeedback (control = Control .PASS )
222- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), false )
223- }
186+ try {
187+ return when (val evaluationResult = manager.run (functionArguments, localAdditionalModules)) {
188+ is PythonEvaluationError -> {
189+ val utError = UtError (
190+ " Error evaluation: ${evaluationResult.status} , ${evaluationResult.message} " ,
191+ Throwable (evaluationResult.stackTrace.joinToString(" \n " ))
192+ )
193+ logger.debug(evaluationResult.stackTrace.joinToString(" \n " ))
194+ PythonExecutionResult (InvalidExecution (utError), PythonFeedback (control = Control .PASS ))
195+ }
224196
225- is PythonEvaluationSuccess -> {
226- val coveredInstructions = result.coverage.coveredInstructions
227- executionFeedback = handleSuccessResult(
228- arguments,
229- parameters,
230- result,
231- description,
232- )
197+ is PythonEvaluationTimeout -> {
198+ val utError = UtError (evaluationResult.message, Throwable ())
199+ PythonExecutionResult (InvalidExecution (utError), PythonFeedback (control = Control .PASS ))
200+ }
233201
234- val trieNode: Trie .Node <Instruction > = description.tracer.add(coveredInstructions)
235- when (executionFeedback) {
236- is ValidExecution -> {
237- limitManager.addSuccessExecution()
238- if (trieNode.count > 1 ) {
239- fuzzingFeedback = PythonFeedback (control = Control .CONTINUE , result = trieNode)
240- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), false )
202+ is PythonEvaluationSuccess -> {
203+ val coveredInstructions = evaluationResult.coverage.coveredInstructions
204+
205+ when (val result = handleSuccessResult(
206+ arguments,
207+ parameters,
208+ evaluationResult,
209+ description,
210+ )) {
211+ is ValidExecution -> {
212+ val trieNode: Trie .Node <Instruction > = description.tracer.add(coveredInstructions)
213+ PythonExecutionResult (
214+ result,
215+ PythonFeedback (control = Control .CONTINUE , result = trieNode)
216+ )
241217 }
242- }
243-
244- is ArgumentsTypeErrorFeedback -> {
245- fuzzingFeedback = PythonFeedback (control = Control .PASS )
246- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), false )
247- }
248218
249- is TypeErrorFeedback -> {
250- limitManager.addInvalidExecution()
251- fuzzingFeedback = PythonFeedback (control = Control .PASS )
252- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), false )
253- }
219+ is ArgumentsTypeErrorFeedback , is TypeErrorFeedback -> {
220+ PythonExecutionResult (result, PythonFeedback (control = Control .PASS ))
221+ }
254222
255- is InvalidExecution -> {
256- limitManager.addInvalidExecution()
257- fuzzingFeedback = PythonFeedback (control = Control .CONTINUE )
258- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), false )
223+ is InvalidExecution -> {
224+ PythonExecutionResult (result, PythonFeedback (control = Control .CONTINUE ))
225+ }
259226 }
260227 }
261- fuzzingFeedback = PythonFeedback (control = Control .CONTINUE , result = trieNode)
262- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), true )
263228 }
229+ } catch (_: TimeoutException ) {
230+ logger.info { " Fuzzing process was interrupted by timeout" }
231+ return null
264232 }
265233 }
266234
@@ -273,14 +241,10 @@ class PythonEngine(
273241 )
274242
275243 if (parameters.isEmpty()) {
276- val result = runWithFuzzedValues( emptyList())
244+ val result = fuzzingResultHandler(pmd, emptyList())
277245 result?.let {
278- val (executionResult, needToEmit) = handleExecutionResult(result, emptyList(), pmd)
279- if (needToEmit) {
280- emit(executionResult.fuzzingExecutionFeedback)
281- }
246+ emit(it.fuzzingExecutionFeedback)
282247 }
283- manager.disconnect()
284248 } else {
285249 try {
286250 PythonFuzzing (pmd.pythonTypeStorage) { description, arguments ->
@@ -289,32 +253,35 @@ class PythonEngine(
289253 manager.disconnect()
290254 return @PythonFuzzing PythonFeedback (control = Control .STOP )
291255 }
256+ if (System .currentTimeMillis() >= until) {
257+ logger.info { " Fuzzing process was interrupted by timeout" }
258+ manager.disconnect()
259+ return @PythonFuzzing PythonFeedback (control = Control .STOP )
260+ }
292261
293262 val pair = Pair (description, arguments.map { PythonTreeWrapper (it.tree) })
294263 val mem = cache.get(pair)
295264 if (mem != null ) {
296265 logger.debug(" Repeat in fuzzing" )
266+ emit(mem.fuzzingExecutionFeedback)
297267 return @PythonFuzzing mem.fuzzingPlatformFeedback
298268 }
299-
300- val result = runWithFuzzedValues(arguments)
269+ val result = fuzzingResultHandler(description, arguments)
301270 if (result == null ) { // timeout
271+ logger.info { " Fuzzing process was interrupted by timeout" }
302272 manager.disconnect()
303273 return @PythonFuzzing PythonFeedback (control = Control .STOP )
304274 }
305275
306- val (executionResult, needToEmit) = handleExecutionResult(result, arguments, description)
307- cache.add(pair, executionResult)
308- if (needToEmit) {
309- emit(executionResult.fuzzingExecutionFeedback)
310- }
311- return @PythonFuzzing executionResult.fuzzingPlatformFeedback
276+ cache.add(pair, result)
277+ emit(result.fuzzingExecutionFeedback)
278+ return @PythonFuzzing result.fuzzingPlatformFeedback
312279 }.fuzz(pmd)
313- } catch (ex : Exception ) { // NoSeedValueException
280+ } catch (_ : Exception ) { // e.g. NoSeedValueException
314281 logger.info { " Cannot fuzz values for types: $parameters " }
315282 }
316- manager.disconnect()
317283 }
284+ manager.disconnect()
318285 }
319286 }
320- }
287+ }
0 commit comments