From 1fb52bb13b11b3241eb89de29fb5dc8a99e8b901 Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Thu, 16 Nov 2023 14:17:32 +0300 Subject: [PATCH 1/3] An attempt to support UTestGlobalMock in converters --- .../converter/JcToUtExecutionConverter.kt | 8 ++-- .../converter/UTestInstToUtModelConverter.kt | 37 ++++++++++++++++++- 2 files changed, 41 insertions(+), 4 deletions(-) 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..37b8766dee 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,20 @@ class JcToUtExecutionConverter( private val toValueConverter = Descriptor2ValueConverter(utContext.classLoader) private var jcToUtModelConverter: JcToUtModelConverter + private var instrumentation: List init { val instToModelConverter = UTestInstToUtModelConverter(idGenerator, jcClasspath, utilMethodProvider) - instToModelConverter.processUTest(jcExecution.uTest) + instToModelConverter.processUTest(jcExecution.uTest).also { + instrumentation = instToModelConverter.findInstrumentations() + } + jcToUtModelConverter = JcToUtModelConverter(idGenerator, jcClasspath, instToModelConverter) } 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( 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..8c044179c6 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 @@ -34,8 +34,10 @@ import org.usvm.instrumentation.testcase.api.UTestShortExpression import org.usvm.instrumentation.testcase.api.UTestStaticMethodCall import org.usvm.instrumentation.testcase.api.UTestStringExpression import org.utbot.framework.codegen.domain.builtin.UtilMethodProvider +import org.utbot.framework.plugin.api.ConstructorId 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,8 +45,10 @@ 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.fuzzer.IdGenerator @@ -71,6 +75,8 @@ class UTestInstToUtModelConverter( return alreadyCreatedModel } + fun findInstrumentations(): List = instrumentations + private fun removeInstantiationCallFromThisInstanceModificationChain(model: UtModel) { if (model is UtAssembleModel) { val instantiationCall = model.instantiationCall @@ -301,7 +307,36 @@ class UTestInstToUtModelConverter( } is UTestGlobalMock -> { - // TODO usvm-sbft: collect instrumentations here + // Daniil said that we can miss [type] and [fields] when converting to [UtInstrumentation] + val methodsToExprs = uTestExpr.methods.entries + + methodsToExprs + .filter { it.key is MethodId } + .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 + } + + methodsToExprs + .filter { it.key is ConstructorId } + .forEach { (jcMethod, uTestExprs) -> + val valueModels = uTestExprs.map { expr -> processExpr(expr) } + val methodInstrumentation = UtNewInstanceInstrumentation( + // TODO usvm-sbft looking at [Traverser] ln 1682, this classId does not seem correct + classId = jcMethod.enclosingClass.classId, + instances = valueModels, + callSites = setOf(jcMethod.enclosingClass.classId), + ) + + instrumentations += methodInstrumentation + } + // UtClassRefModel is returned here for consistency with [Descriptor2ValueConverter] // which returns Class<*> instance for [UTestGlobalMock] descriptors. UtClassRefModel( From 6f18f7a1f2fe4a69f2eee0bec5b9fd3dc47a796a Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Sat, 18 Nov 2023 15:40:06 +0300 Subject: [PATCH 2/3] Apply review fixes --- .../converter/JcToUtExecutionConverter.kt | 15 ++++----- .../converter/UTestInstToUtModelConverter.kt | 33 ++++++++++--------- 2 files changed, 23 insertions(+), 25 deletions(-) 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 37b8766dee..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,16 +56,13 @@ class JcToUtExecutionConverter( private val toValueConverter = Descriptor2ValueConverter(utContext.classLoader) private var jcToUtModelConverter: JcToUtModelConverter - private var instrumentation: List + private var uTestProcessResult: UTestAnalysisResult init { - val instToModelConverter = UTestInstToUtModelConverter(idGenerator, jcClasspath, utilMethodProvider) - - instToModelConverter.processUTest(jcExecution.uTest).also { - instrumentation = instToModelConverter.findInstrumentations() - } - + val instToModelConverter = UTestInstToUtModelConverter(jcExecution.uTest, jcClasspath, idGenerator, utilMethodProvider) jcToUtModelConverter = JcToUtModelConverter(idGenerator, jcClasspath, instToModelConverter) + + uTestProcessResult = instToModelConverter.processUTest() } fun convert(): UtExecution? { @@ -80,7 +77,7 @@ class JcToUtExecutionConverter( jcToUtModelConverter.convert(it, EnvironmentStateKind.FINAL) } ?: UtVoidModel), coverage = coverage, - instrumentation = instrumentation, + instrumentation = uTestProcessResult.instrumentation, ) is UTestExecutionExceptionResult -> { UtUsvmExecution( @@ -91,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 8c044179c6..0265dd5db8 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 @@ -34,7 +34,6 @@ import org.usvm.instrumentation.testcase.api.UTestShortExpression import org.usvm.instrumentation.testcase.api.UTestStaticMethodCall import org.usvm.instrumentation.testcase.api.UTestStringExpression import org.utbot.framework.codegen.domain.builtin.UtilMethodProvider -import org.utbot.framework.plugin.api.ConstructorId import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.FieldId import org.utbot.framework.plugin.api.MethodId @@ -54,19 +53,19 @@ import org.utbot.framework.plugin.api.util.objectClassId 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 { @@ -75,8 +74,6 @@ class UTestInstToUtModelConverter( return alreadyCreatedModel } - fun findInstrumentations(): List = instrumentations - private fun removeInstantiationCallFromThisInstanceModificationChain(model: UtModel) { if (model is UtAssembleModel) { val instantiationCall = model.instantiationCall @@ -307,11 +304,11 @@ class UTestInstToUtModelConverter( } is UTestGlobalMock -> { - // Daniil said that we can miss [type] and [fields] when converting to [UtInstrumentation] val methodsToExprs = uTestExpr.methods.entries + val initMethodExprs = methodsToExprs.filter { it.key.isConstructor } + val otherMethodsExprs = methodsToExprs.minus(initMethodExprs.toSet()) - methodsToExprs - .filter { it.key is MethodId } + otherMethodsExprs .forEach { (jcMethod, uTestExprs) -> val methodId = jcMethod.toExecutableId(jcClasspath) as MethodId val valueModels = uTestExprs.map { expr -> processExpr(expr) } @@ -323,15 +320,15 @@ class UTestInstToUtModelConverter( instrumentations += methodInstrumentation } - methodsToExprs - .filter { it.key is ConstructorId } + initMethodExprs .forEach { (jcMethod, uTestExprs) -> val valueModels = uTestExprs.map { expr -> processExpr(expr) } val methodInstrumentation = UtNewInstanceInstrumentation( - // TODO usvm-sbft looking at [Traverser] ln 1682, this classId does not seem correct classId = jcMethod.enclosingClass.classId, instances = valueModels, - callSites = setOf(jcMethod.enclosingClass.classId), + // [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 @@ -355,4 +352,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 From ddae79ac1c43ee62440495822921b3d705acd448 Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Wed, 22 Nov 2023 11:39:07 +0300 Subject: [PATCH 3/3] Corrected valueModels for global constructors mocks --- .../usvm/converter/UTestInstToUtModelConverter.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 0265dd5db8..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 @@ -50,6 +50,7 @@ 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( @@ -322,7 +323,14 @@ class UTestInstToUtModelConverter( initMethodExprs .forEach { (jcMethod, uTestExprs) -> - val valueModels = uTestExprs.map { expr -> processExpr(expr) } + // 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,