Skip to content

Commit 1a2a61c

Browse files
EgorkaKulikovtepa46
authored andcommitted
Apply discussion fixes.
1 parent 28c9516 commit 1a2a61c

File tree

4 files changed

+77
-52
lines changed

4 files changed

+77
-52
lines changed

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import org.usvm.PathSelectorFairnessStrategy
99
import org.usvm.SolverType
1010
import org.usvm.UMachineOptions
1111
import org.usvm.api.JcCoverage
12+
import org.usvm.instrumentation.testcase.api.UTestExecutionTimedOutResult
1213
import org.usvm.machine.JcMachine
1314
import org.usvm.machine.state.JcState
1415
import org.usvm.types.ClassScorer
@@ -40,6 +41,7 @@ import org.utbot.usvm.jc.JcContainer
4041
import org.utbot.usvm.jc.JcExecution
4142
import org.utbot.usvm.jc.JcJars
4243
import org.utbot.usvm.jc.JcTestExecutor
44+
import org.utbot.usvm.jc.UTestConcreteExecutionResult
4345
import org.utbot.usvm.jc.findMethodOrNull
4446
import org.utbot.usvm.jc.typedMethod
4547
import org.utbot.usvm.machine.analyzeAsync
@@ -58,6 +60,8 @@ object UsvmSymbolicEngine {
5860
timeoutMillis: Long
5961
): List<Pair<ExecutableId, UtResult>> {
6062

63+
JcContainer.specifyContainerTimeout(UtSettings.concreteExecutionDefaultTimeoutInInstrumentedProcessMillis)
64+
6165
val collectedExecutions = mutableListOf<Pair<ExecutableId, UtResult>>()
6266
val classpathFiles = classpath.split(File.pathSeparator).map { File(it) }
6367

@@ -126,7 +130,7 @@ object UsvmSymbolicEngine {
126130
): JcExecution {
127131
val executor = JcTestExecutor(jcContainer.cp, jcContainer.runner)
128132

129-
val realJcExecution = runCatching {
133+
var realJcExecution = runCatching {
130134
executor.execute(
131135
method = state.entrypoint.typedMethod,
132136
state = state,
@@ -139,8 +143,15 @@ object UsvmSymbolicEngine {
139143
null
140144
}
141145

142-
realJcExecution?.let {
143-
return it
146+
if (realJcExecution != null) {
147+
// We should not rely on `UTestExecutionTimedOutResult` from usvm instrumentation as
148+
// it sometimes hides another problems like `IllegalStateMonitorException` and so on.
149+
realJcExecution = realJcExecution.copy(
150+
uTestExecutionResultWrappers = realJcExecution
151+
.uTestExecutionResultWrappers
152+
.filterNot { it is UTestConcreteExecutionResult && it.uTestExecutionResult is UTestExecutionTimedOutResult })
153+
154+
return realJcExecution
144155
}
145156

146157
return JcExecution(

utbot-usvm/src/main/kotlin/org/utbot/usvm/converter/JcToUtExecutionConverter.kt

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,13 @@ class JcToUtExecutionConverter(
182182
}
183183

184184
private fun constructAssemblingMapper(): UtModelDeepMapper = UtModelDeepMapper { model ->
185-
// TODO usvm-sbft: support constructors with parameters here if it is really required
186-
// Unfortunately, it is not possible to use [AssembleModelGeneral] as it requires soot being initialized.
185+
/*
186+
Unfortunately, sometimes it is not possible to use [AssembleModelGeneral]
187+
as it requires soot being initialized. Soot is not used in `ContestUsvm`.
188+
189+
After that, even if Soot is initialized, it required some refactoring to move
190+
some AssembleModelGenerated API related features to `utbot-framework-api`.
191+
*/
187192
if (model !is UtAssembleModel
188193
|| utilMethodProvider.createInstanceMethodId != model.instantiationCall.statement
189194
|| model.modificationsChain.isNotEmpty()) {
@@ -195,6 +200,7 @@ class JcToUtExecutionConverter(
195200
.params
196201
.single() as UtPrimitiveModel).value.toString()
197202

203+
// TODO usvm-sbft: support constructors with parameters here if it is really required
198204
val defaultConstructor = ClassId(instantiatingClassName)
199205
.jClass
200206
.constructors
@@ -358,23 +364,18 @@ class JcToUtExecutionConverter(
358364
constructAssembleToCompositeModelMapper(),
359365
constructConstArrayModelMapper(),
360366
)
361-
private fun UtExecution.applyCommonMappings(): UtExecution {
362-
var mappedExecution = this
363-
commonMappers.forEach { mapper -> mappedExecution = mappedExecution.mapModels(mapper) }
364-
return mappedExecution
365-
}
367+
private fun UtExecution.applyCommonMappings(): UtExecution =
368+
commonMappers.fold(this) { mappedExecution, mapper ->
369+
mappedExecution.mapModels(mapper)
370+
}
366371

367-
private fun EnvironmentModels.applyCommonMappings(): EnvironmentModels {
368-
var mappedEnvironmentalModels = this
369-
commonMappers.forEach { mapper -> mappedEnvironmentalModels = mappedEnvironmentalModels.mapModels(mapper) }
370-
return mappedEnvironmentalModels
371-
}
372+
private fun EnvironmentModels.applyCommonMappings(): EnvironmentModels =
373+
commonMappers.fold(this) { mappedEnvironmentalModels, mapper ->
374+
mappedEnvironmentalModels.mapModels(mapper)
375+
}
372376

373-
private fun List<UtInstrumentation>.applyCommonMappings(): List<UtInstrumentation> {
374-
var mappedInstrumentation = this
375-
commonMappers.forEach {
376-
mapper -> mappedInstrumentation = mappedInstrumentation.map { instr -> instr.mapModels(mapper) }
377+
private fun List<UtInstrumentation>.applyCommonMappings(): List<UtInstrumentation> =
378+
commonMappers.fold(this) { mappedInstrumentation, mapper ->
379+
mappedInstrumentation.map { instr -> instr.mapModels(mapper) }
377380
}
378-
return mappedInstrumentation
379-
}
380381
}

utbot-usvm/src/main/kotlin/org/utbot/usvm/jc/JcContainer.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ class JcContainer(
9393
}
9494

9595
companion object : AutoCloseable {
96-
val TEST_EXECUTION_TIMEOUT = 1.seconds
96+
fun specifyContainerTimeout(timeout: Long) {
97+
testExecutionTimeout = timeout.seconds
98+
}
99+
100+
private var testExecutionTimeout = 1.seconds
101+
102+
val TEST_EXECUTION_TIMEOUT = testExecutionTimeout
97103

98104
private val cache = HashMap<List<File>, JcContainer>()
99105

utbot-usvm/src/main/kotlin/org/utbot/usvm/jc/JcTestExecutor.kt

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ class JcTestExecutor(
5555
val classpath: JcClasspath,
5656
private val runner: UTestConcreteExecutor
5757
) {
58+
private val memoryScopeCache = mutableMapOf<MemoryScopeDescriptor, MemoryScope>()
59+
data class MemoryScopeDescriptor(
60+
val method: JcTypedMethod,
61+
val state: JcState,
62+
val stringConstants: Map<String, UConcreteHeapRef>,
63+
val classConstants: Map<JcType, UConcreteHeapRef>,
64+
)
5865
/**
5966
* Resolves a [JcTest] from a [method] from a [state].
6067
*/
@@ -65,14 +72,6 @@ class JcTestExecutor(
6572
classConstants: Map<JcType, UConcreteHeapRef>,
6673
allowSymbolicResult: Boolean
6774
): JcExecution? {
68-
val model = state.models.first()
69-
val mocker = state.memory.mocker as JcMocker
70-
71-
val resolvedMethodMocks = mocker.symbols
72-
.entries
73-
.groupBy({ model.eval(it.key) }, { it.value })
74-
.mapValues { it.value.flatten() }
75-
7675
val uTest = createUTest(method, state, stringConstants, classConstants)
7776

7877
val concreteResult = runCatching {
@@ -85,20 +84,14 @@ class JcTestExecutor(
8584
}
8685
.getOrNull()
8786

87+
val memoryScopeDescriptor = MemoryScopeDescriptor(method, state, stringConstants, classConstants)
88+
8889
val symbolicResult by lazy {
8990
if (allowSymbolicResult) {
9091
when (val methodResult = state.methodResult) {
9192
is JcMethodResult.JcException -> UTestSymbolicExceptionResult(methodResult.type)
9293
is JcMethodResult.Success -> {
93-
val resultScope = MemoryScope(
94-
state.ctx,
95-
model,
96-
state.memory,
97-
stringConstants,
98-
classConstants,
99-
resolvedMethodMocks,
100-
method
101-
)
94+
val resultScope = createMemoryScope(memoryScopeDescriptor)
10295
val resultExpr = resultScope.resolveExpr(methodResult.value, method.returnType)
10396
val resultInitializer = resultScope.decoderApi.initializerInstructions()
10497
UTestSymbolicSuccessResult(resultInitializer, resultExpr)
@@ -145,23 +138,37 @@ class JcTestExecutor(
145138
stringConstants: Map<String, UConcreteHeapRef>,
146139
classConstants: Map<JcType, UConcreteHeapRef>,
147140
): UTest {
148-
val model = state.models.first()
149-
val ctx = state.ctx
150-
151-
val mocker = state.memory.mocker as JcMocker
152-
// val staticMethodMocks = mocker.statics TODO global mocks?????????????????????????
153-
val methodMocks = mocker.symbols
154-
155-
val resolvedMethodMocks = methodMocks
156-
.entries
157-
.groupBy({ model.eval(it.key) }, { it.value })
158-
.mapValues { it.value.flatten() }
159-
160-
val memoryScope = MemoryScope(ctx, model, model, stringConstants, classConstants, resolvedMethodMocks, method)
141+
val memoryScopeDescriptor = MemoryScopeDescriptor(method, state, stringConstants, classConstants)
142+
val memoryScope = createMemoryScope(memoryScopeDescriptor)
161143

162144
return memoryScope.createUTest()
163145
}
164146

147+
private fun createMemoryScope(descriptor: MemoryScopeDescriptor): MemoryScope =
148+
memoryScopeCache.getOrPut(descriptor) {
149+
val model = descriptor.state.models.first()
150+
val ctx = descriptor.state.ctx
151+
152+
val mocker = descriptor.state.memory.mocker as JcMocker
153+
// val staticMethodMocks = mocker.statics TODO global mocks?????????????????????????
154+
val methodMocks = mocker.symbols
155+
156+
val resolvedMethodMocks = methodMocks
157+
.entries
158+
.groupBy({ model.eval(it.key) }, { it.value })
159+
.mapValues { it.value.flatten() }
160+
161+
MemoryScope(
162+
ctx,
163+
model,
164+
model,
165+
descriptor.stringConstants,
166+
descriptor.classConstants,
167+
resolvedMethodMocks,
168+
descriptor.method,
169+
)
170+
}
171+
165172
@Suppress("UNUSED_PARAMETER")
166173
private fun resolveCoverage(method: JcTypedMethod, state: JcState): JcCoverage {
167174
// TODO: extract coverage

0 commit comments

Comments
 (0)