Skip to content

Commit c4ae051

Browse files
committed
[rd-refactoring]
Multiple refactorings and enhacements for process starting. Removed UtSettings.logConcreteExecutionErrors and UtSettings.engineProcessLogLevel switches. Logs for engine and concrete executor processes are always enabled. Switched log configuration to utbot-intellij/log4j2.xml. Use UtSettings#getIdeaProcessLogConfigFile from ~/.utbot/settings.properties to configure logs for engine and concrete executor processes without rebuilding plugin.
1 parent 4b9ca2d commit c4ae051

File tree

30 files changed

+557
-523
lines changed

30 files changed

+557
-523
lines changed

utbot-analytics/src/main/kotlin/org/utbot/visual/AbstractHtmlReport.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package org.utbot.visual
22

3+
import org.utbot.common.dateTimeFormatter
34
import java.time.LocalDateTime
45
import java.time.format.DateTimeFormatter
56

67

78
abstract class AbstractHtmlReport(bodyWidth: Int = 600) {
89
val builder = HtmlBuilder(bodyMaxWidth = bodyWidth)
910

10-
private val dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy_HH-mm-ss")
11-
1211
private fun nameWithDate() =
1312
"logs/Report_" + dateTimeFormatter.format(LocalDateTime.now()) + ".html"
1413

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ private val javaSpecificationVersion = System.getProperty("java.specification.ve
44
val isJvm8 = javaSpecificationVersion.equals("1.8")
55
val isJvm9Plus = !javaSpecificationVersion.contains(".") && javaSpecificationVersion.toInt() >= 9
66

7-
fun osSpecificJavaExecutable() = if (isWindows) "javaw" else "java"
7+
fun osSpecificJavaExecutable() = if (isWindows) "javaw" else "java"
8+
9+
const val engineProcessDebugPort = 5005
10+
const val childProcessDebugPort = 5006

utbot-core/src/main/kotlin/org/utbot/common/Logging.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,21 @@ package org.utbot.common
33
import mu.KLogger
44
import java.time.format.DateTimeFormatter
55

6-
val dateFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
6+
val timeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
7+
val dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy_HH-mm-ss")
78

89
class LoggerWithLogMethod(val logger: KLogger, val logMethod: (() -> Any?) -> Unit)
910

1011
fun KLogger.info(): LoggerWithLogMethod = LoggerWithLogMethod(this, this::info)
1112
fun KLogger.debug(): LoggerWithLogMethod = LoggerWithLogMethod(this, this::debug)
1213
fun KLogger.trace(): LoggerWithLogMethod = LoggerWithLogMethod(this, this::trace)
1314

14-
15-
/**
16-
*
17-
*/
1815
fun elapsedSecFrom(startNano: Long): String {
1916
val elapsedNano = System.nanoTime() - startNano
2017
val elapsedS = elapsedNano.toDouble() / 1_000_000_000
2118
return String.format("%.3f", elapsedS) + " sec"
2219
}
2320

24-
25-
2621
/**
2722
* Structured logging.
2823
*

utbot-core/src/main/kotlin/org/utbot/common/PathUtil.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ import java.util.*
1010

1111
object PathUtil {
1212

13+
fun String.toPathOrNull(): Path? = try {
14+
Paths.get(this)
15+
} catch (e: Throwable) {
16+
null
17+
}
18+
1319
/**
1420
* Creates a Path from the String.
1521
*/

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,24 +264,17 @@ object UtSettings : AbstractSettings(
264264
DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_CHILD_PROCESS_MS
265265
)
266266

267-
/**
268-
* Log level for engine process, which started in idea on generate tests action.
269-
*/
270-
var engineProcessLogLevel by getEnumProperty(LogLevel.Info)
271-
272267
/**
273268
* Log level for concrete executor process.
274269
*/
275270
var childProcessLogLevel by getEnumProperty(LogLevel.Info)
276271

277272
/**
278-
* Determines whether should errors from a child process be written to a log file or suppressed.
279-
* Note: being enabled, this option can highly increase disk usage when using ContestEstimator.
280-
*
281-
* False by default (for saving disk space).
273+
* Path to custom log4j2 configuration file for EngineProcess.
274+
* By default utbot-intellij/src/main/resources/log4j2.xml is used.
275+
* Also default value is used if provided value is not a file.
282276
*/
283-
var logConcreteExecutionErrors by getBooleanProperty(false)
284-
277+
var ideaProcessLogConfigFile by getStringProperty("")
285278

286279
/**
287280
* Property useful only for idea

utbot-framework-api/src/main/kotlin/org/utbot/framework/process/OpenModulesContainer.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import org.utbot.framework.plugin.services.JdkInfoService
44

55
object OpenModulesContainer {
66
private val modulesContainer: List<String>
7-
val javaVersionSpecificArguments: List<String>
7+
val javaVersionSpecificArguments: List<String>?
88
get() = modulesContainer
99
.takeIf { JdkInfoService.provide().version > 8 }
10-
?: emptyList()
1110

1211
init {
1312
modulesContainer = buildList {

utbot-framework-test/src/test/resources/log4j2.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
filePattern="logs/framework-%d{MM-dd-yyyy}.log.gz"
88
ignoreExceptions="false">
99

10-
<PatternLayout pattern=" | %-5level | %c{1} | %msg%n"/>
10+
<PatternLayout pattern="%d{HH:mm:ss.SSS} | %-5level | %-25c{1} | %msg%n"/>
1111
</File>
1212

1313
<Console name="Console" target="SYSTEM_OUT">
1414
<ThresholdFilter level="DEBUG" onMatch="NEUTRAL" onMismatch="DENY"/>
15-
<PatternLayout pattern="%d{HH:mm:ss.SSS} | %-5level | %c{1} | %msg%n"/>
15+
<PatternLayout pattern="%d{HH:mm:ss.SSS} | %-5level | %-25c{1} | %msg%n"/>
1616
</Console>
1717
</Appenders>
1818
<Loggers>

utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ open class TestCaseGenerator(
204204
method2controller.values.forEach { it.paused = true }
205205
controller.paused = false
206206

207-
logger.info { "|> Resuming method $method" }
207+
logger.info { "Resuming method $method" }
208208
val startTime = System.currentTimeMillis()
209209
while (controller.job!!.isActive &&
210210
(System.currentTimeMillis() - startTime) < executionTimeEstimator.timeslotForOneToplevelMethodTraversalInMillis

utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineMain.kt

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import org.utbot.framework.process.generated.*
3232
import org.utbot.framework.util.ConflictTriggers
3333
import org.utbot.instrumentation.instrumentation.instrumenter.Instrumenter
3434
import org.utbot.instrumentation.util.KryoHelper
35-
import org.utbot.rd.CallsSynchronizer
35+
import org.utbot.rd.IdleWatchdog
3636
import org.utbot.rd.ClientProtocolBuilder
3737
import org.utbot.rd.findRdPort
3838
import org.utbot.rd.loggers.UtRdKLoggerFactory
@@ -56,11 +56,7 @@ suspend fun main(args: Array<String>) = runBlocking {
5656
Logger.set(Lifetime.Eternal, UtRdKLoggerFactory(logger))
5757

5858
ClientProtocolBuilder().withProtocolTimeout(messageFromMainTimeoutMillis).start(port) {
59-
settingsModel
60-
rdSourceFindingStrategy
61-
rdInstrumenterAdapter
62-
63-
AbstractSettings.setupFactory(RdSettingsContainerFactory(protocol))
59+
AbstractSettings.setupFactory(RdSettingsContainerFactory(protocol.settingsModel))
6460
val kryoHelper = KryoHelper(lifetime)
6561
engineProcessModel.setup(kryoHelper, it, protocol)
6662
}
@@ -74,18 +70,16 @@ private val testSets: MutableMap<Long, List<UtMethodTestSet>> = mutableMapOf()
7470
private val testGenerationReports: MutableList<TestsGenerationReport> = mutableListOf()
7571
private var idCounter: Long = 0
7672

77-
private fun EngineProcessModel.setup(
78-
kryoHelper: KryoHelper, synchronizer: CallsSynchronizer, realProtocol: IProtocol
79-
) {
73+
private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatchdog, realProtocol: IProtocol) {
8074
val model = this
81-
synchronizer.measureExecutionForTermination(setupUtContext) { params ->
75+
watchdog.wrapActiveCall(setupUtContext) { params ->
8276
UtContext.setUtContext(UtContext(URLClassLoader(params.classpathForUrlsClassloader.map {
8377
File(it).toURI().toURL()
8478
}.toTypedArray())))
8579
}
86-
synchronizer.measureExecutionForTermination(createTestGenerator) { params ->
80+
watchdog.wrapActiveCall(createTestGenerator) { params ->
8781
AnalyticsConfigureUtil.configureML()
88-
Instrumenter.adapter = RdInstrumenter(realProtocol)
82+
Instrumenter.adapter = RdInstrumenter(realProtocol.rdInstrumenterAdapter)
8983
testGenerator = TestCaseGenerator(buildDirs = params.buildDir.map { Paths.get(it) },
9084
classpath = params.classpath,
9185
dependencyPaths = params.dependencyPaths,
@@ -96,7 +90,7 @@ private fun EngineProcessModel.setup(
9690
}
9791
})
9892
}
99-
synchronizer.measureExecutionForTermination(generate) { params ->
93+
watchdog.wrapActiveCall(generate) { params ->
10094
val mockFrameworkInstalled = params.mockInstalled
10195
val conflictTriggers = ConflictTriggers(kryoHelper.readObject(params.conflictTriggers))
10296
if (!mockFrameworkInstalled) {
@@ -126,7 +120,7 @@ private fun EngineProcessModel.setup(
126120
testSets[id] = result
127121
GenerateResult(result.size, id)
128122
}
129-
synchronizer.measureExecutionForTermination(render) { params ->
123+
watchdog.wrapActiveCall(render) { params ->
130124
val testFramework = testFrameworkByName(params.testFramework)
131125
val staticMocking = if (params.staticsMocking.startsWith("No")) {
132126
NoStaticMocking
@@ -157,11 +151,11 @@ private fun EngineProcessModel.setup(
157151
RenderResult(it.generatedCode, it.utilClassKind?.javaClass?.simpleName)
158152
}
159153
}
160-
synchronizer.measureExecutionForTermination(stopProcess) { synchronizer.stopProtocol() }
161-
synchronizer.measureExecutionForTermination(obtainClassId) { canonicalName ->
154+
watchdog.wrapActiveCall(stopProcess) { watchdog.stopProtocol() }
155+
watchdog.wrapActiveCall(obtainClassId) { canonicalName ->
162156
kryoHelper.writeObject(UtContext.currentContext()!!.classLoader.loadClass(canonicalName).id)
163157
}
164-
synchronizer.measureExecutionForTermination(findMethodsInClassMatchingSelected) { params ->
158+
watchdog.wrapActiveCall(findMethodsInClassMatchingSelected) { params ->
165159
val classId = kryoHelper.readObject<ClassId>(params.classId)
166160
val selectedSignatures = params.signatures.map { Signature(it.name, it.parametersTypes) }
167161
FindMethodsInClassMatchingSelectedResult(kryoHelper.writeObject(classId.jClass.allNestedClasses.flatMap { clazz ->
@@ -170,7 +164,7 @@ private fun EngineProcessModel.setup(
170164
.map { it.executableId }
171165
}))
172166
}
173-
synchronizer.measureExecutionForTermination(findMethodParamNames) { params ->
167+
watchdog.wrapActiveCall(findMethodParamNames) { params ->
174168
val classId = kryoHelper.readObject<ClassId>(params.classId)
175169
val bySignature = kryoHelper.readObject<Map<Signature, List<String>>>(params.bySignature)
176170
FindMethodParamNamesResult(kryoHelper.writeObject(
@@ -179,7 +173,7 @@ private fun EngineProcessModel.setup(
179173
.toMap()
180174
))
181175
}
182-
synchronizer.measureExecutionForTermination(writeSarifReport) { params ->
176+
watchdog.wrapActiveCall(writeSarifReport) { params ->
183177
val reportFilePath = Paths.get(params.reportFilePath)
184178
reportFilePath.parent.toFile().mkdirs()
185179
val sarifReport = SarifReport(
@@ -190,12 +184,12 @@ private fun EngineProcessModel.setup(
190184
reportFilePath.toFile().writeText(sarifReport)
191185
sarifReport
192186
}
193-
synchronizer.measureExecutionForTermination(generateTestReport) { params ->
187+
watchdog.wrapActiveCall(generateTestReport) { params ->
194188
val eventLogMessage = params.eventLogMessage
195189
val testPackageName: String? = params.testPackageName
196190
var hasWarnings = false
197191
val reports = testGenerationReports
198-
if (reports.isEmpty()) return@measureExecutionForTermination GenerateTestReportResult("No tests were generated", null, true)
192+
if (reports.isEmpty()) return@wrapActiveCall GenerateTestReportResult("No tests were generated", null, true)
199193
val isMultiPackage = params.isMultiPackage
200194
val (notifyMessage, statistics) = if (reports.size == 1) {
201195
val report = reports.first()
Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,30 @@
11
package org.utbot.framework.process
22

3-
import com.jetbrains.rd.framework.IProtocol
43
import kotlinx.coroutines.runBlocking
54
import mu.KotlinLogging
5+
import org.utbot.common.logException
66
import org.utbot.framework.process.generated.ComputeSourceFileByClassArguments
7-
import org.utbot.framework.process.generated.rdInstrumenterAdapter
7+
import org.utbot.framework.process.generated.RdInstrumenterAdapter
88
import org.utbot.instrumentation.instrumentation.instrumenter.InstrumenterAdapter
9+
import org.utbot.rd.startBlocking
910
import java.io.File
1011
import java.nio.file.Path
1112

1213
private val logger = KotlinLogging.logger { }
1314

14-
class RdInstrumenter(private val protocol: IProtocol): InstrumenterAdapter() {
15+
class RdInstrumenter(private val rdInstrumenterAdapter: RdInstrumenterAdapter) : InstrumenterAdapter() {
1516
override fun computeSourceFileByClass(
1617
className: String,
1718
packageName: String?,
1819
directoryToSearchRecursively: Path
19-
): File? = runBlocking {
20+
): File? {
2021
logger.debug { "starting computeSourceFileByClass with classname - $className" }
21-
val result = try {
22-
protocol.rdInstrumenterAdapter.computeSourceFileByClass.startSuspending(
23-
ComputeSourceFileByClassArguments(
24-
className,
25-
packageName
26-
)
27-
)
28-
}
29-
catch(e: Exception) {
30-
logger.error(e) { "error during computeSourceFileByClass" }
31-
throw e
22+
val result = logger.logException {
23+
val arguments = ComputeSourceFileByClassArguments(className, packageName)
24+
25+
rdInstrumenterAdapter.computeSourceFileByClass.startBlocking(arguments)
3226
}
33-
logger.debug { "computeSourceFileByClass result for $className from idea: $result"}
34-
return@runBlocking result?.let { File(it) }
27+
logger.debug { "computeSourceFileByClass result for $className from idea: $result" }
28+
return result?.let { File(it) }
3529
}
3630
}

utbot-framework/src/main/kotlin/org/utbot/framework/process/RdSettingsContainer.kt

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

3-
import com.jetbrains.rd.framework.IProtocol
43
import kotlinx.coroutines.runBlocking
54
import mu.KLogger
65
import org.utbot.common.SettingsContainer
76
import org.utbot.common.SettingsContainerFactory
87
import org.utbot.framework.process.generated.SettingForArgument
9-
import org.utbot.framework.process.generated.settingsModel
8+
import org.utbot.framework.process.generated.SettingsModel
9+
import org.utbot.rd.startBlocking
1010
import kotlin.properties.PropertyDelegateProvider
1111
import kotlin.properties.ReadWriteProperty
1212
import kotlin.reflect.KProperty
1313

14-
class RdSettingsContainerFactory(private val protocol: IProtocol) : SettingsContainerFactory {
14+
class RdSettingsContainerFactory(private val settingsModel: SettingsModel) : SettingsContainerFactory {
1515
override fun createSettingsContainer(
1616
logger: KLogger,
1717
defaultKeyForSettingsPath: String,
1818
defaultSettingsPath: String?
1919
): SettingsContainer {
20-
return RdSettingsContainer(logger, defaultKeyForSettingsPath, protocol)
20+
return RdSettingsContainer(logger, defaultKeyForSettingsPath, settingsModel)
2121
}
2222
}
2323

24-
class RdSettingsContainer(val logger: KLogger, val key: String, val protocol: IProtocol): SettingsContainer {
24+
class RdSettingsContainer(val logger: KLogger, val key: String, val settingsModel: SettingsModel) : SettingsContainer {
2525

2626
override fun <T> settingFor(
2727
defaultValue: T,
2828
converter: (String) -> T
2929
): PropertyDelegateProvider<Any?, ReadWriteProperty<Any?, T>> {
30-
return PropertyDelegateProvider { _, prop ->
31-
object: ReadWriteProperty<Any?, T> {
32-
override fun getValue(thisRef: Any?, property: KProperty<*>): T = runBlocking {
33-
return@runBlocking protocol.settingsModel.settingFor.startSuspending(SettingForArgument(key, property.name)).value?.let {
30+
return PropertyDelegateProvider { _, _ ->
31+
object : ReadWriteProperty<Any?, T> {
32+
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
33+
val params = SettingForArgument(key, property.name)
34+
return settingsModel.settingFor.startBlocking(params).value?.let {
3435
converter(it)
3536
} ?: defaultValue
3637
}
3738

3839
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
39-
throw NotImplementedError("Setting properties from child process not supported")
40+
throw NotImplementedError("Setting properties allowed only from plugin process")
4041
}
4142
}
4243
}

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/ConcreteExecutor.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p
244244
val parametersByteArray = kryoHelper.writeObject(parameters)
245245
val params = InvokeMethodCommandParams(className, signature, argumentsByteArray, parametersByteArray)
246246

247-
val ba = protocolModel.invokeMethodCommand.startSuspending(lifetime, params).result
247+
val ba = chidlProcessModel.invokeMethodCommand.startSuspending(lifetime, params).result
248248
kryoHelper.readObject(ba)
249249
}
250250
} catch (e: Throwable) {
@@ -284,7 +284,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p
284284
if (alive) {
285285
try {
286286
processInstance?.run {
287-
protocolModel.stopProcess.start(lifetime, Unit)
287+
chidlProcessModel.stopProcess.start(lifetime, Unit)
288288
}
289289
} catch (_: Exception) {}
290290
processInstance = null
@@ -298,7 +298,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p
298298

299299
fun ConcreteExecutor<*,*>.warmup() = runBlocking {
300300
withProcess {
301-
protocolModel.warmup.start(lifetime, Unit)
301+
chidlProcessModel.warmup.start(lifetime, Unit)
302302
}
303303
}
304304

@@ -310,7 +310,7 @@ fun <T> ConcreteExecutor<*, *>.computeStaticField(fieldId: FieldId): Result<T> =
310310
val fieldIdSerialized = kryoHelper.writeObject(fieldId)
311311
val params = ComputeStaticFieldParams(fieldIdSerialized)
312312

313-
val result = protocolModel.computeStaticField.startSuspending(lifetime, params)
313+
val result = chidlProcessModel.computeStaticField.startSuspending(lifetime, params)
314314

315315
kryoHelper.readObject(result.result)
316316
}

0 commit comments

Comments
 (0)