Skip to content

Commit 3bcf41e

Browse files
Added mutations
1 parent 27ac3a0 commit 3bcf41e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+888
-914
lines changed

utbot-framework/src/main/kotlin/org/utbot/engine/greyboxfuzzer/GreyBoxFuzzer.kt

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import org.utbot.framework.util.sootMethod
1313
import org.utbot.instrumentation.ConcreteExecutor
1414
import java.lang.reflect.Field
1515
import java.lang.reflect.Method
16-
import java.lang.reflect.Modifier
1716
import kotlin.random.Random
1817

1918
class GreyBoxFuzzer(
@@ -23,15 +22,15 @@ class GreyBoxFuzzer(
2322
) {
2423

2524
private val seeds = SeedCollector()
26-
private val explorationStageIterations = 50
25+
private val explorationStageIterations = 100
2726
private val exploitationStageIterations = 100
2827

2928
//TODO make it return Sequence<UtExecution>
3029
suspend fun fuzz(): Sequence<UtExecution> {
3130
logger.debug { "Started to fuzz ${methodUnderTest.name}" }
3231
val javaClazz = methodUnderTest.classId.jClass
33-
val javaMethod = methodUnderTest.sootMethod.toJavaMethod()!!
3432
val sootMethod = methodUnderTest.sootMethod
33+
val javaMethod = sootMethod.toJavaMethod()!!
3534
val classFieldsUsedByFunc = sootMethod.getClassFieldsUsedByFunc(javaClazz)
3635
val methodLines = sootMethod.activeBody.units.map { it.javaSourceStartLineNumber }.filter { it != -1 }.toSet()
3736
val currentCoverageByLines = CoverageCollector.coverage
@@ -43,13 +42,12 @@ class GreyBoxFuzzer(
4342
javaMethod,
4443
explorationStageIterations,
4544
methodLines,
46-
javaClazz,
4745
classFieldsUsedByFunc,
4846
methodUnderTest,
4947
currentCoverageByLines
5048
)
5149
logger.debug { "SEEDS AFTER EXPLORATION STAGE = ${seeds.seedsSize()}" }
52-
//exploitationStage(exploitationStageIterations, javaClazz, methodLines, currentCoverageByLines)
50+
exploitationStage(exploitationStageIterations, javaClazz, methodLines, currentCoverageByLines)
5351
//UtModelGenerator.reset()
5452
return sequenceOf()
5553
}
@@ -58,11 +56,32 @@ class GreyBoxFuzzer(
5856
method: Method,
5957
numberOfIterations: Int,
6058
methodLinesToCover: Set<Int>,
61-
clazz: Class<*>,
6259
classFieldsUsedByFunc: Set<Field>,
6360
methodUnderTest: ExecutableId,
6461
prevMethodCoverage: Set<Int>
6562
) {
63+
// val param = method.parameters.first()
64+
// val firstGenerator = GreyBoxFuzzerGenerators.generatorRepository.getOrProduceGenerator(param, 0)!!
65+
// var generator = firstGenerator
66+
// println("GENERATOR = $generator")
67+
// val generatedValue = generator.generateImpl(GreyBoxFuzzerGenerators.sourceOfRandomness, GreyBoxFuzzerGenerators.genStatus)
68+
// println("GENERATED VALUE = $generatedValue")
69+
// generator.generationState = GenerationState.CACHE
70+
// val valueFromCache = generator.generateImpl(GreyBoxFuzzerGenerators.sourceOfRandomness, GreyBoxFuzzerGenerators.genStatus)
71+
// println("VALUE FROM CACHE = $valueFromCache")
72+
// //generator = firstGenerator.copy()
73+
// generator.generationState = GenerationState.MODIFY
74+
// val modifiedValue = generator.generateImpl(GreyBoxFuzzerGenerators.sourceOfRandomness, GreyBoxFuzzerGenerators.genStatus)
75+
// println("MODIFIED VALUE = $modifiedValue")
76+
// //generator = firstGenerator.copy()
77+
// generator.generationState = GenerationState.MODIFY
78+
// val modifiedValue2 = generator.generateImpl(GreyBoxFuzzerGenerators.sourceOfRandomness, GreyBoxFuzzerGenerators.genStatus)
79+
// println("MODIFIED VALUE = $modifiedValue2")
80+
// //generator = firstGenerator.copy()
81+
// generator.generationState = GenerationState.MODIFY
82+
// val modifiedValue3 = generator.generateImpl(GreyBoxFuzzerGenerators.sourceOfRandomness, GreyBoxFuzzerGenerators.genStatus)
83+
// println("MODIFIED VALUE = $modifiedValue3")
84+
// exitProcess(0)
6685
val parametersToGenericsReplacer = method.parameters.map { it to GenericsReplacer() }
6786
val thisInstancesHistory = ArrayDeque<ThisInstance>()
6887
repeat(numberOfIterations) { iterationNumber ->
@@ -119,6 +138,7 @@ class GreyBoxFuzzer(
119138
)
120139
seeds.addSeed(Seed(thisInstance, generatedParameters, seedScore.toDouble()))
121140
logger.debug { "Execution result: ${executionResult.result}" }
141+
logger.debug { "Seed score = $seedScore" }
122142
} catch (e: Throwable) {
123143
logger.debug(e) { "Exception while execution :(" }
124144
thisInstancesHistory.clear()
@@ -140,24 +160,44 @@ class GreyBoxFuzzer(
140160
.map { it.lineNumber }
141161
//.filter { it in currentMethodLines }
142162
.toSet()
163+
val currentMethodCoverage = coverage.filter { it in currentMethodLines }
143164
executionResult.coverage.coveredInstructions.forEach { CoverageCollector.coverage.add(it) }
144-
return (coverage - prevMethodCoverage).size
165+
return (currentMethodCoverage - prevMethodCoverage).size
145166
}
146167

147168

148169
//TODO under construction
149-
private fun exploitationStage(
170+
private suspend fun exploitationStage(
150171
numberOfIterations: Int,
151172
clazz: Class<*>,
152173
methodLinesToCover: Set<Int>,
153174
prevMethodCoverage: Set<Int>
154175
) {
155176
logger.debug { "Exploitation began" }
156177
repeat(numberOfIterations) {
178+
logger.debug { "Mutation iteration $it" }
157179
val randomSeed = seeds.getRandomWeightedSeed() ?: return@repeat
158-
val randomSeedArgs = randomSeed.arguments.toMutableList()
159-
val randomParameter = randomSeedArgs.random()
160-
Mutator.mutateParameter(randomParameter)
180+
logger.debug { "Random seed params = ${randomSeed.parameters}" }
181+
val mutatedSeed = Mutator.mutateSeed(randomSeed, GreyBoxFuzzerGenerators.sourceOfRandomness, GreyBoxFuzzerGenerators.genStatus)
182+
logger.debug { "Mutated params = ${mutatedSeed.parameters}" }
183+
val stateBefore = mutatedSeed.createEnvironmentModels()
184+
try {
185+
val executionResult = execute(stateBefore, methodUnderTest)
186+
logger.debug { "Execution result: $executionResult" }
187+
val seedScore =
188+
handleCoverage(
189+
executionResult,
190+
prevMethodCoverage,
191+
methodLinesToCover
192+
)
193+
mutatedSeed.score = seedScore.toDouble()
194+
seeds.addSeed(mutatedSeed)
195+
logger.debug { "Execution result: ${executionResult.result}" }
196+
logger.debug { "Seed score = $seedScore" }
197+
} catch (e: Throwable) {
198+
logger.debug(e) { "Exception while execution :(" }
199+
return@repeat
200+
}
161201
}
162202
}
163203
// private suspend fun exploitationStage(

utbot-framework/src/main/kotlin/org/utbot/engine/greyboxfuzzer/generator/DataGenerator.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import org.utbot.framework.plugin.api.ClassId
1111
import org.utbot.framework.plugin.api.UtModel
1212
import org.utbot.framework.plugin.api.UtNullModel
1313
import org.utbot.framework.plugin.api.util.jClass
14-
import soot.SootMethod
1514
import java.lang.reflect.Parameter
1615

1716
object DataGenerator {
@@ -22,20 +21,20 @@ object DataGenerator {
2221
clazz: Class<*>,
2322
random: SourceOfRandomness,
2423
status: GenerationStatus
25-
): UtModel? = generatorRepository.getOrProduceGenerator(clazz)?.generate(random, status)
24+
): UtModel? = generatorRepository.getOrProduceGenerator(clazz)?.generateImpl(random, status)
2625

2726
fun generate(
2827
parameterTypeContext: ParameterTypeContext,
2928
random: SourceOfRandomness,
3029
status: GenerationStatus
31-
): UtModel? = generatorRepository.getOrProduceGenerator(parameterTypeContext, 0)?.generate(random, status)
30+
): UtModel? = generatorRepository.getOrProduceGenerator(parameterTypeContext, 0)?.generateImpl(random, status)
3231

3332
fun generate(
3433
parameterTypeContext: ParameterTypeContext,
3534
random: SourceOfRandomness,
3635
status: GenerationStatus,
3736
depth: Int
38-
): UtModel? = generatorRepository.getOrProduceGenerator(parameterTypeContext, depth)?.generate(random, status)
37+
): UtModel? = generatorRepository.getOrProduceGenerator(parameterTypeContext, depth)?.generateImpl(random, status)
3938

4039
fun generate(
4140
parameter: Parameter,
@@ -74,7 +73,7 @@ object DataGenerator {
7473
repeat(numberOfTries) {
7574
logger.debug { "Try $it" }
7675
try {
77-
generatedValue = generator.generate(random, status)
76+
generatedValue = generator.generateImpl(random, status)
7877
return NormalMethodThisInstance(
7978
generatedValue,
8079
generator,
@@ -105,7 +104,7 @@ object DataGenerator {
105104
repeat(numberOfTries) {
106105
logger.debug { "Try $it" }
107106
try {
108-
generatedValue = generator.generate(random, status)
107+
generatedValue = generator.generateImpl(random, status)
109108
return FParameter(
110109
parameter,
111110
null,

utbot-framework/src/main/kotlin/org/utbot/engine/greyboxfuzzer/generator/FParameter.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.utbot.engine.greyboxfuzzer.generator
22

33
import org.utbot.engine.greyboxfuzzer.mutator.Mutator
4+
import org.utbot.engine.greyboxfuzzer.util.copy
45
import org.utbot.engine.greyboxfuzzer.util.getAllDeclaredFields
56
import org.utbot.quickcheck.generator.Generator
67
import org.utbot.external.api.classIdForType
78
import org.utbot.framework.plugin.api.ClassId
89
import org.utbot.framework.plugin.api.UtAssembleModel
10+
import org.utbot.framework.plugin.api.UtCompositeModel
911
import org.utbot.framework.plugin.api.UtModel
1012
import org.utbot.framework.plugin.api.util.jClass
1113
import java.lang.reflect.Field
@@ -51,10 +53,29 @@ data class FParameter(
5153
fun regenerateFields() {
5254
regenerateFields(classId.jClass.getAllDeclaredFields())
5355
}
56+
5457
fun regenerateFields(fieldsToRegenerate: List<Field>) {
5558
if (utModel is UtAssembleModel) {
5659
utModel = Mutator.regenerateFields(classId.jClass, utModel as UtAssembleModel, fieldsToRegenerate)
5760
}
5861
}
5962

63+
fun copy(): FParameter = FParameter(
64+
parameter,
65+
value,
66+
utModel.copy(),
67+
generator?.copy(),
68+
classId,
69+
fields
70+
)
71+
72+
fun replaceUtModel(newUtModel: UtModel): FParameter = FParameter(
73+
parameter,
74+
value,
75+
newUtModel,
76+
generator?.copy(),
77+
classId,
78+
fields
79+
)
80+
6081
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.utbot.engine.greyboxfuzzer.generator
2+
3+
import org.utbot.engine.greyboxfuzzer.util.copy
4+
import org.utbot.framework.plugin.api.ClassId
5+
import org.utbot.framework.plugin.api.UtModel
6+
import org.utbot.quickcheck.generator.Generator
7+
8+
sealed interface ThisInstance {
9+
val utModelForExecution: UtModel?
10+
fun copy(): ThisInstance
11+
}
12+
13+
data class NormalMethodThisInstance(
14+
val utModel: UtModel,
15+
val generator: Generator,
16+
val classId: ClassId
17+
): ThisInstance {
18+
override val utModelForExecution = utModel
19+
override fun copy(): ThisInstance {
20+
return NormalMethodThisInstance(
21+
utModel.copy(),
22+
generator.copy(),
23+
classId
24+
)
25+
}
26+
}
27+
28+
object StaticMethodThisInstance: ThisInstance {
29+
override val utModelForExecution = null
30+
override fun copy(): ThisInstance {
31+
return StaticMethodThisInstance
32+
}
33+
}

0 commit comments

Comments
 (0)