Skip to content

Commit f25c231

Browse files
committed
Introduce PreservableFuzzedTypeProperty
1 parent 63ec43a commit f25c231

File tree

4 files changed

+80
-32
lines changed

4 files changed

+80
-32
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.utbot.fuzzing.ValueProvider
2828
import org.utbot.fuzzing.providers.AnyDepthNullValueProvider
2929
import org.utbot.fuzzing.spring.GeneratedFieldValueProvider
3030
import org.utbot.fuzzing.spring.SpringBeanValueProvider
31+
import org.utbot.fuzzing.spring.preserveProperties
3132
import org.utbot.fuzzing.spring.valid.EmailValueProvider
3233
import org.utbot.fuzzing.spring.valid.NotEmptyStringValueProvider
3334
import org.utbot.fuzzing.spring.valid.ValidEntityValueProvider
@@ -102,13 +103,13 @@ class SpringIntegrationTestConcreteExecutionContext(
102103
.withFallback(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = true))
103104
.withFallback(EmailValueProvider())
104105
.withFallback(NotEmptyStringValueProvider())
105-
.withFallback(springBeanValueProvider)
106106
.withFallback(
107107
delegateContext.tryCreateValueProvider(concreteExecutor, classUnderTest, idGenerator)
108108
.with(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = false))
109109
.with(createGeneratedFieldValueProviders(relevantRepositories, idGenerator))
110110
.withFallback(AnyDepthNullValueProvider)
111111
)
112+
.preserveProperties()
112113
}
113114

