Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[rd-factoring]
review fix
  • Loading branch information
Domonion committed Nov 25, 2022
commit 9019740f02140a1da8222ac78b7712eed8501a41
2 changes: 1 addition & 1 deletion docs/RD for UnitTestBot.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Other processes ask this process for settings via RD RPC.

### Engine process

`TestCaseGenerator` and `UtBotSymbolicEngine` runs here. Process classpath contains all plugin jars(more precisely - it uses plugin classpath).
`TestCaseGenerator` and `UtBotSymbolicEngine` run here. Process classpath contains all plugin jars(more precisely - it uses plugin classpath).

___Must___ run on JDK, which uses project we analyze. Otherwise there will be numerous problems with code analysis, soot, reflection and
devirgention of generated code Java API.
Expand Down
4 changes: 2 additions & 2 deletions docs/contributing/InterProcessDebugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ For engine and instrumented processes you need to enable some options:
4. Additionally, you can set additional options for JDWP agent if debug is enabled:
* `engineProcessDebugPort` and `instrumentedProcessDebugPort` - port for debugging.
Default values - 5005 for Engine and 5006 for Instrumented processes.
* `engineProcessDebugSuspendPolicy` and `instrumentedProcessSuspendPolicy` - whether JDWP agent should
* `suspendEngineProcessExecutionInDebugMode` and `suspendInstrumentedProcessExecutionInDebugMode` - whether JDWP agent should
suspend process until debugger is connected.

More formally, if debug is enabled following switch is added to engine process JVM at start by default:
Expand All @@ -44,7 +44,7 @@ For engine and instrumented processes you need to enable some options:
```
runEngineProcessWithDebug=true
engineProcessDebugPort=12345
engineProcessDebugSuspendPolicy=false
suspendEngineProcessExecutionInDebugMode=false
```
result switch will be:
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private const val defaultKeyForSettingsPath = "utbot.settings.path"
/**
* Default concrete execution timeout (in milliseconds).
*/
const val DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS = 1000L
const val DEFAULT_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS = 1000L

