@@ -18,7 +18,6 @@ import org.utbot.python.newtyping.PythonTypeStorage
18
18
import org.utbot.python.newtyping.general.Type
19
19
import org.utbot.python.newtyping.pythonModules
20
20
import org.utbot.python.newtyping.pythonTypeRepresentation
21
- import org.utbot.python.utils.TestGenerationLimitManager
22
21
import org.utbot.python.utils.camelToSnakeCase
23
22
import org.utbot.summary.fuzzer.names.TestSuggestedInfo
24
23
import java.net.ServerSocket
@@ -143,30 +142,30 @@ class PythonEngine(
143
142
)
144
143
}
145
144
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 {
147
146
val additionalModules = parameters.flatMap { it.pythonModules() }
148
147
149
148
ServerSocket (0 ).use { serverSocket ->
150
- logger.debug { " Server port: ${serverSocket.localPort} " }
149
+ logger.info { " Server port: ${serverSocket.localPort} " }
151
150
val manager = try {
152
151
PythonWorkerManager (
153
152
serverSocket,
154
153
pythonPath,
155
- limitManager. until,
154
+ until,
156
155
{ constructEvaluationInput(it) },
157
156
timeoutForRun.toInt()
158
157
)
159
158
} catch (_: TimeoutException ) {
160
- logger.info { " Cannot connect to python executor" }
161
159
return @flow
162
160
}
163
161
logger.info { " Executor manager was created successfully" }
164
162
165
- fun runWithFuzzedValues (
166
- arguments : List <PythonFuzzedValue >,
167
- ): PythonEvaluationResult ? {
163
+ fun fuzzingResultHandler (
164
+ description : PythonMethodDescription ,
165
+ arguments : List <PythonFuzzedValue >
166
+ ): PythonExecutionResult ? {
168
167
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())
170
169
val argumentModules = argumentValues
171
170
.flatMap { it.allContainingClassIds }
172
171
.map { it.moduleName }
@@ -184,83 +183,52 @@ class PythonEngine(
184
183
modelList,
185
184
methodUnderTest.argumentsNames
186
185
)
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
+ }
224
196
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
+ }
233
201
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
+ )
241
217
}
242
- }
243
-
244
- is ArgumentsTypeErrorFeedback -> {
245
- fuzzingFeedback = PythonFeedback (control = Control .PASS )
246
- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), false )
247
- }
248
218
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
+ }
254
222
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
+ }
259
226
}
260
227
}
261
- fuzzingFeedback = PythonFeedback (control = Control .CONTINUE , result = trieNode)
262
- return Pair (PythonExecutionResult (executionFeedback, fuzzingFeedback), true )
263
228
}
229
+ } catch (_: TimeoutException ) {
230
+ logger.info { " Fuzzing process was interrupted by timeout" }
231
+ return null
264
232
}
265
233
}
266
234
@@ -273,14 +241,10 @@ class PythonEngine(
273
241
)
274
242
275
243
if (parameters.isEmpty()) {
276
- val result = runWithFuzzedValues( emptyList())
244
+ val result = fuzzingResultHandler(pmd, emptyList())
277
245
result?.let {
278
- val (executionResult, needToEmit) = handleExecutionResult(result, emptyList(), pmd)
279
- if (needToEmit) {
280
- emit(executionResult.fuzzingExecutionFeedback)
281
- }
246
+ emit(it.fuzzingExecutionFeedback)
282
247
}
283
- manager.disconnect()
284
248
} else {
285
249
try {
286
250
PythonFuzzing (pmd.pythonTypeStorage) { description, arguments ->
@@ -289,32 +253,35 @@ class PythonEngine(
289
253
manager.disconnect()
290
254
return @PythonFuzzing PythonFeedback (control = Control .STOP )
291
255
}
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
+ }
292
261
293
262
val pair = Pair (description, arguments.map { PythonTreeWrapper (it.tree) })
294
263
val mem = cache.get(pair)
295
264
if (mem != null ) {
296
265
logger.debug(" Repeat in fuzzing" )
266
+ emit(mem.fuzzingExecutionFeedback)
297
267
return @PythonFuzzing mem.fuzzingPlatformFeedback
298
268
}
299
-
300
- val result = runWithFuzzedValues(arguments)
269
+ val result = fuzzingResultHandler(description, arguments)
301
270
if (result == null ) { // timeout
271
+ logger.info { " Fuzzing process was interrupted by timeout" }
302
272
manager.disconnect()
303
273
return @PythonFuzzing PythonFeedback (control = Control .STOP )
304
274
}
305
275
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
312
279
}.fuzz(pmd)
313
- } catch (ex : Exception ) { // NoSeedValueException
280
+ } catch (_ : Exception ) { // e.g. NoSeedValueException
314
281
logger.info { " Cannot fuzz values for types: $parameters " }
315
282
}
316
- manager.disconnect()
317
283
}
284
+ manager.disconnect()
318
285
}
319
286
}
320
- }
287
+ }
0 commit comments