Skip to content

Commit 97f9ea0

Browse files
committed
Introduce utbot-modification-analyzer, use only methods that modify fields in Fuzzer
1 parent ddff0b0 commit 97f9ea0

File tree

23 files changed

+152
-82
lines changed

23 files changed

+152
-82
lines changed

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ rootProject.name = "utbot"
2828
include("utbot-core")
2929
include("utbot-framework")
3030
include("utbot-framework-api")
31+
include("utbot-modification-analyzer")
3132
include("utbot-intellij")
3233
include("utbot-sample")
3334
include("utbot-java-fuzzing")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.utbot.framework.util
2+
3+
import org.utbot.framework.plugin.api.ExecutableId
4+
import org.utbot.framework.plugin.api.classId
5+
import org.utbot.framework.plugin.api.id
6+
import org.utbot.framework.plugin.api.util.constructorId
7+
import org.utbot.framework.plugin.api.util.methodId
8+
import soot.SootMethod
9+
10+
/**
11+
* Gets method or constructor id of SootMethod.
12+
*/
13+
val SootMethod.executableId: ExecutableId
14+
get() = when {
15+
isConstructor -> constructorId(
16+
classId = declaringClass.id,
17+
arguments = parameterTypes.map { it.classId }.toTypedArray()
18+
)
19+
else -> methodId(
20+
classId = declaringClass.id,
21+
name = name,
22+
returnType = returnType.classId,
23+
arguments = parameterTypes.map { it.classId }.toTypedArray()
24+
)
25+
}

