Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce object creation using builders for fuzzers #2583

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
Rename finally to transformers
  • Loading branch information
Markoutte committed Sep 8, 2023
commit e5be238d8088124fbc38a01c028f81c8844f51f1
52 changes: 31 additions & 21 deletions utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt
Original file line number Diff line number Diff line change
@@ -142,7 +142,7 @@ sealed interface Seed<TYPE, RESULT> {
val construct: Routine.Create<TYPE, RESULT>,
val modify: Sequence<Routine.Call<TYPE, RESULT>> = emptySequence(),
val empty: Routine.Empty<TYPE, RESULT>,
val finally: Routine.Modify<TYPE, RESULT>? = null,
val transformers: Sequence<Routine.Modify<TYPE, RESULT>> = emptySequence(),
) : Seed<TYPE, RESULT>

/**
@@ -550,20 +550,26 @@ private fun <TYPE, RESULT, DESCRIPTION : Description<TYPE>, FEEDBACK : Feedback<
}
)
},
finally = task.finally?.let { finally ->
fuzz(
finally.types,
fuzzing,
description,
random,
configuration,
finally,
state.copy {
recursionTreeDepth++
iterations = -1
parameterIndex = -1
}
)
transformers = task.transformers.let { transformer ->
if (transformer === emptySequence<Node<TYPE, RESULT>>() || transformer.none()) {
emptyList()
} else {
transformer.map { f ->
fuzz(
f.types,
fuzzing,
description,
random,
configuration,
f,
state.copy {
recursionTreeDepth++
iterations = -1
parameterIndex = -1
}
)
}.toList()
}
}
)
} catch (nsv: NoSeedValueException) {
@@ -600,12 +606,16 @@ private fun <TYPE, R> create(result: Result<TYPE, R>): R = when(result) {
else -> error("Undefined object call method ${func.builder}")
}
}
finally?.let { func ->
when (val builder = func.builder) {
is Routine.Modify<TYPE, R> -> builder(obj, func.result.map { create(it) })
else -> error("Undefined object call method ${func.builder}")
transformers.let { transformers ->
var transformed = obj
transformers.forEach { transformer ->
transformed = when (val builder = transformer.builder) {
is Routine.Modify<TYPE, R> -> builder(obj, transformer.result.map { create(it) })
else -> error("Undefined object call method ${transformer.builder}")
}
}
} ?: obj
transformed
}
}
is Result.Collection<TYPE, R> -> with(result) {
val collection: R = when (val c = construct.builder) {
@@ -687,7 +697,7 @@ sealed interface Result<TYPE, RESULT> {
class Recursive<TYPE, RESULT>(
val construct: Node<TYPE, RESULT>,
val modify: List<Node<TYPE, RESULT>>,
val finally: Node<TYPE, RESULT>?,
val transformers: List<Node<TYPE, RESULT>>,
) : Result<TYPE, RESULT>

/**
6 changes: 3 additions & 3 deletions utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Mutations.kt
Original file line number Diff line number Diff line change
@@ -296,7 +296,7 @@ sealed interface RecursiveMutations<TYPE, RESULT> : Mutation<Pair<Result.Recursi
return Result.Recursive(
construct = recursive.mutate(source.construct,random, configuration),
modify = source.modify,
finally = source.finally,
transformers = source.transformers,
)
}
}
@@ -311,7 +311,7 @@ sealed interface RecursiveMutations<TYPE, RESULT> : Mutation<Pair<Result.Recursi
return Result.Recursive(
construct = source.construct,
modify = source.modify.shuffled(random).take(random.nextInt(source.modify.size + 1)),
finally = source.finally
transformers = source.transformers
)
}
}
@@ -329,7 +329,7 @@ sealed interface RecursiveMutations<TYPE, RESULT> : Mutation<Pair<Result.Recursi
val i = random.nextInt(0, source.modify.size)
set(i, recursive.mutate(source.modify[i], random, configuration))
},
finally = source.finally
transformers = source.transformers
)
}

Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@ import org.utbot.framework.util.executableId
import org.utbot.fuzzer.FuzzedType
import org.utbot.fuzzer.FuzzedValue
import org.utbot.fuzzer.IdGenerator
import org.utbot.fuzzer.IdentityPreservingIdGenerator
import org.utbot.fuzzer.fuzzed
import org.utbot.fuzzing.FuzzedDescription
import org.utbot.fuzzing.JavaValueProvider
@@ -58,13 +57,6 @@ private fun isIgnored(type: ClassId): Boolean {
|| (type.isInner && !type.isStatic)
}

fun anyObjectValueProvider(idGenerator: IdentityPreservingIdGenerator<Int>) =
ObjectValueProvider(idGenerator).letIf(UtSettings.fuzzingImplementationOfAbstractClasses) { ovp ->
ovp.withFallback(
AbstractsObjectValueProvider(idGenerator).with(BuilderObjectValueProvider(idGenerator))
)
}.withFallback(AnyDepthNullValueProvider)

class ObjectValueProvider(
val idGenerator: IdGenerator<Int>,
) : JavaValueProvider {
@@ -109,7 +101,7 @@ class ObjectValueProvider(
when {
fd.canBeSetDirectly -> {
yield(Routine.Call(listOf(fd.type)) { self, values ->
val model = self.model as UtAssembleModel
val model = self.model as? UtAssembleModel ?: return@Call
model.modificationsChain as MutableList += UtDirectSetFieldModel(
model,
FieldId(classId, fd.name),
@@ -120,7 +112,7 @@ class ObjectValueProvider(

fd.setter != null && fd.getter != null -> {
yield(Routine.Call(listOf(fd.type)) { self, values ->
val model = self.model as UtAssembleModel
val model = self.model as? UtAssembleModel ?: return@Call
model.modificationsChain as MutableList += UtExecutableCallModel(
model,
fd.setter.executableId,
@@ -245,7 +237,7 @@ class BuilderObjectValueProvider(
}
},
empty = nullRoutine(returnClassId),
finally = Routine.Modify(parameters) { instance, values ->
transformers = sequenceOf(Routine.Modify(parameters) { instance, values ->
UtAssembleModel(
idGenerator.createId(),
returnClassId,
@@ -256,7 +248,7 @@ class BuilderObjectValueProvider(
values.map { it.model }
),
).fuzzed { }
}
})
))
}
}
@@ -272,7 +264,8 @@ private fun SootClass.isUseful(): Boolean {
if (packageName != null) {
if (packageName.startsWith("jdk.internal") ||
packageName.startsWith("org.utbot") ||
packageName.startsWith("sun.")
packageName.startsWith("sun.") ||
packageName.startsWith("com.sun.")
)
return false
}