114115
private fun createGeneratedFieldValueProviders(

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

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,3 @@ fun FuzzedType.withoutProperty(property: FuzzedTypeProperty<*>): FuzzedTypeWithP
3131

3232
fun FuzzedType.addProperties(properties: FuzzedTypeProperties): FuzzedTypeWithProperties =
3333
FuzzedTypeWithProperties(origin, this.properties + properties)
34-
35-
/**
36-
* Unlike [addProperties] adds [properties] not just to the type itself, but also to its
37-
* [FuzzedType.generics], generics of generics, and so on.
38-
*/
39-
fun FuzzedType.addPropertiesDeeply(properties: FuzzedTypeProperties): FuzzedTypeWithProperties {
40-
val cache = mutableMapOf<FuzzedType, FuzzedTypeWithProperties>()
41-
42-
fun FuzzedType.addPropertiesDeeply(): FuzzedTypeWithProperties {
43-
cache[this]?.let { return it }
44-
val generics = mutableListOf<FuzzedTypeWithProperties>()
45-
val result = FuzzedTypeWithProperties(
46-
origin = FuzzedType(classId, generics),
47-
properties = this.properties + properties
48-
)
49-
cache[this] = result
50-
this.generics.forEach { generics.add(it.addPropertiesDeeply()) }
51-
return result
52-
}
53-
54-
return addPropertiesDeeply()
55-
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.utbot.fuzzing.spring
2+
3+
import org.utbot.common.toDynamicProperties
4+
import org.utbot.fuzzer.FuzzedType
5+
import org.utbot.fuzzer.FuzzedValue
6+
import org.utbot.fuzzing.FuzzedDescription
7+
import org.utbot.fuzzing.JavaValueProvider
8+
import org.utbot.fuzzing.Routine
9+
import org.utbot.fuzzing.Scope
10+
import org.utbot.fuzzing.Seed
11+
12+
/**
13+
* @see preserveProperties
14+
*/
15+
interface PreservableFuzzedTypeProperty<T> : FuzzedTypeProperty<T>
16+
17+
/**
18+
* Returns wrapper of [this] provider that preserves [preservable properties][PreservableFuzzedTypeProperty],
19+
* i.e. all [FuzzedType]s mentioned in any returned [Seed] will have all [preservable properties]
20+
* [PreservableFuzzedTypeProperty] of the type that was used to generate that seed.
21+
*
22+
* That's useful if we want a whole part of the object tree created by fuzzer to possess some property
23+
* (e.g. all entities used to create MANAGED entity should themselves be also MANAGED).
24+
*/
25+
fun JavaValueProvider.preserveProperties() : JavaValueProvider =
26+
PropertyPreservingValueProvider(this)
27+
28+
class PropertyPreservingValueProvider(private val delegateProvider: JavaValueProvider) : JavaValueProvider {
29+
override fun enrich(description: FuzzedDescription, type: FuzzedType, scope: Scope) =
30+
delegateProvider.enrich(description, type, scope)
31+
32+
override fun accept(type: FuzzedType): Boolean = delegateProvider.accept(type)
33+
34+
override fun generate(description: FuzzedDescription, type: FuzzedType): Sequence<Seed<FuzzedType, FuzzedValue>> {
35+
val delegateSeeds = delegateProvider.generate(description, type)
36+
37+
val preservedProperties = type.properties.entries
38+
.filter { it.property is PreservableFuzzedTypeProperty }
39+
.toDynamicProperties()
40+
if (preservedProperties.entries.isEmpty()) return delegateSeeds
41+
42+
fun List<FuzzedType>.addPreservedProperties() = map { it.addProperties(preservedProperties) }
43+
44+
return delegateSeeds.map { seed ->
45+
when (seed) {
46+
is Seed.Recursive -> Seed.Recursive(
47+
construct = Routine.Create(
48+
types = seed.construct.types.addPreservedProperties(),
49+
builder = seed.construct.builder
50+
),
51+
modify = seed.modify.map { modification ->
52+
Routine.Call(
53+
types = modification.types.addPreservedProperties(),
54+
callable = modification.callable
55+
)
56+
},
57+
empty = seed.empty
58+
)
59+
is Seed.Collection -> Seed.Collection(
60+
construct = seed.construct,
61+
modify = Routine.ForEach(
62+
types = seed.modify.types.addPreservedProperties(),
63+
callable = seed.modify.callable
64+
)
65+
)
66+
is Seed.Known<FuzzedType, FuzzedValue, *>, is Seed.Simple -> seed
67+
}
68+
}
69+
}
70+
71+
override fun map(transform: (JavaValueProvider) -> JavaValueProvider): JavaValueProvider =
72+
delegateProvider.map(transform).preserveProperties()
73+
74+
override fun except(filter: (JavaValueProvider) -> Boolean): JavaValueProvider =
75+
delegateProvider.except(filter).preserveProperties()
76+
}

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.utbot.fuzzing.spring.valid
22

3-
import org.utbot.common.dynamicPropertiesOf
43
import org.utbot.common.toDynamicProperties
54
import org.utbot.common.withValue
65
import org.utbot.framework.plugin.api.ClassId
@@ -31,9 +30,8 @@ import org.utbot.fuzzing.Routine
3130
import org.utbot.fuzzing.Seed
3231
import org.utbot.fuzzing.providers.findAccessibleModifiableFields
3332
import org.utbot.fuzzing.providers.nullRoutine
34-
import org.utbot.fuzzing.spring.FuzzedTypeProperty
33+
import org.utbot.fuzzing.spring.PreservableFuzzedTypeProperty
3534
import org.utbot.fuzzing.spring.addProperties
36-
import org.utbot.fuzzing.spring.addPropertiesDeeply
3735
import org.utbot.fuzzing.spring.properties
3836
import org.utbot.fuzzing.utils.hex
3937

@@ -48,7 +46,7 @@ enum class EntityLifecycleState(
4846
DETACHED(generatedValueClassIds + idClassIds, { listOfNotNull(persistMethodIdOrNull, detachMethodIdOrNull) }),
4947
}
5048

51-
object EntityLifecycleStateProperty : FuzzedTypeProperty<EntityLifecycleState>
49+
object EntityLifecycleStateProperty : PreservableFuzzedTypeProperty<EntityLifecycleState>
5250

5351
class ValidEntityValueProvider(
5452
val idGenerator: IdGenerator<Int>,
@@ -129,11 +127,6 @@ class ValidEntityValueProvider(
129127
}.toDynamicProperties()
130128

131129
val typeWithProperties = fd.type.addProperties(validationProperties)
132-
.addPropertiesDeeply(
133-
dynamicPropertiesOf(
134-
EntityLifecycleStateProperty.withValue(lifecycleState)
135-
)
136-
)
137130

138131
when {
139132
fd.canBeSetDirectly -> {

0 commit comments

Comments
 (0)