3
3
package org.utbot.greyboxfuzzer.generator.userclasses.generator
4
4
5
5
import org.utbot.common.isAbstract
6
- import org.utbot.greyboxfuzzer.generator.DataGenerator
7
6
import org.utbot.greyboxfuzzer.generator.QuickCheckExtensions
8
7
import org.utbot.greyboxfuzzer.util.*
9
8
import org.utbot.greyboxfuzzer.util.logger
10
9
import org.utbot.framework.plugin.api.*
11
10
import org.utbot.framework.plugin.api.util.executableId
12
11
import org.utbot.framework.plugin.api.util.id
13
12
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
14
16
import org.utbot.greyboxfuzzer.quickcheck.generator.GenerationStatus
15
17
import org.utbot.greyboxfuzzer.quickcheck.generator.GeneratorContext
16
18
import org.utbot.greyboxfuzzer.quickcheck.internal.ParameterTypeContext
@@ -30,6 +32,9 @@ class InterfaceImplementationsInstanceGenerator(
30
32
override fun generate (): UtModel {
31
33
// Try to generate with statics with some probability
32
34
val clazz = resolvedType.toClass() ? : return UtNullModel (objectClassId)
35
+ if (clazz.name.contains(" HttpOutputMessage" )) {
36
+ println ()
37
+ }
33
38
if (Random .getTrue(50 )) {
34
39
try {
35
40
StaticsBasedInstanceGenerator (
@@ -47,10 +52,20 @@ class InterfaceImplementationsInstanceGenerator(
47
52
}
48
53
}
49
54
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
+ }
53
67
}
68
+ logger.debug { " Trying to generate implementer ${genericsContext.currentClass().name} " }
54
69
val resUtModel =
55
70
ClassesInstanceGenerator (
56
71
genericsContext.currentClass(),
@@ -79,13 +94,22 @@ class InterfaceImplementationsInstanceGenerator(
79
94
)
80
95
else -> resUtModel
81
96
}
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
+ }
89
113
}
90
114
}
91
115
@@ -95,33 +119,45 @@ class InterfaceImplementationsInstanceGenerator(
95
119
typeContext : GenericsContext ,
96
120
generatorContext : GeneratorContext
97
121
): UtModel {
122
+ logger.debug { " Mock generation" }
98
123
if (! clazz.isInterface) return UtNullModel (clazz.id)
99
124
val sootClazz = clazz.toSootClass() ? : return UtNullModel (clazz.id)
100
125
val constructor = generatorContext.utModelConstructor
101
126
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)
120
152
val mocks = clazz.methods
121
153
.filter { it.isAbstract }
122
154
.associateTo(mutableMapOf ()) { method ->
123
155
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
+ }
125
161
val methodReturnType =
126
162
if (genericsContextForMethod != null ) {
127
163
genericsContextForMethod.method(method).resolveReturnType().let {
@@ -133,13 +169,7 @@ class InterfaceImplementationsInstanceGenerator(
133
169
val parameterTypeContext = ParameterTypeContext .forType(methodReturnType, genericsContextForMethod)
134
170
val generatedUtModelWithReturnType =
135
171
try {
136
- DataGenerator .generateUtModel(
137
- parameterTypeContext,
138
- depth,
139
- generatorContext,
140
- sourceOfRandomness,
141
- generationStatus
142
- )
172
+ generateUtModelForMock(parameterTypeContext, depth, generatorContext, sourceOfRandomness, generationStatus)
143
173
} catch (_: Throwable ) {
144
174
UtNullModel (methodReturnType.toClass()!! .id)
145
175
}
@@ -148,6 +178,34 @@ class InterfaceImplementationsInstanceGenerator(
148
178
return UtCompositeModel (constructor .computeUnusedIdAndUpdate(), clazz.id, isMock = true , mocks = mocks)
149
179
}
150
180
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
+
151
209
// private fun buildGenericsContextForInterfaceParent(resolvedType: Type, clazz: Class<*>, parentChain: List<Class<*>>): GenericsContext? {
152
210
// val generics = mutableListOf<Pair<Type, MutableList<Type>>>()
153
211
// var curClass = clazz
0 commit comments