Skip to content

Commit e76aaff

Browse files
committed
Extract JavaFuzzingContext into separate interface
1 parent ca7df7c commit e76aaff

File tree

7 files changed

+190
-146
lines changed

7 files changed

+190
-146
lines changed

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -439,12 +439,12 @@ class UtBotSymbolicEngine(
439439
val names = graph.body.method.tags.filterIsInstance<ParamNamesTag>().firstOrNull()?.names ?: emptyList()
440440
var testEmittedByFuzzer = 0
441441

442-
val valueProviders = try {
443-
concreteExecutionContext.tryCreateValueProvider(concreteExecutor, classUnderTest, defaultIdGenerator)
442+
val fuzzingContext = try {
443+
concreteExecutionContext.tryCreateFuzzingContext(concreteExecutor, classUnderTest, defaultIdGenerator)
444444
} catch (e: Exception) {
445445
emit(UtError(e.message ?: "Failed to create ValueProvider", e))
446446
return@flow
447-
}.let(transform)
447+
}
448448

449449
val coverageToMinStateBeforeSize = mutableMapOf<Trie.Node<Instruction>, Int>()
450450

@@ -453,7 +453,7 @@ class UtBotSymbolicEngine(
453453
methodUnderTest,
454454
constants = collectConstantsForFuzzer(graph),
455455
names = names,
456-
providers = listOf(valueProviders),
456+
providers = listOf(transform(fuzzingContext.valueProvider)),
457457
) { thisInstance, descr, values ->
458458
val diff = until - System.currentTimeMillis()
459459
val thresholdMillisForFuzzingOperation = 0 // may be better use 10-20 millis as it might not be possible
@@ -474,12 +474,11 @@ class UtBotSymbolicEngine(
474474
return@runJavaFuzzing BaseFeedback(Trie.emptyNode(), Control.PASS)
475475
}
476476

477-
val stateBefore = concreteExecutionContext.createStateBefore(
477+
val stateBefore = fuzzingContext.createStateBefore(
478478
thisInstance = thisInstance?.model,
479479
parameters = values.map { it.model },
480480
statics = emptyMap(),
481481
executableToCall = methodUnderTest,
482-
idGenerator = defaultIdGenerator
483482
)
484483

485484
val concreteExecutionResult: UtConcreteExecutionResult? = try {
@@ -496,6 +495,8 @@ class UtBotSymbolicEngine(
496495
// in case an exception occurred from the concrete execution
497496
concreteExecutionResult ?: return@runJavaFuzzing BaseFeedback(result = Trie.emptyNode(), control = Control.PASS)
498497

498+
fuzzingContext.handleFuzzedConcreteExecutionResult(concreteExecutionResult)
499+
499500
// in case of processed failure in the concrete execution
500501
concreteExecutionResult.processedFailure()?.let { failure ->
501502
logger.debug { "Instrumented process failed with exception ${failure.exception} before concrete execution started" }

utbot-framework/src/main/kotlin/org/utbot/framework/context/ConcreteExecutionContext.kt

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@ package org.utbot.framework.context
22

33
import org.utbot.framework.plugin.api.ClassId
44
import org.utbot.framework.plugin.api.ConcreteContextLoadingResult
5-
import org.utbot.framework.plugin.api.EnvironmentModels
6-
import org.utbot.framework.plugin.api.ExecutableId
7-
import org.utbot.framework.plugin.api.FieldId
85
import org.utbot.framework.plugin.api.UtExecution
9-
import org.utbot.framework.plugin.api.UtModel
10-
import org.utbot.fuzzer.IdGenerator
116
import org.utbot.fuzzer.IdentityPreservingIdGenerator
12-
import org.utbot.fuzzing.JavaValueProvider
137
import org.utbot.instrumentation.ConcreteExecutor
148
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
159
import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation
@@ -26,17 +20,9 @@ interface ConcreteExecutionContext {
2620
classUnderTestId: ClassId
2721
): List<UtExecution>
2822

29-
fun tryCreateValueProvider(
23+
fun tryCreateFuzzingContext(
3024
concreteExecutor: ConcreteExecutor<UtConcreteExecutionResult, UtExecutionInstrumentation>,
3125
classUnderTest: ClassId,
3226
idGenerator: IdentityPreservingIdGenerator<Int>,
33-
): JavaValueProvider
34-
35-
fun createStateBefore(
36-
thisInstance: UtModel?,
37-
parameters: List<UtModel>,
38-
statics: Map<FieldId, UtModel>,
39-
executableToCall: ExecutableId,
40-
idGenerator: IdGenerator<Int>
41-
): EnvironmentModels
27+
): JavaFuzzingContext
4228
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.utbot.framework.context
2+
3+
import org.utbot.framework.plugin.api.ClassId
4+
import org.utbot.framework.plugin.api.EnvironmentModels
5+
import org.utbot.framework.plugin.api.ExecutableId
6+
import org.utbot.framework.plugin.api.FieldId
7+
import org.utbot.framework.plugin.api.UtModel
8+
import org.utbot.fuzzer.IdentityPreservingIdGenerator
9+
import org.utbot.fuzzing.JavaValueProvider
10+
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
11+
12+
interface JavaFuzzingContext {
13+
val classUnderTest: ClassId
14+
val idGenerator: IdentityPreservingIdGenerator<Int>
15+
val valueProvider: JavaValueProvider
16+
17+
fun createStateBefore(
18+
thisInstance: UtModel?,
19+
parameters: List<UtModel>,
20+
statics: Map<FieldId, UtModel>,
21+
executableToCall: ExecutableId,
22+
): EnvironmentModels
23+
24+
fun handleFuzzedConcreteExecutionResult(concreteExecutionResult: UtConcreteExecutionResult)
25+
}
Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
package org.utbot.framework.context.simple
22

33
import org.utbot.framework.context.ConcreteExecutionContext
4+
import org.utbot.framework.context.JavaFuzzingContext
45
import org.utbot.framework.plugin.api.ClassId
56
import org.utbot.framework.plugin.api.ConcreteContextLoadingResult
6-
import org.utbot.framework.plugin.api.EnvironmentModels
7-
import org.utbot.framework.plugin.api.ExecutableId
8-
import org.utbot.framework.plugin.api.FieldId
97
import org.utbot.framework.plugin.api.UtExecution
10-
import org.utbot.framework.plugin.api.UtModel
11-
import org.utbot.fuzzer.IdGenerator
128
import org.utbot.fuzzer.IdentityPreservingIdGenerator
13-
import org.utbot.fuzzing.JavaValueProvider
14-
import org.utbot.fuzzing.ValueProvider
15-
import org.utbot.fuzzing.defaultValueProviders
169
import org.utbot.instrumentation.ConcreteExecutor
1710
import org.utbot.instrumentation.instrumentation.execution.SimpleUtExecutionInstrumentation
1811
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
@@ -32,22 +25,9 @@ class SimpleConcreteExecutionContext(fullClassPath: String) : ConcreteExecutionC
3225
classUnderTestId: ClassId
3326
): List<UtExecution> = executions
3427

35-
override fun tryCreateValueProvider(
28+
override fun tryCreateFuzzingContext(
3629
concreteExecutor: ConcreteExecutor<UtConcreteExecutionResult, UtExecutionInstrumentation>,
3730
classUnderTest: ClassId,
3831
idGenerator: IdentityPreservingIdGenerator<Int>
39-
): JavaValueProvider = ValueProvider.of(defaultValueProviders(idGenerator))
40-
41-
override fun createStateBefore(
42-
thisInstance: UtModel?,
43-
parameters: List<UtModel>,
44-
statics: Map<FieldId, UtModel>,
45-
executableToCall: ExecutableId,
46-
idGenerator: IdGenerator<Int>
47-
): EnvironmentModels = EnvironmentModels(
48-
thisInstance = thisInstance,
49-
parameters = parameters,
50-
statics = statics,
51-
executableToCall = executableToCall
52-
)
32+
): JavaFuzzingContext = SimpleJavaFuzzingContext(classUnderTest, idGenerator)
5333
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.utbot.framework.context.simple
2+
3+
import org.utbot.framework.context.JavaFuzzingContext
4+
import org.utbot.framework.plugin.api.ClassId
5+
import org.utbot.framework.plugin.api.EnvironmentModels
6+
import org.utbot.framework.plugin.api.ExecutableId
7+
import org.utbot.framework.plugin.api.FieldId
8+
import org.utbot.framework.plugin.api.UtModel
9+
import org.utbot.fuzzer.IdentityPreservingIdGenerator
10+
import org.utbot.fuzzing.JavaValueProvider
11+
import org.utbot.fuzzing.ValueProvider
12+
import org.utbot.fuzzing.defaultValueProviders
13+
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
14+
15+
class SimpleJavaFuzzingContext(
16+
override val classUnderTest: ClassId,
17+
override val idGenerator: IdentityPreservingIdGenerator<Int>,
18+
) : JavaFuzzingContext {
19+
override val valueProvider: JavaValueProvider =
20+
ValueProvider.of(defaultValueProviders(idGenerator))
21+
22+
override fun createStateBefore(
23+
thisInstance: UtModel?,
24+
parameters: List<UtModel>,
25+
statics: Map<FieldId, UtModel>,
26+
executableToCall: ExecutableId,
27+
): EnvironmentModels = EnvironmentModels(
28+
thisInstance = thisInstance,
29+
parameters = parameters,
30+
statics = statics,
31+
executableToCall = executableToCall
32+
)
33+
34+
override fun handleFuzzedConcreteExecutionResult(concreteExecutionResult: UtConcreteExecutionResult) =
35+
Unit
36+
}
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,20 @@
11
package org.utbot.framework.context.spring
22

33
import mu.KotlinLogging
4-
import org.utbot.common.tryLoadClass
54
import org.utbot.framework.context.ConcreteExecutionContext
5+
import org.utbot.framework.context.JavaFuzzingContext
66
import org.utbot.framework.plugin.api.ClassId
77
import org.utbot.framework.plugin.api.ConcreteContextLoadingResult
8-
import org.utbot.framework.plugin.api.ConstructorId
9-
import org.utbot.framework.plugin.api.EnvironmentModels
10-
import org.utbot.framework.plugin.api.ExecutableId
11-
import org.utbot.framework.plugin.api.FieldId
12-
import org.utbot.framework.plugin.api.MethodId
13-
import org.utbot.framework.plugin.api.SpringRepositoryId
148
import org.utbot.framework.plugin.api.SpringSettings
159
import org.utbot.framework.plugin.api.UtExecution
16-
import org.utbot.framework.plugin.api.UtModel
17-
import org.utbot.framework.plugin.api.util.SpringModelUtils
18-
import org.utbot.framework.plugin.api.util.SpringModelUtils.createMockMvcModel
19-
import org.utbot.framework.plugin.api.util.SpringModelUtils.createRequestBuilderModelOrNull
20-
import org.utbot.framework.plugin.api.util.SpringModelUtils.mockMvcPerformMethodId
21-
import org.utbot.framework.plugin.api.util.allDeclaredFieldIds
22-
import org.utbot.framework.plugin.api.util.jField
23-
import org.utbot.framework.plugin.api.util.utContext
24-
import org.utbot.fuzzer.IdGenerator
2510
import org.utbot.fuzzer.IdentityPreservingIdGenerator
26-
import org.utbot.fuzzing.JavaValueProvider
27-
import org.utbot.fuzzing.ValueProvider
28-
import org.utbot.fuzzing.providers.AnyDepthNullValueProvider
29-
import org.utbot.fuzzing.spring.GeneratedFieldValueProvider
30-
import org.utbot.fuzzing.spring.SpringBeanValueProvider
31-
import org.utbot.fuzzing.spring.preserveProperties
32-
import org.utbot.fuzzing.spring.valid.EmailValueProvider
33-
import org.utbot.fuzzing.spring.valid.NotBlankStringValueProvider
34-
import org.utbot.fuzzing.spring.valid.NotEmptyStringValueProvider
35-
import org.utbot.fuzzing.spring.valid.ValidEntityValueProvider
3611
import org.utbot.instrumentation.ConcreteExecutor
3712
import org.utbot.instrumentation.getRelevantSpringRepositories
3813
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
3914
import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation
4015
import org.utbot.instrumentation.instrumentation.spring.SpringUtExecutionInstrumentation
4116
import org.utbot.instrumentation.tryLoadingSpringContext
4217
import java.io.File
43-
import org.utbot.fuzzing.providers.ObjectValueProvider
44-
import org.utbot.fuzzing.providers.anyObjectValueProvider
4518

4619
class SpringIntegrationTestConcreteExecutionContext(
4720
private val delegateContext: ConcreteExecutionContext,
@@ -79,11 +52,11 @@ class SpringIntegrationTestConcreteExecutionContext(
7952
classUnderTestId: ClassId
8053
): List<UtExecution> = delegateContext.transformExecutionsBeforeMinimization(executions, classUnderTestId)
8154

82-
override fun tryCreateValueProvider(
55+
override fun tryCreateFuzzingContext(
8356
concreteExecutor: ConcreteExecutor<UtConcreteExecutionResult, UtExecutionInstrumentation>,
8457
classUnderTest: ClassId,
8558
idGenerator: IdentityPreservingIdGenerator<Int>
86-
): JavaValueProvider {
59+
): JavaFuzzingContext {
8760
if (springApplicationContext.getBeansAssignableTo(classUnderTest).isEmpty())
8861
error(
8962
"No beans of type ${classUnderTest.name} are found. " +
@@ -94,77 +67,10 @@ class SpringIntegrationTestConcreteExecutionContext(
9467
val relevantRepositories = concreteExecutor.getRelevantSpringRepositories(classUnderTest)
9568
logger.info { "Detected relevant repositories for class $classUnderTest: $relevantRepositories" }
9669

97-
val springBeanValueProvider = SpringBeanValueProvider(
98-
idGenerator,
99-
beanNameProvider = { classId ->
100-
springApplicationContext.getBeansAssignableTo(classId).map { it.beanName }
101-
},
102-
relevantRepositories = relevantRepositories
70+
return SpringIntegrationTestJavaFuzzingContext(
71+
delegateContext = delegateContext.tryCreateFuzzingContext(concreteExecutor, classUnderTest, idGenerator),
72+
relevantRepositories = relevantRepositories,
73+
springApplicationContext = springApplicationContext,
10374
)
104-
105-
return springBeanValueProvider
106-
.withFallback(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = true))
107-
.withFallback(EmailValueProvider())
108-
.withFallback(NotBlankStringValueProvider())
109-
.withFallback(NotEmptyStringValueProvider())
110-
.withFallback(
111-
delegateContext.tryCreateValueProvider(concreteExecutor, classUnderTest, idGenerator)
112-
.except { p -> p is ObjectValueProvider }
113-
.with(anyObjectValueProvider(idGenerator, shouldMutateWithMethods = true))
114-
.with(ValidEntityValueProvider(idGenerator, onlyAcceptWhenValidIsRequired = false))
115-
.with(createGeneratedFieldValueProviders(relevantRepositories, idGenerator))
116-
.withFallback(AnyDepthNullValueProvider)
117-
)
118-
.preserveProperties()
119-
}
120-
121-
private fun createGeneratedFieldValueProviders(
122-
relevantRepositories: Set<SpringRepositoryId>,
123-
idGenerator: IdentityPreservingIdGenerator<Int>
124-
): JavaValueProvider {
125-
val generatedValueAnnotationClasses = SpringModelUtils.generatedValueClassIds.mapNotNull {
126-
@Suppress("UNCHECKED_CAST") // type system fails to understand that @GeneratedValue is indeed an annotation
127-
utContext.classLoader.tryLoadClass(it.name) as Class<out Annotation>?
128-
}
129-
130-
val generatedValueFields =
131-
relevantRepositories
132-
.flatMap { springRepositoryId ->
133-
val entityClassId = springRepositoryId.entityClassId
134-
entityClassId.allDeclaredFieldIds
135-
.filter { fieldId -> generatedValueAnnotationClasses.any { fieldId.jField.isAnnotationPresent(it) } }
136-
.map { entityClassId to it }
137-
}
138-
139-
logger.info { "Detected @GeneratedValue fields: $generatedValueFields" }
140-
141-
return ValueProvider.of(generatedValueFields.map { (entityClassId, fieldId) ->
142-
GeneratedFieldValueProvider(idGenerator, entityClassId, fieldId)
143-
})
144-
}
145-
146-
override fun createStateBefore(
147-
thisInstance: UtModel?,
148-
parameters: List<UtModel>,
149-
statics: Map<FieldId, UtModel>,
150-
executableToCall: ExecutableId,
151-
idGenerator: IdGenerator<Int>
152-
): EnvironmentModels {
153-
val delegateStateBefore = delegateContext.createStateBefore(thisInstance, parameters, statics, executableToCall, idGenerator)
154-
return when (executableToCall) {
155-
is ConstructorId -> delegateStateBefore
156-
is MethodId -> {
157-
val requestBuilderModel = createRequestBuilderModelOrNull(
158-
methodId = executableToCall,
159-
arguments = parameters,
160-
idGenerator = { idGenerator.createId() }
161-
) ?: return delegateStateBefore
162-
delegateStateBefore.copy(
163-
thisInstance = createMockMvcModel { idGenerator.createId() },
164-
parameters = listOf(requestBuilderModel),
165-
executableToCall = mockMvcPerformMethodId,
166-
)
167-
}
168-
}
16975
}
17076
}

0 commit comments

Comments
 (0)