Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dbeaf15
Add usvm engine option on UI
EgorkaKulikov Dec 11, 2023
8c4a3ea
Sens engine type data to engine process via Rd
EgorkaKulikov Dec 11, 2023
e1e7139
Use appropriate engine in flow
EgorkaKulikov Dec 11, 2023
3fc587e
Introduce `UtilMethodProviderPlaceholder` (#2717)
IlyaMuravjov Dec 13, 2023
5d68839
Make `TestCaseGenerator` use `UsvmSymbolicEngine` for entire class (#…
IlyaMuravjov Dec 13, 2023
24d1003
Initial implementation of usvm tests generation in UtBot flow
EgorkaKulikov Dec 18, 2023
4ad8c4a
Apply some improvements
EgorkaKulikov Dec 19, 2023
91803c2
Update usvm version and related updates in JcContainer
EgorkaKulikov Dec 19, 2023
7779a3b
Update usvm version and related updates in ClassScorer usages
EgorkaKulikov Dec 20, 2023
44f0c2a
Correct applyCommonMappings methods
EgorkaKulikov Dec 20, 2023
ce16821
Several UI corrections
EgorkaKulikov Dec 20, 2023
3b3ab15
Fix JcContainer caching
EgorkaKulikov Dec 20, 2023
3a0da82
Apply discussion fixes.
EgorkaKulikov Dec 21, 2023
cf23242
Fix enablement of useExperimentalEngine
EgorkaKulikov Dec 21, 2023
0108b05
Refactoring
tepa46 Dec 21, 2023
06529ea
Add assemble models in USVM symbolic engine
tepa46 Dec 21, 2023
aba7c4f
Update utResult value
tepa46 Dec 21, 2023
fe1cee7
Resrtore Python IDE
EgorkaKulikov Dec 22, 2023
351c10d
Do not initialize Jc-flow if timeout = 0
EgorkaKulikov Dec 22, 2023
aa84d2a
Fix `modificationsChain` mapping when removing `UtilMethodProviderPla…
IlyaMuravjov Dec 22, 2023
fd47bc7
Make `UtSymbolicExecution.copy` method also copy `containsMocking` field
IlyaMuravjov Dec 22, 2023
e30f887
Set `zip64 = true` in `:utbot-cli:jar` Gradle task
IlyaMuravjov Dec 22, 2023
c8fc4a5
Revert redundant refactoring
IlyaMuravjov Dec 22, 2023
c89b3b2
Use same `memoryScope` to resolve `uTest` and `symbolicResult`.
IlyaMuravjov Dec 22, 2023
8831369
Preserve identity when mapping `MissingState`
IlyaMuravjov Dec 22, 2023
392d784
Set `zip64 = true` in `:utbot-cli-go:jar`, `:utbot-cli-js:jar`, `:utb…
IlyaMuravjov Dec 22, 2023
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
Prev Previous commit
Next Next commit
Make TestCaseGenerator use UsvmSymbolicEngine for entire class (#…
  • Loading branch information
IlyaMuravjov authored and EgorkaKulikov committed Dec 22, 2023
commit 5d688394938916fc0742347c41f506fff5a7ca1a
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ package org.utbot.engine

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import org.utbot.framework.plugin.api.ExecutableId
import org.utbot.framework.plugin.api.UtResult

class UsvmSymbolicEngine {

fun generateWithUsvm(): Flow<UtResult> = emptyFlow()
object UsvmSymbolicEngine {
// TODO implement
fun runUsvmGeneration(
methods: List<ExecutableId>,
classpath: String,
timeoutMillis: Long
): Flow<Pair<ExecutableId, UtResult>> =
emptyFlow()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
Expand All @@ -16,6 +17,7 @@ import mu.KotlinLogging
import org.utbot.common.*
import org.utbot.engine.EngineController
import org.utbot.engine.Mocker
import org.utbot.engine.UsvmSymbolicEngine
import org.utbot.engine.UtBotSymbolicEngine
import org.utbot.engine.util.mockListeners.ForceMockListener
import org.utbot.engine.util.mockListeners.ForceStaticMockListener
Expand Down Expand Up @@ -173,9 +175,10 @@ open class TestCaseGenerator(
methods: List<ExecutableId>,
mockStrategy: MockStrategyApi,
chosenClassesToMockAlways: Set<ClassId> = Mocker.javaDefaultClasses.mapTo(mutableSetOf()) { it.id },
methodsGenerationTimeout: Long = utBotGenerationTimeoutInMillis,
utBotTimeout: Long = utBotGenerationTimeoutInMillis,
userTaintConfigurationProvider: TaintConfigurationProvider? = null,
generate: (engine: UtBotSymbolicEngine) -> Flow<UtResult> = defaultTestFlow(methodsGenerationTimeout)
generate: (engine: UtBotSymbolicEngine) -> Flow<UtResult> = defaultTestFlow(utBotTimeout),
usvmTimeoutMillis: Long = 0,
): List<UtMethodTestSet> = ConcreteExecutor.defaultPool.use { _ -> // TODO: think on appropriate way to close instrumented processes
if (isCanceled()) return@use methods.map { UtMethodTestSet(it) }

Expand All @@ -189,7 +192,7 @@ open class TestCaseGenerator(
return@use methods.map { method -> UtMethodTestSet(method, errors = method2errors.getValue(method)) }

val executionStartInMillis = System.currentTimeMillis()
val executionTimeEstimator = ExecutionTimeEstimator(methodsGenerationTimeout, methods.size)
val executionTimeEstimator = ExecutionTimeEstimator(utBotTimeout, methods.size)

val currentUtContext = utContext

Expand All @@ -200,6 +203,29 @@ open class TestCaseGenerator(
val forceMockListener = ForceMockListener.create(this, conflictTriggers)
val forceStaticMockListener = ForceStaticMockListener.create(this, conflictTriggers)

suspend fun consumeUtResultFlow(utResultFlow: Flow<Pair<ExecutableId, UtResult>>) =
utResultFlow.catch {
logger.error(it) { "Error in flow" }
}
.collect { (executableId, utResult) ->
when (utResult) {
is UtExecution -> {
if (utResult is UtSymbolicExecution &&
(conflictTriggers.triggered(Conflict.ForceMockHappened) ||
conflictTriggers.triggered(Conflict.ForceStaticMockHappened))
) {
utResult.containsMocking = true
}
method2executions.getValue(executableId) += utResult
}

is UtError -> {
method2errors.getValue(executableId).merge(utResult.description, 1, Int::plus)
logger.error(utResult.error) { "UtError occurred" }
}
}
}

runIgnoringCancellationException {
runBlockingWithCancellationPredicate(isCanceled) {
for ((method, controller) in method2controller) {
Expand All @@ -223,27 +249,7 @@ open class TestCaseGenerator(
engineActions.map { engine.apply(it) }
engineActions.clear()

generate(engine)
.catch {
logger.error(it) { "Error in flow" }
}
.collect {
when (it) {
is UtExecution -> {
if (it is UtSymbolicExecution &&
(conflictTriggers.triggered(Conflict.ForceMockHappened) ||
conflictTriggers.triggered(Conflict.ForceStaticMockHappened))
) {
it.containsMocking = true
}
method2executions.getValue(method) += it
}
is UtError -> {
method2errors.getValue(method).merge(it.description, 1, Int::plus)
logger.error(it.error) { "UtError occurred" }
}
}
}
consumeUtResultFlow(generate(engine).map { utResult -> method to utResult })
} catch (e: Exception) {
logger.error(e) {"Error in engine"}
throw e
Expand Down Expand Up @@ -284,6 +290,8 @@ open class TestCaseGenerator(
}
logger.debug("test generator global scope lifecycle check ended")
}

consumeUtResultFlow(UsvmSymbolicEngine.runUsvmGeneration(methods, classpathForEngine, usvmTimeoutMillis))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flattenConcat
import kotlinx.coroutines.flow.flowOf
import org.utbot.engine.UsvmSymbolicEngine
import org.utbot.engine.UtBotSymbolicEngine
import org.utbot.framework.UtSettings
import org.utbot.framework.codegen.domain.SymbolicEngineSource

/**
* Constructs [TestFlow] for customization and creates flow producer.
Expand All @@ -18,8 +16,7 @@ fun testFlow(block: TestFlow.() -> Unit): UtBotSymbolicEngine.() -> Flow<UtResul
* Creates default flow that uses [UtSettings] for customization.
*/
fun defaultTestFlow(timeout: Long) = testFlow {
isSymbolicEngineEnabled = true
symbolicEngineType = SymbolicEngineSource.UnitTestBot
isUtBotSymbolicEngineEnabled = true
generationTimeout = timeout
isFuzzingEnabled = UtSettings.useFuzzing
if (generationTimeout > 0) {
Expand All @@ -42,8 +39,7 @@ class TestFlow internal constructor(block: TestFlow.() -> Unit) {
set(value) {
field = maxOf(0, value)
}
var isSymbolicEngineEnabled = true
var symbolicEngineType = SymbolicEngineSource.UnitTestBot
var isUtBotSymbolicEngineEnabled = true
var isFuzzingEnabled = false
var fuzzingValue: Double = 0.1
set(value) {
Expand All @@ -64,7 +60,7 @@ class TestFlow internal constructor(block: TestFlow.() -> Unit) {
return when {
generationTimeout == 0L -> emptyFlow()
isFuzzingEnabled -> {
when (val value = if (isSymbolicEngineEnabled) (fuzzingValue * generationTimeout).toLong() else generationTimeout) {
when (val value = if (isUtBotSymbolicEngineEnabled) (fuzzingValue * generationTimeout).toLong() else generationTimeout) {
0L -> engine.traverse()
generationTimeout -> engine.fuzzing(System.currentTimeMillis() + value)
else -> flowOf(
Expand All @@ -73,12 +69,7 @@ class TestFlow internal constructor(block: TestFlow.() -> Unit) {
).flattenConcat()
}
}
isSymbolicEngineEnabled -> {
when (symbolicEngineType) {
SymbolicEngineSource.UnitTestBot -> engine.traverse()
SymbolicEngineSource.Usvm -> UsvmSymbolicEngine().generateWithUsvm()
}
}
isUtBotSymbolicEngineEnabled -> engine.traverse()
else -> emptyFlow()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.utbot.framework.codegen.domain.ParametrizedTestSource
import org.utbot.framework.codegen.domain.ProjectType
import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour
import org.utbot.framework.codegen.domain.SymbolicEngineSource
import org.utbot.framework.codegen.domain.SymbolicEngineSource.*
import org.utbot.framework.codegen.domain.testFrameworkByName
import org.utbot.framework.codegen.generator.AbstractCodeGenerator
import org.utbot.framework.codegen.generator.CodeGeneratorParams
Expand Down Expand Up @@ -114,10 +115,17 @@ private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatch
val methods: List<ExecutableId> = kryoHelper.readObject(params.methods)
logger.debug()
.measureTime({ "starting generation for ${methods.size} methods, starting with ${methods.first()}" }) {
val symbolicEngineSource = SymbolicEngineSource.valueOf(params.symbolicEngineType)
val utBotTimeout = when {
!params.isSymbolicEngineEnabled -> params.timeout
symbolicEngineSource == UnitTestBot -> params.timeout
params.isFuzzingEnabled -> (params.fuzzingValue * params.timeout).toLong()
else -> 0L
}

val generateFlow = testFlow {
generationTimeout = params.generationTimeout
isSymbolicEngineEnabled = params.isSymbolicEngineEnabled
symbolicEngineType = SymbolicEngineSource.valueOf(params.symbolicEngineType)
generationTimeout = utBotTimeout
isUtBotSymbolicEngineEnabled = params.isSymbolicEngineEnabled && symbolicEngineSource == UnitTestBot
isFuzzingEnabled = params.isFuzzingEnabled
fuzzingValue = params.fuzzingValue
}
Expand All @@ -130,9 +138,10 @@ private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatch
methods,
MockStrategyApi.valueOf(params.mockStrategy),
kryoHelper.readObject(params.chosenClassesToMockAlways),
params.timeout,
utBotTimeout,
userTaintConfigurationProvider,
generate = generateFlow,
usvmTimeoutMillis = params.generationTimeout - utBotTimeout,
)
.summarizeAll(Paths.get(params.searchDirectory), null)
.filterNot { it.executions.isEmpty() && it.errors.isEmpty() }
Expand Down