Skip to content

Adapt force mock listener for plugin #845

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

Closed
wants to merge 3 commits into from
Closed
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 @@ -8,6 +8,7 @@ import org.utbot.framework.plugin.api.UtExecution
import org.utbot.framework.plugin.api.UtExecutionFailure
import org.utbot.framework.plugin.api.UtExecutionSuccess
import org.utbot.framework.plugin.api.UtMethodTestSet
import org.utbot.framework.plugin.api.UtSymbolicExecution
import org.utbot.framework.plugin.api.util.executableId
import org.utbot.framework.plugin.api.util.objectClassId
import org.utbot.framework.plugin.api.util.voidClassId
Expand Down Expand Up @@ -66,6 +67,12 @@ data class CgMethodTestSet private constructor(
return executionsByStaticsUsage.map { (_, executions) -> substituteExecutions(executions) }
}

fun extractSymbolicExecutions(): CgMethodTestSet {
val executionsBySource = executions.filterIsInstance<UtSymbolicExecution>()

return substituteExecutions(executionsBySource)
}

/**
* Finds a [ClassId] of all result models in executions.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,20 @@ internal class CgTestClassConstructor(val context: CgContext) :
}
}
ParametrizedTestSource.PARAMETRIZE -> {
for (splitByExecutionTestSet in testSet.splitExecutionsByResult()) {
for (splitByChangedStaticsTestSet in splitByExecutionTestSet.splitExecutionsByChangedStatics()) {
createParametrizedTestAndDataProvider(
splitByChangedStaticsTestSet,
requiredFields,
regions,
methodUnderTest
)
// We filter out Fuzzer executions because sometimes we need to turn off
// Symbolic Engine and stop the test generation in case of mocking taking place
// and do not collect this execution. But having Fuzzer executions may cause
// unwanted executions being present.
testSet.extractSymbolicExecutions().also {
for (splitByExecutionTestSet in it.splitExecutionsByResult()) {
for (splitByChangedStaticsTestSet in splitByExecutionTestSet.splitExecutionsByChangedStatics()) {
createParametrizedTestAndDataProvider(
splitByChangedStaticsTestSet,
requiredFields,
regions,
methodUnderTest
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.utbot.framework.plugin.api

import org.utbot.engine.UtBotSymbolicEngine

class EngineActionsController {
private val actions: MutableList<(UtBotSymbolicEngine) -> Unit> = mutableListOf()

fun add(action: (UtBotSymbolicEngine) -> Unit) {
actions.add(action)
}

fun apply(symbolicEngine: UtBotSymbolicEngine) {
actions.forEach { symbolicEngine.apply(it) }
actions.clear()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ open class TestCaseGenerator(
private val buildDir: Path,
private val classpath: String?,
private val dependencyPaths: String,
val engineActions: MutableList<(UtBotSymbolicEngine) -> Unit> = mutableListOf(),
val isCanceled: () -> Boolean = { false },
val forceSootReload: Boolean = true
) {
val engineActions: EngineActionsController = EngineActionsController()
private val logger: KLogger = KotlinLogging.logger {}
private val timeoutLogger: KLogger = KotlinLogging.logger(logger.name + ".timeout")

Expand Down Expand Up @@ -121,9 +121,9 @@ open class TestCaseGenerator(
chosenClassesToMockAlways: Set<ClassId> = Mocker.javaDefaultClasses.mapTo(mutableSetOf()) { it.id },
executionTimeEstimator: ExecutionTimeEstimator = ExecutionTimeEstimator(utBotGenerationTimeoutInMillis, 1)
): Flow<UtResult> {
val engine = createSymbolicEngine(controller, method, mockStrategy, chosenClassesToMockAlways, executionTimeEstimator)
engineActions.map { engine.apply(it) }
engineActions.clear()
val engine =
createSymbolicEngine(controller, method, mockStrategy, chosenClassesToMockAlways, executionTimeEstimator)
.also { engine -> engineActions.apply(engine) }
return defaultTestFlow(engine, executionTimeEstimator.userTimeout)
}

Expand Down Expand Up @@ -160,9 +160,7 @@ open class TestCaseGenerator(
mockStrategy,
chosenClassesToMockAlways,
executionTimeEstimator
)

engineActions.map { engine.apply(it) }
).also { engine -> engineActions.apply(engine) }

generate(engine)
.catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ class TestSpecificTestCaseGenerator(
buildDir: Path,
classpath: String?,
dependencyPaths: String,
engineActions: MutableList<(UtBotSymbolicEngine) -> Unit> = mutableListOf(),
isCanceled: () -> Boolean = { false },
): TestCaseGenerator(buildDir, classpath, dependencyPaths, engineActions, isCanceled, forceSootReload = false) {
): TestCaseGenerator(buildDir, classpath, dependencyPaths, isCanceled, forceSootReload = false) {

private val logger = KotlinLogging.logger {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import java.nio.file.Paths
import java.util.concurrent.TimeUnit
import org.utbot.engine.util.mockListeners.ForceStaticMockListener
import org.utbot.framework.PathSelectorType
import org.utbot.framework.codegen.ParametrizedTestSource
import org.utbot.framework.plugin.services.WorkingDirService
import org.utbot.intellij.plugin.models.packageName
import org.utbot.intellij.plugin.settings.Settings
Expand Down Expand Up @@ -205,14 +206,25 @@ object UtTestsDialogProcessor {
.executeSynchronously()

withStaticsSubstitutionRequired(true) {
val mockFrameworkInstalled = model.mockFramework?.isInstalled ?: true

if (!mockFrameworkInstalled) {
ForceMockListener.create(testCaseGenerator, model.conflictTriggers)
}
val mockFrameworkInstalled = model.mockFramework.isInstalled
var forceMockListener: ForceMockListener? = null
var forceStaticMockListener: ForceStaticMockListener? = null

when (model.parametrizedTestSource) {
ParametrizedTestSource.DO_NOT_PARAMETRIZE -> {
when {
!mockFrameworkInstalled -> forceMockListener =
ForceMockListener.create(testCaseGenerator, model.conflictTriggers)

!model.staticsMocking.isConfigured ->
forceStaticMockListener = ForceStaticMockListener.create(testCaseGenerator, model.conflictTriggers)
}
}

if (!model.staticsMocking.isConfigured) {
ForceStaticMockListener.create(testCaseGenerator, model.conflictTriggers)
ParametrizedTestSource.PARAMETRIZE -> {
forceMockListener = ForceMockListener.create(testCaseGenerator, model.conflictTriggers)
forceStaticMockListener = ForceStaticMockListener.create(testCaseGenerator, model.conflictTriggers)
}
}

val notEmptyCases = runCatching {
Expand All @@ -235,6 +247,9 @@ object UtTestsDialogProcessor {
}
}.getOrDefault(listOf())

forceMockListener?.detach(testCaseGenerator, forceMockListener)
forceStaticMockListener?.detach(testCaseGenerator, forceStaticMockListener)

if (notEmptyCases.isEmpty()) {
if (model.srcClasses.size > 1) {
logger.error { "Failed to generate any tests cases for class $className" }
Expand Down