From 4efb0ab6aec5780009663594f33199d05cfb706d Mon Sep 17 00:00:00 2001 From: Vyacheslav Tamarin Date: Thu, 16 Mar 2023 16:56:01 +0300 Subject: [PATCH 1/4] utbot_executor version update --- .../main/kotlin/org/utbot/python/utils/RequirementsUtils.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt b/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt index f600bf084d..4a2eb4dcea 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt @@ -3,8 +3,7 @@ package org.utbot.python.utils object RequirementsUtils { val requirements: List = listOf( "mypy==1.0.0", - "coverage==6.5.0", - "utbot-executor==1.2.0", + "utbot-executor==0.100.1", "utbot-mypy-runner==0.2.8", ) From 3b81e596af53843ad76512ff48d7a8772f24aee9 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tamarin Date: Mon, 20 Mar 2023 15:49:20 +0300 Subject: [PATCH 2/4] Try to fix execution timeout --- .../evaluation/PythonCodeSocketExecutor.kt | 23 +++++++++++++------ .../python/evaluation/PythonWorkerManager.kt | 10 ++++---- .../utbot/python/utils/RequirementsUtils.kt | 3 ++- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt index dc7bd8219f..1033998fe4 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt @@ -1,5 +1,7 @@ package org.utbot.python.evaluation +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import mu.KotlinLogging import org.utbot.framework.plugin.api.Coverage import org.utbot.framework.plugin.api.Instruction @@ -76,14 +78,21 @@ class PythonCodeSocketExecutor( logger.info { "Send data error" } return parseExecutionResult(FailExecution("Send data error")) } - val response = pythonWorker.receiveMessage() - val executionResult = if (response == null) { - logger.info { "Response error" } - FailExecution("Execution result error") - } else { - ExecutionResultDeserializer.parseExecutionResult(response) - ?: error("Cannot parse execution result: $response") + var response: String? = null + + val job = launch { + response = pythonWorker.receiveMessage() } + delay(executionTimeout) + job.cancelAndJoin() + + + val executionResult = response?.let { + ExecutionResultDeserializer.parseExecutionResult(response!!) + ?: error("Cannot parse execution result: $response") + } ?: FailExecution("Execution result error") + + return parseExecutionResult(executionResult) } diff --git a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt index 31ca73db03..5a27852aa9 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt @@ -12,6 +12,7 @@ import java.net.Socket import java.net.SocketTimeoutException private val logger = KotlinLogging.logger {} +const val ADDITIONAL_EXECUTION_TIME = 250 class PythonWorkerManager( private val serverSocket: ServerSocket, @@ -39,22 +40,21 @@ class PythonWorkerManager( "localhost", serverSocket.localPort.toString(), "--logfile", logfile.absolutePath, - "--loglevel", "INFO", // "DEBUG", "INFO", "ERROR" + "--loglevel", "DEBUG", // "DEBUG", "INFO", "WARNING", "ERROR" )) timeout = max(until - processStartTime, 0) workerSocket = try { serverSocket.soTimeout = timeout.toInt() serverSocket.accept() } catch (e: SocketTimeoutException) { - timeout = max(until - processStartTime, 0) - val result = getResult(process, timeout) - logger.info("utbot_executor exit value: ${result.exitValue}. stderr: ${result.stderr}.") + val result = getResult(process, max(until - processStartTime, 0)) + logger.info("utbot_executor exit value: ${result.exitValue}. stderr: ${result.stderr}, stdout: ${result.stdout}.") process.destroy() throw TimeoutException("Worker not connected") } logger.debug { "Worker connected successfully" } - workerSocket.soTimeout = timeoutForRun // TODO: maybe +eps for serialization/deserialization? +// workerSocket.soTimeout = timeoutForRun + ADDITIONAL_EXECUTION_TIME // TODO: maybe +eps for serialization/deserialization? val pythonWorker = PythonWorker(workerSocket) codeExecutor = pythonCodeExecutorConstructor(pythonWorker) } diff --git a/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt b/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt index 4a2eb4dcea..061ceb8833 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/utils/RequirementsUtils.kt @@ -3,7 +3,7 @@ package org.utbot.python.utils object RequirementsUtils { val requirements: List = listOf( "mypy==1.0.0", - "utbot-executor==0.100.1", + "utbot-executor==1.3.1", "utbot-mypy-runner==0.2.8", ) @@ -25,6 +25,7 @@ object RequirementsUtils { requirementsScript.path ) + requirementList ) + requirementsScript.delete() return result.exitValue == 0 } From efea0cb7102740db7ea38ae9814c36902e9e28ca Mon Sep 17 00:00:00 2001 From: Vyacheslav Tamarin Date: Mon, 20 Mar 2023 21:02:45 +0300 Subject: [PATCH 3/4] Fix one execution timeout --- .../evaluation/PythonCodeSocketExecutor.kt | 28 +++++++-------- .../python/evaluation/UtExecutorThread.kt | 36 +++++++++++++++++++ 2 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 utbot-python/src/main/kotlin/org/utbot/python/evaluation/UtExecutorThread.kt diff --git a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt index 1033998fe4..585d6052f7 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonCodeSocketExecutor.kt @@ -1,7 +1,5 @@ package org.utbot.python.evaluation -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import mu.KotlinLogging import org.utbot.framework.plugin.api.Coverage import org.utbot.framework.plugin.api.Instruction @@ -78,22 +76,22 @@ class PythonCodeSocketExecutor( logger.info { "Send data error" } return parseExecutionResult(FailExecution("Send data error")) } - var response: String? = null - val job = launch { - response = pythonWorker.receiveMessage() - } - delay(executionTimeout) - job.cancelAndJoin() - - - val executionResult = response?.let { - ExecutionResultDeserializer.parseExecutionResult(response!!) - ?: error("Cannot parse execution result: $response") - } ?: FailExecution("Execution result error") + val (status, response) = UtExecutorThread.run(pythonWorker, executionTimeout) + return when (status) { + UtExecutorThread.Status.TIMEOUT -> { + PythonEvaluationTimeout() + } + UtExecutorThread.Status.OK -> { + val executionResult = response?.let { + ExecutionResultDeserializer.parseExecutionResult(it) + ?: error("Cannot parse execution result: $it") + } ?: FailExecution("Execution result error") - return parseExecutionResult(executionResult) + parseExecutionResult(executionResult) + } + } } private fun parseExecutionResult(executionResult: PythonExecutionResult): PythonEvaluationResult { diff --git a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/UtExecutorThread.kt b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/UtExecutorThread.kt new file mode 100644 index 0000000000..d749c1883d --- /dev/null +++ b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/UtExecutorThread.kt @@ -0,0 +1,36 @@ +package org.utbot.python.evaluation + +class UtExecutorThread : Thread() { + override fun run() { + response = pythonWorker?.receiveMessage() + } + + enum class Status { + TIMEOUT, + OK, + } + + companion object { + var pythonWorker: PythonWorker? = null + var response: String? = null + + fun run(worker: PythonWorker, executionTimeout: Long): Pair { + pythonWorker = worker + response = null + val thread = UtExecutorThread() + thread.start() + // Wait for the thread to finish + val finishTime = System.currentTimeMillis() + executionTimeout + while (thread.isAlive && System.currentTimeMillis() < finishTime) { + sleep(1) + } + val status = if (thread.isAlive) { + thread.interrupt() + Status.TIMEOUT + } else { + Status.OK + } + return status to response + } + } +} From 0a53acbc7a227b106f11e221755d4f74792c6bb9 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tamarin Date: Mon, 20 Mar 2023 21:17:11 +0300 Subject: [PATCH 4/4] Remove unused timeout --- .../src/main/kotlin/org/utbot/python/PythonEngine.kt | 1 - .../org/utbot/python/evaluation/PythonWorkerManager.kt | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/utbot-python/src/main/kotlin/org/utbot/python/PythonEngine.kt b/utbot-python/src/main/kotlin/org/utbot/python/PythonEngine.kt index f7a5101b6a..528cf1f560 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/PythonEngine.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/PythonEngine.kt @@ -154,7 +154,6 @@ class PythonEngine( pythonPath, until, { constructEvaluationInput(it) }, - timeoutForRun.toInt() ) } catch (_: TimeoutException) { return@flow diff --git a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt index 5a27852aa9..1b701b0e70 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/evaluation/PythonWorkerManager.kt @@ -12,14 +12,12 @@ import java.net.Socket import java.net.SocketTimeoutException private val logger = KotlinLogging.logger {} -const val ADDITIONAL_EXECUTION_TIME = 250 class PythonWorkerManager( private val serverSocket: ServerSocket, val pythonPath: String, val until: Long, val pythonCodeExecutorConstructor: (PythonWorker) -> PythonCodeExecutor, - private val timeoutForRun: Int ) { private val logfile = TemporaryFileManager.createTemporaryFile("","utbot_executor.log", "log", true) @@ -40,7 +38,7 @@ class PythonWorkerManager( "localhost", serverSocket.localPort.toString(), "--logfile", logfile.absolutePath, - "--loglevel", "DEBUG", // "DEBUG", "INFO", "WARNING", "ERROR" + "--loglevel", "INFO", // "DEBUG", "INFO", "WARNING", "ERROR" )) timeout = max(until - processStartTime, 0) workerSocket = try { @@ -54,7 +52,7 @@ class PythonWorkerManager( } logger.debug { "Worker connected successfully" } -// workerSocket.soTimeout = timeoutForRun + ADDITIONAL_EXECUTION_TIME // TODO: maybe +eps for serialization/deserialization? +// workerSocket.soTimeout = timeoutForRun // TODO: maybe +eps for serialization/deserialization? val pythonWorker = PythonWorker(workerSocket) codeExecutor = pythonCodeExecutorConstructor(pythonWorker) }