Skip to content

Commit 23dc52a

Browse files
committed
Fixes after review
1 parent 0299e13 commit 23dc52a

File tree

7 files changed

+118
-104
lines changed

7 files changed

+118
-104
lines changed

utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/FuzzedValue.kt

+12-15
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,19 @@ import org.utbot.framework.plugin.api.UtModel
55
/**
66
* Fuzzed Value stores information about concrete UtModel, reference to [ModelProvider]
77
* and reasons about why this value was generated.
8+
*
9+
* [summary] is a piece of useful information that clarify why this value has a concrete value.
10+
*
11+
* It supports a special character `%var%` that is used as a placeholder for parameter name.
12+
*
13+
* For example:
14+
* 1. `%var% = 2` for a value that have value 2
15+
* 2. `%var% >= 4` for a value that shouldn't be less than 4
16+
* 3. `foo(%var%) returns true` for values that should be passed as a function parameter
17+
* 4. `%var% has special characters` to describe content
818
*/
919
open class FuzzedValue(
1020
val model: UtModel,
1121
val createdBy: ModelProvider? = null,
12-
) {
13-
14-
/**
15-
* Summary is a piece of useful information that clarify why this value has a concrete value.
16-
*
17-
* It supports a special character `%var%` that is used as a placeholder for parameter name.
18-
*
19-
* For example:
20-
* 1. `%var% = 2` for a value that have value 2
21-
* 2. `%var% >= 4` for a value that shouldn't be less than 4
22-
* 3. `foo(%var%) returns true` for values that should be passed as a function parameter
23-
* 4. `%var% has special characters` to describe content
24-
*/
25-
var summary: String? = null
26-
}
22+
var summary: String? = null,
23+
)

utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/Fuzzer.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import org.utbot.framework.plugin.api.util.voidClassId
77
import org.utbot.fuzzer.mutators.NumberRandomMutator
88
import org.utbot.fuzzer.mutators.RegexStringModelMutator
99
import org.utbot.fuzzer.mutators.StringRandomMutator
10-
import org.utbot.fuzzer.objects.replaceToMock
10+
import org.utbot.fuzzer.objects.replaceWithMock
1111
import org.utbot.fuzzer.providers.ArrayModelProvider
1212
import org.utbot.fuzzer.providers.CharToStringModelProvider
1313
import org.utbot.fuzzer.providers.CollectionWithEmptyStatesModelProvider
@@ -118,7 +118,7 @@ fun fuzz(description: FuzzedMethodDescription, vararg modelProviders: ModelProvi
118118
val values = List<MutableList<FuzzedValue>>(description.parameters.size) { mutableListOf() }
119119
modelProviders.forEach { fuzzingProvider ->
120120
fuzzingProvider.generate(description).forEach { (index, model) ->
121-
val mock = replaceToMock(model.model, description.shouldMock)
121+
val mock = replaceWithMock(model.model, description.shouldMock)
122122
values[index].add(FuzzedValue(mock, model.createdBy).apply {
123123
summary = model.summary
124124
})

utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt

-38
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import org.utbot.framework.plugin.api.ExecutableId
66
import org.utbot.framework.plugin.api.FieldId
77
import org.utbot.framework.plugin.api.MethodId
88
import org.utbot.framework.plugin.api.UtAssembleModel
9-
import org.utbot.framework.plugin.api.UtCompositeModel
109
import org.utbot.framework.plugin.api.UtDirectSetFieldModel
1110
import org.utbot.framework.plugin.api.UtExecutableCallModel
1211
import org.utbot.framework.plugin.api.UtModel
@@ -28,43 +27,6 @@ fun ModelProvider.assembleModel(id: Int, constructorId: ConstructorId, params: L
2827
}
2928
}
3029

31-
fun replaceToMock(assembleModel: UtModel, shouldMock: (ClassId) -> Boolean): UtModel {
32-
if (assembleModel !is UtAssembleModel) return assembleModel
33-
if (shouldMock(assembleModel.classId)) {
34-
return UtCompositeModel(assembleModel.id, assembleModel.classId, true).apply {
35-
assembleModel.modificationsChain.forEach {
36-
if (it is UtDirectSetFieldModel) {
37-
fields[it.fieldId] = replaceToMock(it.fieldModel, shouldMock)
38-
}
39-
if (it is UtExecutableCallModel && it.executable is FuzzerMockableMethodId) {
40-
(it.executable as FuzzerMockableMethodId).mock().forEach { (executionId, models) ->
41-
mocks[executionId] = models.map { p -> replaceToMock(p, shouldMock) }
42-
}
43-
}
44-
}
45-
}
46-
} else {
47-
val models = assembleModel.modificationsChain.map { call ->
48-
var mockedStatementModel: UtStatementModel? = null
49-
if (call is UtDirectSetFieldModel) {
50-
val mock = replaceToMock(call.fieldModel, shouldMock)
51-
if (mock != call.fieldModel) {
52-
mockedStatementModel = UtDirectSetFieldModel(call.instance, call.fieldId, mock)
53-
}
54-
} else if (call is UtExecutableCallModel) {
55-
val params = call.params.map { m -> replaceToMock(m, shouldMock) }
56-
if (params != call.params) {
57-
mockedStatementModel = UtExecutableCallModel(call.instance, call.executable, params)
58-
}
59-
}
60-
mockedStatementModel ?: call
61-
}
62-
return with(assembleModel) {
63-
UtAssembleModel(id, classId, modelName, instantiationCall, origin) { models }
64-
}
65-
}
66-
}
67-
6830
fun ClassId.create(
6931
block: AssembleModelDsl.() -> Unit
7032
): UtAssembleModel {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.utbot.fuzzer.objects
2+
3+
import org.utbot.framework.plugin.api.ClassId
4+
import org.utbot.framework.plugin.api.ExecutableId
5+
import org.utbot.framework.plugin.api.MethodId
6+
import org.utbot.framework.plugin.api.UtAssembleModel
7+
import org.utbot.framework.plugin.api.UtCompositeModel
8+
import org.utbot.framework.plugin.api.UtDirectSetFieldModel
9+
import org.utbot.framework.plugin.api.UtExecutableCallModel
10+
import org.utbot.framework.plugin.api.UtModel
11+
import org.utbot.framework.plugin.api.UtStatementModel
12+
13+
/**
14+
* Implements [MethodId] but also can supply a mock for this execution.
15+
*
16+
* Simplest example: setter and getter,
17+
* when this methodId is a setter, getter can be used for a mock to supply correct value.
18+
*/
19+
internal class FuzzerMockableMethodId(
20+
classId: ClassId,
21+
name: String,
22+
returnType: ClassId,
23+
parameters: List<ClassId>,
24+
val mock: () -> Map<ExecutableId, List<UtModel>> = { emptyMap() },
25+
) : MethodId(classId, name, returnType, parameters) {
26+
27+
constructor(copyOf: MethodId, mock: () -> Map<ExecutableId, List<UtModel>> = { emptyMap() }) : this(
28+
copyOf.classId, copyOf.name, copyOf.returnType, copyOf.parameters, mock
29+
)
30+
31+
}
32+
33+
internal fun MethodId.toFuzzerMockable(block: suspend SequenceScope<Pair<MethodId, List<UtModel>>>.() -> Unit): FuzzerMockableMethodId {
34+
return FuzzerMockableMethodId(this) {
35+
sequence { block() }.toMap()
36+
}
37+
}
38+
39+
internal fun replaceWithMock(assembleModel: UtModel, shouldMock: (ClassId) -> Boolean): UtModel = when {
40+
assembleModel !is UtAssembleModel -> assembleModel
41+
shouldMock(assembleModel.classId) -> createMockModelFromFuzzerMockable(assembleModel, shouldMock)
42+
else -> updateInnerModels(assembleModel, shouldMock)
43+
}
44+
45+
private fun createMockModelFromFuzzerMockable(model: UtAssembleModel, shouldMock: (ClassId) -> Boolean): UtCompositeModel {
46+
val mock = UtCompositeModel(model.id, model.classId, true)
47+
for (mutator in model.modificationsChain) {
48+
if (mutator is UtDirectSetFieldModel) {
49+
mock.fields[mutator.fieldId] = replaceWithMock(mutator.fieldModel, shouldMock)
50+
}
51+
if (mutator is UtExecutableCallModel && mutator.executable is FuzzerMockableMethodId) {
52+
(mutator.executable as FuzzerMockableMethodId).mock().forEach { (executionId, models) ->
53+
mock.mocks[executionId] = models.map { p -> replaceWithMock(p, shouldMock) }
54+
}
55+
}
56+
}
57+
return mock
58+
}
59+
60+
private fun updateInnerModels(model: UtAssembleModel, shouldMock: (ClassId) -> Boolean): UtAssembleModel {
61+
val models = model.modificationsChain.map { call ->
62+
var mockedStatementModel: UtStatementModel? = null
63+
when (call) {
64+
is UtDirectSetFieldModel -> {
65+
val mock = replaceWithMock(call.fieldModel, shouldMock)
66+
if (mock != call.fieldModel) {
67+
mockedStatementModel = UtDirectSetFieldModel(call.instance, call.fieldId, mock)
68+
}
69+
}
70+
is UtExecutableCallModel -> {
71+
val params = call.params.map { m -> replaceWithMock(m, shouldMock) }
72+
if (params != call.params) {
73+
mockedStatementModel = UtExecutableCallModel(call.instance, call.executable, params)
74+
}
75+
}
76+
}
77+
mockedStatementModel ?: call
78+
}
79+
return with(model) {
80+
UtAssembleModel(id, classId, modelName, instantiationCall, origin) { models }
81+
}
82+
}

utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/FuzzerMockableMethodId.kt

-32
This file was deleted.

utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/ObjectModelProvider.kt

+16-11
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ class ObjectModelProvider(
110110
mock = {
111111
field.getter?.let { g ->
112112
val getterMethodID = MethodId(
113-
constructorId.classId,
114-
g.name,
115-
g.returnType.id,
116-
emptyList()
113+
classId = constructorId.classId,
114+
name = g.name,
115+
returnType = g.returnType.id,
116+
parameters = emptyList()
117117
)
118118
mapOf(getterMethodID to listOf(value.model))
119119
} ?: emptyMap()
@@ -158,16 +158,21 @@ class ObjectModelProvider(
158158
return jClass.declaredFields.map { field ->
159159
val setterAndGetter = jClass.findPublicSetterGetterIfHasPublicGetter(field, description)
160160
FieldDescription(
161-
field.name,
162-
field.type.id,
163-
isAccessible(field, description.packageName) && !isFinal(field.modifiers) && !isStatic(field.modifiers),
164-
setterAndGetter?.first,
165-
setterAndGetter?.second,
161+
name = field.name,
162+
classId = field.type.id,
163+
canBeSetDirectly = isAccessible(field, description.packageName) && !isFinal(field.modifiers) && !isStatic(field.modifiers),
164+
setter = setterAndGetter?.setter,
165+
getter = setterAndGetter?.getter,
166166
)
167167
}
168168
}
169169

170-
private fun Class<*>.findPublicSetterGetterIfHasPublicGetter(field: Field, description: FuzzedMethodDescription): Pair<Method, Method>? {
170+
private class PublicSetterGetter(
171+
val setter: Method,
172+
val getter: Method,
173+
)
174+
175+
private fun Class<*>.findPublicSetterGetterIfHasPublicGetter(field: Field, description: FuzzedMethodDescription): PublicSetterGetter? {
171176
val postfixName = field.name.capitalize()
172177
val setterName = "set$postfixName"
173178
val getterName = "get$postfixName"
@@ -178,7 +183,7 @@ class ObjectModelProvider(
178183
it.name == setterName &&
179184
it.parameterCount == 1 &&
180185
it.parameterTypes[0] == field.type
181-
}?.let { it to getter }
186+
}?.let { PublicSetterGetter(it, getter) }
182187
} else {
183188
null
184189
}

utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/MockOfObjectModelProviderTest.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import org.utbot.framework.plugin.api.util.voidClassId
99
import org.utbot.framework.plugin.api.util.withUtContext
1010
import org.utbot.fuzzer.FuzzedMethodDescription
1111
import org.utbot.fuzzer.objects.create
12-
import org.utbot.fuzzer.objects.replaceToMock
12+
import org.utbot.fuzzer.objects.replaceWithMock
1313
import org.utbot.fuzzer.objects.toFuzzerMockable
1414
import org.utbot.fuzzer.providers.ObjectModelProvider
1515

@@ -25,7 +25,7 @@ class MockOfObjectModelProviderTest {
2525
val description = FuzzedMethodDescription("test", voidClassId, listOf(Some::class.id))
2626
val provider = ObjectModelProvider(TestIdentityPreservingIdGenerator)
2727
val results = provider.generate(description).map { it.value.model }.map {
28-
replaceToMock(it) { m -> description.shouldMock(m) }
28+
replaceWithMock(it) { m -> description.shouldMock(m) }
2929
}.toList()
3030
assertEquals(2, results.size)
3131
results.forEach { model ->
@@ -42,7 +42,7 @@ class MockOfObjectModelProviderTest {
4242
}
4343
val provider = ObjectModelProvider(TestIdentityPreservingIdGenerator)
4444
val results = provider.generate(description).map { it.value.model }.map {
45-
replaceToMock(it) { m -> description.shouldMock(m) }
45+
replaceWithMock(it) { m -> description.shouldMock(m) }
4646
}.toList()
4747
assertEquals(2, results.size)
4848
results.forEach { model ->
@@ -58,7 +58,7 @@ class MockOfObjectModelProviderTest {
5858
}
5959
val provider = ObjectModelProvider(TestIdentityPreservingIdGenerator, recursionDepthLeft = 2)
6060
val results = provider.generate(description).map { it.value.model }.map {
61-
replaceToMock(it) { m -> description.shouldMock(m) }
61+
replaceWithMock(it) { m -> description.shouldMock(m) }
6262
}.toList()
6363
assertEquals(2, results.size)
6464
results.forEach { model ->
@@ -80,7 +80,7 @@ class MockOfObjectModelProviderTest {
8080
using empty constructor
8181
call instance field("some") with UtNullModel(Nothing::class.id)
8282
}
83-
val replacedModel = replaceToMock(customModel) { true }
83+
val replacedModel = replaceWithMock(customModel) { true }
8484
assertInstanceOf(UtCompositeModel::class.java, replacedModel)
8585
replacedModel as UtCompositeModel
8686
assertEquals(0, replacedModel.mocks.size)
@@ -99,7 +99,7 @@ class MockOfObjectModelProviderTest {
9999
yield(MethodId(classId, "another", doubleWrapperClassId, emptyList()) to listOf(UtPrimitiveModel(2.0)))
100100
} with values(UtNullModel(Nothing::class.id))
101101
}
102-
val replacedModel = replaceToMock(customModel) { true }
102+
val replacedModel = replaceWithMock(customModel) { true }
103103
assertInstanceOf(UtCompositeModel::class.java, replacedModel)
104104
replacedModel as UtCompositeModel
105105
assertEquals(0, replacedModel.fields.size)

0 commit comments

Comments
 (0)