Skip to content

Commit 6cb8e93

Browse files
committed
Add custom serializer for utmock exception
1 parent 049564e commit 6cb8e93

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package org.utbot.api.exception;
22

33
public class UtMockAssumptionViolatedException extends RuntimeException {
4-
5-
public static final String errorMessage = "UtMock assumption violated";
6-
74
@Override
85
public String getMessage() {
9-
return errorMessage;
6+
return "UtMock assumption violated";
107
}
118
}

utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ class UtBotSymbolicEngine(
248248
val concreteExecutionResult =
249249
concreteExecutor.executeConcretely(methodUnderTest, stateBefore, instrumentation)
250250

251+
if (concreteExecutionResult.violatesUtMockAssumption()) {
252+
logger.debug { "Generated test case violates the UtMock assumption: $concreteExecutionResult" }
253+
return@bracket
254+
}
255+
251256
val concreteUtExecution = UtSymbolicExecution(
252257
stateBefore,
253258
concreteExecutionResult.stateAfter,
@@ -368,12 +373,8 @@ class UtBotSymbolicEngine(
368373
// in case an exception occurred from the concrete execution
369374
concreteExecutionResult ?: return@runJavaFuzzing BaseFeedback(result = Trie.emptyNode(), control = Control.PASS)
370375

371-
// We should compare messages instead of `if (... is UtMockAssumptionViolatedException)`
372-
// because the exception from the `concreteExecutionResult` is loaded by user's ClassLoader,
373-
// but the `UtMockAssumptionViolatedException` is loaded by the current ClassLoader,
374-
// so we can't cast them to each other.
375-
if (concreteExecutionResult.result.exceptionOrNull()?.message == UtMockAssumptionViolatedException.errorMessage) {
376-
logger.debug { "Generated test case by fuzzer violates the UtMock assumption" }
376+
if (concreteExecutionResult.violatesUtMockAssumption()) {
377+
logger.debug { "Generated test case by fuzzer violates the UtMock assumption: $concreteExecutionResult" }
377378
return@runJavaFuzzing BaseFeedback(result = Trie.emptyNode(), control = Control.PASS)
378379
}
379380

@@ -501,6 +502,11 @@ class UtBotSymbolicEngine(
501502
instrumentation
502503
)
503504

505+
if (concreteExecutionResult.violatesUtMockAssumption()) {
506+
logger.debug { "Generated test case violates the UtMock assumption: $concreteExecutionResult" }
507+
return
508+
}
509+
504510
val concolicUtExecution = symbolicUtExecution.copy(
505511
stateAfter = concreteExecutionResult.stateAfter,
506512
result = concreteExecutionResult.result,
@@ -597,3 +603,11 @@ private fun makeWrapperConsistencyCheck(
597603
val visitedSelectExpression = memory.isVisited(symbolicValue.addr)
598604
visitedConstraints += mkEq(visitedSelectExpression, mkInt(1))
599605
}
606+
607+
private fun UtConcreteExecutionResult.violatesUtMockAssumption(): Boolean {
608+
// We should compare FQNs instead of `if (... is UtMockAssumptionViolatedException)`
609+
// because the exception from the `concreteExecutionResult` is loaded by user's ClassLoader,
610+
// but the `UtMockAssumptionViolatedException` is loaded by the current ClassLoader,
611+
// so we can't cast them to each other.
612+
return result.exceptionOrNull()?.javaClass?.name == UtMockAssumptionViolatedException::class.java.name
613+
}

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/KryoHelper.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.esotericsoftware.kryo.kryo5.serializers.JavaSerializer
1212
import com.esotericsoftware.kryo.kryo5.util.DefaultInstantiatorStrategy
1313
import com.jetbrains.rd.util.lifetime.Lifetime
1414
import com.jetbrains.rd.util.lifetime.throwIfNotAlive
15+
import org.utbot.api.exception.UtMockAssumptionViolatedException
1516
import org.utbot.framework.plugin.api.TimeoutException
1617
import java.io.ByteArrayOutputStream
1718

@@ -123,6 +124,7 @@ internal class TunedKryo : Kryo() {
123124

124125
this.setOptimizedGenerics(false)
125126
register(TimeoutException::class.java, TimeoutExceptionSerializer())
127+
register(UtMockAssumptionViolatedException::class.java, UtMockAssumptionViolatedExceptionSerializer())
126128

127129
// TODO: JIRA:1492
128130
addDefaultSerializer(java.lang.Throwable::class.java, JavaSerializer())
@@ -149,4 +151,19 @@ internal class TunedKryo : Kryo() {
149151
override fun read(kryo: Kryo?, input: Input, type: Class<out TimeoutException>?): TimeoutException =
150152
TimeoutException(input.readString())
151153
}
154+
155+
/**
156+
* Specific serializer for [UtMockAssumptionViolatedException] - [JavaSerializer] is not applicable
157+
* because [UtMockAssumptionViolatedException] is not in class loader.
158+
*/
159+
private class UtMockAssumptionViolatedExceptionSerializer : Serializer<UtMockAssumptionViolatedException>() {
160+
override fun write(kryo: Kryo, output: Output, value: UtMockAssumptionViolatedException) {
161+
output.writeString(value.message)
162+
}
163+
164+
override fun read(kryo: Kryo?, input: Input, type: Class<out UtMockAssumptionViolatedException>?): UtMockAssumptionViolatedException {
165+
input.readString() // shift the reading position
166+
return UtMockAssumptionViolatedException()
167+
}
168+
}
152169
}

0 commit comments

Comments
 (0)