diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt index ac467db81c..7efaed85ee 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt @@ -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 diff --git a/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt b/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt index fc1ace3ea4..8c0c47bfcf 100644 --- a/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt +++ b/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/Api.kt @@ -248,7 +248,7 @@ private object EmptyFeedback : Feedback { } } -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") @@ -463,7 +463,11 @@ private fun , 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, @@ -474,15 +478,13 @@ private fun , 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 } diff --git a/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/utils/Functions.kt b/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/utils/Functions.kt index b32d13b45f..c2f9add11b 100644 --- a/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/utils/Functions.kt +++ b/utbot-fuzzing/src/main/kotlin/org/utbot/fuzzing/utils/Functions.kt @@ -81,7 +81,7 @@ internal enum class BinaryFormat : (Int) -> Boolean { DOUBLE { override fun invoke(index: Int) = index % 16 == 0 && index != 0 }, } -internal fun List.transformIfNotEmpty(transform: List.() -> List): List { +internal fun MutableList.transformIfNotEmpty(transform: MutableList.() -> List): List { return if (isNotEmpty()) transform() else this } diff --git a/utbot-fuzzing/src/test/kotlin/org/utbot/fuzzing/FuzzerSmokeTest.kt b/utbot-fuzzing/src/test/kotlin/org/utbot/fuzzing/FuzzerSmokeTest.kt index 57d5ddd092..14cc68290b 100644 --- a/utbot-fuzzing/src/test/kotlin/org/utbot/fuzzing/FuzzerSmokeTest.kt +++ b/utbot-fuzzing/src/test/kotlin/org/utbot/fuzzing/FuzzerSmokeTest.kt @@ -27,12 +27,15 @@ class FuzzerSmokeTest { @Test fun `fuzzing throws an exception if no values generated for some type`() { - assertThrows { + assertThrows { runBlocking { var count = 0 runFuzzing, BaseFeedback>( - { _, _ -> sequenceOf() }, - Description(listOf(Unit)) + provider = { _, _ -> sequenceOf() }, + description = Description(listOf(Unit)), + configuration = Configuration( + generateEmptyCollectionsForMissedTypes = false + ) ) { _, _ -> count += 1 BaseFeedback(Unit, Control.STOP)