Skip to content

Commit 4a34655

Browse files
committed
Activated fuzzing for tp.Any inside objects
1 parent 809d6e8 commit 4a34655

24 files changed

+296
-237
lines changed

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/PythonApi.kt

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import org.utbot.fuzzing.Feedback
88
import org.utbot.fuzzing.Fuzzing
99
import org.utbot.fuzzing.Seed
1010
import org.utbot.fuzzing.Statistic
11+
import org.utbot.fuzzing.ValueProvider
1112
import org.utbot.fuzzing.utils.Trie
1213
import org.utbot.python.coverage.PyInstruction
1314
import org.utbot.python.engine.ExecutionFeedback
1415
import org.utbot.python.framework.api.python.PythonTree
16+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
1517
import org.utbot.python.fuzzing.provider.BoolValueProvider
1618
import org.utbot.python.fuzzing.provider.BytearrayValueProvider
1719
import org.utbot.python.fuzzing.provider.BytesValueProvider
@@ -41,6 +43,9 @@ import org.utbot.python.newtyping.inference.InferredTypeFeedback
4143
import org.utbot.python.newtyping.inference.InvalidTypeFeedback
4244
import org.utbot.python.newtyping.inference.SuccessFeedback
4345
import org.utbot.python.newtyping.inference.baseline.BaselineAlgorithm
46+
import org.utbot.python.newtyping.pythonModuleName
47+
import org.utbot.python.newtyping.pythonName
48+
import org.utbot.python.newtyping.pythonTypeName
4449
import org.utbot.python.newtyping.pythonTypeRepresentation
4550
import org.utbot.python.utils.ExecutionWithTimoutMode
4651
import org.utbot.python.utils.FakeWithTimeoutMode
@@ -49,12 +54,33 @@ import kotlin.random.Random
4954

5055
private val logger = KotlinLogging.logger {}
5156

57+
typealias PythonValueProvider = ValueProvider<FuzzedUtType, PythonFuzzedValue, PythonMethodDescription>
58+
5259
data class PythonFuzzedConcreteValue(
5360
val type: UtType,
5461
val value: Any,
5562
val fuzzedContext: FuzzedContext = FuzzedContext.Unknown,
5663
)
5764

65+
data class FuzzedUtType(
66+
val utType: UtType,
67+
val fuzzAny: Boolean = false,
68+
) {
69+
fun activateAny() = FuzzedUtType(utType, true)
70+
71+
fun isAny(): Boolean = utType.isAny()
72+
fun pythonName(): String = utType.pythonName()
73+
fun pythonTypeName(): String = utType.pythonTypeName()
74+
fun pythonModuleName(): String = utType.pythonModuleName()
75+
fun pythonTypeRepresentation(): String = utType.pythonTypeRepresentation()
76+
77+
companion object {
78+
fun Collection<UtType>.toFuzzed() = this.map { it.toFuzzed() }
79+
fun UtType.toFuzzed() = FuzzedUtType(this)
80+
fun Collection<FuzzedUtType>.activateAny() = this.map { it.activateAny() }
81+
}
82+
}
83+
5884
class PythonMethodDescription(
5985
val name: String,
6086
val concreteValues: Collection<PythonFuzzedConcreteValue> = emptyList(),
@@ -63,7 +89,7 @@ class PythonMethodDescription(
6389
val random: Random,
6490
val limitManager: TestGenerationLimitManager,
6591
val type: FunctionType,
66-
) : Description<UtType>(type.arguments)
92+
) : Description<FuzzedUtType>(type.arguments.toFuzzed())
6793

