Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0587302

Browse files
Better method mutations in Spring fuzzing #2502 (#2541)
1 parent abb6268 commit 0587302

File tree

19 files changed

+250
-149
lines changed

19 files changed

+250
-149
lines changed

‎utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ object UtSettings : AbstractSettings(logger, defaultKeyForSettingsPath, defaultS
241241
*/
242242
var fuzzingImplementationOfAbstractClasses: Boolean by getBooleanProperty(true)
243243

244+
/**
245+
* Use methods to mutate fields of classes different from class under test or not.
246+
*/
247+
var tryMutateOtherClassesFieldsWithMethods: Boolean by getBooleanProperty(false)
248+
244249
/**
245250
* Generate tests that treat possible overflows in arithmetic operations as errors
246251
* that throw Arithmetic Exception.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.BeforeEach
2626
import org.junit.jupiter.api.Test
2727
import org.utbot.framework.plugin.services.JdkInfoDefaultProvider
2828
import org.utbot.framework.util.SootUtils
29-
import org.utbot.modifications.ModificationTransformationMode
29+
import org.utbot.modifications.FieldInvolvementMode
3030

3131
internal class UtBotFieldModificatorsTest {
3232
private lateinit var fieldsModificatorsSearcher: UtBotFieldsModificatorsSearcher
@@ -177,7 +177,7 @@ internal class UtBotFieldModificatorsTest {
177177
jdkInfo = JdkInfoDefaultProvider().info
178178
)
179179
fieldsModificatorsSearcher = UtBotFieldsModificatorsSearcher(
180-
modificationTransformationMode = ModificationTransformationMode.WriteOnly
180+
fieldInvolvementMode = FieldInvolvementMode.WriteOnly
181181
)
182182
}
183183

‎utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import org.utbot.framework.plugin.services.JdkInfoDefaultProvider
3939
import org.utbot.fuzzer.FuzzedType
4040
import org.utbot.fuzzer.FuzzedValue
4141
import org.utbot.fuzzing.FuzzedDescription
42+
import org.utbot.fuzzing.JavaValueProvider
4243
import org.utbot.fuzzing.Seed
4344
import org.utbot.fuzzing.ValueProvider
4445
import org.utbot.instrumentation.ConcreteExecutor
@@ -173,7 +174,7 @@ object UtBotJavaApi {
173174
}
174175
?.map { UtPrimitiveModel(it) } ?: emptySequence()
175176

176-
val customModelProvider = ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> { _, type ->
177+
val customModelProvider = JavaValueProvider { _, type ->
177178
sequence {
178179
createPrimitiveModels(primitiveValuesSupplier, type.classId).forEach { model ->
179180
yield(Seed.Simple(FuzzedValue(model)))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import org.utbot.framework.plugin.api.util.jClass
4848
import org.utbot.framework.util.nextModelName
4949
import java.lang.reflect.Constructor
5050
import java.util.IdentityHashMap
51-
import org.utbot.modifications.ModificationTransformationMode
51+
import org.utbot.modifications.FieldInvolvementMode
5252

5353
/**
5454
* Creates [UtAssembleModel] from any [UtModel] or it's inner models if possible
@@ -75,7 +75,7 @@ class AssembleModelGenerator(private val basePackageName: String) {
7575

7676
private val modificatorsSearcher =
7777
UtBotFieldsModificatorsSearcher(
78-
modificationTransformationMode = ModificationTransformationMode.WriteOnly
78+
fieldInvolvementMode = FieldInvolvementMode.WriteOnly
7979
)
8080
private val constructorAnalyzer = ConstructorAnalyzer()
8181

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ import org.utbot.framework.plugin.api.util.utContext
1717
import org.utbot.fuzzer.IdentityPreservingIdGenerator
1818
import org.utbot.fuzzing.JavaValueProvider
1919
import org.utbot.fuzzing.ValueProvider
20+
import org.utbot.fuzzing.providers.AbstractsObjectValueProvider
2021
import org.utbot.fuzzing.providers.AnyDepthNullValueProvider
22+
import org.utbot.fuzzing.providers.ModifyingWithMethodsProviderWrapper
2123
import org.utbot.fuzzing.providers.ObjectValueProvider
22-
import org.utbot.fuzzing.providers.anyObjectValueProvider
2324
import org.utbot.fuzzing.spring.GeneratedFieldValueProvider
2425
import org.utbot.fuzzing.spring.SpringBeanValueProvider
2526
import org.utbot.fuzzing.spring.preserveProperties
@@ -37,28 +38,37 @@ class SpringIntegrationTestJavaFuzzingContext(
3738
private val logger = KotlinLogging.logger {}
3839
}
3940

40-
override val valueProvider: JavaValueProvider =
41+
private val springBeanValueProvider: JavaValueProvider =
4142
SpringBeanValueProvider(
4243
idGenerator,
4344
beanNameProvider = { classId ->
4445
springApplicationContext.getBeansAssignableTo(classId).map { it.beanName }
4546
},
4647
relevantRepositories = relevantRepositories
4748
)
48-
.withFallback(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = true))
49+
50+
override val valueProvider: JavaValueProvider =
51+
springBeanValueProvider.withModifyingMethodsBuddy()
52+
.withFallback(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = true).withModifyingMethodsBuddy())
4953
.withFallback(EmailValueProvider())
5054
.withFallback(NotBlankStringValueProvider())
5155
.withFallback(NotEmptyStringValueProvider())
5256
.withFallback(
5357
delegateContext.valueProvider
54-
.except { p -> p is ObjectValueProvider }
55-
.with(anyObjectValueProvider(idGenerator, shouldMutateWithMethods = true))
56-
.with(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = false))
58+
.with(ObjectValueProvider(idGenerator).withModifyingMethodsBuddy())
59+
.with(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = false).withModifyingMethodsBuddy())
5760
.with(createGeneratedFieldValueProviders(relevantRepositories, idGenerator))
5861
.withFallback(AnyDepthNullValueProvider)
5962
)
6063
.preserveProperties()
6164

65+
private fun JavaValueProvider.withModifyingMethodsBuddy(): JavaValueProvider =
66+
with(modifyingMethodsBuddy(this))
67+
68+
private fun modifyingMethodsBuddy(provider: JavaValueProvider): JavaValueProvider =
69+
ModifyingWithMethodsProviderWrapper(classUnderTest, provider)
70+
71+
6272
private fun createGeneratedFieldValueProviders(
6373
relevantRepositories: Set<SpringRepositoryId>,
6474
idGenerator: IdentityPreservingIdGenerator<Int>

‎utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/JavaLanguage.kt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fun defaultValueProviders(idGenerator: IdentityPreservingIdGenerator<Int>) = lis
4242
FloatValueProvider,
4343
StringValueProvider,
4444
NumberValueProvider,
45-
anyObjectValueProvider(idGenerator, shouldMutateWithMethods =false),
45+
anyObjectValueProvider(idGenerator),
4646
ArrayValueProvider(idGenerator),
4747
EnumValueProvider(idGenerator),
4848
ListSetValueProvider(idGenerator),
@@ -59,7 +59,7 @@ suspend fun runJavaFuzzing(
5959
methodUnderTest: ExecutableId,
6060
constants: Collection<FuzzedConcreteValue>,
6161
names: List<String>,
62-
providers: List<ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription>> = defaultValueProviders(idGenerator),
62+
providers: List<JavaValueProvider> = defaultValueProviders(idGenerator),
6363
exec: suspend (thisInstance: FuzzedValue?, description: FuzzedDescription, values: List<FuzzedValue>) -> BaseFeedback<Trie.Node<Instruction>, FuzzedType, FuzzedValue>
6464
) {
6565
val random = Random(0)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import org.utbot.fuzzing.*
1111

1212
class ArrayValueProvider(
1313
val idGenerator: IdGenerator<Int>,
14-
) : ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> {
14+
) : JavaValueProvider {
1515

1616
override fun accept(type: FuzzedType) = type.classId.isArray
1717

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import kotlin.reflect.KClass
1212

1313
class EmptyCollectionValueProvider(
1414
val idGenerator: IdGenerator<Int>
15-
) : ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> {
15+
) : JavaValueProvider {
1616
private class Info(val classId: ClassId, val methodName: String, val returnType: ClassId = classId)
1717

1818
private val unmodifiableCollections = listOf(
@@ -150,7 +150,7 @@ class ListSetValueProvider(
150150
abstract class CollectionValueProvider(
151151
private val idGenerator: IdGenerator<Int>,
152152
vararg acceptableCollectionTypes: ClassId
153-
) : ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> {
153+
) : JavaValueProvider {
154154

155155
private val acceptableCollectionTypes = acceptableCollectionTypes.toList()
156156

@@ -216,7 +216,7 @@ abstract class CollectionValueProvider(
216216
}
217217
}
218218

219-
class IteratorValueProvider(val idGenerator: IdGenerator<Int>) : ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> {
219+
class IteratorValueProvider(val idGenerator: IdGenerator<Int>) : JavaValueProvider {
220220
override fun accept(type: FuzzedType): Boolean {
221221
return type.classId == Iterator::class.id
222222
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import org.utbot.fuzzer.FuzzedValue
88
import org.utbot.fuzzer.IdentityPreservingIdGenerator
99
import org.utbot.fuzzer.fuzzed
1010
import org.utbot.fuzzing.FuzzedDescription
11+
import org.utbot.fuzzing.JavaValueProvider
1112
import org.utbot.fuzzing.Seed
12-
import org.utbot.fuzzing.ValueProvider
1313

1414
class EnumValueProvider(
1515
val idGenerator: IdentityPreservingIdGenerator<Int>,
16-
) : ValueProvider<FuzzedType, FuzzedValue, FuzzedDescription> {
16+
) : JavaValueProvider {
1717
override fun accept(type: FuzzedType) = type.classId.isEnum
1818

1919
override fun generate(
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.utbot.fuzzing.providers
2+
3+
import org.utbot.framework.plugin.api.ClassId
4+
import org.utbot.framework.plugin.api.UtAssembleModel
5+
import org.utbot.framework.plugin.api.UtExecutableCallModel
6+
import org.utbot.framework.plugin.api.util.executableId
7+
import org.utbot.fuzzer.FuzzedType
8+
import org.utbot.fuzzer.FuzzedValue
9+
import org.utbot.fuzzing.FuzzedDescription
10+
import org.utbot.fuzzing.JavaValueProvider
11+
import org.utbot.fuzzing.Routine
12+
import org.utbot.fuzzing.Scope
13+
import org.utbot.fuzzing.Seed
14+
15+
/**
16+
* Value provider that is a buddy for another provider
17+
* that keeps all it's functionality and also allows
18+
* to use methods to mutate field states of an object.
19+
*
20+
* NOTE!!!
21+
* Instances represented by [UtAssembleModel] only can be mutated with methods.
22+
*/
23+
class ModifyingWithMethodsProviderWrapper(
24+
private val classUnderTest: ClassId,
25+
private val delegate: JavaValueProvider
26+
) : JavaValueProvider by delegate {
27+
28+
override fun generate(description: FuzzedDescription, type: FuzzedType): Sequence<Seed<FuzzedType, FuzzedValue>> =
29+
delegate
30+
.generate(description, type)
31+
.map { seed ->
32+
if (seed is Seed.Recursive) {
33+
Seed.Recursive(
34+
construct = seed.construct,
35+
modify = seed.modify +
36+
findMethodsToModifyWith(description, type.classId, classUnderTest)
37+
.asSequence()
38+
.map { md ->
39+
Routine.Call(md.parameterTypes) { self, values ->
40+
val model = self.model as UtAssembleModel
41+
model.modificationsChain as MutableList +=
42+
UtExecutableCallModel(
43+
model,
44+
md.method.executableId,
45+
values.map { it.model }
46+
)
47+
}
48+
},
49+
empty = seed.empty,
50+
)
51+
} else seed
52+
}
53+
54+
override fun enrich(description: FuzzedDescription, type: FuzzedType, scope: Scope) =
55+
delegate.enrich(description, type, scope)
56+
57+
override fun accept(type: FuzzedType): Boolean = delegate.accept(type)
58+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /