Skip to content

Correctly handle randomizing of Seed.Recursive modifications #1996

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,12 @@ class UtBotSymbolicEngine(
names,
listOf(transform(ValueProvider.of(defaultValueProviders(defaultIdGenerator))))
) { thisInstance, descr, values ->
if (thisInstance?.model is UtNullModel) {
// We should not try to run concretely any models with null-this.
// But fuzzer does generate such values, because it can fail to generate any "good" values.
return@runJavaFuzzing BaseFeedback(Trie.emptyNode(), Control.PASS)
}

val diff = until - System.currentTimeMillis()
val thresholdMillisForFuzzingOperation = 0 // may be better use 10-20 millis as it might not be possible
// to concretely execute that values because request to instrumentation process involves
Expand Down
12 changes: 7 additions & 5 deletions utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ private object EmptyFeedback : Feedback<Nothing, Nothing> {
}
}

private class NoSeedValueException(
class NoSeedValueException internal constructor(
// this type cannot be generalized because Java forbids types for [Throwable].
val type: Any?
) : Exception("No seed candidates generated for type: $type")
Expand Down Expand Up @@ -463,7 +463,11 @@ private fun <TYPE, RESULT, DESCRIPTION : Description<TYPE>, FEEDBACK : Feedback<
State(state.recursionTreeDepth + 1, state.cache, state.missedTypes)
),
modify = task.modify
.shuffled(random)
.toMutableList()
.transformIfNotEmpty {
shuffle(random)
take(random.nextInt(size + 1))
}
.mapTo(arrayListOf()) { routine ->
fuzz(
routine.types,
Expand All @@ -474,15 +478,13 @@ private fun <TYPE, RESULT, DESCRIPTION : Description<TYPE>, FEEDBACK : Feedback<
routine,
State(state.recursionTreeDepth + 1, state.cache, state.missedTypes)
)
}.transformIfNotEmpty {
take(random.nextInt(size + 1).coerceAtLeast(1))
}
)
} catch (nsv: NoSeedValueException) {
@Suppress("UNCHECKED_CAST")
state.missedTypes[nsv.type as TYPE] = task
if (configuration.generateEmptyRecursiveForMissedTypes) {
Result.Empty { task.empty() }
Result.Empty { task.empty.builder() }
} else {
throw nsv
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ internal enum class BinaryFormat : (Int) -> Boolean {
DOUBLE { override fun invoke(index: Int) = index % 16 == 0 && index != 0 },
}

internal fun <T> List<T>.transformIfNotEmpty(transform: List<T>.() -> List<T>): List<T> {
internal fun <T> MutableList<T>.transformIfNotEmpty(transform: MutableList<T>.() -> List<T>): List<T> {
return if (isNotEmpty()) transform() else this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ class FuzzerSmokeTest {

@Test
fun `fuzzing throws an exception if no values generated for some type`() {
assertThrows<IllegalStateException> {
assertThrows<NoSeedValueException> {
runBlocking {
var count = 0
runFuzzing<Unit, Unit, Description<Unit>, BaseFeedback<Unit, Unit, Unit>>(
{ _, _ -> sequenceOf() },
Description(listOf(Unit))
provider = { _, _ -> sequenceOf() },
description = Description(listOf(Unit)),
configuration = Configuration(
generateEmptyCollectionsForMissedTypes = false
)
) { _, _ ->
count += 1
BaseFeedback(Unit, Control.STOP)
Expand Down