Skip to content

Commit 04fe674

Browse files
fixes
1 parent 554a9c9 commit 04fe674

File tree

8 files changed

+128
-52
lines changed

8 files changed

+128
-52
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class GreyBoxFuzzer(
4141
private val timeOfStart = System.currentTimeMillis()
4242
private val percentageOfTimeBudgetToChangeMode = 25
4343
private val logger = KotlinLogging.logger {}
44+
private val classMutator = Mutator()
4445

4546
init {
4647
GenericsInfoFactory.disableCache()
@@ -97,7 +98,7 @@ class GreyBoxFuzzer(
9798
regenerateThis = false
9899
} else if (Random.getTrue(60)) {
99100
logger.debug { "Trying to mutate this instance" }
100-
thisInstancesHistory += Mutator.mutateThisInstance(
101+
thisInstancesHistory += classMutator.mutateThisInstance(
101102
thisInstancesHistory.last(),
102103
classFieldsUsedByFunc.toList(),
103104
generatorContext
@@ -207,7 +208,7 @@ class GreyBoxFuzzer(
207208
val randomSeed = seeds.getRandomWeightedSeed()
208209
logger.debug { "Random seed params = ${randomSeed.parameters}" }
209210
val mutatedSeed =
210-
Mutator.mutateSeed(
211+
classMutator.mutateSeed(
211212
randomSeed,
212213
GreyBoxFuzzerGeneratorsAndSettings.sourceOfRandomness,
213214
GreyBoxFuzzerGeneratorsAndSettings.genStatus

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ object DataGenerator {
2929
): UtModel {
3030
val classId = parameterTypeContext.rawClass.id
3131
logger.debug { "Trying to generate UtModel of type ${classId.name} 3 times" }
32-
var generatedInstance: UtModel? = null
32+
var generatedInstance: UtModel?
3333
repeat(3) {
3434
generatedInstance =
3535
try {

utbot-greyboxfuzzer/src/main/kotlin/org/utbot/greyboxfuzzer/generator/userclasses/UserClassGenerator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class UserClassGenerator : ComponentizedGenerator(Any::class.java) {
164164
val resolvedJavaType = parameterTypeContext!!.generics.resolveType(parameterTypeContext!!.type())
165165
val gctx = resolvedJavaType.createGenericsContext(clazz!!)
166166
if (clazz == randomFieldDeclaringClass) {
167-
return Mutator.regenerateFieldWithContext(gctx, cachedUtModel, randomField, generatorContext)?.let {
167+
return Mutator().regenerateFieldWithContext(gctx, cachedUtModel, randomField, generatorContext)?.let {
168168
mutatedFields[randomField] = it.second
169169
it.first
170170
} ?: cachedUtModel
@@ -184,7 +184,7 @@ class UserClassGenerator : ComponentizedGenerator(Any::class.java) {
184184
clazz!!,
185185
chain.map { it!! }.reversed().drop(1)
186186
) ?: return cachedUtModel
187-
return Mutator.regenerateFieldWithContext(genericsContext, cachedUtModel, randomField, generatorContext)
187+
return Mutator().regenerateFieldWithContext(genericsContext, cachedUtModel, randomField, generatorContext)
188188
?.let {
189189
mutatedFields[randomField] = it.second
190190
it.first

utbot-greyboxfuzzer/src/main/kotlin/org/utbot/greyboxfuzzer/generator/userclasses/generator/InterfaceImplementationsInstanceGenerator.kt

Lines changed: 95 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
package org.utbot.greyboxfuzzer.generator.userclasses.generator
44

55
import org.utbot.common.isAbstract
6-
import org.utbot.greyboxfuzzer.generator.DataGenerator
76
import org.utbot.greyboxfuzzer.generator.QuickCheckExtensions
87
import org.utbot.greyboxfuzzer.util.*
98
import org.utbot.greyboxfuzzer.util.logger
109
import org.utbot.framework.plugin.api.*
1110
import org.utbot.framework.plugin.api.util.executableId
1211
import org.utbot.framework.plugin.api.util.id
1312
import org.utbot.framework.plugin.api.util.objectClassId
13+
import org.utbot.greyboxfuzzer.generator.GreyBoxFuzzerGeneratorsAndSettings.generatorRepository
14+
import org.utbot.greyboxfuzzer.generator.getOrProduceGenerator
15+
import org.utbot.greyboxfuzzer.generator.userclasses.UserClassGenerator
1416
import org.utbot.greyboxfuzzer.quickcheck.generator.GenerationStatus
1517
import org.utbot.greyboxfuzzer.quickcheck.generator.GeneratorContext
1618
import org.utbot.greyboxfuzzer.quickcheck.internal.ParameterTypeContext
@@ -30,6 +32,9 @@ class InterfaceImplementationsInstanceGenerator(
3032
override fun generate(): UtModel {
3133
//Try to generate with statics with some probability
3234
val clazz = resolvedType.toClass() ?: return UtNullModel(objectClassId)
35+
if (clazz.name.contains("HttpOutputMessage")) {
36+
println()
37+
}
3338
if (Random.getTrue(50)) {
3439
try {
3540
StaticsBasedInstanceGenerator(
@@ -47,10 +52,20 @@ class InterfaceImplementationsInstanceGenerator(
4752
}
4853
}
4954
val genericsContext =
50-
QuickCheckExtensions.getRandomImplementerGenericContext(clazz, resolvedType)// ?: return UtNullModel(clazz.id)
51-
if (genericsContext == null || Random.getTrue(30)) {
52-
return generateMock(clazz, resolvedType, typeContext, generatorContext)
55+
QuickCheckExtensions.getRandomImplementerGenericContext(
56+
clazz,
57+
resolvedType
58+
)// ?: return UtNullModel(clazz.id)
59+
logger.debug { "Implementer of ${clazz.name}! It is a ${genericsContext?.currentClass()?.name}" }
60+
if (genericsContext == null || Random.getTrue(5)) {
61+
logger.debug { "Generate mock anyway" }
62+
return try {
63+
generateMock(clazz, resolvedType, typeContext, generatorContext)
64+
} catch (e: Throwable) {
65+
UtNullModel(clazz.id)
66+
}
5367
}
68+
logger.debug { "Trying to generate implementer ${genericsContext.currentClass().name}" }
5469
val resUtModel =
5570
ClassesInstanceGenerator(
5671
genericsContext.currentClass(),
@@ -79,13 +94,22 @@ class InterfaceImplementationsInstanceGenerator(
7994
)
8095
else -> resUtModel
8196
}
82-
.let {
83-
if (it is UtNullModel && Random.getTrue(50)) generateMock(
84-
clazz,
85-
resolvedType,
86-
typeContext,
87-
generatorContext
88-
) else it
97+
.let {
98+
if (it is UtNullModel && Random.getTrue(50)) {
99+
try {
100+
generateMock(
101+
clazz,
102+
resolvedType,
103+
typeContext,
104+
generatorContext
105+
)
106+
}catch (e: Throwable) {
107+
it
108+
}
109+
}
110+
else {
111+
it
112+
}
89113
}
90114
}
91115

@@ -95,33 +119,45 @@ class InterfaceImplementationsInstanceGenerator(
95119
typeContext: GenericsContext,
96120
generatorContext: GeneratorContext
97121
): UtModel {
122+
logger.debug { "Mock generation" }
98123
if (!clazz.isInterface) return UtNullModel(clazz.id)
99124
val sootClazz = clazz.toSootClass() ?: return UtNullModel(clazz.id)
100125
val constructor = generatorContext.utModelConstructor
101126
val allNeededInterfaces = clazz.methods.map { it.declaringClass }.filter { it != clazz }.toSet()
102-
val chainToGenericsContext = allNeededInterfaces.map { cl ->
103-
val chain = cl.toSootClass()
104-
?.getImplementersOfWithChain()
105-
?.filter { it.contains(sootClazz) }
106-
?.map { it.dropLastWhile { it != sootClazz } }
107-
?.minByOrNull { it.size }
108-
?.map { it.toJavaClass() }
109-
if (chain == null || chain.any { it == null }) {
110-
null
111-
} else {
112-
cl to QuickCheckExtensions.buildGenericsContextForInterfaceParent(
113-
resolvedType,
114-
clazz,
115-
chain.map { it!! }.reversed().drop(1)
116-
)
117-
}
118-
}
119-
val allChainToGenericsContext = chainToGenericsContext + (clazz to typeContext)
127+
val allChainToGenericsContext = allNeededInterfaces.map { it to ParameterTypeContext.forClass(it).generics } + (clazz to typeContext)
128+
// if (allNeededInterfaces.all { it.typeParameters.isEmpty() }) {
129+
// allNeededInterfaces.map { it to ParameterTypeContext.forType(it).generics }
130+
// } else {
131+
// //TODO debug this
132+
// val chainToGenericsContext = allNeededInterfaces.map { cl ->
133+
// val chain = cl.toSootClass()
134+
// ?.getImplementersOfWithChain(onlyConcreteClasses = false, allowNotOnlyStdLib = true)
135+
// ?.filter { it.contains(sootClazz) }
136+
// ?.map { it.dropLastWhile { it != sootClazz } }
137+
// ?.minByOrNull { it.size }
138+
// ?.map { it.toJavaClass() }
139+
// if (chain == null || chain.any { it == null }) {
140+
// null
141+
// } else {
142+
// cl to QuickCheckExtensions.buildGenericsContextForInterfaceParent(
143+
// resolvedType,
144+
// clazz,
145+
// chain.map { it!! }.reversed().drop(1)
146+
// )
147+
// }
148+
// }
149+
// chainToGenericsContext + (clazz to typeContext)
150+
// }
151+
//val allChainToGenericsContext = chainToGenericsContext + (clazz to typeContext)
120152
val mocks = clazz.methods
121153
.filter { it.isAbstract }
122154
.associateTo(mutableMapOf()) { method ->
123155
val genericsContextForMethod =
124-
allChainToGenericsContext.find { it!!.first == method.declaringClass }?.second
156+
try {
157+
allChainToGenericsContext.find { it!!.first == method.declaringClass }?.second
158+
} catch (e: Throwable) {
159+
null
160+
}
125161
val methodReturnType =
126162
if (genericsContextForMethod != null) {
127163
genericsContextForMethod.method(method).resolveReturnType().let {
@@ -133,13 +169,7 @@ class InterfaceImplementationsInstanceGenerator(
133169
val parameterTypeContext = ParameterTypeContext.forType(methodReturnType, genericsContextForMethod)
134170
val generatedUtModelWithReturnType =
135171
try {
136-
DataGenerator.generateUtModel(
137-
parameterTypeContext,
138-
depth,
139-
generatorContext,
140-
sourceOfRandomness,
141-
generationStatus
142-
)
172+
generateUtModelForMock(parameterTypeContext, depth, generatorContext, sourceOfRandomness, generationStatus)
143173
} catch (_: Throwable) {
144174
UtNullModel(methodReturnType.toClass()!!.id)
145175
}
@@ -148,6 +178,34 @@ class InterfaceImplementationsInstanceGenerator(
148178
return UtCompositeModel(constructor.computeUnusedIdAndUpdate(), clazz.id, isMock = true, mocks = mocks)
149179
}
150180

181+
private fun generateUtModelForMock(
182+
parameterTypeContext: ParameterTypeContext,
183+
depth: Int = 0,
184+
generatorContext: GeneratorContext,
185+
random: SourceOfRandomness,
186+
status: GenerationStatus
187+
): UtModel {
188+
val classId = parameterTypeContext.rawClass.id
189+
logger.debug { "Trying to generate UtModel of type ${classId.name} 3 times" }
190+
if (parameterTypeContext.getAllSubParameterTypeContexts(sourceOfRandomness).any { it.rawClass.isInterface }) {
191+
return UtNullModel(classId)
192+
}
193+
var generatedInstance: UtModel?
194+
repeat(3) {
195+
generatedInstance =
196+
try {
197+
val generator =
198+
generatorRepository.getOrProduceGenerator(parameterTypeContext, generatorContext, depth)
199+
?: return@repeat
200+
generator.generateImpl(random, status)
201+
} catch (_: Throwable) {
202+
null
203+
}
204+
generatedInstance?.let { if (it !is UtNullModel) return it }
205+
}
206+
return UtNullModel(classId)
207+
}
208+
151209
// private fun buildGenericsContextForInterfaceParent(resolvedType: Type, clazz: Class<*>, parentChain: List<Class<*>>): GenericsContext? {
152210
// val generics = mutableListOf<Pair<Type, MutableList<Type>>>()
153211
// var curClass = clazz

utbot-greyboxfuzzer/src/main/kotlin/org/utbot/greyboxfuzzer/mutator/Mutator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import java.lang.reflect.Field
1717
import java.lang.reflect.Modifier
1818
import kotlin.random.Random
1919

20-
object Mutator {
20+
class Mutator {
2121

2222
fun mutateSeed(seed: Seed, sourceOfRandomness: SourceOfRandomness, genStatus: GenerationStatus): Seed {
2323
val seedCopy = seed.copy()

utbot-greyboxfuzzer/src/main/kotlin/org/utbot/greyboxfuzzer/util/ReflectionUtils.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,17 @@ val ParameterizedTypeImpl.actualTypeArgumentsRecursive: List<Type>
228228
return res
229229
}
230230

231+
fun Class<*>.isFromSameJar(other: Class<*>) =
232+
try {
233+
val thisJar =
234+
this.getResource('/' + this.name.replace('.', '/') + ".class")?.path?.substringBefore(".jar!") ?: "1"
235+
val otherJar =
236+
other.getResource('/' + other.name.replace('.', '/') + ".class")?.path?.substringBefore(".jar!") ?: "2"
237+
thisJar == otherJar
238+
} catch (e: Throwable) {
239+
false
240+
}
241+
231242

232243
//fun Parameter.replaceUnresolvedGenericsToRandomTypes() {
233244
// val allUnresolvedTypesInType = (this.parameterizedType as? ParameterizedTypeImpl)

utbot-greyboxfuzzer/src/main/kotlin/org/utbot/greyboxfuzzer/util/SootUtils.kt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,28 @@ import java.lang.reflect.Method
2222
import kotlin.reflect.KFunction
2323
import kotlin.reflect.jvm.javaMethod
2424

25-
fun SootClass.getImplementersOfWithChain(): List<List<SootClass>> {
25+
fun SootClass.getImplementersOfWithChain(onlyConcreteClasses: Boolean = true, allowNotOnlyStdLib: Boolean = false): List<List<SootClass>> {
2626
this.checkLevel(SootClass.HIERARCHY)
2727
// if (!this.isInterface && !this.isAbstract) {
2828
// throw RuntimeException("interfaced needed; got $this")
2929
// }
30-
val hierarchy = Hierarchy()
30+
val thisAsJavaClass = this.toJavaClass() ?: return emptyList()
3131
val res = mutableListOf(mutableListOf(this))
3232
val queue = ArrayDeque<SootClass>()
3333
queue.add(this)
3434
while (queue.isNotEmpty()) {
3535
val curSootClass = queue.removeFirst()
3636
val implementers =
3737
if (curSootClass.isInterface) {
38-
hierarchy.getDirectImplementersOf(curSootClass)
39-
.filter { it.interfaces.contains(curSootClass) } + hierarchy.getDirectSubinterfacesOf(curSootClass)
38+
Scene.v().classes.filter { it.interfaces.contains(curSootClass) }
39+
.filter { it.interfaces.contains(curSootClass) } //+ hierarchy.getDirectSubinterfacesOf(curSootClass)
4040
} else {
41-
hierarchy.getDirectSubclassesOf(curSootClass)
41+
Scene.v().classes.filter { it.superclassOrNull == curSootClass }
42+
//hierarchy.getDirectSubclassesOf(curSootClass)
4243
}
4344
if (implementers.isEmpty()) continue
4445
val oldLists = res.removeIfAndReturnRemovedElements { it.last() == curSootClass }
45-
if (curSootClass.isConcrete) {
46+
if (curSootClass.isConcrete || !onlyConcreteClasses) {
4647
oldLists.forEach { res.add(it.toMutableList()) }
4748
}
4849
for (implementer in implementers) {
@@ -51,12 +52,14 @@ fun SootClass.getImplementersOfWithChain(): List<List<SootClass>> {
5152
}
5253
}
5354
return res.filter {
54-
val isJavaStdLibClass = it.last().javaPackageName.startsWith("java")
55-
val isFromSameProject = it.last().javaPackageName.contains(this.javaPackageName) || this.javaPackageName.contains(it.last().javaPackageName)
55+
val isJavaStdLibClass = it.last().javaPackageName.startsWith("java") || allowNotOnlyStdLib
56+
val isFromSameProject = it.last().toJavaClass()?.isFromSameJar(thisAsJavaClass) ?: false
57+
//it.last().javaPackageName.contains(this.javaPackageName) || this.javaPackageName.contains(it.last().javaPackageName)
5658
val isFromSamePackage = it.last().javaPackageName == this.javaPackageName
5759
val isSupportedPackage = isJavaStdLibClass || isFromSameProject
5860
val isAccessible = it.last().isPublic || (!it.last().isPublic && isFromSamePackage)
59-
it.all { !it.toString().contains("$") } && isAccessible && it.last().isConcrete && isSupportedPackage
61+
val isConcrete = !onlyConcreteClasses || it.last().isConcrete
62+
it.all { !it.toString().contains("$") } && isAccessible && isConcrete && isSupportedPackage
6063
}
6164
}
6265

utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/visitor/CgPythonRenderer.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import org.utbot.framework.codegen.domain.models.CgStatement
4747
import org.utbot.framework.codegen.domain.models.CgSwitchCase
4848
import org.utbot.framework.codegen.domain.models.CgSwitchCaseLabel
4949
import org.utbot.framework.codegen.domain.models.CgTestMethod
50+
import org.utbot.framework.codegen.domain.models.CgMockMethod
5051
import org.utbot.framework.codegen.domain.models.CgThisInstance
5152
import org.utbot.framework.codegen.domain.models.CgTripleSlashMultilineComment
5253
import org.utbot.framework.codegen.domain.models.CgTryCatch
@@ -310,6 +311,8 @@ internal class CgPythonRenderer(
310311
print(")")
311312
}
312313

314+
override fun renderMethodSignature(element: CgMockMethod): Unit = renderMethodSignature(element)
315+
313316
override fun renderMethodSignature(element: CgErrorTestMethod) {
314317
print("def ")
315318
print(element.name)

0 commit comments

Comments
 (0)