diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt index 9a7fc3406b..f3a53670cd 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt @@ -1149,14 +1149,21 @@ open class TypeParameters(val parameters: List = emptyList()) class WildcardTypeParameter : TypeParameters(emptyList()) /** - * Additional data describing user project. - */ -interface ApplicationContext - -/** - * A context to use when no additional data is required. + * A context to use when no specific data is required. + * + * @param mockFrameworkInstalled shows if we have installed framework dependencies + * @param staticsMockingIsConfigured shows if we have installed static mocking tools */ -object EmptyApplicationContext: ApplicationContext +open class StandardApplicationContext( + val mockFrameworkInstalled: Boolean = true, + val staticsMockingIsConfigured: Boolean = true, +) { + init { + if (!mockFrameworkInstalled) { + require(!staticsMockingIsConfigured) { "Static mocking cannot be used without mock framework" } + } + } +} /** * Data we get from Spring application context @@ -1164,9 +1171,11 @@ object EmptyApplicationContext: ApplicationContext * * @param beanQualifiedNames describes fqn of injected classes */ -data class SpringApplicationContext( +class SpringApplicationContext( + mockInstalled: Boolean, + staticsMockingIsConfigured: Boolean, val beanQualifiedNames: List = emptyList(), -): ApplicationContext { +): StandardApplicationContext(mockInstalled, staticsMockingIsConfigured) { private val springInjectedClasses: List by lazy { beanQualifiedNames.map { fqn -> utContext.classLoader.loadClass(fqn).id } } diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt index 9dc536f2e6..ae2609d787 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt @@ -3,18 +3,33 @@ package org.utbot.examples.mock import org.utbot.framework.plugin.api.MockStrategyApi import org.junit.jupiter.api.Test import org.utbot.testcheckers.eq -import org.utbot.testing.DoNotCalculate import org.utbot.testing.UtValueTestCaseChecker +import org.utbot.testing.atLeast internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = CommonMocksExample::class) { + + //TODO: coverage values here require further investigation by experts + @Test - fun testMockInterfaceWithoutImplementors() { + fun testMockInterfaceWithoutImplementorsWithNoMocksStrategy() { + checkMocks( + CommonMocksExample::mockInterfaceWithoutImplementors, + eq(1), + { v, mocks, _ -> v == null && mocks.isEmpty() }, + mockStrategy = MockStrategyApi.NO_MOCKS, + coverage = atLeast(75), + ) + } + + @Test + fun testMockInterfaceWithoutImplementorsWithMockingStrategy() { checkMocks( CommonMocksExample::mockInterfaceWithoutImplementors, eq(2), { v, mocks, _ -> v == null && mocks.isEmpty() }, { _, mocks, _ -> mocks.singleOrNull() != null }, - coverage = DoNotCalculate + mockStrategy = MockStrategyApi.OTHER_CLASSES, + coverage = atLeast(75), ) } @@ -27,7 +42,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common { fst, _, mocks, _ -> fst == null && mocks.isEmpty() }, { _, _, mocks, _ -> mocks.isEmpty() }, // should be changed to not null fst when 1449 will be finished mockStrategy = MockStrategyApi.OTHER_PACKAGES, - coverage = DoNotCalculate + coverage = atLeast(75) ) } @@ -42,7 +57,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common // node == node.next // node.next.value == node.value + 1 mockStrategy = MockStrategyApi.OTHER_CLASSES, - coverage = DoNotCalculate + coverage = atLeast(13) ) } @@ -53,7 +68,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common eq(1), { r -> r == -420 }, mockStrategy = MockStrategyApi.OTHER_CLASSES, - coverage = DoNotCalculate + coverage = atLeast(70), ) } @@ -63,7 +78,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common CommonMocksExample::mocksForNullOfDifferentTypes, eq(1), mockStrategy = MockStrategyApi.OTHER_PACKAGES, - coverage = DoNotCalculate + coverage = atLeast(75) ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Mocks.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Mocks.kt index 231d31c187..27b436e24d 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Mocks.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Mocks.kt @@ -19,6 +19,7 @@ import kotlinx.collections.immutable.persistentListOf import org.utbot.common.nameOfPackage import org.utbot.engine.types.OBJECT_TYPE import org.utbot.engine.util.mockListeners.MockListenerController +import org.utbot.framework.plugin.api.StandardApplicationContext import org.utbot.framework.plugin.api.util.isInaccessibleViaReflection import soot.BooleanType import soot.RefType @@ -128,6 +129,36 @@ data class UtStaticMethodMockInfo( val methodId: MethodId ) : UtMockInfo(methodId.classId, addr) +/** + * A wrapper for [ObjectValue] to store additional info. + */ +sealed class MockedObjectInfo { + abstract val value: ObjectValue? +} + +object NoMock: MockedObjectInfo() { + override val value: ObjectValue? = null +} + +/** + * Represents a mock that occurs when mock strategy allows it + * or when an object type requires always requires mocking. + * + * See [Mocker.mockAlways] for more details. + */ +class ExpectedMock(objectValue: ObjectValue): MockedObjectInfo() { + override val value: ObjectValue = objectValue +} + +/** + * Represents a mock that occurs when it is not allowed. + * E.g. mock framework is not installed or + * mock strategy is [MockStrategy.NO_MOCKS] and class is not in [Mocker.mockAlways] set. + */ +class UnexpectedMock(objectValue: ObjectValue): MockedObjectInfo() { + override val value: ObjectValue = objectValue +} + /** * Service to mock things. Knows mock strategy, class under test and class hierarchy. */ @@ -137,21 +168,30 @@ class Mocker( private val hierarchy: Hierarchy, chosenClassesToMockAlways: Set, internal val mockListenerController: MockListenerController? = null, + private val applicationContext: StandardApplicationContext, ) { + private val mocksAreDesired: Boolean = strategy != MockStrategy.NO_MOCKS + /** - * Creates mocked instance of the [type] using mock info if it should be mocked by the mocker, - * otherwise returns null. + * Creates mocked instance (if it should be mocked by the mocker) of the [type] using [mockInfo] + * otherwise returns [NoMock]. * * @see shouldMock */ - fun mock(type: RefType, mockInfo: UtMockInfo): ObjectValue? = - if (shouldMock(type, mockInfo)) createMockObject(type, mockInfo) else null + fun mock(type: RefType, mockInfo: UtMockInfo): MockedObjectInfo { + val objectValue = if (shouldMock(type, mockInfo)) createMockObject(type, mockInfo) else null + return construct(objectValue, mockInfo) + } /** - * Creates mocked instance of the [type] using mock info. Unlike to [mock], it does not - * check anything and always returns the constructed mock. + * Unlike to [mock], unconditionally creates a mocked instance of the [type] using [mockInfo]. */ - fun forceMock(type: RefType, mockInfo: UtMockInfo): ObjectValue = createMockObject(type, mockInfo) + fun forceMock(type: RefType, mockInfo: UtMockInfo): MockedObjectInfo { + mockListenerController?.onShouldMock(strategy, mockInfo) + + val objectValue = createMockObject(type, mockInfo) + return construct(objectValue, mockInfo) + } /** * Checks if Engine should mock objects of particular type with current mock strategy and mock type. @@ -177,6 +217,30 @@ class Mocker( } } + /** + * Constructs [MockedObjectInfo]: enriches given [mockedValue] with an information if mocking is expected or not. + */ + private fun construct(mockedValue: ObjectValue?, mockInfo: UtMockInfo): MockedObjectInfo { + if (mockedValue == null) { + return NoMock + } + + val mockingIsPossible = when (mockInfo) { + is UtFieldMockInfo, + is UtObjectMockInfo -> applicationContext.mockFrameworkInstalled + is UtNewInstanceMockInfo, + is UtStaticMethodMockInfo, + is UtStaticObjectMockInfo -> applicationContext.staticsMockingIsConfigured + } + val mockingIsForcedAndPossible = mockAlways(mockedValue.type) && mockingIsPossible + + return if (mocksAreDesired || mockingIsForcedAndPossible) { + ExpectedMock(mockedValue) + } else { + UnexpectedMock(mockedValue) + } + } + private fun checkIfShouldMock( type: RefType, mockInfo: UtMockInfo diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt index 5f8ce0d1f3..cf4bbdae0c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt @@ -116,12 +116,11 @@ import org.utbot.framework.UtSettings import org.utbot.framework.UtSettings.maximizeCoverageUsingReflection import org.utbot.framework.UtSettings.preferredCexOption import org.utbot.framework.UtSettings.substituteStaticsWithSymbolicVariable -import org.utbot.framework.plugin.api.ApplicationContext +import org.utbot.framework.plugin.api.StandardApplicationContext import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.FieldId import org.utbot.framework.plugin.api.MethodId -import org.utbot.framework.plugin.api.SpringApplicationContext import org.utbot.framework.plugin.api.classId import org.utbot.framework.plugin.api.id import org.utbot.framework.plugin.api.util.executable @@ -240,7 +239,7 @@ class Traverser( internal val typeResolver: TypeResolver, private val globalGraph: InterProceduralUnitGraph, private val mocker: Mocker, - private val applicationContext: ApplicationContext?, + private val applicationContext: StandardApplicationContext?, ) : UtContextInitializer() { private val visitedStmts: MutableSet = mutableSetOf() @@ -277,8 +276,6 @@ class Traverser( internal val objectCounter = ObjectCounter(TypeRegistry.objectCounterInitialValue) - - private fun findNewAddr(insideStaticInitializer: Boolean): UtAddrExpression { val newAddr = objectCounter.createNewAddr() // return negative address for objects created inside static initializer @@ -1383,8 +1380,17 @@ class Traverser( queuedSymbolicStateUpdates += MemoryUpdate(addrToMockInfo = persistentHashMapOf(addr to mockInfo)) - val mockedObject = mocker.mock(type, mockInfo) + val mockedObjectInfo = mocker.mock(type, mockInfo) + + if (mockedObjectInfo is UnexpectedMock) { + // if mock occurs, but it is unexpected due to some reasons + // (e.g. we do not have mock framework installed), + // we can only generate a test that uses null value for mocked object + queuedSymbolicStateUpdates += nullEqualityConstraint.asHardConstraint() + return mockedObjectInfo.value + } + val mockedObject = mockedObjectInfo.value if (mockedObject != null) { queuedSymbolicStateUpdates += MemoryUpdate(mockInfos = persistentListOf(MockInfoEnriched(mockInfo))) @@ -1470,7 +1476,24 @@ class Traverser( } val mockInfo = mockInfoGenerator.generate(addr) - val mockedObject = mocker.forceMock(type, mockInfoGenerator.generate(addr)) + val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr)) + + val mockedObject: ObjectValue = when (mockedObjectInfo) { + is NoMock -> error("Value must be mocked after the force mock") + is ExpectedMock -> mockedObjectInfo.value + is UnexpectedMock -> { + // if mock occurs, but it is unexpected due to some reasons + // (e.g. we do not have mock framework installed), + // we can only generate a test that uses null value for mocked object + queuedSymbolicStateUpdates += nullEqualityConstraint.asHardConstraint() + + mockedObjectInfo.value + } + } + + if (mockedObjectInfo is UnexpectedMock) { + return mockedObject + } queuedSymbolicStateUpdates += MemoryUpdate(mockInfos = persistentListOf(MockInfoEnriched(mockInfo))) @@ -2675,7 +2698,7 @@ class Traverser( .map { (method, implementationClass, possibleTypes) -> val typeStorage = typeResolver.constructTypeStorage(implementationClass, possibleTypes) val mockInfo = memory.mockInfoByAddr(instance.addr) - val mockedObject = mockInfo?.let { + val mockedObjectInfo = mockInfo?.let { // TODO rewrite to fix JIRA:1611 val type = Scene.v().getSootClass(mockInfo.classId.name).type val ancestorTypes = typeResolver.findOrConstructAncestorsIncludingTypes(type) @@ -2684,28 +2707,42 @@ class Traverser( } else { it.copyWithClassId(classId = implementationClass.id) } - mocker.mock(implementationClass, updatedMockInfo) - } - - if (mockedObject == null) { - // Above we might get implementationClass that has to be substituted. - // For example, for a call "Collection.size()" such classes will be produced. - val wrapperOrInstance = wrapper(implementationClass, instance.addr) - ?: instance.copy(typeStorage = typeStorage) - val typeConstraint = typeRegistry.typeConstraint(instance.addr, wrapperOrInstance.typeStorage) - val constraints = setOf(typeConstraint.isOrNullConstraint()) + mocker.mock(implementationClass, updatedMockInfo) + } ?: NoMock - // TODO add memory updated for types JIRA:1523 + when (mockedObjectInfo) { + is NoMock -> { + // Above we might get implementationClass that has to be substituted. + // For example, for a call "Collection.size()" such classes will be produced. + val wrapperOrInstance = wrapper(implementationClass, instance.addr) + ?: instance.copy(typeStorage = typeStorage) - InvocationTarget(wrapperOrInstance, method, constraints) - } else { - val typeConstraint = typeRegistry.typeConstraint(mockedObject.addr, mockedObject.typeStorage) - val constraints = setOf(typeConstraint.isOrNullConstraint()) + val typeConstraint = typeRegistry.typeConstraint(instance.addr, wrapperOrInstance.typeStorage) + val constraints = setOf(typeConstraint.isOrNullConstraint()) - // TODO add memory updated for types JIRA:1523 - // TODO isMock???? - InvocationTarget(mockedObject, method, constraints) + // TODO add memory updated for types JIRA:1523 + InvocationTarget(wrapperOrInstance, method, constraints) + } + is ExpectedMock -> { + val mockedObject = mockedObjectInfo.value + val typeConstraint = typeRegistry.typeConstraint(mockedObject.addr, mockedObject.typeStorage) + val constraints = setOf(typeConstraint.isOrNullConstraint()) + + // TODO add memory updated for types JIRA:1523 + // TODO isMock???? + InvocationTarget(mockedObject, method, constraints) + } + /* + Currently, it is unclear how this could happen. + Perhaps, the answer is somewhere in the following situation: + you have an interface with an abstract method `foo`, and it has an abstract inheritor with the implementation of the method, + but this inheritor doesn't have any concrete inheritors. It looks like in this case we would mock this instance + (because it doesn't have any possible concrete type), but it is impossible since either this class cannot present + in possible types of the object on which we call `foo` (since they contain only concrete types), + or this class would be already mocked (since it doesn't contain any concrete implementors). + */ + is UnexpectedMock -> unreachableBranch("If it ever happens, it should be investigated") } } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt index 083efdde51..2b913f31eb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt @@ -105,7 +105,7 @@ class UtBotSymbolicEngine( dependencyPaths: String, val mockStrategy: MockStrategy = NO_MOCKS, chosenClassesToMockAlways: Set, - applicationContext: ApplicationContext?, + applicationContext: StandardApplicationContext, private val solverTimeoutInMillis: Int = checkSolverTimeoutMillis ) : UtContextInitializer() { private val graph = methodUnderTest.sootMethod.jimpleBody().apply { @@ -129,7 +129,8 @@ class UtBotSymbolicEngine( classUnderTest, hierarchy, chosenClassesToMockAlways, - MockListenerController(controller) + MockListenerController(controller), + applicationContext = applicationContext, ) fun attachMockListener(mockListener: MockListener) = mocker.mockListenerController?.attach(mockListener) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceMockListener.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceMockListener.kt index f07f906259..ac9001dd39 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceMockListener.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceMockListener.kt @@ -8,21 +8,17 @@ import org.utbot.framework.util.ConflictTriggers /** * Listener for mocker events in [org.utbot.engine.UtBotSymbolicEngine]. - * If forced mock happened, cancels the engine job. * * Supposed to be created only if Mockito is not installed. */ -class ForceMockListener private constructor(triggers: ConflictTriggers, private val cancelJob: Boolean): MockListener(triggers) { +class ForceMockListener private constructor(triggers: ConflictTriggers): MockListener(triggers) { override fun onShouldMock(controller: EngineController, strategy: MockStrategy, mockInfo: UtMockInfo) { - // If force mocking happened -- сancel engine job - if (cancelJob) controller.job?.cancel(ForceMockCancellationException()) - triggers[Conflict.ForceMockHappened] = true } companion object { - fun create(testCaseGenerator: TestCaseGenerator, conflictTriggers: ConflictTriggers, cancelJob: Boolean = true) : ForceMockListener { - val listener = ForceMockListener(conflictTriggers, cancelJob) + fun create(testCaseGenerator: TestCaseGenerator, conflictTriggers: ConflictTriggers) : ForceMockListener { + val listener = ForceMockListener(conflictTriggers) testCaseGenerator.engineActions.add { engine -> engine.attachMockListener(listener) } return listener diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceStaticMockListener.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceStaticMockListener.kt index 1e0ec17016..4bd3330c46 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceStaticMockListener.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/util/mockListeners/ForceStaticMockListener.kt @@ -12,25 +12,17 @@ import org.utbot.framework.util.ConflictTriggers /** * Listener for mocker events in [org.utbot.engine.UtBotSymbolicEngine]. - * If forced static mock happened, cancels the engine job. * * Supposed to be created only if Mockito inline is not installed. */ -class ForceStaticMockListener private constructor(triggers: ConflictTriggers, private val cancelJob: Boolean): MockListener(triggers) { +class ForceStaticMockListener private constructor(triggers: ConflictTriggers): MockListener(triggers) { override fun onShouldMock(controller: EngineController, strategy: MockStrategy, mockInfo: UtMockInfo) { - if (mockInfo is UtNewInstanceMockInfo - || mockInfo is UtStaticMethodMockInfo - || mockInfo is UtStaticObjectMockInfo) { - // If force static mocking happened -- сancel engine job - if (cancelJob) controller.job?.cancel(ForceStaticMockCancellationException()) - triggers[Conflict.ForceStaticMockHappened] = true } - } companion object { - fun create(testCaseGenerator: TestCaseGenerator, conflictTriggers: ConflictTriggers, cancelJob: Boolean = true) : ForceStaticMockListener { - val listener = ForceStaticMockListener(conflictTriggers, cancelJob) + fun create(testCaseGenerator: TestCaseGenerator, conflictTriggers: ConflictTriggers) : ForceStaticMockListener { + val listener = ForceStaticMockListener(conflictTriggers) testCaseGenerator.engineActions.add { engine -> engine.attachMockListener(listener) } return listener 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 3977e178c7..1fadbc6698 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 @@ -61,7 +61,7 @@ open class TestCaseGenerator( val engineActions: MutableList<(UtBotSymbolicEngine) -> Unit> = mutableListOf(), val isCanceled: () -> Boolean = { false }, val forceSootReload: Boolean = true, - val applicationContext: ApplicationContext? = null, + val applicationContext: StandardApplicationContext = StandardApplicationContext(), ) { private val logger: KLogger = KotlinLogging.logger {} private val timeoutLogger: KLogger = KotlinLogging.logger(logger.name + ".timeout") @@ -118,7 +118,7 @@ open class TestCaseGenerator( method, mockStrategy, chosenClassesToMockAlways, - applicationContext = null, + applicationContext, executionTimeEstimator, ) engineActions.map { engine.apply(it) } @@ -149,8 +149,8 @@ open class TestCaseGenerator( val method2errors = methods.associateWith { mutableMapOf() } val conflictTriggers = ConflictTriggers() - val forceMockListener = ForceMockListener.create(this, conflictTriggers, cancelJob = false) - val forceStaticMockListener = ForceStaticMockListener.create(this, conflictTriggers, cancelJob = false) + val forceMockListener = ForceMockListener.create(this, conflictTriggers) + val forceStaticMockListener = ForceStaticMockListener.create(this, conflictTriggers) runIgnoringCancellationException { runBlockingWithCancellationPredicate(isCanceled) { @@ -257,7 +257,7 @@ open class TestCaseGenerator( method: ExecutableId, mockStrategyApi: MockStrategyApi, chosenClassesToMockAlways: Set, - applicationContext: ApplicationContext?, + applicationContext: StandardApplicationContext, executionTimeEstimator: ExecutionTimeEstimator ): UtBotSymbolicEngine { logger.debug("Starting symbolic execution for $method --$mockStrategyApi--") diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt index 3ef77f5a65..84f3cda3c4 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/process/EngineProcessMain.kt @@ -7,8 +7,6 @@ import kotlinx.coroutines.runBlocking import mu.KotlinLogging import org.utbot.analytics.AnalyticsConfigureUtil import org.utbot.common.* -import org.utbot.engine.util.mockListeners.ForceMockListener -import org.utbot.engine.util.mockListeners.ForceStaticMockListener import org.utbot.framework.codegen.* import org.utbot.framework.codegen.domain.HangingTestsTimeout import org.utbot.framework.codegen.domain.MockitoStaticMocking @@ -26,7 +24,6 @@ import org.utbot.framework.plugin.api.util.jClass import org.utbot.framework.plugin.api.util.method import org.utbot.framework.plugin.services.JdkInfo import org.utbot.framework.process.generated.* -import org.utbot.framework.util.ConflictTriggers import org.utbot.instrumentation.instrumentation.instrumenter.Instrumenter import org.utbot.instrumentation.util.KryoHelper import org.utbot.rd.IdleWatchdog @@ -83,7 +80,7 @@ private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatch watchdog.measureTimeForActiveCall(createTestGenerator, "Creating Test Generator") { params -> AnalyticsConfigureUtil.configureML() Instrumenter.adapter = RdInstrumenter(realProtocol.rdInstrumenterAdapter) - val applicationContext: ApplicationContext = kryoHelper.readObject(params.applicationContext) + val applicationContext: StandardApplicationContext = kryoHelper.readObject(params.applicationContext) testGenerator = TestCaseGenerator(buildDirs = params.buildDir.map { Paths.get(it) }, classpath = params.classpath, @@ -99,19 +96,9 @@ private fun EngineProcessModel.setup(kryoHelper: KryoHelper, watchdog: IdleWatch watchdog.measureTimeForActiveCall(generate, "Generating tests") { params -> val methods: List = kryoHelper.readObject(params.methods) logger.debug().measureTime({ "starting generation for ${methods.size} methods, starting with ${methods.first()}" }) { - val mockFrameworkInstalled = params.mockInstalled - val conflictTriggers = ConflictTriggers(kryoHelper.readObject(params.conflictTriggers)) - if (!mockFrameworkInstalled) { - ForceMockListener.create(testGenerator, conflictTriggers, cancelJob = true) - } - val staticsMockingConfigured = params.staticsMockingIsConfigureda - if (!staticsMockingConfigured) { - ForceStaticMockListener.create(testGenerator, conflictTriggers, cancelJob = true) - } - val generateFlow = when (testGenerator.applicationContext) { is SpringApplicationContext -> defaultSpringFlow(params.generationTimeout) - is EmptyApplicationContext -> testFlow { + is StandardApplicationContext -> testFlow { generationTimeout = params.generationTimeout isSymbolicEngineEnabled = params.isSymbolicEngineEnabled isFuzzingEnabled = params.isFuzzingEnabled diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt index 9a136e45bd..420bb476f8 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/process/generated/EngineProcessModel.Generated.kt @@ -72,7 +72,7 @@ class EngineProcessModel private constructor( } - const val serializationHash = -4839464828913070560L + const val serializationHash = -120710112541549600L } override val serializersOwner: ISerializersOwner get() = EngineProcessModel @@ -173,7 +173,7 @@ val IProtocol.engineProcessModel get() = getOrCreateExtension(EngineProcessModel /** - * #### Generated from [EngineProcessModel.kt:102] + * #### Generated from [EngineProcessModel.kt:98] */ data class FindMethodParamNamesArguments ( val classId: ByteArray, @@ -236,7 +236,7 @@ data class FindMethodParamNamesArguments ( /** - * #### Generated from [EngineProcessModel.kt:106] + * #### Generated from [EngineProcessModel.kt:102] */ data class FindMethodParamNamesResult ( val paramNames: ByteArray @@ -293,7 +293,7 @@ data class FindMethodParamNamesResult ( /** - * #### Generated from [EngineProcessModel.kt:95] + * #### Generated from [EngineProcessModel.kt:91] */ data class FindMethodsInClassMatchingSelectedArguments ( val classId: ByteArray, @@ -356,7 +356,7 @@ data class FindMethodsInClassMatchingSelectedArguments ( /** - * #### Generated from [EngineProcessModel.kt:99] + * #### Generated from [EngineProcessModel.kt:95] */ data class FindMethodsInClassMatchingSelectedResult ( val executableIds: ByteArray @@ -416,9 +416,6 @@ data class FindMethodsInClassMatchingSelectedResult ( * #### Generated from [EngineProcessModel.kt:44] */ data class GenerateParams ( - val mockInstalled: Boolean, - val staticsMockingIsConfigureda: Boolean, - val conflictTriggers: ByteArray, val methods: ByteArray, val mockStrategy: String, val chosenClassesToMockAlways: ByteArray, @@ -436,9 +433,6 @@ data class GenerateParams ( @Suppress("UNCHECKED_CAST") override fun read(ctx: SerializationCtx, buffer: AbstractBuffer): GenerateParams { - val mockInstalled = buffer.readBool() - val staticsMockingIsConfigureda = buffer.readBool() - val conflictTriggers = buffer.readByteArray() val methods = buffer.readByteArray() val mockStrategy = buffer.readString() val chosenClassesToMockAlways = buffer.readByteArray() @@ -448,13 +442,10 @@ data class GenerateParams ( val isFuzzingEnabled = buffer.readBool() val fuzzingValue = buffer.readDouble() val searchDirectory = buffer.readString() - return GenerateParams(mockInstalled, staticsMockingIsConfigureda, conflictTriggers, methods, mockStrategy, chosenClassesToMockAlways, timeout, generationTimeout, isSymbolicEngineEnabled, isFuzzingEnabled, fuzzingValue, searchDirectory) + return GenerateParams(methods, mockStrategy, chosenClassesToMockAlways, timeout, generationTimeout, isSymbolicEngineEnabled, isFuzzingEnabled, fuzzingValue, searchDirectory) } override fun write(ctx: SerializationCtx, buffer: AbstractBuffer, value: GenerateParams) { - buffer.writeBool(value.mockInstalled) - buffer.writeBool(value.staticsMockingIsConfigureda) - buffer.writeByteArray(value.conflictTriggers) buffer.writeByteArray(value.methods) buffer.writeString(value.mockStrategy) buffer.writeByteArray(value.chosenClassesToMockAlways) @@ -479,9 +470,6 @@ data class GenerateParams ( other as GenerateParams - if (mockInstalled != other.mockInstalled) return false - if (staticsMockingIsConfigureda != other.staticsMockingIsConfigureda) return false - if (!(conflictTriggers contentEquals other.conflictTriggers)) return false if (!(methods contentEquals other.methods)) return false if (mockStrategy != other.mockStrategy) return false if (!(chosenClassesToMockAlways contentEquals other.chosenClassesToMockAlways)) return false @@ -497,9 +485,6 @@ data class GenerateParams ( //hash code trait override fun hashCode(): Int { var __r = 0 - __r = __r*31 + mockInstalled.hashCode() - __r = __r*31 + staticsMockingIsConfigureda.hashCode() - __r = __r*31 + conflictTriggers.contentHashCode() __r = __r*31 + methods.contentHashCode() __r = __r*31 + mockStrategy.hashCode() __r = __r*31 + chosenClassesToMockAlways.contentHashCode() @@ -515,9 +500,6 @@ data class GenerateParams ( override fun print(printer: PrettyPrinter) { printer.println("GenerateParams (") printer.indent { - print("mockInstalled = "); mockInstalled.print(printer); println() - print("staticsMockingIsConfigureda = "); staticsMockingIsConfigureda.print(printer); println() - print("conflictTriggers = "); conflictTriggers.print(printer); println() print("methods = "); methods.print(printer); println() print("mockStrategy = "); mockStrategy.print(printer); println() print("chosenClassesToMockAlways = "); chosenClassesToMockAlways.print(printer); println() @@ -536,7 +518,7 @@ data class GenerateParams ( /** - * #### Generated from [EngineProcessModel.kt:62] + * #### Generated from [EngineProcessModel.kt:58] */ data class GenerateResult ( val notEmptyCases: Int, @@ -599,7 +581,7 @@ data class GenerateResult ( /** - * #### Generated from [EngineProcessModel.kt:114] + * #### Generated from [EngineProcessModel.kt:110] */ data class GenerateTestReportArgs ( val eventLogMessage: String?, @@ -692,7 +674,7 @@ data class GenerateTestReportArgs ( /** - * #### Generated from [EngineProcessModel.kt:123] + * #### Generated from [EngineProcessModel.kt:119] */ data class GenerateTestReportResult ( val notifyMessage: String, @@ -824,7 +806,7 @@ data class JdkInfo ( /** - * #### Generated from [EngineProcessModel.kt:90] + * #### Generated from [EngineProcessModel.kt:86] */ data class MethodDescription ( val name: String, @@ -893,7 +875,7 @@ data class MethodDescription ( /** - * #### Generated from [EngineProcessModel.kt:66] + * #### Generated from [EngineProcessModel.kt:62] */ data class RenderParams ( val testSetsId: Long, @@ -1034,7 +1016,7 @@ data class RenderParams ( /** - * #### Generated from [EngineProcessModel.kt:83] + * #### Generated from [EngineProcessModel.kt:79] */ data class RenderResult ( val generatedCode: String, @@ -1097,7 +1079,7 @@ data class RenderResult ( /** - * #### Generated from [EngineProcessModel.kt:87] + * #### Generated from [EngineProcessModel.kt:83] */ data class SetupContextParams ( val classpathForUrlsClassloader: List @@ -1235,7 +1217,7 @@ data class TestGeneratorParams ( /** - * #### Generated from [EngineProcessModel.kt:109] + * #### Generated from [EngineProcessModel.kt:105] */ data class WriteSarifReportArguments ( val testSetsId: Long, 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 001e206784..6bda5c9f2d 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 @@ -26,7 +26,7 @@ import org.utbot.framework.CancellationStrategyType.NONE import org.utbot.framework.CancellationStrategyType.SAVE_PROCESSED_RESULTS import org.utbot.framework.UtSettings import org.utbot.framework.plugin.api.ClassId -import org.utbot.framework.plugin.api.EmptyApplicationContext +import org.utbot.framework.plugin.api.StandardApplicationContext import org.utbot.framework.plugin.api.JavaDocCommentStyle import org.utbot.framework.plugin.api.util.LockFile import org.utbot.framework.plugin.api.util.withStaticsSubstitutionRequired @@ -170,7 +170,10 @@ object UtTestsDialogProcessor { }.toMap() } - val applicationContext = EmptyApplicationContext + val applicationContext = StandardApplicationContext( + model.mockFramework.isInstalled, + model.staticsMocking.isConfigured, + ) // TODO: obtain bean definitions and other info from `utbot-spring-analyzer` //SpringApplicationContext(beanQualifiedNames = emptyList()) @@ -249,8 +252,6 @@ object UtTestsDialogProcessor { .executeSynchronously() withStaticsSubstitutionRequired(true) { - val mockFrameworkInstalled = model.mockFramework?.isInstalled ?: true - val startTime = System.currentTimeMillis() val timerHandler = AppExecutorUtil.getAppScheduledExecutorService().scheduleWithFixedDelay({ @@ -266,8 +267,6 @@ object UtTestsDialogProcessor { }, 0, 500, TimeUnit.MILLISECONDS) try { val rdGenerateResult = process.generate( - mockFrameworkInstalled, - model.staticsMocking.isConfigured, model.conflictTriggers, methods, model.mockStrategy, diff --git a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt index b0eec3639b..13f735d3ea 100644 --- a/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt +++ b/utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/process/EngineProcess.kt @@ -10,10 +10,6 @@ import com.intellij.psi.impl.file.impl.JavaFileManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.refactoring.util.classMembers.MemberInfo import com.jetbrains.rd.util.ConcurrentHashMap -import com.jetbrains.rd.util.ILoggerFactory -import com.jetbrains.rd.util.Logger -import com.jetbrains.rd.util.Statics -import com.jetbrains.rd.util.lifetime.Lifetime import com.jetbrains.rd.util.lifetime.LifetimeDefinition import kotlinx.coroutines.runBlocking import mu.KotlinLogging @@ -42,7 +38,6 @@ import org.utbot.rd.generated.SettingForResult import org.utbot.rd.generated.SettingsModel import org.utbot.rd.generated.settingsModel import org.utbot.rd.generated.synchronizationModel -import org.utbot.rd.loggers.UtRdKLoggerFactory import org.utbot.rd.loggers.overrideDefaultRdLoggerFactoryWithKLogger import org.utbot.sarif.SourceFindingStrategy import java.io.File @@ -188,7 +183,7 @@ class EngineProcess private constructor(val project: Project, private val classN classPath: String?, dependencyPaths: String, jdkInfo: JdkInfo, - applicationContext: ApplicationContext, + applicationContext: StandardApplicationContext, isCancelled: (Unit) -> Boolean ) { assertReadAccessNotAllowed() @@ -252,8 +247,6 @@ class EngineProcess private constructor(val project: Project, private val classN } fun generate( - mockInstalled: Boolean, - staticsMockingIsConfigured: Boolean, conflictTriggers: ConflictTriggers, methods: List, mockStrategyApi: MockStrategyApi, @@ -267,9 +260,6 @@ class EngineProcess private constructor(val project: Project, private val classN ): RdTestGenerationResult { assertReadAccessNotAllowed() val params = GenerateParams( - mockInstalled, - staticsMockingIsConfigured, - kryoHelper.writeObject(conflictTriggers.toMutableMap()), kryoHelper.writeObject(methods), mockStrategyApi.name, kryoHelper.writeObject(chosenClassesToMockAlways), diff --git a/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt b/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt index 08484c8273..be656c25d1 100644 --- a/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt +++ b/utbot-rd/src/main/rdgen/org/utbot/rd/models/EngineProcessModel.kt @@ -42,10 +42,6 @@ object EngineProcessModel : Ext(EngineProcessRoot) { field("applicationContext", array(PredefinedType.byte)) } val generateParams = structdef { - // mocks - field("mockInstalled", PredefinedType.bool) - field("staticsMockingIsConfigureda", PredefinedType.bool) - field("conflictTriggers", array(PredefinedType.byte)) // generate field("methods", array(PredefinedType.byte)) field("mockStrategy", PredefinedType.string) diff --git a/utbot-testing/src/main/kotlin/org/utbot/testing/TestSpecificTestCaseGenerator.kt b/utbot-testing/src/main/kotlin/org/utbot/testing/TestSpecificTestCaseGenerator.kt index ea3c761f54..71d9e2d233 100644 --- a/utbot-testing/src/main/kotlin/org/utbot/testing/TestSpecificTestCaseGenerator.kt +++ b/utbot-testing/src/main/kotlin/org/utbot/testing/TestSpecificTestCaseGenerator.kt @@ -57,8 +57,8 @@ class TestSpecificTestCaseGenerator( val mockAlwaysDefaults = Mocker.javaDefaultClasses.mapTo(mutableSetOf()) { it.id } val defaultTimeEstimator = ExecutionTimeEstimator(UtSettings.utBotGenerationTimeoutInMillis, 1) - val forceMockListener = ForceMockListener.create(this, conflictTriggers, cancelJob = false) - val forceStaticMockListener = ForceStaticMockListener.create(this, conflictTriggers, cancelJob = false) + val forceMockListener = ForceMockListener.create(this, conflictTriggers) + val forceStaticMockListener = ForceStaticMockListener.create(this, conflictTriggers) runBlocking { val controller = EngineController()