From 5cbf35270cb3eaebf20cb2afe5a31e2c4af55f2e Mon Sep 17 00:00:00 2001 From: Andrey Tarbeev Date: Fri, 2 Sep 2022 12:03:00 +0300 Subject: [PATCH 1/3] Adapt force mock listener for plugin --- .../model/constructor/CgMethodTestSet.kt | 7 ++++ .../tree/CgTestClassConstructor.kt | 22 ++++++++----- .../framework/plugin/api/TestCaseGenerator.kt | 1 + .../generator/UtTestsDialogProcessor.kt | 33 ++++++++++++++++--- 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/CgMethodTestSet.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/CgMethodTestSet.kt index cf47bea1ec..d86411f5a8 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/CgMethodTestSet.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/CgMethodTestSet.kt @@ -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 @@ -66,6 +67,12 @@ data class CgMethodTestSet private constructor( return executionsByStaticsUsage.map { (_, executions) -> substituteExecutions(executions) } } + fun extractSymbolicExecutions(): CgMethodTestSet { + val executionsBySource = executions.filterIsInstance() + + return substituteExecutions(executionsBySource) + } + /** * Finds a [ClassId] of all result models in executions. * diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgTestClassConstructor.kt index c83942a177..05e0bdb746 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgTestClassConstructor.kt @@ -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 + ) + } } } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt index d2d3a6c7ea..3a313e226c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt @@ -163,6 +163,7 @@ open class TestCaseGenerator( ) engineActions.map { engine.apply(it) } + engineActions.clear() generate(engine) .catch { diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt index be293ee821..ecca696672 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt @@ -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 @@ -206,13 +207,32 @@ object UtTestsDialogProcessor { withStaticsSubstitutionRequired(true) { val mockFrameworkInstalled = model.mockFramework?.isInstalled ?: true + var forceMockListener: ForceMockListener? = null + var forceStaticMockListener: ForceStaticMockListener? = null + + when (model.parametrizedTestSource) { + ParametrizedTestSource.PARAMETRIZE -> { + forceMockListener = ForceMockListener.create(testCaseGenerator, model.conflictTriggers) + forceStaticMockListener = ForceStaticMockListener.create( + testCaseGenerator, + model.conflictTriggers + ) + } - if (!mockFrameworkInstalled) { - ForceMockListener.create(testCaseGenerator, model.conflictTriggers) - } + ParametrizedTestSource.DO_NOT_PARAMETRIZE -> { + when { + !mockFrameworkInstalled -> forceMockListener = ForceMockListener.create( + testCaseGenerator, + model.conflictTriggers + ) - if (!model.staticsMocking.isConfigured) { - ForceStaticMockListener.create(testCaseGenerator, model.conflictTriggers) + !model.staticsMocking.isConfigured -> forceStaticMockListener = + ForceStaticMockListener.create( + testCaseGenerator, + model.conflictTriggers + ) + } + } } val notEmptyCases = runCatching { @@ -235,6 +255,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" } From 87765bd317fbe242b8fb3ec254d9178505277049 Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Fri, 2 Sep 2022 17:01:00 +0300 Subject: [PATCH 2/3] Cosmetic improvement --- .../generator/UtTestsDialogProcessor.kt | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt index ecca696672..cb7edd2628 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/UtTestsDialogProcessor.kt @@ -206,33 +206,25 @@ object UtTestsDialogProcessor { .executeSynchronously() withStaticsSubstitutionRequired(true) { - val mockFrameworkInstalled = model.mockFramework?.isInstalled ?: true + val mockFrameworkInstalled = model.mockFramework.isInstalled var forceMockListener: ForceMockListener? = null var forceStaticMockListener: ForceStaticMockListener? = null when (model.parametrizedTestSource) { - ParametrizedTestSource.PARAMETRIZE -> { - forceMockListener = ForceMockListener.create(testCaseGenerator, model.conflictTriggers) - forceStaticMockListener = ForceStaticMockListener.create( - testCaseGenerator, - model.conflictTriggers - ) - } - ParametrizedTestSource.DO_NOT_PARAMETRIZE -> { when { - !mockFrameworkInstalled -> forceMockListener = ForceMockListener.create( - testCaseGenerator, - model.conflictTriggers - ) + !mockFrameworkInstalled -> forceMockListener = + ForceMockListener.create(testCaseGenerator, model.conflictTriggers) - !model.staticsMocking.isConfigured -> forceStaticMockListener = - ForceStaticMockListener.create( - testCaseGenerator, - model.conflictTriggers - ) + !model.staticsMocking.isConfigured -> + forceStaticMockListener = ForceStaticMockListener.create(testCaseGenerator, model.conflictTriggers) } } + + ParametrizedTestSource.PARAMETRIZE -> { + forceMockListener = ForceMockListener.create(testCaseGenerator, model.conflictTriggers) + forceStaticMockListener = ForceStaticMockListener.create(testCaseGenerator, model.conflictTriggers) + } } val notEmptyCases = runCatching { From e2f6c516ed1229faa396100e4b847aac2a59d6e9 Mon Sep 17 00:00:00 2001 From: Andrey Tarbeev Date: Mon, 5 Sep 2022 11:26:36 +0300 Subject: [PATCH 3/3] Refactor engine actions --- .../plugin/api/EngineActionsController.kt | 16 ++++++++++++++++ .../framework/plugin/api/TestCaseGenerator.kt | 13 +++++-------- .../TestSpecificTestCaseGenerator.kt | 3 +-- 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/EngineActionsController.kt diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/EngineActionsController.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/EngineActionsController.kt new file mode 100644 index 0000000000..bd499aa991 --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/EngineActionsController.kt @@ -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() + } +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt index 3a313e226c..c06182c157 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/plugin/api/TestCaseGenerator.kt @@ -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") @@ -121,9 +121,9 @@ open class TestCaseGenerator( chosenClassesToMockAlways: Set = Mocker.javaDefaultClasses.mapTo(mutableSetOf()) { it.id }, executionTimeEstimator: ExecutionTimeEstimator = ExecutionTimeEstimator(utBotGenerationTimeoutInMillis, 1) ): Flow { - 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) } @@ -160,10 +160,7 @@ open class TestCaseGenerator( mockStrategy, chosenClassesToMockAlways, executionTimeEstimator - ) - - engineActions.map { engine.apply(it) } - engineActions.clear() + ).also { engine -> engineActions.apply(engine) } generate(engine) .catch { diff --git a/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/TestSpecificTestCaseGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/TestSpecificTestCaseGenerator.kt index 5ea62846cf..b2e9ed2362 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/TestSpecificTestCaseGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/TestSpecificTestCaseGenerator.kt @@ -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 {}