Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7483ca6

Browse files
committedOct 6, 2022
1. added ability to set log level for EngineProcess and ChildProcess.kt. Look for related UtSettings.engineProcessLogLevel and UtSettings.childProcessLogLevels
2. opening additional packages to support jdk17+, see OpenModulesContainer 3. fixed using javaw on unix environments 4. fixed using readaction in dumb mode
1 parent f83f62c commit 7483ca6

File tree

11 files changed

+120
-81
lines changed

11 files changed

+120
-81
lines changed
 

‎utbot-core/src/main/kotlin/org/utbot/common/JvmUtil.kt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ package org.utbot.common
33
private val javaSpecificationVersion = System.getProperty("java.specification.version")
44
val isJvm8 = javaSpecificationVersion.equals("1.8")
55
val isJvm9Plus = !javaSpecificationVersion.contains(".") && javaSpecificationVersion.toInt() >= 9
6+
7+
fun osSpecificJavaExecutable() = if (isWindows) "javaw" else "java"

‎utbot-framework-api/build.gradle.kts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ plugins {
1212
dependencies {
1313
api(project(":utbot-core"))
1414
api(project(":utbot-api"))
15+
api(project(":utbot-rd"))
16+
implementation(group ="com.jetbrains.rd", name = "rd-framework", version = "2022.3.1")
17+
implementation(group ="com.jetbrains.rd", name = "rd-core", version = "2022.3.1")
1518
implementation("com.github.UnitTestBot:soot:${sootCommitHash}")
1619
implementation(group = "io.github.microutils", name = "kotlin-logging", version = kotlinLoggingVersion)
1720
// TODO do we really need apache commons?

‎utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package org.utbot.framework
22

3+
import com.jetbrains.rd.util.LogLevel
34
import mu.KotlinLogging
45
import org.utbot.common.AbstractSettings
5-
import org.utbot.common.PropertiesSettingsContainer
6-
import kotlin.reflect.KProperty
7-
86
private val logger = KotlinLogging.logger {}
97

108
/**
@@ -259,12 +257,22 @@ object UtSettings : AbstractSettings(
259257
)
260258

261259
/**
262-
* Determines whether should errors from a child process and idea engine process be written to a log file or suppressed.
260+
* Log level for engine process, which started in idea on generate tests action.
261+
*/
262+
var engineProcessLogLevel by getEnumProperty(LogLevel.Info)
263+
264+
/**
265+
* Log level for concrete executor process.
266+
*/
267+
var childProcessLogLevel by getEnumProperty(LogLevel.Info)
268+
269+
/**
270+
* Determines whether should errors from a child process be written to a log file or suppressed.
263271
* Note: being enabled, this option can highly increase disk usage when using ContestEstimator.
264272
*
265273
* False by default (for saving disk space).
266274
*/
267-
var logConcreteExecutionErrors by getBooleanProperty(false)
275+
var logConcreteExecutionErrors by getBooleanProperty(true)
268276

269277
/**
270278
* Number of branch instructions using for clustering executions in the test minimization phase.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.utbot.framework.process
2+
3+
import org.utbot.framework.plugin.services.JdkInfoService
4+
5+
object OpenModulesContainer {
6+
private val modulesContainer: List<String>
7+
val javaVersionSpecificArguments: List<String>
8+
get() = modulesContainer
9+
.takeIf { JdkInfoService.provide().version > 8 }
10+
?: emptyList()
11+
12+
init {
13+
modulesContainer = buildList {
14+
openPackage("java.base", "jdk.internal.misc")
15+
openPackage("java.base", "java.lang")
16+
openPackage("java.base", "java.lang.reflect")
17+
openPackage("java.base", "sun.security.provider")
18+
add("--illegal-access=warn")
19+
}
20+
}
21+
22+
private fun MutableList<String>.openPackage(module: String, pakage: String) {
23+
add("--add-opens")
24+
add("$module/$pakage=ALL-UNNAMED")
25+
}
26+
}

‎utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/process/ChildProcess.kt‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,20 @@ internal object HandlerClassesLoader : URLClassLoader(emptyArray()) {
5353
* Command-line option to disable the sandbox
5454
*/
5555
const val DISABLE_SANDBOX_OPTION = "--disable-sandbox"
56-
private val defaultLogLevel = LogLevel.Info
56+
const val ENABLE_LOGS_OPTION = "--enable-logs"
5757
private val logger = getLogger("ChildProcess")
5858
private val messageFromMainTimeout: Duration = 120.seconds
5959

60+
fun logLevelArgument(level: LogLevel): String {
61+
return "$ENABLE_LOGS_OPTION=$level"
62+
}
63+
64+
private fun findLogLevel(args: Array<String>): LogLevel {
65+
val logArgument = args.find{ it.contains(ENABLE_LOGS_OPTION) } ?: return LogLevel.Fatal
66+
67+
return enumValueOf(logArgument.split("=").last())
68+
}
69+
6070
/**
6171
* It should be compiled into separate jar file (child_process.jar) and be run with an agent (agent.jar) option.
6272
*/
@@ -76,7 +86,9 @@ fun main(args: Array<String>) = runBlocking {
7686
}
7787
}
7888

79-
Logger.set(Lifetime.Eternal, UtRdConsoleLoggerFactory(defaultLogLevel, System.err))
89+
val logLevel: LogLevel = findLogLevel(args)
90+
Logger.set(Lifetime.Eternal, UtRdConsoleLoggerFactory(logLevel, System.err))
91+
8092
val port = findRdPort(args)
8193

8294
try {

‎utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/process/ChildProcessRunner.kt‎

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.utbot.common.utBotTempDirectory
77
import org.utbot.framework.plugin.services.JdkInfoService
88
import org.utbot.framework.UtSettings
99
import org.utbot.framework.plugin.services.WorkingDirService
10+
import org.utbot.framework.process.OpenModulesContainer
1011
import org.utbot.instrumentation.Settings
1112
import org.utbot.instrumentation.agent.DynamicClassTransformer
1213
import org.utbot.rd.rdPortArgument
@@ -19,26 +20,20 @@ class ChildProcessRunner {
1920
private val id = Random.nextLong()
2021
private var processSeqN = 0
2122
private val cmds: List<String> by lazy {
22-
val debugCmd =
23-
listOfNotNull(DEBUG_RUN_CMD.takeIf { Settings.runChildProcessWithDebug} )
24-
25-
val javaVersionSpecificArguments =
26-
listOf("--add-opens", "java.base/jdk.internal.misc=ALL-UNNAMED", "--illegal-access=warn")
27-
.takeIf { JdkInfoService.provide().version > 8 }
28-
?: emptyList()
29-
23+
val debugCmd = listOfNotNull(DEBUG_RUN_CMD.takeIf { Settings.runChildProcessWithDebug })
24+
val javaVersionSpecificArguments = OpenModulesContainer.javaVersionSpecificArguments
3025
val pathToJava = JdkInfoService.provide().path
3126

32-
listOf(pathToJava.resolve("bin${File.separatorChar}java").toString()) +
27+
listOf(pathToJava.resolve("bin${File.separatorChar}${osSpecificJavaExecutable()}").toString()) +
3328
debugCmd +
3429
javaVersionSpecificArguments +
3530
listOf("-javaagent:$jarFile", "-ea", "-jar", "$jarFile")
3631
}
3732

3833
var errorLogFile: File = NULL_FILE
3934

40-
fun start(port: Int): Process {
41-
val portArgument = rdPortArgument(port)
35+
fun start(rdPort: Int): Process {
36+
val portArgument = rdPortArgument(rdPort)
4237

4338
logger.debug { "Starting child process: ${cmds.joinToString(" ")} $portArgument" }
4439
processSeqN++
@@ -54,6 +49,9 @@ class ChildProcessRunner {
5449
if (!UtSettings.useSandbox) {
5550
add(DISABLE_SANDBOX_OPTION)
5651
}
52+
if (UtSettings.logConcreteExecutionErrors) {
53+
add(logLevelArgument(UtSettings.childProcessLogLevel))
54+
}
5755
add(portArgument)
5856
}
5957

@@ -62,10 +60,10 @@ class ChildProcessRunner {
6260
.directory(directory)
6361

6462
return processBuilder.start().also {
65-
logger.debug { "Process started with PID=${it.getPid}" }
63+
logger.info { "Process started with PID=${it.getPid}" }
6664

6765
if (UtSettings.logConcreteExecutionErrors) {
68-
logger.debug { "Child process error log: ${errorLogFile.absolutePath}" }
66+
logger.info { "Child process error log: ${errorLogFile.absolutePath}" }
6967
}
7068
}
7169
}
@@ -75,7 +73,7 @@ class ChildProcessRunner {
7573
private const val ERRORS_FILE_PREFIX = "utbot-childprocess-errors"
7674
private const val INSTRUMENTATION_LIB = "lib"
7775

78-
private const val DEBUG_RUN_CMD = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=5005"
76+
private const val DEBUG_RUN_CMD = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=5006"
7977

8078
private val UT_BOT_TEMP_DIR: File = File(utBotTempDirectory.toFile(), ERRORS_FILE_PREFIX)
8179

‎utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import org.utbot.framework.plugin.api.CodegenLanguage
5454
import org.utbot.intellij.plugin.models.GenerateTestsModel
5555
import org.utbot.intellij.plugin.models.packageName
5656
import org.utbot.intellij.plugin.process.EngineProcess
57-
import org.utbot.intellij.plugin.process.RdGTestenerationResult
57+
import org.utbot.intellij.plugin.process.RdTestGenerationResult
5858
import org.utbot.intellij.plugin.sarif.SarifReportIdea
5959
import org.utbot.intellij.plugin.sarif.SourceFindingStrategyIdea
6060
import org.utbot.intellij.plugin.ui.*
@@ -83,7 +83,7 @@ object CodeGenerationController {
8383

8484
fun generateTests(
8585
model: GenerateTestsModel,
86-
classesWithTests: Map<PsiClass, RdGTestenerationResult>,
86+
classesWithTests: Map<PsiClass, RdTestGenerationResult>,
8787
psi2KClass: Map<PsiClass, ClassId>,
8888
proc: EngineProcess
8989
) {

‎utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt‎

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import org.utbot.intellij.plugin.generator.CodeGenerationController.generateTest
3636
import org.utbot.intellij.plugin.models.GenerateTestsModel
3737
import org.utbot.intellij.plugin.models.packageName
3838
import org.utbot.intellij.plugin.process.EngineProcess
39-
import org.utbot.intellij.plugin.process.RdGTestenerationResult
39+
import org.utbot.intellij.plugin.process.RdTestGenerationResult
4040
import org.utbot.intellij.plugin.settings.Settings
4141
import org.utbot.intellij.plugin.ui.GenerateTestsDialogWindow
4242
import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
@@ -46,7 +46,6 @@ import org.utbot.intellij.plugin.ui.utils.testModules
4646
import org.utbot.intellij.plugin.util.*
4747
import org.utbot.rd.terminateOnException
4848
import java.io.File
49-
import java.net.URLClassLoader
5049
import java.nio.file.Path
5150
import java.nio.file.Paths
5251
import java.util.concurrent.TimeUnit
@@ -133,12 +132,12 @@ object UtTestsDialogProcessor {
133132

134133
val (buildDirs, classpath, classpathList, pluginJarsPath) = buildPaths
135134

136-
val testSetsByClass = mutableMapOf<PsiClass, RdGTestenerationResult>()
135+
val testSetsByClass = mutableMapOf<PsiClass, RdTestGenerationResult>()
137136
val psi2KClass = mutableMapOf<PsiClass, ClassId>()
138137
var processedClasses = 0
139138
val totalClasses = model.srcClasses.size
140139

141-
val proc = EngineProcess(lifetime)
140+
val proc = EngineProcess(lifetime, project)
142141

143142
proc.setupUtContext(buildDirs + classpathList)
144143
proc.createTestGenerator(
@@ -280,10 +279,6 @@ object UtTestsDialogProcessor {
280279
appendLine("Alternatively, you could try to increase current timeout $timeout sec for generating tests in generation dialog.")
281280
}
282281

283-
284-
private fun urlClassLoader(classpath: List<String>) =
285-
URLClassLoader(classpath.map { File(it).toURI().toURL() }.toTypedArray())
286-
287282
private fun findSrcModule(srcClasses: Set<PsiClass>): Module {
288283
val srcModules = srcClasses.mapNotNull { it.module }.distinct()
289284
return when (srcModules.size) {

‎utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt‎

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
package org.utbot.intellij.plugin.process
22

33
import com.intellij.ide.plugins.cl.PluginClassLoader
4-
import com.intellij.openapi.application.ApplicationManager
4+
import com.intellij.openapi.project.DumbService
5+
import com.intellij.openapi.project.Project
56
import com.intellij.psi.PsiMethod
67
import com.intellij.refactoring.util.classMembers.MemberInfo
78
import com.jetbrains.rd.util.lifetime.Lifetime
8-
import com.jetbrains.rd.util.lifetime.onTermination
99
import com.jetbrains.rd.util.lifetime.throwIfNotAlive
1010
import kotlinx.coroutines.runBlocking
1111
import kotlinx.coroutines.sync.Mutex
1212
import kotlinx.coroutines.sync.withLock
1313
import mu.KotlinLogging
14-
import org.jetbrains.kotlin.scripting.resolve.classId
1514
import org.utbot.common.AbstractSettings
1615
import org.utbot.common.getPid
16+
import org.utbot.common.osSpecificJavaExecutable
1717
import org.utbot.common.utBotTempDirectory
1818
import org.utbot.framework.UtSettings
1919
import org.utbot.framework.codegen.*
2020
import org.utbot.framework.codegen.model.UtilClassKind
21-
import org.utbot.framework.codegen.model.constructor.tree.TestsGenerationReport
2221
import org.utbot.framework.plugin.api.*
2322
import org.utbot.framework.plugin.services.JdkInfo
2423
import org.utbot.framework.plugin.services.JdkInfoDefaultProvider
2524
import org.utbot.framework.plugin.services.JdkInfoService
2625
import org.utbot.framework.plugin.services.WorkingDirService
26+
import org.utbot.framework.process.OpenModulesContainer
2727
import org.utbot.framework.process.generated.*
2828
import org.utbot.framework.process.generated.Signature
2929
import org.utbot.framework.util.Conflict
@@ -39,85 +39,77 @@ import org.utbot.rd.startUtProcessWithRdServer
3939
import org.utbot.sarif.SourceFindingStrategy
4040
import java.io.File
4141
import java.nio.file.Path
42-
import java.util.*
42+
import kotlin.io.path.deleteIfExists
4343
import kotlin.io.path.pathString
4444
import kotlin.random.Random
4545
import kotlin.reflect.KProperty1
4646
import kotlin.reflect.full.memberProperties
4747

48+
private val engineProcessLogConfigurations = utBotTempDirectory.toFile().resolve("rdEngineProcessLogConfigurations")
4849
private val logger = KotlinLogging.logger {}
4950
private val engineProcessLogDirectory = utBotTempDirectory.toFile().resolve("rdEngineProcessLogs")
5051

51-
data class RdGTestenerationResult(val notEmptyCases: Int, val testSetsId: Long)
52+
data class RdTestGenerationResult(val notEmptyCases: Int, val testSetsId: Long)
5253

53-
class EngineProcess(val lifetime: Lifetime) {
54+
class EngineProcess(parent: Lifetime, val project: Project) {
55+
private val ldef = parent.createNested()
5456
private val id = Random.nextLong()
5557
private var count = 0
58+
private var configPath: Path? = null
5659

57-
companion object {
58-
private var configPath: Path? = null
59-
private fun getOrCreateLogConfig(): String {
60-
var realPath = configPath
61-
if (realPath == null) {
62-
synchronized(this) {
63-
realPath = configPath
64-
if (realPath == null) {
65-
utBotTempDirectory.toFile().mkdirs()
66-
configPath = utBotTempDirectory.toFile().resolve("EngineProcess_log4j2.xml").apply {
67-
writeText(
68-
"""<?xml version="1.0" encoding="UTF-8"?>
60+
private fun getOrCreateLogConfig(): String {
61+
var realPath = configPath
62+
if (realPath == null) {
63+
engineProcessLogConfigurations.mkdirs()
64+
configPath = File.createTempFile("epl", ".xml", engineProcessLogConfigurations).apply {
65+
val onMatch = if (UtSettings.logConcreteExecutionErrors) "NEUTRAL" else "DENY"
66+
writeText(
67+
"""<?xml version="1.0" encoding="UTF-8"?>
6968
<Configuration>
7069
<Appenders>
7170
<Console name="Console" target="SYSTEM_OUT">
72-
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="DENY"/>
71+
<ThresholdFilter level="${UtSettings.engineProcessLogLevel.name.uppercase()}" onMatch="$onMatch" onMismatch="DENY"/>
7372
<PatternLayout pattern="%d{HH:mm:ss.SSS} | %-5level | %c{1} | %msg%n"/>
7473
</Console>
7574
</Appenders>
7675
<Loggers>
77-
<Root level="error">
76+
<Root level="${UtSettings.engineProcessLogLevel.name.lowercase()}">
7877
<AppenderRef ref="Console"/>
7978
</Root>
8079
</Loggers>
8180
</Configuration>"""
82-
)
83-
}.toPath()
84-
realPath = configPath
85-
}
86-
}
87-
}
88-
return realPath!!.pathString
81+
)
82+
}.toPath()
83+
realPath = configPath
8984
}
85+
return realPath!!.pathString
9086
}
91-
// because we cannot load idea bundled lifetime or it will break everything
9287

9388
private fun debugArgument(): String {
9489
return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,quiet=y,address=5005".takeIf { Settings.runIdeaProcessWithDebug }
9590
?: ""
9691
}
9792

98-
private val kryoHelper = KryoHelper(lifetime)
93+
private val kryoHelper = KryoHelper(ldef)
9994

10095
private suspend fun engineModel(): EngineProcessModel {
101-
lifetime.throwIfNotAlive()
96+
ldef.throwIfNotAlive()
10297
return lock.withLock {
10398
var proc = current
10499

105100
if (proc == null) {
106-
proc = startUtProcessWithRdServer(lifetime) { port ->
101+
proc = startUtProcessWithRdServer(ldef) { port ->
107102
val current = JdkInfoDefaultProvider().info
108103
val required = JdkInfoService.jdkInfoProvider.info
109104
val java =
110-
JdkInfoService.jdkInfoProvider.info.path.resolve("bin${File.separatorChar}javaw").toString()
105+
JdkInfoService.jdkInfoProvider.info.path.resolve("bin${File.separatorChar}${osSpecificJavaExecutable()}").toString()
111106
val cp = (this.javaClass.classLoader as PluginClassLoader).classPath.baseUrls.joinToString(
112107
separator = ";",
113108
prefix = "\"",
114109
postfix = "\""
115110
)
116111
val classname = "org.utbot.framework.process.EngineMainKt"
117-
val javaVersionSpecificArguments =
118-
listOf("--add-opens", "java.base/jdk.internal.misc=ALL-UNNAMED", "--illegal-access=warn")
119-
.takeIf { JdkInfoService.provide().version > 8 }
120-
?: emptyList()
112+
val javaVersionSpecificArguments = OpenModulesContainer.javaVersionSpecificArguments
121113
val directory = WorkingDirService.provide().toFile()
122114
val log4j2ConfigFile = "\"-Dlog4j2.configurationFile=${getOrCreateLogConfig()}\""
123115
val debugArg = debugArgument()
@@ -172,7 +164,7 @@ class EngineProcess(val lifetime: Lifetime) {
172164
private var current: ProcessWithRdServer? = null
173165

174166
fun setupUtContext(classpathForUrlsClassloader: List<String>) = runBlocking {
175-
engineModel().setupUtContext.startSuspending(lifetime, SetupContextParams(classpathForUrlsClassloader))
167+
engineModel().setupUtContext.startSuspending(ldef, SetupContextParams(classpathForUrlsClassloader))
176168
}
177169

178170
// suppose that only 1 simultaneous test generator process can be executed in idea
@@ -186,7 +178,7 @@ class EngineProcess(val lifetime: Lifetime) {
186178
) = runBlocking {
187179
engineModel().isCancelled.set(handler = isCancelled)
188180
engineModel().createTestGenerator.startSuspending(
189-
lifetime,
181+
ldef,
190182
TestGeneratorParams(buildDir.toTypedArray(), classPath, dependencyPaths, JdkInfo(jdkInfo.path.pathString, jdkInfo.version))
191183
)
192184
}
@@ -238,9 +230,9 @@ class EngineProcess(val lifetime: Lifetime) {
238230
isFuzzingEnabled: Boolean,
239231
fuzzingValue: Double,
240232
searchDirectory: String
241-
): RdGTestenerationResult = runBlocking {
233+
): RdTestGenerationResult = runBlocking {
242234
val result = engineModel().generate.startSuspending(
243-
lifetime,
235+
ldef,
244236
GenerateParams(
245237
mockInstalled,
246238
staticsMockingIsConfigured,
@@ -257,7 +249,7 @@ class EngineProcess(val lifetime: Lifetime) {
257249
)
258250
)
259251

260-
return@runBlocking RdGTestenerationResult(result.notEmptyCases, result.testSetsId)
252+
return@runBlocking RdTestGenerationResult(result.notEmptyCases, result.testSetsId)
261253
}
262254

263255
fun render(
@@ -278,7 +270,7 @@ class EngineProcess(val lifetime: Lifetime) {
278270
testClassPackageName: String
279271
): Pair<String, UtilClassKind?> = runBlocking {
280272
val result = engineModel().render.startSuspending(
281-
lifetime, RenderParams(
273+
ldef, RenderParams(
282274
testSetsId,
283275
kryoHelper.writeObject(classUnderTest),
284276
kryoHelper.writeObject(paramNames),
@@ -300,9 +292,9 @@ class EngineProcess(val lifetime: Lifetime) {
300292
}
301293

302294
fun forceTermination() = runBlocking {
295+
configPath?.deleteIfExists()
303296
engineModel().stopProcess.start(Unit)
304297
current?.terminate()
305-
engineModel().writeSarifReport
306298
}
307299

308300
fun writeSarif(reportFilePath: Path,
@@ -312,23 +304,23 @@ class EngineProcess(val lifetime: Lifetime) {
312304
) = runBlocking {
313305
current!!.protocol.rdSourceFindingStrategy.let {
314306
it.getSourceFile.set { params ->
315-
ApplicationManager.getApplication().runReadAction<String?> {
307+
DumbService.getInstance(project).runReadActionInSmartMode<String?> {
316308
sourceFindingStrategy.getSourceFile(
317309
params.classFqn,
318310
params.extension
319311
)?.canonicalPath
320312
}
321313
}
322314
it.getSourceRelativePath.set { params ->
323-
ApplicationManager.getApplication().runReadAction<String> {
315+
DumbService.getInstance(project).runReadActionInSmartMode<String> {
324316
sourceFindingStrategy.getSourceRelativePath(
325317
params.classFqn,
326318
params.extension
327319
)
328320
}
329321
}
330322
it.testsRelativePath.set { _ ->
331-
ApplicationManager.getApplication().runReadAction<String> {
323+
DumbService.getInstance(project).runReadActionInSmartMode<String> {
332324
sourceFindingStrategy.testsRelativePath
333325
}
334326
}
@@ -374,8 +366,8 @@ class EngineProcess(val lifetime: Lifetime) {
374366
}
375367

376368
init {
377-
lifetime.onTermination {
378-
current?.terminate()
369+
ldef.onTermination {
370+
forceTermination()
379371
}
380372
}
381373
}

‎utbot-rd/src/main/kotlin/org/utbot/rd/ClientProcessUtil.kt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class ClientProtocolBuilder {
113113
private var timeout = Duration.INFINITE
114114

115115
suspend fun start(port: Int, parent: Lifetime? = null, bindables: Protocol.(CallsSynchronizer) -> Unit) {
116+
UtRdCoroutineScope.current // coroutine scope initialization
116117
val pid = currentProcessPid.toInt()
117118
val ldef = parent?.createNested() ?: LifetimeDefinition()
118119
ldef.terminateOnException { _ ->

‎utbot-rd/src/main/kotlin/org/utbot/rd/UtRdCoroutineScope.kt‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.jetbrains.rd.framework.util.RdCoroutineScope
44
import com.jetbrains.rd.framework.util.asCoroutineDispatcher
55
import com.jetbrains.rd.util.lifetime.Lifetime
66

7+
private val coroutineDispatcher = UtSingleThreadScheduler("UtCoroutineScheduler").asCoroutineDispatcher
8+
79
class UtRdCoroutineScope(lifetime: Lifetime) : RdCoroutineScope(lifetime) {
810
companion object {
911
val current = UtRdCoroutineScope(Lifetime.Eternal)
@@ -13,5 +15,5 @@ class UtRdCoroutineScope(lifetime: Lifetime) : RdCoroutineScope(lifetime) {
1315
override(lifetime, this)
1416
}
1517

16-
override val defaultDispatcher = UtSingleThreadScheduler("UtCoroutineScheduler").asCoroutineDispatcher
18+
override val defaultDispatcher = coroutineDispatcher
1719
}

0 commit comments

Comments
 (0)
Please sign in to comment.