object UtSettings : AbstractSettings(
logger, defaultKeyForSettingsPath, defaultSettingsPath
Expand Down Expand Up @@ -261,7 +261,7 @@ object UtSettings : AbstractSettings(
* Timeout for specific concrete execution (in milliseconds).
*/
var concreteExecutionTimeoutInInstrumentedProcess: Long by getLongProperty(
DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
DEFAULT_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
)

// region engine process debug
Expand All @@ -274,35 +274,39 @@ object UtSettings : AbstractSettings(
var engineProcessLogConfigFile by getStringProperty("")

/**
* Property useful only for idea
* If true - runs engine process with the ability to attach a debugger
* The property is useful only for the IntelliJ IDEs.
* If the property is set in true the engine process opens a debug port.
* @see runInstrumentedProcessWithDebug
* @see org.utbot.intellij.plugin.process.EngineProcess
Comment thread
Domonion marked this conversation as resolved.
*/
var runEngineProcessWithDebug by getBooleanProperty(false)

/**
* Port which will be used for debugging engine process
* The engine process JDWP agent's port of the instrumented process.
* A debugger attaches to the port in order to debug the process.
*/
var engineProcessDebugPort by getIntProperty(5005)

/**
* Whether engine process should suspend until debugger attached
* Value of the suspend mode for the JDWP agent of the engine process.
* If the value is true, the engine process will suspend until a debugger attaches to it.
*/
var engineProcessDebugSuspendPolicy by getBooleanProperty(true)
var suspendEngineProcessExecutionInDebugMode by getBooleanProperty(true)

// endregion

// region instrumented process debug
/**
* Port which will be used for debugging instrumented process
* The instrumented process JDWP agent's port of the instrumented process.
* A debugger attaches to the port in order to debug the process.
*/
var instrumentedProcessDebugPort by getIntProperty(5006)

/**
* Whether instrumented process should suspend until debugger attached
* Value of the suspend mode for the JDWP agent of the instrumented process.
* If the value is true, the instrumented process will suspend until a debugger attaches to it.
*/
var instrumentedProcessSuspendPolicy by getBooleanProperty(true)
var suspendInstrumentedProcessExecutionInDebugMode by getBooleanProperty(true)

/**
* If true, runs the instrumented process with the ability to attach a debugger.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import org.utbot.framework.plugin.services.JdkInfoService

object OpenModulesContainer {
private val modulesContainer: List<String>
val javaVersionSpecificArguments: List<String>?
val javaVersionSpecificArguments: List<String>
get() = modulesContainer
.takeIf { JdkInfoService.provide().version > 8 }
.takeIf { JdkInfoService.provide().version > 8 } ?: emptyList()

init {
modulesContainer = buildList {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.utbot.framework.codegen.domain

import org.utbot.framework.DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
import org.utbot.framework.DEFAULT_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
import org.utbot.framework.codegen.domain.builtin.mockitoClassId
import org.utbot.framework.codegen.domain.builtin.ongoingStubbingClassId
import org.utbot.framework.codegen.domain.models.CgClassId
Expand Down Expand Up @@ -581,7 +581,7 @@ data class HangingTestsTimeout(val timeoutMs: Long) {
constructor() : this(DEFAULT_TIMEOUT_MS)

companion object {
const val DEFAULT_TIMEOUT_MS = DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
const val DEFAULT_TIMEOUT_MS = DEFAULT_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
const val MIN_TIMEOUT_MS = 100L
const val MAX_TIMEOUT_MS = 1_000_000L
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p
val parametersByteArray = kryoHelper.writeObject(parameters)
val params = InvokeMethodCommandParams(className, signature, argumentsByteArray, parametersByteArray)

val ba = chidlProcessModel.invokeMethodCommand.startSuspending(lifetime, params).result
val ba = instrumentedProcessModel.invokeMethodCommand.startSuspending(lifetime, params).result
kryoHelper.readObject(ba)
}
} catch (e: Throwable) {
Expand Down Expand Up @@ -282,7 +282,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p
if (alive) {
try {
processInstance?.run {
chidlProcessModel.stopProcess.start(lifetime, Unit)
instrumentedProcessModel.stopProcess.start(lifetime, Unit)
}
} catch (_: Exception) {}
processInstance = null
Expand All @@ -296,7 +296,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p

fun ConcreteExecutor<*,*>.warmup() = runBlocking {
withProcess {
chidlProcessModel.warmup.start(lifetime, Unit)
instrumentedProcessModel.warmup.start(lifetime, Unit)
}
}

Expand All @@ -308,7 +308,7 @@ fun <T> ConcreteExecutor<*, *>.computeStaticField(fieldId: FieldId): Result<T> =
val fieldIdSerialized = kryoHelper.writeObject(fieldId)
val params = ComputeStaticFieldParams(fieldIdSerialized)

val result = chidlProcessModel.computeStaticField.startSuspending(lifetime, params)
val result = instrumentedProcessModel.computeStaticField.startSuspending(lifetime, params)

kryoHelper.readObject(result.result)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ fun ConcreteExecutor<Result<*>, CoverageInstrumentation>.collectCoverage(clazz:
withProcess {
val clazzByteArray = kryoHelper.writeObject(clazz)

kryoHelper.readObject(chidlProcessModel.collectCoverage.startSuspending(lifetime, CollectCoverageParams(clazzByteArray)).coverageInfo)
kryoHelper.readObject(instrumentedProcessModel.collectCoverage.startSuspending(lifetime, CollectCoverageParams(clazzByteArray)).coverageInfo)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private val logger = KotlinLogging.logger {}
class InstrumentedProcessRunner {
private val cmds: List<String> by lazy {
val debugCmd = listOfNotNull(DEBUG_RUN_CMD.takeIf { UtSettings.runInstrumentedProcessWithDebug })
val javaVersionSpecificArguments = OpenModulesContainer.javaVersionSpecificArguments ?: emptyList()
val javaVersionSpecificArguments = OpenModulesContainer.javaVersionSpecificArguments
val pathToJava = JdkInfoService.provide().path

listOf(pathToJava.resolve("bin${File.separatorChar}${osSpecificJavaExecutable()}").toString()) +
Expand Down Expand Up @@ -59,7 +59,7 @@ class InstrumentedProcessRunner {
}

companion object {
private fun suspendValue(): String = if (UtSettings.engineProcessDebugSuspendPolicy) "y" else "n"
private fun suspendValue(): String = if (UtSettings.suspendInstrumentedProcessExecutionInDebugMode) "y" else "n"

private const val UTBOT_INSTRUMENTATION = "utbot-instrumentation"
private const val ERRORS_FILE_PREFIX = "utbot-instrumentedprocess-errors"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class InstrumentedProcess private constructor(
val kryoHelper = KryoHelper(lifetime.createNested()).apply {
classLoader?.let { setKryoClassLoader(it) }
}
val chidlProcessModel: InstrumentedProcessModel = onSchedulerBlocking { protocol.instrumentedProcessModel }
val instrumentedProcessModel: InstrumentedProcessModel = onSchedulerBlocking { protocol.instrumentedProcessModel }

companion object {
suspend operator fun <TIResult, TInstrumentation : Instrumentation<TIResult>> invoke(
Expand Down Expand Up @@ -65,15 +65,15 @@ class InstrumentedProcess private constructor(
}

logger.trace("sending add paths")
proc.chidlProcessModel.addPaths.startSuspending(
proc.instrumentedProcessModel.addPaths.startSuspending(
proc.lifetime, AddPathsParams(
pathsToUserClasses,
pathsToDependencyClasses
)
)

logger.trace("sending instrumentation")
proc.chidlProcessModel.setInstrumentation.startSuspending(
proc.instrumentedProcessModel.setInstrumentation.startSuspending(
proc.lifetime, SetInstrumentationParams(
proc.kryoHelper.writeObject(instrumentation)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class EngineProcess private constructor(val project: Project, rdProcess: Process

private val log4j2ConfigSwitch = "-Dlog4j2.configurationFile=${log4j2ConfigFile.canonicalPath}"

private fun suspendValue(): String = if (UtSettings.engineProcessDebugSuspendPolicy) "y" else "n"
private fun suspendValue(): String = if (UtSettings.suspendEngineProcessExecutionInDebugMode) "y" else "n"

private val debugArgument: String?
get() = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=${suspendValue()},quiet=y,address=${UtSettings.engineProcessDebugPort}"
Expand All @@ -111,7 +111,10 @@ class EngineProcess private constructor(val project: Project, rdProcess: Process
private fun obtainEngineProcessCommandLine(port: Int) = buildList {
add(javaExecutablePathString.pathString)
add("-ea")
OpenModulesContainer.javaVersionSpecificArguments?.let { addAll(it) }
val javaVersionSpecificArgs = vaOpenModulesContainer.javaVersionSpecificArguments
if (javaVersionSpecificArgs.isNotEmpty()) {
addAll(it)
}
debugArgument?.let { add(it) }
add(log4j2ConfigSwitch)
add("-cp")
Expand Down
4 changes: 2 additions & 2 deletions utbot-rd/src/main/kotlin/org/utbot/rd/ClientProcessUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal fun childCreatedFileName(port: Int): String {
return "$port.created"
}

internal fun signalInstrumentedReady(port: Int) {
internal fun signalProcessReady(port: Int) {
processSyncDirectory.mkdirs()

val signalFile = File(processSyncDirectory, childCreatedFileName(port))
Expand Down Expand Up @@ -161,7 +161,7 @@ class ClientProtocolBuilder {
clientProtocol.block(synchronizer)
}

signalInstrumentedReady(port)
signalProcessReady(port)
logger.info { "signalled" }
clientProtocol.synchronizationModel.synchronizationSignal.let { sync ->
val answerFromMainProcess = sync.adviseForConditionAsync(ldef) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class RdSettingsContainer(val logger: KLogger, val key: String, val settingsMode
}

override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
throw NotImplementedError("Setting properties allowed only from plugin process")
throw IllegalStateException("Setting properties allowed only from plugin process")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class UtRdCoroutineScope(lifetime: Lifetime) : RdCoroutineScope(lifetime) {
companion object {
val current = UtRdCoroutineScope(Lifetime.Eternal)
fun initialize() {
// only to initialize load and initialize class
// only to load and initialize class
}
}

Expand Down
10 changes: 5 additions & 5 deletions utbot-rd/src/main/kotlin/org/utbot/rd/UtRdUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ suspend fun <T> ProcessWithRdServer.onScheduler(block: () -> T): T {

fun <T> ProcessWithRdServer.onSchedulerBlocking(block: () -> T): T = runBlocking { onScheduler(block) }

Comment thread
Domonion marked this conversation as resolved.

fun <TReq, TRes> IRdCall<TReq, TRes>.startBlocking(req: TReq): TRes {
val call = this
// We do not use RdCall.sync because it requires timeouts for execution, after which request will be stopped.
Expand Down Expand Up @@ -75,11 +74,12 @@ suspend fun <T> IScheduler.pump(lifetime: Lifetime, block: (Lifetime) -> T): T {
suspend fun <T> IScheduler.pump(block: (Lifetime) -> T): T = this.pump(Lifetime.Eternal, block)

/**
* Advises provided condition on source and returns Deferred,
* which will be completed when condition satisfied, or cancelled when provided lifetime terminated.
* If you don't need this condition no more - you can cancel deferred.
* Asynchronously checks the condition.
* The condition can be satisfied or canceled.
* As soon as the condition is checked, the lifetime is terminated.
* In order to cancel the calculation, use the function return value of Deferred type.
*
* N.B. in case you need timeout - wrap deferred in withTimeout coroutine builder
* @see kotlinx.coroutines.withTimeout coroutine builder in case you need cancel the calculation by timeout.
*/
fun <T> ISource<T>.adviseForConditionAsync(lifetime: Lifetime, condition: (T) -> Boolean): Deferred<Unit> {
Comment thread
Domonion marked this conversation as resolved.
val ldef = lifetime.createNested()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.utbot.rd.exceptions

/**
* This exception is designed to be thrown any time you start child process,
* but
*/
abstract class InstantProcessDeathException(private val debugPort: Int, private val isProcessDebug: Boolean) : Exception() {
Comment thread
Domonion marked this conversation as resolved.
override val message: String?
get() {
Expand Down