diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/JcToUtExecutionConverter.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/JcToUtExecutionConverter.kt index 7d97a082cd..adab60cc8f 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/JcToUtExecutionConverter.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/JcToUtExecutionConverter.kt @@ -56,18 +56,17 @@ class JcToUtExecutionConverter( private val toValueConverter = Descriptor2ValueConverter(utContext.classLoader) private var jcToUtModelConverter: JcToUtModelConverter + private var uTestProcessResult: UTestAnalysisResult init { - val instToModelConverter = UTestInstToUtModelConverter(idGenerator, jcClasspath, utilMethodProvider) - - instToModelConverter.processUTest(jcExecution.uTest) + val instToModelConverter = UTestInstToUtModelConverter(jcExecution.uTest, jcClasspath, idGenerator, utilMethodProvider) jcToUtModelConverter = JcToUtModelConverter(idGenerator, jcClasspath, instToModelConverter) + + uTestProcessResult = instToModelConverter.processUTest() } fun convert(): UtExecution? { val coverage = convertCoverage(getTrace(jcExecution.uTestExecutionResult), jcExecution.method.enclosingType.jcClass) - // TODO usvm-sbft: fill up instrumentation with data from UTest - val instrumentation = emptyList() val utUsvmExecution: UtUsvmExecution = when (val executionResult = jcExecution.uTestExecutionResult) { is UTestExecutionSuccessResult -> UtUsvmExecution( @@ -78,7 +77,7 @@ class JcToUtExecutionConverter( jcToUtModelConverter.convert(it, EnvironmentStateKind.FINAL) } ?: UtVoidModel), coverage = coverage, - instrumentation = instrumentation, + instrumentation = uTestProcessResult.instrumentation, ) is UTestExecutionExceptionResult -> { UtUsvmExecution( @@ -89,7 +88,7 @@ class JcToUtExecutionConverter( jcExecution.method, ), coverage = coverage, - instrumentation = instrumentation, + instrumentation = uTestProcessResult.instrumentation, ) } diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/UTestInstToUtModelConverter.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/UTestInstToUtModelConverter.kt index 42634d0ff3..be2d579ed5 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/UTestInstToUtModelConverter.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/converter/UTestInstToUtModelConverter.kt @@ -36,6 +36,7 @@ import org.usvm.instrumentation.testcase.api.UTestStringExpression import org.utbot.framework.codegen.domain.builtin.UtilMethodProvider import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.FieldId +import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.UtArrayModel import org.utbot.framework.plugin.api.UtAssembleModel import org.utbot.framework.plugin.api.UtClassRefModel @@ -43,26 +44,29 @@ import org.utbot.framework.plugin.api.UtCompositeModel import org.utbot.framework.plugin.api.UtExecutableCallModel import org.utbot.framework.plugin.api.UtInstrumentation import org.utbot.framework.plugin.api.UtModel +import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation import org.utbot.framework.plugin.api.UtNullModel import org.utbot.framework.plugin.api.UtPrimitiveModel +import org.utbot.framework.plugin.api.UtStaticMethodInstrumentation import org.utbot.framework.plugin.api.util.classClassId import org.utbot.framework.plugin.api.util.objectClassId +import org.utbot.framework.plugin.api.util.voidClassId import org.utbot.fuzzer.IdGenerator class UTestInstToUtModelConverter( - private val idGenerator: IdGenerator, + private val uTest: UTest, private val jcClasspath: JcClasspath, + private val idGenerator: IdGenerator, private val utilMethodProvider: UtilMethodProvider, ) { private val exprToModelCache = mutableMapOf() private val instrumentations = mutableListOf() - fun processUTest(uTest: UTest) { - exprToModelCache.clear() - instrumentations.clear() - + fun processUTest(): UTestAnalysisResult { uTest.initStatements.forEach { uInst -> processInst(uInst) } removeInstantiationCallFromThisInstanceModificationChain(processExpr(uTest.callMethodExpression)) + + return UTestAnalysisResult(instrumentations) } fun findModelByInst(expr: UTestExpression): UtModel { @@ -301,7 +305,43 @@ class UTestInstToUtModelConverter( } is UTestGlobalMock -> { - // TODO usvm-sbft: collect instrumentations here + val methodsToExprs = uTestExpr.methods.entries + val initMethodExprs = methodsToExprs.filter { it.key.isConstructor } + val otherMethodsExprs = methodsToExprs.minus(initMethodExprs.toSet()) + + otherMethodsExprs + .forEach { (jcMethod, uTestExprs) -> + val methodId = jcMethod.toExecutableId(jcClasspath) as MethodId + val valueModels = uTestExprs.map { expr -> processExpr(expr) } + val methodInstrumentation = UtStaticMethodInstrumentation( + methodId = methodId, + values = valueModels, + ) + + instrumentations += methodInstrumentation + } + + initMethodExprs + .forEach { (jcMethod, uTestExprs) -> + // TODO usvm-sbft-merge: it can be .map { expr -> processExpr(expr) } here + // However, there's no special treatment for cases when method occurs in a global mock + val valueModels = uTestExprs.map { _ -> UtCompositeModel( + id=idGenerator.createId(), + classId = voidClassId, + isMock = true, + ) + } + val methodInstrumentation = UtNewInstanceInstrumentation( + classId = jcMethod.enclosingClass.classId, + instances = valueModels, + // [UTestGlobalMock] does not have an equivalent of [callSites], + // but it is used only in UtBot instrumentation. We use USVM one, so it is not a problem. + callSites = emptySet(), + ) + + instrumentations += methodInstrumentation + } + // UtClassRefModel is returned here for consistency with [Descriptor2ValueConverter] // which returns Class<*> instance for [UTestGlobalMock] descriptors. UtClassRefModel( @@ -320,4 +360,8 @@ class UTestInstToUtModelConverter( is UTestArrayLengthExpression -> error("This expression type is not supported") } } -} \ No newline at end of file +} + +data class UTestAnalysisResult( + val instrumentation: List, +) \ No newline at end of file