Skip to content

Commit 4236987

Browse files
committed
Adding executionId to some models to differ them.
1 parent 8d7d740 commit 4236987

File tree

7 files changed

+89
-20
lines changed

7 files changed

+89
-20
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ open class CodeGenerator(
9090

9191
private fun generateForSimpleClass(testSets: List<CgMethodTestSet>): CodeGeneratorResult {
9292
val astConstructor = CgSimpleTestClassConstructor(context)
93-
val testClassModel = SimpleTestClassModelBuilder().createTestClassModel(classUnderTest, testSets)
93+
val testClassModel = SimpleTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets)
9494

9595
logger.info { "Code generation phase started at ${now()}" }
9696
val testClassFile = astConstructor.construct(testClassModel)
@@ -107,7 +107,7 @@ open class CodeGenerator(
107107

108108
private fun generateForSpringClass(testSets: List<CgMethodTestSet>): CodeGeneratorResult {
109109
val astConstructor = CgSpringTestClassConstructor(context)
110-
val testClassModel = SpringTestClassModelBuilder().createTestClassModel(classUnderTest, testSets)
110+
val testClassModel = SpringTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets)
111111

112112
logger.info { "Code generation phase started at ${now()}" }
113113
val testClassFile = astConstructor.construct(testClassModel)

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/Domain.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.utbot.framework.codegen.domain
33
import org.utbot.framework.DEFAULT_EXECUTION_TIMEOUT_IN_INSTRUMENTED_PROCESS_MS
44
import org.utbot.framework.codegen.domain.builtin.mockitoClassId
55
import org.utbot.framework.codegen.domain.builtin.ongoingStubbingClassId
6+
import org.utbot.framework.codegen.domain.context.CgContext
67
import org.utbot.framework.codegen.domain.models.CgClassId
78
import org.utbot.framework.codegen.tree.argumentsClassId
89
import org.utbot.framework.plugin.api.BuiltinClassId
@@ -11,6 +12,8 @@ import org.utbot.framework.plugin.api.CodeGenerationSettingBox
1112
import org.utbot.framework.plugin.api.CodeGenerationSettingItem
1213
import org.utbot.framework.plugin.api.MethodId
1314
import org.utbot.framework.plugin.api.TypeParameters
15+
import org.utbot.framework.plugin.api.UtModel
16+
import org.utbot.framework.plugin.api.idOrNull
1417
import org.utbot.framework.plugin.api.isolateCommandLineArgumentsToArgumentFile
1518
import org.utbot.framework.plugin.api.util.booleanArrayClassId
1619
import org.utbot.framework.plugin.api.util.booleanClassId
@@ -773,3 +776,17 @@ object SpringBoot : DependencyInjectionFramework(
773776
id = "spring-boot",
774777
displayName = "Spring Boot"
775778
)
779+
780+
/**
781+
* Extended id of [UtModel], unique for whole test set.
782+
*
783+
* Allows to distinguish models from different executions,
784+
* even if they have the same value of `UtModel.id`.
785+
*/
786+
data class ModelId(
787+
private val id: Int?,
788+
private val executionId: Int,
789+
)
790+
791+
fun UtModel.modelId(executionId: Int = -1): ModelId = ModelId(this.idOrNull(), executionId)
792+

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/context/CgContext.kt

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ import kotlinx.collections.immutable.PersistentSet
2222
import kotlinx.collections.immutable.persistentListOf
2323
import kotlinx.collections.immutable.persistentMapOf
2424
import kotlinx.collections.immutable.persistentSetOf
25+
import org.utbot.framework.codegen.domain.ModelId
2526
import org.utbot.framework.codegen.domain.ProjectType
2627
import org.utbot.framework.codegen.domain.models.CgMethodTestSet
2728
import org.utbot.framework.codegen.domain.builtin.TestClassUtilMethodProvider
2829
import org.utbot.framework.codegen.domain.builtin.UtilClassFileMethodProvider
2930
import org.utbot.framework.codegen.domain.builtin.UtilMethodProvider
3031
import org.utbot.framework.codegen.domain.models.SimpleTestClassModel
3132
import org.utbot.framework.codegen.domain.models.CgParameterKind
33+
import org.utbot.framework.codegen.domain.modelId
3234
import org.utbot.framework.codegen.services.access.Block
3335
import org.utbot.framework.codegen.tree.EnvironmentFieldStateCache
3436
import org.utbot.framework.codegen.tree.importIfNeeded
@@ -197,7 +199,7 @@ interface CgContextOwner {
197199
var valueByModel: IdentityHashMap<UtModel, CgValue>
198200

199201
// use it to compare stateBefore and result variables - in case of equality do not create new variable
200-
var valueByModelId: MutableMap<Int?, CgValue>
202+
var valueByModelId: MutableMap<ModelId, CgValue>
201203

202204
// parameters of the method currently being generated
203205
val currentMethodParameters: MutableMap<CgParameterKind, CgVariable>
@@ -226,6 +228,12 @@ interface CgContextOwner {
226228
*/
227229
var successfulExecutionsModels: List<UtModel>
228230

231+
/**
232+
* Gives a unique identifier to model in test set.
233+
* Determines which execution current model belongs to.
234+
*/
235+
var modelIds: Map<UtModel, ModelId>
236+
229237
fun block(init: () -> Unit): Block {
230238
val prevBlock = currentBlock
231239
return try {
@@ -311,7 +319,10 @@ interface CgContextOwner {
311319
model?.let {
312320
valueByModel[it] = variable
313321
(model as UtReferenceModel).let { refModel ->
314-
refModel.id.let { id -> valueByModelId[id] = variable }
322+
refModel.id.let {
323+
val modelId = getIdByModel(model)
324+
valueByModelId[modelId] = variable
325+
}
315326
}
316327
}
317328
}
@@ -428,6 +439,8 @@ interface CgContextOwner {
428439

429440
val getLambdaMethod: MethodId
430441
get() = utilMethodProvider.getLambdaMethodMethodId
442+
443+
fun getIdByModel(model: UtModel): ModelId
431444
}
432445

433446
/**
@@ -478,6 +491,7 @@ data class CgContext(
478491
override lateinit var statesCache: EnvironmentFieldStateCache
479492
override lateinit var actual: CgVariable
480493
override lateinit var successfulExecutionsModels: List<UtModel>
494+
override lateinit var modelIds: Map<UtModel, ModelId>
481495

482496
/**
483497
* This property cannot be accessed outside of test class file scope
@@ -556,6 +570,15 @@ data class CgContext(
556570
}
557571
}
558572

573+
override fun getIdByModel(model: UtModel): ModelId {
574+
if (model !in this.modelIds) {
575+
this.modelIds += model to model.modelId()
576+
}
577+
578+
return modelIds[model]
579+
?: error("ModelId for $model should have also been created")
580+
}
581+
559582
private fun createClassIdForNestedClass(testClassModel: SimpleTestClassModel): ClassId {
560583
val simpleName = "${testClassModel.classUnderTest.simpleName}Test"
561584
return BuiltinClassId(
@@ -580,7 +603,7 @@ data class CgContext(
580603

581604
override var valueByModel: IdentityHashMap<UtModel, CgValue> = IdentityHashMap()
582605

583-
override var valueByModelId: MutableMap<Int?, CgValue> = mutableMapOf()
606+
override var valueByModelId: MutableMap<ModelId, CgValue> = mutableMapOf()
584607

585608
override val currentMethodParameters: MutableMap<CgParameterKind, CgVariable> = mutableMapOf()
586609

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SimpleTestClassModelBuilder.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package org.utbot.framework.codegen.domain.models.builders
22

3+
import org.utbot.framework.codegen.domain.context.CgContext
34
import org.utbot.framework.codegen.domain.models.CgMethodTestSet
45
import org.utbot.framework.codegen.domain.models.SimpleTestClassModel
56
import org.utbot.framework.plugin.api.ClassId
67
import org.utbot.framework.plugin.api.util.enclosingClass
78

8-
open class SimpleTestClassModelBuilder: TestClassModelBuilder() {
9-
override fun createTestClassModel(classUnderTest: ClassId, testSets: List<CgMethodTestSet>): SimpleTestClassModel {
9+
open class SimpleTestClassModelBuilder(context: CgContext): TestClassModelBuilder() {
10+
override fun createTestClassModel(
11+
classUnderTest: ClassId,
12+
testSets: List<CgMethodTestSet>,
13+
): SimpleTestClassModel {
1014
// For each class stores list of methods declared in this class (methods from nested classes are excluded)
1115
val class2methodTestSets = testSets.groupBy { it.executableId.classId }
1216

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.utbot.framework.codegen.domain.models.builders
22

3+
import org.utbot.framework.codegen.domain.context.CgContext
34
import org.utbot.framework.codegen.domain.models.CgMethodTestSet
45
import org.utbot.framework.codegen.domain.models.SpringTestClassModel
6+
import org.utbot.framework.codegen.domain.modelId
57
import org.utbot.framework.plugin.api.ClassId
68
import org.utbot.framework.plugin.api.UtArrayModel
79
import org.utbot.framework.plugin.api.UtAssembleModel
@@ -17,10 +19,10 @@ import org.utbot.framework.plugin.api.UtPrimitiveModel
1719
import org.utbot.framework.plugin.api.UtVoidModel
1820
import org.utbot.framework.plugin.api.isMockModel
1921

20-
class SpringTestClassModelBuilder: TestClassModelBuilder() {
22+
class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder() {
2123

2224
override fun createTestClassModel(classUnderTest: ClassId, testSets: List<CgMethodTestSet>): SpringTestClassModel {
23-
val baseModel = SimpleTestClassModelBuilder().createTestClassModel(classUnderTest, testSets)
25+
val baseModel = SimpleTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets)
2426
val (injectedModels, mockedModels) = collectInjectedAndMockedModels(testSets)
2527

2628
return SpringTestClassModel(
@@ -39,14 +41,24 @@ class SpringTestClassModelBuilder: TestClassModelBuilder() {
3941
val thisInstancesDependentModels = mutableSetOf<UtModel>()
4042

4143
for (testSet in testSets) {
42-
for (execution in testSet.executions) {
43-
execution.stateBefore.thisInstance?.let { thisInstances += it }
44+
for ((index, execution) in testSet.executions.withIndex()) {
45+
execution.stateBefore.thisInstance?.let { model ->
46+
thisInstances += model
47+
context.modelIds += model to model.modelId(index)
48+
49+
val dependentModels = mutableSetOf<UtModel>()
50+
collectRecursively(model, dependentModels)
51+
52+
dependentModels.forEach { model ->
53+
context.modelIds += model to model.modelId(index)
54+
}
55+
thisInstancesDependentModels += dependentModels
56+
}
57+
4458
execution.stateAfter.thisInstance?.let { thisInstances += it }
4559
}
4660
}
4761

48-
thisInstances.forEach { model -> collectRecursively(model, thisInstancesDependentModels) }
49-
5062
val dependentMockModels =
5163
thisInstancesDependentModels.filterTo(mutableSetOf()) { it.isMockModel() && it !in thisInstances }
5264

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.utbot.framework.codegen.tree
22

33
import org.utbot.common.isStatic
4+
import org.utbot.framework.codegen.domain.ModelId
45
import org.utbot.framework.codegen.domain.builtin.forName
56
import org.utbot.framework.codegen.domain.builtin.setArrayElement
67
import org.utbot.framework.codegen.domain.context.CgContext
@@ -102,7 +103,9 @@ open class CgVariableConstructor(val context: CgContext) :
102103
open fun getOrCreateVariable(model: UtModel, name: String? = null): CgValue {
103104
// name could be taken from existing names, or be specified manually, or be created from generator
104105
val baseName = name ?: nameGenerator.nameFrom(model.classId)
105-
return if (model is UtReferenceModel) valueByModelId.getOrPut(model.id) {
106+
val modelId: ModelId = context.getIdByModel(model)
107+
108+
return if (model is UtReferenceModel) valueByModelId.getOrPut(modelId) {
106109
when (model) {
107110
is UtCompositeModel -> constructComposite(model, baseName)
108111
is UtAssembleModel -> constructAssemble(model, baseName)
@@ -172,7 +175,8 @@ open class CgVariableConstructor(val context: CgContext) :
172175
newVar(variableType, baseName) { utilsClassId[createInstance](model.classId.name) }
173176
}
174177

175-
valueByModelId[model.id] = obj
178+
val modelId = context.getIdByModel(model)
179+
valueByModelId[modelId] = obj
176180

177181
require(obj.type !is BuiltinClassId) {
178182
"Unexpected BuiltinClassId ${obj.type} found while constructing from composite model"
@@ -225,7 +229,8 @@ open class CgVariableConstructor(val context: CgContext) :
225229
}
226230
}
227231

228-
return valueByModelId.getValue(model.id)
232+
val modelId = context.getIdByModel(model)
233+
return valueByModelId.getValue(modelId)
229234
}
230235

231236
private fun processInstantiationStatement(
@@ -248,7 +253,10 @@ open class CgVariableConstructor(val context: CgContext) :
248253
}
249254
newVar(type, model, baseName) {
250255
initExpr
251-
}.also { valueByModelId[model.id] = it }
256+
}.also {
257+
val modelId = context.getIdByModel(model)
258+
valueByModelId[modelId] = it
259+
}
252260
}
253261

254262

@@ -345,7 +353,8 @@ open class CgVariableConstructor(val context: CgContext) :
345353
}
346354

347355
val array = newVar(arrayModel.classId, baseName) { initializer }
348-
valueByModelId[arrayModel.id] = array
356+
val arrayModelId = context.getIdByModel(arrayModel)
357+
valueByModelId[arrayModelId] = array
349358

350359
if (canInitWithValues) {
351360
return array

utbot-js/src/main/kotlin/framework/codegen/model/constructor/tree/JsCgVariableConstructor.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class JsCgVariableConstructor(ctx: CgContext) : CgVariableConstructor(ctx) {
3939
private val nameGenerator = CgComponents.getNameGeneratorBy(context)
4040

4141
override fun getOrCreateVariable(model: UtModel, name: String?): CgValue {
42-
return if (model is UtAssembleModel) valueByModelId.getOrPut(model.id) {
42+
val modelId: ModelId = context.getIdByModel(model)
43+
44+
return if (model is UtAssembleModel) valueByModelId.getOrPut(modelId) {
4345
// TODO SEVERE: May lead to unexpected behavior in case of changes to the original method
4446
super.getOrCreateVariable(model, name)
4547
} else valueByModel.getOrPut(model) {
@@ -128,7 +130,9 @@ class JsCgVariableConstructor(ctx: CgContext) : CgVariableConstructor(ctx) {
128130
}
129131

130132
val array = newVar(arrayModel.classId, baseName) { initializer }
131-
valueByModelId[arrayModel.id] = array
133+
val arrayModelId = context.getIdByModel(arrayModel)
134+
135+
valueByModelId[arrayModelId] = array
132136

133137
if (canInitWithValues) {
134138
return array

0 commit comments

Comments
 (0)