utbot-framework-test/src/test/kotlin/org/utbot/framework/modificators/UtBotFieldModificatorsTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import org.utbot.examples.modificators.StronglyConnectedComponents
1212
import org.utbot.examples.modificators.coupling.ClassA
1313
import org.utbot.examples.modificators.coupling.ClassB
1414
import org.utbot.examples.modificators.hierarchy.InheritedModifications
15-
import org.utbot.framework.modifications.AnalysisMode
16-
import org.utbot.framework.modifications.AnalysisMode.AllModificators
17-
import org.utbot.framework.modifications.AnalysisMode.SettersAndDirectAccessors
18-
import org.utbot.framework.modifications.UtBotFieldsModificatorsSearcher
15+
import org.utbot.modifications.AnalysisMode
16+
import org.utbot.modifications.AnalysisMode.AllModificators
17+
import org.utbot.modifications.AnalysisMode.SettersAndDirectAccessors
18+
import org.utbot.modifications.UtBotFieldsModificatorsSearcher
1919
import org.utbot.framework.plugin.api.util.UtContext
2020
import org.utbot.framework.plugin.api.util.id
2121
import kotlin.reflect.KClass
@@ -193,7 +193,7 @@ internal class UtBotFieldModificatorsTest {
193193

194194
//We use sorting here to make comparing with sorted in advance expected collections easier
195195
private fun runFieldModificatorsSearch(analysisMode: AnalysisMode) =
196-
fieldsModificatorsSearcher.findModificators(analysisMode)
196+
fieldsModificatorsSearcher.getFieldToModificators(analysisMode)
197197
.map { (key, value) ->
198198
val modificatorNames = value.filterNot { it.name.startsWith("direct_set_") }.map { it.name }
199199
key.name to modificatorNames.toSortedSet()

utbot-framework/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies {
1414
api project(':utbot-summary')
1515
api project(':utbot-framework-api')
1616
api project(':utbot-rd')
17+
api project(':utbot-modification-analyzer')
1718

1819
implementation group: 'com.jetbrains.rd', name: 'rd-framework', version: rdVersion
1920
implementation group: 'com.jetbrains.rd', name: 'rd-core', version: rdVersion

utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import org.utbot.framework.plugin.api.UtAssembleModel
1616
import org.utbot.framework.plugin.api.UtExecutableCallModel
1717
import org.utbot.framework.plugin.api.UtNullModel
1818
import org.utbot.framework.plugin.api.UtPrimitiveModel
19-
import org.utbot.framework.plugin.api.UtStatementModel
2019
import org.utbot.framework.plugin.api.classId
2120
import org.utbot.framework.plugin.api.id
2221
import org.utbot.framework.plugin.api.util.defaultValueModel

utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ import org.utbot.framework.plugin.api.UtExecutableCallModel
1313
import org.utbot.framework.plugin.api.UtModel
1414
import org.utbot.framework.plugin.api.UtNullModel
1515
import org.utbot.framework.plugin.api.UtPrimitiveModel
16-
import org.utbot.framework.plugin.api.UtStatementModel
1716
import org.utbot.framework.plugin.api.classId
1817
import org.utbot.framework.plugin.api.util.defaultValueModel
1918
import org.utbot.framework.plugin.api.util.doubleArrayClassId
2019
import org.utbot.framework.plugin.api.util.doubleClassId
2120
import org.utbot.framework.plugin.api.util.doubleStreamClassId
22-
import org.utbot.framework.plugin.api.util.id
2321
import org.utbot.framework.plugin.api.util.intArrayClassId
2422
import org.utbot.framework.plugin.api.util.intClassId
2523
import org.utbot.framework.plugin.api.util.intStreamClassId

utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import org.utbot.engine.ResolvedExecution
77
import org.utbot.engine.ResolvedModels
88
import org.utbot.framework.UtSettings
99
import org.utbot.framework.codegen.util.isAccessibleFrom
10-
import org.utbot.framework.modifications.AnalysisMode.SettersAndDirectAccessors
11-
import org.utbot.framework.modifications.ConstructorAnalyzer
12-
import org.utbot.framework.modifications.ConstructorAssembleInfo
13-
import org.utbot.framework.modifications.UtBotFieldsModificatorsSearcher
10+
import org.utbot.modifications.AnalysisMode.SettersAndDirectAccessors
11+
import org.utbot.modifications.ConstructorAnalyzer
12+
import org.utbot.modifications.ConstructorAssembleInfo
13+
import org.utbot.modifications.UtBotFieldsModificatorsSearcher
1414
import org.utbot.framework.plugin.api.ClassId
1515
import org.utbot.framework.plugin.api.ConstructorId
1616
import org.utbot.framework.plugin.api.DirectFieldAccessId
@@ -490,7 +490,7 @@ class AssembleModelGenerator(private val basePackageName: String) {
490490
* Finds setters and direct accessors for fields of particular class.
491491
*/
492492
private fun findSettersAndDirectAccessors(classId: ClassId): Map<FieldId, StatementId> {
493-
val allModificatorsOfClass = modificatorsSearcher.findModificators(SettersAndDirectAccessors)
493+
val allModificatorsOfClass = modificatorsSearcher.getFieldToModificators(SettersAndDirectAccessors)
494494

495495
return allModificatorsOfClass
496496
.mapNotNull { (fieldId, possibleModificators) ->

utbot-framework/src/main/kotlin/org/utbot/framework/context/spring/SpringIntegrationTestConcreteExecutionContext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class SpringIntegrationTestConcreteExecutionContext(
8787
springApplicationContext.getBeansAssignableTo(classId).map { it.beanName }
8888
},
8989
relevantRepositories = relevantRepositories
90-
).withFallback(anyObjectValueProvider(idGenerator, isSpringProject = true))
90+
).withFallback(anyObjectValueProvider(idGenerator, shouldMutateWithMethods = true))
9191

9292
return delegateContext.tryCreateValueProvider(concreteExecutor, classUnderTest, idGenerator)
9393
.except { p -> p is ObjectValueProvider }

utbot-framework/src/main/kotlin/org/utbot/framework/modifications/AnalysisUtils.kt

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

utbot-framework/src/main/kotlin/org/utbot/framework/util/EngineUtils.kt

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,18 @@ package org.utbot.framework.util
33
import mu.KotlinLogging
44
import org.utbot.common.logException
55
import org.utbot.framework.plugin.api.util.constructor.ValueConstructor
6-
import org.utbot.framework.plugin.api.ExecutableId
76
import org.utbot.framework.plugin.api.MissingState
87
import org.utbot.framework.plugin.api.UtSymbolicExecution
98
import org.utbot.framework.plugin.api.UtModel
109
import org.utbot.framework.plugin.api.UtMethodTestSet
1110
import org.utbot.framework.plugin.api.UtMethodValueTestSet
1211
import org.utbot.framework.plugin.api.UtVoidModel
13-
import org.utbot.framework.plugin.api.classId
14-
import org.utbot.framework.plugin.api.id
15-
import org.utbot.framework.plugin.api.util.constructorId
16-
import org.utbot.framework.plugin.api.util.methodId
1712
import java.util.concurrent.atomic.AtomicInteger
18-
import soot.SootMethod
1913

2014

2115
private val logger = KotlinLogging.logger { }
2216

23-
/**
24-
* Gets method or constructor id of SootMethod.
25-
*/
26-
val SootMethod.executableId: ExecutableId
27-
get() = when {
28-
isConstructor -> constructorId(
29-
classId = declaringClass.id,
30-
arguments = parameterTypes.map { it.classId }.toTypedArray()
31-
)
32-
else -> methodId(
33-
classId = declaringClass.id,
34-
name = name,
35-
returnType = returnType.classId,
36-
arguments = parameterTypes.map { it.classId }.toTypedArray()
37-
)
38-
}
39-
40-
val instanceCounter = AtomicInteger(0)
17+
private val instanceCounter = AtomicInteger(0)
4118

4219
fun nextModelName(base: String): String = "$base${instanceCounter.incrementAndGet()}"
4320

utbot-java-fuzzing/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ val rgxgenVersion: String by rootProject
55
dependencies {
66
implementation(project(":utbot-framework-api"))
77
api(project(":utbot-fuzzing"))
8+
api(project(":utbot-modification-analyzer"))
89

910
implementation("org.unittestbot.soot:soot-utbot-fork:${sootVersion}") {
1011
exclude(group="com.google.guava", module="guava")

utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/providers/Objects.kt

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import java.lang.reflect.Field
1313
import java.lang.reflect.Member
1414
import java.lang.reflect.Method
1515
import java.lang.reflect.Modifier
16+
import java.lang.reflect.TypeVariable
17+
import org.utbot.modifications.AnalysisMode
18+
import org.utbot.modifications.UtBotFieldsModificatorsSearcher
1619

1720
private val logger = KotlinLogging.logger {}
1821

@@ -31,14 +34,14 @@ private fun isIgnored(type: ClassId): Boolean {
3134
|| (type.isInner && !type.isStatic)
3235
}
3336

34-
fun anyObjectValueProvider(idGenerator: IdentityPreservingIdGenerator<Int>, isSpringProject: Boolean = false) =
35-
ObjectValueProvider(idGenerator, isSpringProject).letIf(UtSettings.fuzzingImplementationOfAbstractClasses) { ovp ->
37+
fun anyObjectValueProvider(idGenerator: IdentityPreservingIdGenerator<Int>, shouldMutateWithMethods: Boolean = false) =
38+
ObjectValueProvider(idGenerator, shouldMutateWithMethods).letIf(UtSettings.fuzzingImplementationOfAbstractClasses) { ovp ->
3639
ovp.withFallback(AbstractsObjectValueProvider(idGenerator))
3740
}
3841

3942
class ObjectValueProvider(
4043
val idGenerator: IdGenerator<Int>,
41-
private val isSpringProject: Boolean,
44+
private val shouldMutateWithMethods: Boolean,
4245
) : ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> {
4346

4447
override fun accept(type: FuzzedType) = !isIgnored(type.classId)
@@ -101,8 +104,8 @@ class ObjectValueProvider(
101104
}
102105
}
103106
}
104-
if (isSpringProject) {
105-
findAllPublicMethods(description, classId, description.description.packageName).forEach { md ->
107+
if (true || shouldMutateWithMethods) {
108+
findAllAvailableMethods(description, classId, description.description.packageName).forEach { md ->
106109
yield(Routine.Call(md.parameterTypes) { self, values ->
107110
val model = self.model as UtAssembleModel
108111
model.modificationsChain as MutableList +=
@@ -260,14 +263,20 @@ internal fun findAccessibleModifiableFields(description: FuzzedDescription?, cla
260263
}.toList()
261264
}
262265

263-
internal fun findAllPublicMethods(
266+
/**
267+
* text.
268+
*/
269+
internal fun findAllAvailableMethods(
264270
description: FuzzedDescription?,
265271
classId: ClassId,
266272
packageName: String?
267-
): List<MethodDescription> =
268-
classId.jClass.declaredMethods.mapNotNull { method ->
273+
): List<MethodDescription> {
274+
val modifyingMethods = findModifyingMethodNames(classId)
275+
return classId.jClass.declaredMethods.mapNotNull { method ->
269276
if (isAccessible(method, packageName)) {
270-
if (method.genericParameterTypes.any { it !is Class<*> }) return@mapNotNull null
277+
if (method.name !in modifyingMethods) return@mapNotNull null
278+
if (method.genericParameterTypes.any { it is TypeVariable<*> }) return@mapNotNull null
279+
271280
val parameterTypes =
272281
method
273282
.parameterTypes
@@ -287,11 +296,7 @@ internal fun findAllPublicMethods(
287296
)
288297
} else null
289298
}
290-
291-
internal fun List<MethodDescription>.removeSetters(): List<MethodDescription> =
292-
filterNot { md ->
293-
md.method.name.startsWith("set") && md.method.parameterCount == 1
294-
}
299+
}
295300

296301
internal fun Class<*>.findPublicSetterGetterIfHasPublicGetter(field: Field, packageName: String?): PublicSetterGetter? {
297302
@Suppress("DEPRECATION") val postfixName = field.name.capitalize()
@@ -325,7 +330,16 @@ internal fun isAccessible(clazz: Class<*>, packageName: String?): Boolean {
325330
(packageName != null && isNotPrivateOrProtected(clazz.modifiers) && clazz.`package`?.name == packageName)
326331
}
327332

333+
private fun findModifyingMethodNames(classId: ClassId) =
334+
UtBotFieldsModificatorsSearcher()
335+
.let { searcher ->
336+
searcher.update(setOf(classId))
337+
searcher.getModificatorToFields(AnalysisMode.AllModificators)
338+
.keys
339+
.mapTo(mutableSetOf()) { it.name }
340+
}
341+
328342
private fun isNotPrivateOrProtected(modifiers: Int): Boolean {
329343
val hasAnyAccessModifier = Modifier.isPrivate(modifiers) || Modifier.isProtected(modifiers)
330344
return !hasAnyAccessModifier
331-
}
345+
}

utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/spring/SpringBeanValueProvider.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import org.utbot.fuzzer.FuzzedValue
99
import org.utbot.fuzzer.IdGenerator
1010
import org.utbot.fuzzer.fuzzed
1111
import org.utbot.fuzzing.*
12+
import org.utbot.fuzzing.providers.MethodDescription
1213
import org.utbot.fuzzing.providers.SPRING_BEAN_PROP
13-
import org.utbot.fuzzing.providers.findAllPublicMethods
14+
import org.utbot.fuzzing.providers.findAllAvailableMethods
1415
import org.utbot.fuzzing.providers.nullRoutine
15-
import org.utbot.fuzzing.providers.removeSetters
1616

1717
class SpringBeanValueProvider(
1818
private val idGenerator: IdGenerator<Int>,
@@ -62,7 +62,11 @@ class SpringBeanValueProvider(
6262
)
6363
})
6464
}
65-
findAllPublicMethods(description, type.classId, description.description.packageName)
65+
/**
66+
* We find all methods that are public, accessible, are not setters and modify at least one field.
67+
* We don't take setters because they may
68+
*/
69+
findAllAvailableMethods(description, type.classId, description.description.packageName)
6670
.removeSetters()
6771
.forEach { md ->
6872
yield(Routine.Call(md.parameterTypes) { self, values ->
@@ -81,4 +85,9 @@ class SpringBeanValueProvider(
8185
)
8286
}
8387
}
88+
89+
private fun List<MethodDescription>.removeSetters(): List<MethodDescription> =
90+
filterNot { md ->
91+
md.method.name.startsWith("set") && md.method.parameterCount == 1
92+
}
8493
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
val sootVersion: String by rootProject
2+
3+
dependencies {
4+
api(project(":utbot-framework-api"))
5+
6+
implementation("org.unittestbot.soot:soot-utbot-fork:${sootVersion}") {
7+
exclude(group="com.google.guava", module="guava")
8+
}
9+
}

utbot-framework/src/main/kotlin/org/utbot/framework/modifications/AnalysisMode.kt renamed to utbot-modification-analyzer/src/main/kotlin/org/utbot/modifications/AnalysisMode.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.utbot.framework.modifications
1+
package org.utbot.modifications
22

33
/**
44
* Restrictions on demanded modificators
@@ -19,4 +19,6 @@ enum class AnalysisMode {
1919
* Search constructors only
2020
*/
2121
Constructors,
22+
23+
// TODO?: add all modificators without constructors (methods only)
2224
}

utbot-framework/src/main/kotlin/org/utbot/framework/modifications/ConstructorAnalyzer.kt renamed to utbot-modification-analyzer/src/main/kotlin/org/utbot/modifications/ConstructorAnalyzer.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.utbot.framework.modifications
1+
package org.utbot.modifications
22

33
import org.utbot.framework.plugin.api.ClassId
44
import org.utbot.framework.plugin.api.ConstructorId
@@ -7,7 +7,8 @@ import org.utbot.framework.plugin.api.id
77
import org.utbot.framework.plugin.api.util.isArray
88
import org.utbot.framework.plugin.api.util.isRefType
99
import org.utbot.framework.plugin.api.util.jClass
10-
import org.utbot.framework.util.kotlinIntrinsicsClassId
10+
import org.utbot.modifications.util.kotlinIntrinsicsClassId
11+
import org.utbot.modifications.util.retrieveJimpleBody
1112
import soot.Scene
1213
import soot.SootMethod
1314
import soot.Type

utbot-framework/src/main/kotlin/org/utbot/framework/modifications/DirectAccessorsAnalyzer.kt renamed to utbot-modification-analyzer/src/main/kotlin/org/utbot/modifications/DirectAccessorsAnalyzer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.utbot.framework.modifications
1+
package org.utbot.modifications
22

33
import org.utbot.framework.plugin.api.ClassId
44
import org.utbot.framework.plugin.api.DirectFieldAccessId

utbot-framework/src/main/kotlin/org/utbot/framework/modifications/ExecutablesAnalyzer.kt renamed to utbot-modification-analyzer/src/main/kotlin/org/utbot/modifications/ExecutablesAnalyzer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
package org.utbot.framework.modifications
1+
package org.utbot.modifications
22

33
import org.utbot.framework.plugin.api.ClassId
44
import org.utbot.framework.plugin.api.ExecutableId
55
import org.utbot.framework.plugin.api.FieldId
66
import org.utbot.framework.plugin.api.id
77
import org.utbot.framework.plugin.api.util.fieldId
88
import org.utbot.framework.util.executableId
9+
import org.utbot.modifications.util.retrieveJimpleBody
910
import soot.Scene
1011
import soot.SootMethod
1112
import soot.jimple.InvokeExpr

utbot-framework/src/main/kotlin/org/utbot/framework/modifications/StatementInfo.kt renamed to utbot-modification-analyzer/src/main/kotlin/org/utbot/modifications/StatementInfo.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.utbot.framework.modifications
1+
package org.utbot.modifications
22

33
import org.utbot.framework.plugin.api.ClassId
44
import org.utbot.framework.plugin.api.ExecutableId

0 commit comments

Comments
 (0)