Skip to content
Open
43 changes: 41 additions & 2 deletions utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ sealed interface Seed<TYPE, RESULT> {
class Recursive<TYPE, RESULT>(
val construct: Routine.Create<TYPE, RESULT>,
val modify: Sequence<Routine.Call<TYPE, RESULT>> = emptySequence(),
val empty: Routine.Empty<TYPE, RESULT>
val empty: Routine.Empty<TYPE, RESULT>,
val transformers: Sequence<Routine.Modify<TYPE, RESULT>> = emptySequence(),
) : Seed<TYPE, RESULT>

/**
Expand Down Expand Up @@ -186,6 +187,13 @@ sealed class Routine<T, R>(val types: List<T>) : Iterable<T> by types {
}
}

class Modify<T, R>(
types: List<T>,
val callable: (instance: R, arguments: List<R>) -> R
) : Routine<T, R>(types) {
operator fun invoke(instance: R, arguments: List<R>): R = callable(instance, arguments)
}

/**
* Creates a collection of concrete sizes.
*/
Expand Down Expand Up @@ -541,7 +549,28 @@ private fun <TYPE, RESULT, DESCRIPTION : Description<TYPE>, FEEDBACK : Feedback<
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) {
@Suppress("UNCHECKED_CAST")
Expand Down Expand Up @@ -577,7 +606,16 @@ private fun <TYPE, R> create(result: Result<TYPE, R>): R = when(result) {
else -> error("Undefined object call method ${func.builder}")
}
}
obj
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}")
}
}
transformed
}
}
is Result.Collection<TYPE, R> -> with(result) {
val collection: R = when (val c = construct.builder) {
Expand Down Expand Up @@ -659,6 +697,7 @@ sealed interface Result<TYPE, RESULT> {
class Recursive<TYPE, RESULT>(
val construct: Node<TYPE, RESULT>,
val modify: List<Node<TYPE, RESULT>>,
val transformers: List<Node<TYPE, RESULT>>,
) : Result<TYPE, RESULT>

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ data class Configuration(
*
* To stop recursion [Seed.Recursive.empty] is called to create new values.
*/
var recursionTreeDepth: Int = 4,
var recursionTreeDepth: Int = 5,

/**
* The limit of collection size to create.
Expand Down
9 changes: 6 additions & 3 deletions utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Mutations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ sealed interface RecursiveMutations<TYPE, RESULT> : Mutation<Pair<Result.Recursi
): Result.Recursive<TYPE, RESULT> {
return Result.Recursive(
construct = recursive.mutate(source.construct,random, configuration),
modify = source.modify
modify = source.modify,
transformers = source.transformers,
)
}
}
Expand All @@ -309,7 +310,8 @@ sealed interface RecursiveMutations<TYPE, RESULT> : Mutation<Pair<Result.Recursi
): Result.Recursive<TYPE, RESULT> {
return Result.Recursive(
construct = source.construct,
modify = source.modify.shuffled(random).take(random.nextInt(source.modify.size + 1))
modify = source.modify.shuffled(random).take(random.nextInt(source.modify.size + 1)),
transformers = source.transformers
)
}
}
Expand All @@ -326,7 +328,8 @@ sealed interface RecursiveMutations<TYPE, RESULT> : Mutation<Pair<Result.Recursi
modify = source.modify.toMutableList().apply {
val i = random.nextInt(0, source.modify.size)
set(i, recursive.mutate(source.modify[i], random, configuration))
}
},
transformers = source.transformers
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@ fun defaultValueProviders(idGenerator: IdentityPreservingIdGenerator<Int>) = lis
FloatValueProvider,
StringValueProvider,
NumberValueProvider,
anyObjectValueProvider(idGenerator),
ArrayValueProvider(idGenerator),
EnumValueProvider(idGenerator),
ListSetValueProvider(idGenerator),
MapValueProvider(idGenerator),
IteratorValueProvider(idGenerator),
EmptyCollectionValueProvider(idGenerator),
DateValueProvider(idGenerator),
(ObjectValueProvider(idGenerator)
with ArrayValueProvider(idGenerator)
with EnumValueProvider(idGenerator)
with ListSetValueProvider(idGenerator)
with MapValueProvider(idGenerator)
with IteratorValueProvider(idGenerator)
with EmptyCollectionValueProvider(idGenerator)
with DateValueProvider(idGenerator))
.withFallback(
AbstractsObjectValueProvider(idGenerator)
with BuilderObjectValueProvider(idGenerator)
),
VoidValueProvider,
NullValueProvider,
)
Expand Down Expand Up @@ -235,6 +239,7 @@ private fun toClassId(type: Type, cache: MutableMap<Type, FuzzedType>): ClassId
}
is ParameterizedType -> (type.rawType as Class<*>).id
is Class<*> -> type.id
is TypeVariable<*> -> type.bounds.firstOrNull()?.let { toClassId(it, cache) } ?: objectClassId
else -> error("unknown type: $type")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class ModifyingWithMethodsProviderWrapper(
}
},
empty = seed.empty,
transformers = seed.transformers,
)
} else seed
}
Expand Down
Loading