Skip to content

Commit e1f03ce

Browse files
committed
Fixed losses of symbolic executions
1 parent 7148d93 commit e1f03ce

File tree

6 files changed

+93
-57
lines changed

6 files changed

+93
-57
lines changed

utbot-python/src/main/kotlin/org/utbot/python/engine/GlobalPythonEngine.kt

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.utbot.python.engine
22

3+
import kotlinx.coroutines.runBlocking
34
import mu.KotlinLogging
45
import org.usvm.runner.StandardLayout
56
import org.usvm.runner.USVMPythonConfig
@@ -66,36 +67,39 @@ class GlobalPythonEngine(
6667
configuration.sysPathDirectories,
6768
extractVenvConfig(configuration.pythonPath)
6869
)
69-
val receiver = USVMPythonAnalysisResultReceiverImpl(
70-
method,
71-
configuration,
72-
executionStorage,
73-
until,
74-
)
75-
val config = if (method.containingPythonClass == null) {
76-
USVMPythonFunctionConfig(configuration.testFileInformation.moduleName, method.name)
77-
} else {
78-
USVMPythonMethodConfig(
79-
configuration.testFileInformation.moduleName,
80-
method.name,
81-
method.containingPythonClass!!.pythonName()
70+
runBlocking {
71+
val receiver = USVMPythonAnalysisResultReceiverImpl(
72+
method,
73+
configuration,
74+
executionStorage,
75+
until,
76+
this
8277
)
83-
}
84-
val engine = SymbolicEngine(
85-
usvmPythonConfig,
86-
configuration,
87-
)
88-
val usvmConfig = USVMPythonRunConfig(config, until - System.currentTimeMillis(), configuration.timeoutForRun * 2)
89-
if (debug) {
90-
engine.debugRun(usvmConfig)
91-
} else {
92-
engine.analyze(
93-
usvmConfig,
94-
receiver
78+
val config = if (method.containingPythonClass == null) {
79+
USVMPythonFunctionConfig(configuration.testFileInformation.moduleName, method.name)
80+
} else {
81+
USVMPythonMethodConfig(
82+
configuration.testFileInformation.moduleName,
83+
method.name,
84+
method.containingPythonClass!!.pythonName()
85+
)
86+
}
87+
val engine = SymbolicEngine(
88+
usvmPythonConfig,
89+
configuration,
9590
)
91+
val usvmConfig = USVMPythonRunConfig(config, until - System.currentTimeMillis(), configuration.timeoutForRun * 2)
92+
if (debug) {
93+
engine.debugRun(usvmConfig)
94+
} else {
95+
engine.analyze(
96+
usvmConfig,
97+
receiver
98+
)
99+
}
100+
receiver.close()
96101
}
97102
logger.info { "Symbolic: stop receiver" }
98-
receiver.close()
99103
}
100104

101105
fun run() {

utbot-python/src/main/kotlin/org/utbot/python/engine/symbolic/SymbolicEngine.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import org.usvm.runner.PythonSymbolicAnalysisRunnerImpl
66
import org.usvm.runner.USVMPythonConfig
77
import org.usvm.runner.USVMPythonRunConfig
88
import org.utbot.python.PythonTestGenerationConfig
9-
import org.utbot.python.engine.ExecutionStorage
109

1110
private val logger = KotlinLogging.logger {}
1211

1312
interface SymbolicEngineApi {
1413
fun analyze(runConfig: USVMPythonRunConfig, receiver: USVMPythonAnalysisResultReceiverImpl)
1514
}
1615

16+
/*
1717
class DummySymbolicEngine(
1818
val configuration: PythonTestGenerationConfig,
1919
val executionStorage: ExecutionStorage,
@@ -29,8 +29,8 @@ class DummySymbolicEngine(
2929
Thread.sleep(100)
3030
}
3131
}
32-
3332
}
33+
*/
3434

3535
class SymbolicEngine(
3636
val usvmPythonConfig: USVMPythonConfig,

utbot-python/src/main/kotlin/org/utbot/python/engine/symbolic/USVMPythonAnalysisResultReceiverImpl.kt

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package org.utbot.python.engine.symbolic
22

3+
import kotlinx.coroutines.CoroutineScope
4+
import kotlinx.coroutines.launch
5+
import kotlinx.coroutines.sync.Mutex
6+
import kotlinx.coroutines.sync.withLock
37
import mu.KotlinLogging
48
import org.usvm.runner.USVMPythonAnalysisResultReceiver
59
import org.utbot.framework.plugin.api.DocRegularStmt
@@ -41,6 +45,7 @@ class USVMPythonAnalysisResultReceiverImpl(
4145
val configuration: PythonTestGenerationConfig,
4246
val executionStorage: ExecutionStorage,
4347
val until: Long,
48+
private val coroutineScope: CoroutineScope
4449
) : USVMPythonAnalysisResultReceiver() {
4550
private lateinit var serverSocket: ServerSocket
4651
private lateinit var manager: PythonWorkerManager
@@ -80,39 +85,48 @@ class USVMPythonAnalysisResultReceiverImpl(
8085
serverSocket.close()
8186
}
8287

83-
fun receivePickledInputValuesWithFeedback(pickledTuple: String): ExecutionFeedback? {
84-
try {
85-
// logger.info("Receiving $pickledTuple")
86-
val coverageId = CoverageIdGenerator.createId()
87-
return when (
88-
val evaluationResult = manager.runWithCoverage(pickledTuple, coverageId)
89-
) {
90-
is PythonEvaluationError -> {
91-
val stackTraceMessage = evaluationResult.stackTrace.joinToString("\n")
92-
val utError = UtError(
93-
"Error evaluation: ${evaluationResult.status}, ${evaluationResult.message}\n${stackTraceMessage}",
94-
Throwable(stackTraceMessage)
95-
)
96-
logger.debug(stackTraceMessage)
97-
InvalidExecution(utError)
98-
}
88+
private val mutex = Mutex()
89+
90+
suspend fun receivePickledInputValuesWithFeedback(pickledTuple: String): ExecutionFeedback? {
91+
if (System.currentTimeMillis() >= until)
92+
return null
93+
mutex.withLock {
94+
try {
95+
logger.info("Running $pickledTuple")
96+
val coverageId = CoverageIdGenerator.createId()
97+
return when (
98+
val evaluationResult = manager.runWithCoverage(pickledTuple, coverageId)
99+
) {
100+
is PythonEvaluationError -> {
101+
logger.info("PythonEvaluationError")
102+
val stackTraceMessage = evaluationResult.stackTrace.joinToString("\n")
103+
val utError = UtError(
104+
"Error evaluation: ${evaluationResult.status}, ${evaluationResult.message}\n${stackTraceMessage}",
105+
Throwable(stackTraceMessage)
106+
)
107+
logger.debug(stackTraceMessage)
108+
InvalidExecution(utError)
109+
}
99110

100-
is PythonEvaluationTimeout -> {
111+
is PythonEvaluationTimeout -> {
101112
// val coveredInstructions = manager.coverageReceiver.coverageStorage.getOrDefault(coverageId, mutableListOf())
102113
// handleTimeoutResult(method, coveredInstructions)
103-
null
104-
}
114+
logger.info("PythonEvaluationTimeout")
115+
null
116+
}
105117

106-
is PythonEvaluationSuccess -> {
107-
handleSuccessResult(method, evaluationResult)
118+
is PythonEvaluationSuccess -> {
119+
logger.info("PythonEvaluationSuccess")
120+
handleSuccessResult(method, evaluationResult)
121+
}
108122
}
123+
} catch (_: TimeoutException) {
124+
logger.debug { "Symbolic process was interrupted by timeout" }
125+
return null
126+
} catch (_: SocketException) {
127+
connect()
128+
return null
109129
}
110-
} catch (_: TimeoutException) {
111-
logger.debug { "Symbolic process was interrupted by timeout" }
112-
return null
113-
} catch (_: SocketException) {
114-
connect()
115-
return null
116130
}
117131
}
118132

@@ -176,8 +190,10 @@ class USVMPythonAnalysisResultReceiverImpl(
176190

177191
override fun receivePickledInputValues(pickledTuple: String) {
178192
logger.debug { "SYMBOLIC: $pickledTuple" }
179-
receivePickledInputValuesWithFeedback(pickledTuple)?.let {
180-
executionStorage.saveSymbolicExecution(it)
193+
coroutineScope.launch {
194+
receivePickledInputValuesWithFeedback(pickledTuple)?.let {
195+
executionStorage.saveSymbolicExecution(it)
196+
}
181197
}
182198
}
183199
}

utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.utbot.python.evaluation
22

3+
import mu.KotlinLogging
34
import org.utbot.python.FunctionArguments
45
import org.utbot.python.PythonMethod
56
import org.utbot.python.evaluation.serialization.ExecutionRequest
@@ -18,6 +19,8 @@ import org.utbot.python.newtyping.pythonTypeName
1819
import org.utbot.python.newtyping.utils.isNamed
1920
import java.net.SocketException
2021

22+
private val logger = KotlinLogging.logger {}
23+
2124
class PythonCodeSocketExecutor(
2225
override val method: PythonMethod,
2326
override val moduleToImport: String,
@@ -139,13 +142,18 @@ class PythonCodeSocketExecutor(
139142
coverageId,
140143
)
141144
val message = ExecutionRequestSerializer.serializeRequest(request) ?: error("Cannot serialize request to python executor")
145+
logger.info("Serialized request")
142146
try {
143147
pythonWorker.sendData(message)
144148
} catch (_: SocketException) {
145149
return parseExecutionResult(FailExecution("Send data error"))
146150
}
151+
logger.info("Sent data")
147152

148153
val (status, response) = UtExecutorThread.run(pythonWorker, executionTimeout)
154+
155+
logger.info("Got response")
156+
149157
return when (status) {
150158
UtExecutorThread.Status.TIMEOUT -> {
151159
PythonEvaluationTimeout()

utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class PythonWorkerManager(
121121
pickledArguments: String,
122122
coverageId: String
123123
): PythonEvaluationResult {
124+
logger.info("Here!")
124125
val evaluationResult = try {
125126
codeExecutor.runWithCoverage(pickledArguments, coverageId)
126127
} catch (_: SocketTimeoutException) {

utbot-python/src/main/kotlin/org/utbot/python/evaluation/UtExecutorThread.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.utbot.python.evaluation
22

3+
import mu.KotlinLogging
34
import java.net.SocketException
45
import java.util.concurrent.Callable
56
import java.util.concurrent.Executors
67
import java.util.concurrent.TimeUnit
78
import java.util.concurrent.TimeoutException
89

10+
private val logger = KotlinLogging.logger {}
911

1012
class UtExecutorThread {
1113
enum class Status {
@@ -18,12 +20,17 @@ class UtExecutorThread {
1820
val executor = Executors.newSingleThreadExecutor()
1921
val future = executor.submit(Task(worker))
2022

23+
logger.info("Running with timeout $executionTimeout")
24+
2125
val result = try {
2226
Status.OK to future.get(executionTimeout, TimeUnit.MILLISECONDS)
2327
} catch (ex: TimeoutException) {
2428
future.cancel(true)
2529
Status.TIMEOUT to null
2630
}
31+
32+
logger.info("Stopped running. Result: ${result.first}")
33+
2734
executor.shutdown()
2835
return result
2936
}

0 commit comments

Comments
 (0)