Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.FieldId
import org.utbot.framework.plugin.api.ConcreteContextLoadingResult
import org.utbot.framework.plugin.api.SpringRepositoryId
import org.utbot.framework.plugin.api.ExecutableId
import org.utbot.framework.plugin.api.util.UtContext
import org.utbot.framework.plugin.api.util.signature
import org.utbot.instrumentation.instrumentation.Instrumentation
import org.utbot.instrumentation.instrumentation.execution.ResultOfInstrumentation
import org.utbot.instrumentation.process.generated.ComputeStaticFieldParams
import org.utbot.instrumentation.process.generated.GetResultOfInstrumentationParams
import org.utbot.instrumentation.process.generated.GetSpringRepositoriesParams
import org.utbot.instrumentation.process.generated.InvokeMethodCommandParams
import org.utbot.instrumentation.rd.InstrumentedProcess
Expand Down Expand Up @@ -313,3 +316,12 @@ fun <T> ConcreteExecutor<*, *>.computeStaticField(fieldId: FieldId): Result<T> =
kryoHelper.readObject(result.result)
}
}

fun ConcreteExecutor<*, *>.getInstrumentationResult(methodUnderTest: ExecutableId): ResultOfInstrumentation =
runBlocking {
withProcess {
val params = GetResultOfInstrumentationParams(methodUnderTest.classId.name, methodUnderTest.signature)
val result = instrumentedProcessModel.getResultOfInstrumentation.startSuspending(lifetime, params)
kryoHelper.readObject(result.result)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ data class PutStaticInstruction(

private data class ClassToMethod(
val className: String,
val methodName: String
val methodSignature: String
)

class ProcessingStorage {
Expand All @@ -65,6 +65,8 @@ class ProcessingStorage {
private val instructionsData = mutableMapOf<Long, InstructionData>()
private val classToInstructionsCount = mutableMapOf<String, Long>()

private val methodIdToInstructionsIds = mutableMapOf<Int, MutableList<Long>>()

fun addClass(className: String): Int {
val id = classToId.getOrPut(className) { classToId.size }
idToClass.putIfAbsent(id, className)
Expand All @@ -75,8 +77,8 @@ class ProcessingStorage {
return classToId[className]!!.toLong() * SHIFT + localId
}

fun addClassMethod(className: String, methodName: String): Int {
val classToMethod = ClassToMethod(className, methodName)
fun addClassMethod(className: String, methodSignature: String): Int {
val classToMethod = ClassToMethod(className, methodSignature)
val id = classMethodToId.getOrPut(classToMethod) { classMethodToId.size }
idToClassMethod.putIfAbsent(id, classToMethod)
return id
Expand All @@ -88,10 +90,11 @@ class ProcessingStorage {
return className to localId
}

fun addInstruction(id: Long, instructionData: InstructionData) {
fun addInstruction(id: Long, methodId: Int, instructionData: InstructionData) {
instructionsData.computeIfAbsent(id) {
val (className, _) = computeClassNameAndLocalId(id)
classToInstructionsCount.merge(className, 1, Long::plus)
methodIdToInstructionsIds.getOrPut(methodId) { mutableListOf() }.add(id)
instructionData
}
}
Expand All @@ -103,6 +106,11 @@ class ProcessingStorage {
return instructionsData.getValue(id)
}

fun getInstructionsIds(className: String, methodSignature: String): List<Long>? {
val methodId = classMethodToId[ClassToMethod(className, methodSignature)]
return methodIdToInstructionsIds[methodId]
}

companion object {
private const val SHIFT = 1.toLong().shl(32) // 2 ^ 32
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class TraceListStrategy(
methodVisitor: MethodVisitor
) {
currentMethodSignature = name + descriptor
currentClassMethodId = storage.addClassMethod(className, name)
currentClassMethodId = storage.addClassMethod(className, currentMethodSignature)
}

override fun visitCode(mv: MethodVisitor, lvs: LocalVariablesSorter) {
Expand Down Expand Up @@ -74,7 +74,7 @@ class TraceListStrategy(

private fun processNewInstruction(mv: MethodVisitor, instructionData: InstructionData): MethodVisitor {
val id = nextId()
storage.addInstruction(id, instructionData)
storage.addInstruction(id, currentClassMethodId, instructionData)
return inserter.insertUtilityInstructions(mv, id)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class RemovingConstructFailsUtExecutionInstrumentation(
}
}

override fun getResultOfInstrumentation(className: String, methodSignature: String): ResultOfInstrumentation =
delegateInstrumentation.getResultOfInstrumentation(className, methodSignature)

private fun shallowlyRemoveFailingCalls(model: UtModel): UtModel = when {
model !is UtAssembleModel -> model
model.instantiationCall.thrownConcreteException != null -> model.classId.defaultValueModel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ class SimpleUtExecutionInstrumentation(
)
}

override fun getResultOfInstrumentation(className: String, methodSignature: String): ResultOfInstrumentation =
ResultOfInstrumentation(traceHandler.processingStorage.getInstructionsIds(className, methodSignature))

override fun getStaticField(fieldId: FieldId): Result<UtModel> =
delegateInstrumentation.getStaticField(fieldId).map { value ->
UtModelConstructor.createOnlyUserClassesConstructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ data class UtConcreteExecutionResult(
}
}

data class ResultOfInstrumentation(val instructionsIds: List<Long>?)

interface UtExecutionInstrumentation : Instrumentation<UtConcreteExecutionResult> {
override fun invoke(
clazz: Class<*>,
Expand All @@ -88,6 +90,8 @@ interface UtExecutionInstrumentation : Instrumentation<UtConcreteExecutionResult
phasesWrapper: PhasesController.(invokeBasePhases: () -> PreliminaryUtConcreteExecutionResult) -> PreliminaryUtConcreteExecutionResult
): UtConcreteExecutionResult

fun getResultOfInstrumentation(className: String, methodSignature: String): ResultOfInstrumentation

interface Factory<out TInstrumentation : UtExecutionInstrumentation> : Instrumentation.Factory<UtConcreteExecutionResult, TInstrumentation> {
override fun create(): TInstrumentation = create(SimpleInstrumentationContext())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.utbot.framework.plugin.api.util.SpringModelUtils.mockMvcPerformMethod
import org.utbot.framework.plugin.api.util.jClass
import org.utbot.framework.process.kryo.KryoHelper
import org.utbot.instrumentation.instrumentation.ArgumentList
import org.utbot.instrumentation.instrumentation.execution.ResultOfInstrumentation
import org.utbot.instrumentation.instrumentation.execution.PreliminaryUtConcreteExecutionResult
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
Expand Down Expand Up @@ -118,6 +119,9 @@ class SpringUtExecutionInstrumentation(
}
}

override fun getResultOfInstrumentation(className: String, methodSignature: String): ResultOfInstrumentation =
delegateInstrumentation.getResultOfInstrumentation(className, methodSignature)

override fun getStaticField(fieldId: FieldId): Result<*> = delegateInstrumentation.getStaticField(fieldId)

private fun getRelevantBeans(clazz: Class<*>): Set<String> = relatedBeansCache.getOrPut(clazz) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import org.utbot.framework.process.kryo.KryoHelper
import org.utbot.instrumentation.agent.Agent
import org.utbot.instrumentation.instrumentation.Instrumentation
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation
import org.utbot.instrumentation.process.generated.CollectCoverageResult
import org.utbot.instrumentation.process.generated.InstrumentedProcessModel
import org.utbot.instrumentation.process.generated.InvokeMethodCommandResult
import org.utbot.instrumentation.process.generated.instrumentedProcessModel
import org.utbot.instrumentation.process.generated.GetResultOfInstrumentationResult
import org.utbot.rd.IdleWatchdog
import org.utbot.rd.ClientProtocolBuilder
import org.utbot.rd.RdSettingsContainerFactory
Expand Down Expand Up @@ -146,6 +148,13 @@ private fun InstrumentedProcessModel.setup(kryoHelper: KryoHelper, watchdog: Idl
Agent.dynamicClassTransformer.addUserPaths(pathsToUserClasses)
instrumentation.run { setupAdditionalRdResponses(kryoHelper, watchdog) }
}
watchdog.measureTimeForActiveCall(getResultOfInstrumentation, "Getting instrumentation result") { params ->
HandlerClassesLoader.loadClass(params.className)
val result = (instrumentation as UtExecutionInstrumentation).getResultOfInstrumentation(
params.className, params.methodSignature
)
GetResultOfInstrumentationResult(kryoHelper.writeObject(result))
}
watchdog.measureTimeForActiveCall(addPaths, "User and dependency classpath setup") { params ->
pathsToUserClasses = params.pathsToUserClasses.split(File.pathSeparatorChar).toSet()
HandlerClassesLoader.addUrls(pathsToUserClasses)
Expand Down
Loading