Skip to content

Commit f071d40

Browse files
committed
[utbot-rd]
removed reflexion, proxied all reflection calls to another process, some fixes, removed test generation report, sarif generation proxied to another process, fixed logs
1 parent 51d5e92 commit f071d40

File tree

22 files changed

+889
-202
lines changed

22 files changed

+889
-202
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ object UtSettings : AbstractSettings(
264264
*
265265
* False by default (for saving disk space).
266266
*/
267-
var logConcreteExecutionErrors by getBooleanProperty(true)
267+
var logConcreteExecutionErrors by getBooleanProperty(false)
268268

269269
/**
270270
* Number of branch instructions using for clustering executions in the test minimization phase.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const val SYMBOLIC_NULL_ADDR: Int = 0
4646
data class UtMethodTestSet(
4747
val method: ExecutableId,
4848
val executions: List<UtExecution> = emptyList(),
49+
// in idea process this property is null
4950
val jimpleBody: JimpleBody? = null,
5051
val errors: Map<String, Int> = emptyMap(),
5152
val clustersInfo: List<Pair<UtClusterInfo?, IntRange>> = listOf(null to executions.indices)

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/CodeGenerator.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ data class CodeGeneratorResult(
121121
val generatedCode: String,
122122
// null if no util class needed, e.g. when we are generating utils directly into test class
123123
val utilClassKind: UtilClassKind?,
124+
// in idea process this property is null
124125
val testsGenerationReport: TestsGenerationReport?,
125126
)
126127

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.utbot.framework.plugin.api
2+
3+
import kotlin.reflect.KFunction
4+
import kotlin.reflect.KParameter
5+
import kotlin.reflect.jvm.javaType
6+
7+
fun KFunction<*>.signature() =
8+
Signature(this.name, this.parameters.filter { it.kind == KParameter.Kind.VALUE }.map { it.type.javaType.typeName })
9+
10+
data class Signature(val name: String, val parameterTypes: List<String?>) {
11+
12+
fun normalized() = this.copy(
13+
parameterTypes = parameterTypes.map {
14+
it?.replace("$", ".") // normalize names of nested classes
15+
}
16+
)
17+
}

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

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.utbot.framework.process
22

3+
import com.jetbrains.rd.framework.IProtocol
4+
import com.jetbrains.rd.framework.Protocol
35
import com.jetbrains.rd.util.Logger
46
import com.jetbrains.rd.util.info
57
import com.jetbrains.rd.util.lifetime.Lifetime
@@ -8,30 +10,42 @@ import kotlinx.coroutines.runBlocking
810
import mu.KotlinLogging
911
import org.utbot.analytics.AnalyticsConfigureUtil
1012
import org.utbot.common.AbstractSettings
13+
import org.utbot.common.allNestedClasses
1114
import org.utbot.engine.util.mockListeners.ForceMockListener
1215
import org.utbot.engine.util.mockListeners.ForceStaticMockListener
1316
import org.utbot.framework.codegen.*
1417
import org.utbot.framework.codegen.model.CodeGenerator
1518
import org.utbot.framework.plugin.api.*
19+
import org.utbot.framework.plugin.api.Signature
1620
import org.utbot.framework.plugin.api.util.UtContext
21+
import org.utbot.framework.plugin.api.util.executableId
22+
import org.utbot.framework.plugin.api.util.id
23+
import org.utbot.framework.plugin.api.util.jClass
1724
import org.utbot.framework.plugin.services.JdkInfo
1825
import org.utbot.framework.process.generated.*
1926
import org.utbot.framework.util.ConflictTriggers
2027
import org.utbot.framework.util.jimpleBody
2128
import org.utbot.instrumentation.util.KryoHelper
2229
import org.utbot.rd.CallsSynchronizer
2330
import org.utbot.rd.ClientProtocolBuilder
24-
import org.utbot.rd.awaitTermination
2531
import org.utbot.rd.findRdPort
2632
import org.utbot.rd.loggers.UtRdKLoggerFactory
33+
import org.utbot.sarif.RdSourceFindingStrategyFacade
34+
import org.utbot.sarif.SarifRegion
35+
import org.utbot.sarif.SarifReport
2736
import org.utbot.summary.summarize
2837
import soot.SootMethod
2938
import soot.UnitPatchingChain
3039
import soot.util.HashChain
3140
import java.io.File
3241
import java.net.URLClassLoader
42+
import java.nio.file.Path
3343
import java.nio.file.Paths
3444
import java.util.*
45+
import kotlin.reflect.KFunction
46+
import kotlin.reflect.KParameter
47+
import kotlin.reflect.full.functions
48+
import kotlin.reflect.jvm.javaType
3549
import kotlin.time.Duration.Companion.seconds
3650

3751
private val messageFromMainTimeoutMillis = 120.seconds
@@ -61,20 +75,22 @@ suspend fun main(args: Array<String>) = runBlocking {
6175

6276
ClientProtocolBuilder().withProtocolTimeout(messageFromMainTimeoutMillis).start(port) {
6377
settingsModel
78+
rdSourceFindingStrategy
79+
6480
AbstractSettings.setupFactory(RdSettingsContainerFactory(protocol))
6581
val kryoHelper = KryoHelper(lifetime).setup()
66-
67-
engineProcessModel.setup(kryoHelper, it)
82+
engineProcessModel.setup(kryoHelper, it, protocol)
6883
}
6984
logger.info { "runBlocking ending" }
7085
}.also {
7186
logger.info { "runBlocking ended" }
7287
}
88+
7389
private lateinit var testGenerator: TestCaseGenerator
90+
private lateinit var testSets: List<UtMethodTestSet>
7491

7592
private fun EngineProcessModel.setup(
76-
kryoHelper: KryoHelper,
77-
synchronizer: CallsSynchronizer
93+
kryoHelper: KryoHelper, synchronizer: CallsSynchronizer, realProtocol: IProtocol
7894
) {
7995
val model = this
8096
synchronizer.measureExecutionForTermination(setupUtContext) { params ->
@@ -96,8 +112,7 @@ private fun EngineProcessModel.setup(
96112
}
97113
synchronizer.measureExecutionForTermination(generate) { params ->
98114
val mockFrameworkInstalled = params.mockInstalled
99-
val conflictTriggers =
100-
ConflictTriggers(kryoHelper.readObject(params.conflictTriggers))
115+
val conflictTriggers = ConflictTriggers(kryoHelper.readObject(params.conflictTriggers))
101116
if (!mockFrameworkInstalled) {
102117
ForceMockListener.create(testGenerator, conflictTriggers)
103118
}
@@ -114,15 +129,25 @@ private fun EngineProcessModel.setup(
114129
isSymbolicEngineEnabled = params.isSymbolicEngineEnabled
115130
isFuzzingEnabled = params.isFuzzingEnabled
116131
fuzzingValue = params.fuzzingValue
117-
}).map { it.summarize(Paths.get(params.searchDirectory)) }
118-
.filterNot { it.executions.isEmpty() && it.errors.isEmpty() }.map {
132+
})
133+
.map { it.summarize(Paths.get(params.searchDirectory)) }
134+
.filterNot { it.executions.isEmpty() && it.errors.isEmpty() }
135+
.apply {
136+
testSets = this
137+
}
138+
.map {
139+
// kryo cannot serialize structures such as JimpleBody or Api.Step.stmt
140+
// because soot entities use classes and collections with complex initialization logic
141+
// which kryo cannot guess.
142+
// so in the idea process such entities will be either null or empty, operating on them supported only
143+
// in engine process.
144+
// jimpleBody can be obtained from executionId, logic for path and fullpath should be discussed
119145
it.copy(jimpleBody = null, executions = it.executions.map { execution ->
120146
if (execution is UtSymbolicExecution) execution.apply {
121147
path = mutableListOf()
122148
fullPath = mutableListOf()
123149
}
124-
else
125-
execution
150+
else execution
126151
})
127152
}
128153

@@ -154,12 +179,46 @@ private fun EngineProcessModel.setup(
154179
)
155180
RenderResult(
156181
kryoHelper.writeObject(
157-
codeGenerator.generateAsStringWithTestReport(
158-
kryoHelper.readObject<List<UtMethodTestSet>>(
159-
params.testSets
160-
).map { it.copy(jimpleBody = jimpleBody(it.method)) }).copy(testsGenerationReport = null)
182+
codeGenerator.generateAsStringWithTestReport(kryoHelper.readObject<List<UtMethodTestSet>>(
183+
params.testSets
184+
).map { it.copy(jimpleBody = jimpleBody(it.method)) })
185+
// currently due to moving engine out of idea process we cannot show test generation report
186+
// because it contains CgElements, which kryo cannot deserialize because they use complex collections
187+
// potentially it is possible to implement a lot of additional kryo serializers for that collections
188+
.copy(testsGenerationReport = null)
161189
)
162190
)
163191
}
164192
synchronizer.measureExecutionForTermination(stopProcess) { synchronizer.stopProtocol() }
165-
}
193+
synchronizer.measureExecutionForTermination(obtainClassId) { canonicalName ->
194+
kryoHelper.writeObject(UtContext.currentContext()!!.classLoader.loadClass(canonicalName).id)
195+
}
196+
synchronizer.measureExecutionForTermination(findMethodsInClassMatchingSelected) { params ->
197+
val classId = kryoHelper.readObject<ClassId>(params.classId)
198+
val selectedSignatures = params.signatures.map { Signature(it.name, it.parametersTypes) }
199+
FindMethodsInClassMatchingSelectedResult(kryoHelper.writeObject(classId.jClass.kotlin.allNestedClasses.flatMap { clazz ->
200+
clazz.functions.sortedWith(compareBy { selectedSignatures.indexOf(it.signature()) })
201+
.filter { it.signature().normalized() in selectedSignatures }
202+
.map { it.executableId }
203+
}))
204+
}
205+
synchronizer.measureExecutionForTermination(findMethodParamNames) { params ->
206+
val classId = kryoHelper.readObject<ClassId>(params.classId)
207+
val bySignature = kryoHelper.readObject<Map<Signature, List<String>>>(params.bySignature)
208+
FindMethodParamNamesResult(kryoHelper.writeObject(
209+
classId.jClass.kotlin.allNestedClasses.flatMap { it.functions }
210+
.mapNotNull { method -> bySignature[method.signature()]?.let { params -> method.executableId to params } }
211+
.toMap()
212+
))
213+
}
214+
synchronizer.measureExecutionForTermination(writeSarifReport) { params ->
215+
val reportFilePath = Paths.get(params.reportFilePath)
216+
reportFilePath.toFile().writeText(
217+
SarifReport(
218+
testSets,
219+
params.generatedTestsCode,
220+
RdSourceFindingStrategyFacade(realProtocol.rdSourceFindingStrategy)
221+
).createReport()
222+
)
223+
}
224+
}

utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/.rdgen

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)