6894
data class PythonExecutionResult(
6995
val executionFeedback: ExecutionFeedback,
@@ -75,7 +101,7 @@ data class PythonFeedback(
75101
val result: Trie.Node<PyInstruction> = Trie.emptyNode(),
76102
val typeInferenceFeedback: InferredTypeFeedback = InvalidTypeFeedback,
77103
val fromCache: Boolean = false,
78-
) : Feedback<UtType, PythonFuzzedValue> {
104+
) : Feedback<FuzzedUtType, PythonFuzzedValue> {
79105
fun fromCache(): PythonFeedback {
80106
return PythonFeedback(
81107
control = control,
@@ -132,27 +158,38 @@ class PythonFuzzing(
132158
private val typeInferenceAlgorithm: BaselineAlgorithm,
133159
private val globalIsCancelled: () -> Boolean,
134160
val execute: suspend (description: PythonMethodDescription, values: List<PythonFuzzedValue>) -> PythonFeedback,
135-
) : Fuzzing<UtType, PythonFuzzedValue, PythonMethodDescription, PythonFeedback> {
161+
) : Fuzzing<FuzzedUtType, PythonFuzzedValue, PythonMethodDescription, PythonFeedback> {
136162

137-
private fun generateDefault(description: PythonMethodDescription, type: UtType)= sequence {
138-
pythonDefaultValueProviders(pythonTypeStorage).asSequence().forEach { provider ->
163+
private fun generateDefault(providers: List<PythonValueProvider>, description: PythonMethodDescription, type: FuzzedUtType)= sequence {
164+
providers.asSequence().forEach { provider ->
139165
if (provider.accept(type)) {
140166
logger.debug { "Provider ${provider.javaClass.simpleName} accepts type ${type.pythonTypeRepresentation()}" }
141167
yieldAll(provider.generate(description, type))
142168
}
143169
}
144170
}
145171

146-
override fun generate(description: PythonMethodDescription, type: UtType): Sequence<Seed<UtType, PythonFuzzedValue>> {
147-
var providers = emptyList<Seed<UtType, PythonFuzzedValue>>().asSequence()
172+
private fun generateAnyProviders(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
173+
pythonAnyTypeValueProviders().asSequence().forEach { provider ->
174+
logger.debug { "Provider ${provider.javaClass.simpleName} accepts type ${type.pythonTypeRepresentation()} with activated any" }
175+
yieldAll(provider.generate(description, type))
176+
}
177+
}
178+
179+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType): Sequence<Seed<FuzzedUtType, PythonFuzzedValue>> {
180+
val providers = mutableSetOf<Seed<FuzzedUtType, PythonFuzzedValue>>()
148181

149182
if (type.isAny()) {
150-
logger.debug("Any does not have provider")
183+
if (type.fuzzAny) {
184+
providers += generateAnyProviders(description, type)
185+
} else {
186+
logger.debug("Any does not have provider")
187+
}
151188
} else {
152-
providers += generateDefault(description, type)
189+
providers += generateDefault(pythonDefaultValueProviders(pythonTypeStorage), description, type)
153190
}
154191

155-
return providers
192+
return providers.asSequence()
156193
}
157194

158195
override suspend fun handle(description: PythonMethodDescription, values: List<PythonFuzzedValue>): PythonFeedback {
@@ -166,7 +203,7 @@ class PythonFuzzing(
166203
return result
167204
}
168205

169-
private suspend fun forkType(description: PythonMethodDescription, stats: Statistic<UtType, PythonFuzzedValue>) {
206+
private suspend fun forkType(description: PythonMethodDescription, stats: Statistic<FuzzedUtType, PythonFuzzedValue>) {
170207
val type: UtType? = typeInferenceAlgorithm.expandState()
171208
if (type != null) {
172209
val d = PythonMethodDescription(
@@ -190,12 +227,12 @@ class PythonFuzzing(
190227

191228
override suspend fun isCancelled(
192229
description: PythonMethodDescription,
193-
stats: Statistic<UtType, PythonFuzzedValue>
230+
stats: Statistic<FuzzedUtType, PythonFuzzedValue>
194231
): Boolean {
195232
if (globalIsCancelled()) {
196233
return true
197234
}
198-
if (description.limitManager.isCancelled() || description.parameters.any { it.isAny() }) {
235+
if (description.limitManager.isCancelled()) {// || description.parameters.any { it.isAny() }) {
199236
forkType(description, stats)
200237
if (description.limitManager.isRootManager) {
201238
return FakeWithTimeoutMode.isCancelled(description.limitManager)

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/BoolValueProvider.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Seed
4-
import org.utbot.fuzzing.ValueProvider
54
import org.utbot.fuzzing.seeds.Bool
65
import org.utbot.fuzzing.seeds.KnownValue
76
import org.utbot.python.framework.api.python.PythonTree
87
import org.utbot.python.framework.api.python.util.pythonBoolClassId
8+
import org.utbot.python.fuzzing.FuzzedUtType
99
import org.utbot.python.fuzzing.PythonFuzzedValue
1010
import org.utbot.python.fuzzing.PythonMethodDescription
11+
import org.utbot.python.fuzzing.PythonValueProvider
1112
import org.utbot.python.fuzzing.provider.utils.generateSummary
12-
import org.utbot.python.newtyping.general.UtType
13-
import org.utbot.python.newtyping.pythonTypeName
1413

15-
object BoolValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription>{
16-
override fun accept(type: UtType): Boolean {
14+
object BoolValueProvider : PythonValueProvider {
15+
override fun accept(type: FuzzedUtType): Boolean {
1716
return type.pythonTypeName() == pythonBoolClassId.canonicalName
1817
}
1918

20-
override fun generate(description: PythonMethodDescription, type: UtType) = sequence {
19+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
2120
yieldBool(Bool.TRUE()) { true }
2221
yieldBool(Bool.FALSE()) { false }
2322
}
2423

25-
private suspend fun <T : KnownValue<T>> SequenceScope<Seed<UtType, PythonFuzzedValue>>.yieldBool(value: T, block: T.() -> Boolean) {
24+
private suspend fun <T : KnownValue<T>> SequenceScope<Seed<FuzzedUtType, PythonFuzzedValue>>.yieldBool(value: T, block: T.() -> Boolean) {
2625
yield(Seed.Known(value) {
2726
PythonFuzzedValue(
2827
PythonTree.fromBool(block(it)),

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/BytearrayValueProvider.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,25 @@ package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Routine
44
import org.utbot.fuzzing.Seed
5-
import org.utbot.fuzzing.ValueProvider
65
import org.utbot.python.framework.api.python.PythonTree
76
import org.utbot.python.framework.api.python.util.pythonBytearrayClassId
7+
import org.utbot.python.fuzzing.FuzzedUtType
8+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
89
import org.utbot.python.fuzzing.PythonFuzzedValue
910
import org.utbot.python.fuzzing.PythonMethodDescription
10-
import org.utbot.python.newtyping.general.UtType
11-
import org.utbot.python.newtyping.pythonTypeName
12-
import org.utbot.python.newtyping.pythonTypeRepresentation
11+
import org.utbot.python.fuzzing.PythonValueProvider
1312

14-
object BytearrayValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription> {
15-
override fun accept(type: UtType): Boolean {
13+
object BytearrayValueProvider : PythonValueProvider {
14+
override fun accept(type: FuzzedUtType): Boolean {
1615
return type.pythonTypeName() == pythonBytearrayClassId.canonicalName
1716
}
1817

19-
override fun generate(description: PythonMethodDescription, type: UtType) = sequence {
18+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
2019
yield(Seed.Recursive(
2120
construct = Routine.Create(
2221
listOf(
2322
description.pythonTypeStorage.pythonInt,
24-
)
23+
).toFuzzed()
2524
) { v ->
2625
val value = v.first().tree as PythonTree.PrimitiveNode
2726
PythonFuzzedValue(

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/BytesValueProvider.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,25 @@ package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Routine
44
import org.utbot.fuzzing.Seed
5-
import org.utbot.fuzzing.ValueProvider
65
import org.utbot.python.framework.api.python.PythonTree
76
import org.utbot.python.framework.api.python.util.pythonBytesClassId
7+
import org.utbot.python.fuzzing.FuzzedUtType
8+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
89
import org.utbot.python.fuzzing.PythonFuzzedValue
910
import org.utbot.python.fuzzing.PythonMethodDescription
10-
import org.utbot.python.newtyping.general.UtType
11-
import org.utbot.python.newtyping.pythonTypeName
12-
import org.utbot.python.newtyping.pythonTypeRepresentation
11+
import org.utbot.python.fuzzing.PythonValueProvider
1312

14-
object BytesValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription> {
15-
override fun accept(type: UtType): Boolean {
13+
object BytesValueProvider : PythonValueProvider {
14+
override fun accept(type: FuzzedUtType): Boolean {
1615
return type.pythonTypeName() == pythonBytesClassId.canonicalName
1716
}
1817

19-
override fun generate(description: PythonMethodDescription, type: UtType) = sequence {
18+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
2019
yield(Seed.Recursive(
2120
construct = Routine.Create(
2221
listOf(
2322
description.pythonTypeStorage.pythonInt,
24-
)
23+
).toFuzzed()
2524
) { v ->
2625
val value = v.first().tree as PythonTree.PrimitiveNode
2726
PythonFuzzedValue(

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/ComplexValueProvider.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@ package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Routine
44
import org.utbot.fuzzing.Seed
5-
import org.utbot.fuzzing.ValueProvider
65
import org.utbot.python.framework.api.python.PythonTree
76
import org.utbot.python.framework.api.python.util.pythonComplexClassId
7+
import org.utbot.python.fuzzing.FuzzedUtType
8+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
89
import org.utbot.python.fuzzing.PythonFuzzedValue
910
import org.utbot.python.fuzzing.PythonMethodDescription
11+
import org.utbot.python.fuzzing.PythonValueProvider
1012
import org.utbot.python.newtyping.createPythonUnionType
11-
import org.utbot.python.newtyping.general.UtType
12-
import org.utbot.python.newtyping.pythonTypeName
13-
import org.utbot.python.newtyping.pythonTypeRepresentation
1413

15-
object ComplexValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription> {
16-
override fun accept(type: UtType): Boolean {
14+
object ComplexValueProvider : PythonValueProvider {
15+
override fun accept(type: FuzzedUtType): Boolean {
1716
return type.pythonTypeName() == pythonComplexClassId.canonicalName
1817
}
1918

20-
override fun generate(description: PythonMethodDescription, type: UtType) = sequence {
19+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
2120
val numberType = createPythonUnionType(
2221
listOf(
2322
description.pythonTypeStorage.pythonFloat,
@@ -37,7 +36,7 @@ object ComplexValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMet
3736
listOf(
3837
numberType,
3938
numberType
40-
)
39+
).toFuzzed()
4140
) { v ->
4241
if (v[0].tree is PythonTree.FakeNode || v[1].tree is PythonTree.FakeNode) {
4342
emptyValue

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/ConstantValueProvider.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Seed
4-
import org.utbot.fuzzing.ValueProvider
54
import org.utbot.python.framework.api.python.PythonClassId
65
import org.utbot.python.framework.api.python.PythonTree
6+
import org.utbot.python.fuzzing.FuzzedUtType
77
import org.utbot.python.fuzzing.PythonFuzzedValue
88
import org.utbot.python.fuzzing.PythonMethodDescription
9-
import org.utbot.python.newtyping.general.UtType
10-
import org.utbot.python.newtyping.pythonTypeName
9+
import org.utbot.python.fuzzing.PythonValueProvider
1110
import org.utbot.python.fuzzing.value.TypesFromJSONStorage
1211

13-
object ConstantValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription> {
14-
override fun accept(type: UtType): Boolean {
12+
object ConstantValueProvider : PythonValueProvider {
13+
override fun accept(type: FuzzedUtType): Boolean {
1514
return TypesFromJSONStorage.getTypesFromJsonStorage().containsKey(type.pythonTypeName())
1615
}
1716

18-
override fun generate(description: PythonMethodDescription, type: UtType): Sequence<Seed<UtType, PythonFuzzedValue>> =
17+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType): Sequence<Seed<FuzzedUtType, PythonFuzzedValue>> =
1918
sequence {
2019
val storage = TypesFromJSONStorage.getTypesFromJsonStorage()
2120
storage.values.forEach { values ->

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/DictValueProvider.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@ package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Routine
44
import org.utbot.fuzzing.Seed
5-
import org.utbot.fuzzing.ValueProvider
65
import org.utbot.python.framework.api.python.PythonTree
76
import org.utbot.python.framework.api.python.util.pythonDictClassId
7+
import org.utbot.python.fuzzing.FuzzedUtType
8+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.activateAny
9+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
810
import org.utbot.python.fuzzing.PythonFuzzedValue
911
import org.utbot.python.fuzzing.PythonMethodDescription
10-
import org.utbot.python.newtyping.general.UtType
12+
import org.utbot.python.fuzzing.PythonValueProvider
1113
import org.utbot.python.newtyping.pythonAnnotationParameters
12-
import org.utbot.python.newtyping.pythonTypeName
13-
import org.utbot.python.newtyping.pythonTypeRepresentation
1414

15-
object DictValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription> {
16-
override fun accept(type: UtType): Boolean {
15+
object DictValueProvider : PythonValueProvider {
16+
override fun accept(type: FuzzedUtType): Boolean {
1717
return type.pythonTypeName() == pythonDictClassId.canonicalName
1818
}
1919

20-
override fun generate(description: PythonMethodDescription, type: UtType) = sequence {
21-
val params = type.pythonAnnotationParameters()
20+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType) = sequence {
21+
val params = type.utType.pythonAnnotationParameters()
2222

2323
yield(Seed.Collection(
2424
construct = Routine.Collection { _ ->
@@ -27,7 +27,7 @@ object DictValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethod
2727
"%var% = ${type.pythonTypeRepresentation()}"
2828
)
2929
},
30-
modify = Routine.ForEach(params) { instance, _, arguments ->
30+
modify = Routine.ForEach(params.toFuzzed().activateAny()) { instance, _, arguments ->
3131
val key = arguments[0].tree
3232
val value = arguments[1].tree
3333
val dict = instance.tree as PythonTree.DictNode

utbot-python/src/main/kotlin/org/utbot/python/fuzzing/provider/FloatValueProvider.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
package org.utbot.python.fuzzing.provider
22

33
import org.utbot.fuzzing.Seed
4-
import org.utbot.fuzzing.ValueProvider
54
import org.utbot.fuzzing.seeds.IEEE754Value
65
import org.utbot.python.framework.api.python.PythonTree
76
import org.utbot.python.framework.api.python.util.pythonFloatClassId
87
import org.utbot.python.framework.api.python.util.pythonIntClassId
8+
import org.utbot.python.fuzzing.FuzzedUtType
9+
import org.utbot.python.fuzzing.FuzzedUtType.Companion.toFuzzed
910
import org.utbot.python.fuzzing.PythonFuzzedConcreteValue
1011
import org.utbot.python.fuzzing.PythonFuzzedValue
1112
import org.utbot.python.fuzzing.PythonMethodDescription
13+
import org.utbot.python.fuzzing.PythonValueProvider
1214
import org.utbot.python.fuzzing.provider.utils.generateSummary
13-
import org.utbot.python.newtyping.general.UtType
1415
import org.utbot.python.newtyping.pythonTypeName
1516
import java.math.BigDecimal
1617
import java.math.BigInteger
1718

18-
object FloatValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMethodDescription> {
19-
override fun accept(type: UtType): Boolean {
19+
object FloatValueProvider : PythonValueProvider {
20+
override fun accept(type: FuzzedUtType): Boolean {
2021
return type.pythonTypeName() == pythonFloatClassId.canonicalName
2122
}
2223

2324
private fun getFloatConstants(concreteValues: Collection<PythonFuzzedConcreteValue>): List<IEEE754Value> {
2425
return concreteValues
25-
.filter { accept(it.type) }
26+
.filter { accept(it.type.toFuzzed()) }
2627
.map { fuzzedValue ->
2728
(fuzzedValue.value as BigDecimal).let {
2829
IEEE754Value.fromValue(it.toDouble())
@@ -40,7 +41,7 @@ object FloatValueProvider : ValueProvider<UtType, PythonFuzzedValue, PythonMetho
4041
}
4142
}
4243

43-
override fun generate(description: PythonMethodDescription, type: UtType): Sequence<Seed<UtType, PythonFuzzedValue>> = sequence {
44+
override fun generate(description: PythonMethodDescription, type: FuzzedUtType): Sequence<Seed<FuzzedUtType, PythonFuzzedValue>> = sequence {
4445
val floatConstants = getFloatConstants(description.concreteValues)
4546
val intConstants = getIntConstants(description.concreteValues)
4647
val constants = floatConstants + intConstants + listOf(0, 1).map { IEEE754Value.fromValue(it.toDouble()) }

0 commit comments

Comments
 (0)