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 9b719c8d6e..cc19322abc 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 @@ -135,31 +135,49 @@ data class Step( */ sealed class UtResult + /** * Execution. * * Contains: * - execution parameters, including thisInstance; * - result; - * - static fields changed during execution; - * - required instrumentation details (such as randoms, time, static methods). * - coverage information (instructions) if this execution was obtained from the concrete execution. - * - the engine type that created this execution. * - comments, method names and display names created by utbot-summary module. */ -data class UtExecution( +open class UtExecution( val stateBefore: EnvironmentModels, val stateAfter: EnvironmentModels, val result: UtExecutionResult, - val instrumentation: List, - val path: MutableList, - val fullPath: List, val coverage: Coverage? = null, - val createdBy: UtExecutionCreator? = null, var summary: List? = null, var testMethodName: String? = null, - var displayName: String? = null, -) : UtResult() { + var displayName: String? = null +) : UtResult() + +/** + * Symbolic execution. + * + * Contains: + * - execution parameters, including thisInstance; + * - result; + * - static fields changed during execution; + * - required instrumentation details (such as randoms, time, static methods). + * - coverage information (instructions) if this execution was obtained from the concrete execution. + * - comments, method names and display names created by utbot-summary module. + */ +class UtSymbolicExecution( + stateBefore: EnvironmentModels, + stateAfter: EnvironmentModels, + result: UtExecutionResult, + val instrumentation: List, + val path: MutableList, + val fullPath: List, + coverage: Coverage? = null, + summary: List? = null, + testMethodName: String? = null, + displayName: String? = null +) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName) { /** * By design the 'before' and 'after' states contain info about the same fields. * It means that it is not possible for a field to be present at 'before' and to be absent at 'after'. @@ -169,7 +187,7 @@ data class UtExecution( get() = stateBefore.statics.keys override fun toString(): String = buildString { - append("UtExecution(") + append("UtSymbolicExecution(") appendLine() append(":") @@ -190,6 +208,21 @@ data class UtExecution( appendOptional("instrumentation", instrumentation) append(")") } + + fun copy(stateAfter: EnvironmentModels, result: UtExecutionResult, coverage: Coverage): UtResult { + return UtSymbolicExecution( + stateBefore, + stateAfter, + result, + instrumentation, + path, + fullPath, + coverage, + summary, + testMethodName, + displayName + ) + } } open class EnvironmentModels( @@ -209,7 +242,7 @@ open class EnvironmentModels( } /** - * Represents missing state. Useful for [UtConcreteExecutionFailure] because it does not have [UtExecution.stateAfter] + * Represents missing state. Useful for [UtConcreteExecutionFailure] because it does not have [UtSymbolicExecution.stateAfter] */ object MissingState : EnvironmentModels( thisInstance = null, @@ -553,12 +586,12 @@ data class UtDirectSetFieldModel( val fieldModel: UtModel, ) : UtStatementModel(instance) { override fun toString(): String = withToStringThreadLocalReentrancyGuard { - val modelRepresentation = when (fieldModel) { - is UtAssembleModel -> fieldModel.modelName - else -> fieldModel.toString() - } - "${instance.modelName}.${fieldId.name} = $modelRepresentation" + val modelRepresentation = when (fieldModel) { + is UtAssembleModel -> fieldModel.modelName + else -> fieldModel.toString() } + "${instance.modelName}.${fieldId.name} = $modelRepresentation" + } } @@ -1034,7 +1067,7 @@ class BuiltinMethodId( open class TypeParameters(val parameters: List = emptyList()) -class WildcardTypeParameter: TypeParameters(emptyList()) +class WildcardTypeParameter : TypeParameters(emptyList()) interface CodeGenerationSettingItem { val displayName: String @@ -1164,6 +1197,7 @@ enum class CodegenLanguage( "-cp", classPath, "-XDignore.symbol.file" // to let javac use classes from rt.jar ).plus(sourcesFiles) + KOTLIN -> listOf("-d", buildDirectory, "-jvm-target", jvmTarget, "-cp", classPath).plus(sourcesFiles) } if (this == KOTLIN && System.getenv("KOTLIN_HOME") == null) { diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionState.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionState.kt index 25add73ecd..3a232a210a 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionState.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionState.kt @@ -18,7 +18,7 @@ import soot.SootMethod import soot.jimple.Stmt import java.util.Objects import org.utbot.engine.symbolic.Assumption -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution const val RETURN_DECISION_NUM = -1 const val CALL_DECISION_NUM = -2 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 7bbffe688c..d9ae72ecc2 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt @@ -68,31 +68,30 @@ import org.utbot.framework.plugin.api.UtAssembleModel import org.utbot.framework.plugin.api.UtConcreteExecutionFailure import org.utbot.framework.plugin.api.UtError import org.utbot.framework.plugin.api.UtExecution -import org.utbot.framework.plugin.api.UtExecutionCreator import org.utbot.framework.plugin.api.UtInstrumentation import org.utbot.framework.plugin.api.UtMethod import org.utbot.framework.plugin.api.UtNullModel import org.utbot.framework.plugin.api.UtOverflowFailure import org.utbot.framework.plugin.api.UtResult -import org.utbot.framework.util.graph +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.onSuccess +import org.utbot.framework.util.graph import org.utbot.framework.plugin.api.util.executableId import org.utbot.framework.plugin.api.util.id import org.utbot.framework.plugin.api.util.utContext import org.utbot.framework.plugin.api.util.description import org.utbot.framework.util.jimpleBody import org.utbot.framework.plugin.api.util.voidClassId -import org.utbot.fuzzer.ReferencePreservingIntIdGenerator import org.utbot.fuzzer.FallbackModelProvider import org.utbot.fuzzer.FuzzedMethodDescription import org.utbot.fuzzer.FuzzedValue import org.utbot.fuzzer.ModelProvider +import org.utbot.fuzzer.ReferencePreservingIntIdGenerator import org.utbot.fuzzer.Trie +import org.utbot.fuzzer.UtFuzzedExecution import org.utbot.fuzzer.collectConstantsForFuzzer import org.utbot.fuzzer.defaultModelProviders import org.utbot.fuzzer.fuzz -import org.utbot.fuzzer.names.MethodBasedNameSuggester -import org.utbot.fuzzer.names.ModelBasedNameSuggester import org.utbot.fuzzer.providers.ObjectModelProvider import org.utbot.instrumentation.ConcreteExecutor import soot.jimple.Stmt @@ -298,15 +297,14 @@ class UtBotSymbolicEngine( val concreteExecutionResult = concreteExecutor.executeConcretely(methodUnderTest, stateBefore, instrumentation) - val concreteUtExecution = UtExecution( + val concreteUtExecution = UtSymbolicExecution( stateBefore, concreteExecutionResult.stateAfter, concreteExecutionResult.result, instrumentation, mutableListOf(), listOf(), - concreteExecutionResult.coverage, - UtExecutionCreator.SYMBOLIC_ENGINE + concreteExecutionResult.coverage ) emit(concreteUtExecution) @@ -486,32 +484,15 @@ class UtBotSymbolicEngine( } else { logger.error { "Coverage is empty for $methodUnderTest with ${values.map { it.model }}" } } - val nameSuggester = sequenceOf(ModelBasedNameSuggester(), MethodBasedNameSuggester()) - val testMethodName = try { - nameSuggester.flatMap { - it.suggest( - methodUnderTestDescription, - values, - concreteExecutionResult.result - ) - }.firstOrNull() - } catch (t: Throwable) { - logger.error(t) { "Cannot create suggested test name for ${methodUnderTest.displayName}" } - null - } emit( - UtExecution( + UtFuzzedExecution( stateBefore = initialEnvironmentModels, stateAfter = concreteExecutionResult.stateAfter, result = concreteExecutionResult.result, - instrumentation = emptyList(), - path = mutableListOf(), - fullPath = emptyList(), coverage = concreteExecutionResult.coverage, - createdBy = UtExecutionCreator.FUZZER, - testMethodName = testMethodName?.testName, - displayName = testMethodName?.takeIf { hasMethodUnderTestParametersToFuzz }?.displayName + fuzzingValues = values, + fuzzedMethodDescription = methodUnderTestDescription ) ) } @@ -524,11 +505,7 @@ class UtBotSymbolicEngine( val failedConcreteExecution = UtExecution( stateBefore = stateBefore, stateAfter = MissingState, - result = UtConcreteExecutionFailure(e), - instrumentation = emptyList(), - path = mutableListOf(), - fullPath = listOf(), - createdBy = UtExecutionCreator.SYMBOLIC_ENGINE, + result = UtConcreteExecutionFailure(e) ) emit(failedConcreteExecution) @@ -562,14 +539,13 @@ class UtBotSymbolicEngine( val stateAfter = modelsAfter.constructStateForMethod(methodUnderTest) require(stateBefore.parameters.size == stateAfter.parameters.size) - val symbolicUtExecution = UtExecution( + val symbolicUtExecution = UtSymbolicExecution( stateBefore = stateBefore, stateAfter = stateAfter, result = symbolicExecutionResult, instrumentation = instrumentation, path = entryMethodPath(state), - fullPath = state.fullPath(), - createdBy = UtExecutionCreator.SYMBOLIC_ENGINE, + fullPath = state.fullPath() ) globalGraph.traversed(state) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt index 74750c6005..a3301c1828 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt @@ -30,6 +30,7 @@ import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.UtNullModel import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtReferenceModel +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtValueExecution import org.utbot.framework.plugin.api.UtValueExecutionState import org.utbot.framework.plugin.api.UtVoidModel @@ -123,17 +124,31 @@ class ValueConstructor { val (stateAfter, _) = constructState(execution.stateAfter) val returnValue = execution.result.map { construct(listOf(it)).single().value } - return UtValueExecution( - stateBefore, - stateAfter, - returnValue, - execution.path, - mocks, - execution.instrumentation, - execution.summary, - execution.testMethodName, - execution.displayName - ) + if (execution is UtSymbolicExecution) { + return UtValueExecution( + stateBefore, + stateAfter, + returnValue, + execution.path, + mocks, + execution.instrumentation, + execution.summary, + execution.testMethodName, + execution.displayName + ) + } else { + return UtValueExecution( + stateBefore, + stateAfter, + returnValue, + emptyList(), + mocks, + emptyList(), + execution.summary, + execution.testMethodName, + execution.displayName + ) + } } private fun constructParamsAndMocks( diff --git a/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt b/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt index d526c587cb..634ec44bab 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/external/api/UtBotJavaApi.kt @@ -17,8 +17,7 @@ import org.utbot.framework.plugin.api.CodegenLanguage import org.utbot.framework.plugin.api.MockFramework import org.utbot.framework.plugin.api.MockStrategyApi import org.utbot.framework.plugin.api.TestCaseGenerator -import org.utbot.framework.plugin.api.UtExecution -import org.utbot.framework.plugin.api.UtExecutionCreator +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtMethod import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtMethodTestSet @@ -240,7 +239,7 @@ object UtBotJavaApi { testInfo.utResult } - val utExecution = UtExecution( + val utExecution = UtSymbolicExecution( stateBefore = testInfo.initialState, stateAfter = testInfo.initialState, // it seems ok for concrete execution result = utExecutionResult, diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/context/CgContext.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/context/CgContext.kt index fdd2c3637e..dd9cc7c0cb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/context/CgContext.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/context/CgContext.kt @@ -34,16 +34,6 @@ import org.utbot.framework.codegen.model.tree.CgThisInstance import org.utbot.framework.codegen.model.tree.CgValue import org.utbot.framework.codegen.model.tree.CgVariable import org.utbot.framework.codegen.model.util.createTestClassName -import org.utbot.framework.plugin.api.BuiltinClassId -import org.utbot.framework.plugin.api.ClassId -import org.utbot.framework.plugin.api.CodegenLanguage -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.MockFramework -import org.utbot.framework.plugin.api.UtExecution -import org.utbot.framework.plugin.api.UtModel -import org.utbot.framework.plugin.api.UtReferenceModel import java.util.IdentityHashMap import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentMap @@ -54,6 +44,16 @@ import kotlinx.collections.immutable.persistentSetOf import org.utbot.framework.codegen.model.constructor.CgMethodTestSet import org.utbot.framework.codegen.model.constructor.builtin.streamsDeepEqualsMethodId import org.utbot.framework.codegen.model.tree.CgParameterKind +import org.utbot.framework.plugin.api.BuiltinClassId +import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.CodegenLanguage +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.MockFramework +import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtModel +import org.utbot.framework.plugin.api.UtReferenceModel import org.utbot.framework.plugin.api.util.id import org.utbot.framework.plugin.api.util.isCheckedException import org.utbot.framework.plugin.api.util.isSubtypeOf diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgFieldStateManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgFieldStateManager.kt index 64a50e17a8..ea2a141db4 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgFieldStateManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgFieldStateManager.kt @@ -26,12 +26,14 @@ import org.utbot.framework.fields.FieldPath import org.utbot.framework.fields.ModifiedFields import org.utbot.framework.fields.StateModificationInfo import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.util.hasField import org.utbot.framework.plugin.api.util.id import org.utbot.framework.plugin.api.util.isArray import org.utbot.framework.plugin.api.util.isRefType import org.utbot.framework.plugin.api.util.objectClassId import org.utbot.framework.util.hasThisInstance +import org.utbot.fuzzer.UtFuzzedExecution import java.lang.reflect.Array internal interface CgFieldStateManager { @@ -67,13 +69,23 @@ internal class CgFieldStateManagerImpl(val context: CgContext) } private fun rememberThisInstanceState(info: StateModificationInfo, state: FieldState) { - if (!currentExecution!!.hasThisInstance()) { - return + when (currentExecution) { + is UtSymbolicExecution -> { + if (!(currentExecution!! as UtSymbolicExecution).hasThisInstance()) { + return + } + val thisInstance = context.thisInstance!! + val modifiedFields = info.thisInstance + // by now this instance variable must have already been created + saveFieldsState(thisInstance, modifiedFields, statesCache.thisInstance, state) + } + is UtFuzzedExecution -> { + return + } + else -> { + return + } } - val thisInstance = context.thisInstance!! - val modifiedFields = info.thisInstance - // by now this instance variable must have already been created - saveFieldsState(thisInstance, modifiedFields, statesCache.thisInstance, state) } private fun rememberArgumentsState(info: StateModificationInfo, state: FieldState) { diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgMethodConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgMethodConstructor.kt index b6f8bb3148..a54b59004b 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgMethodConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgMethodConstructor.kt @@ -111,6 +111,7 @@ import org.utbot.framework.plugin.api.UtNullModel import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtReferenceModel import org.utbot.framework.plugin.api.UtStaticMethodInstrumentation +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtTimeoutException import org.utbot.framework.plugin.api.UtVoidModel import org.utbot.framework.plugin.api.onFailure @@ -171,26 +172,29 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c private lateinit var methodType: CgTestMethodType private fun setupInstrumentation() { - val instrumentation = currentExecution!!.instrumentation - if (instrumentation.isEmpty()) return - - if (generateWarningsForStaticMocking && forceStaticMocking == ForceStaticMocking.DO_NOT_FORCE) { - // warn user about possible flaky tests - multilineComment(forceStaticMocking.warningMessage) - return - } + if (currentExecution is UtSymbolicExecution) { + val execution = currentExecution as UtSymbolicExecution + val instrumentation = execution.instrumentation + if (instrumentation.isEmpty()) return + + if (generateWarningsForStaticMocking && forceStaticMocking == ForceStaticMocking.DO_NOT_FORCE) { + // warn user about possible flaky tests + multilineComment(forceStaticMocking.warningMessage) + return + } - instrumentation - .filterIsInstance() - .forEach { mockFrameworkManager.mockNewInstance(it) } - instrumentation - .filterIsInstance() - .groupBy { it.methodId.classId } - .forEach { (classId, methodMocks) -> mockFrameworkManager.mockStaticMethodsOfClass(classId, methodMocks) } - - if (generateWarningsForStaticMocking && forceStaticMocking == ForceStaticMocking.FORCE) { - // warn user about forced using static mocks - multilineComment(forceStaticMocking.warningMessage) + instrumentation + .filterIsInstance() + .forEach { mockFrameworkManager.mockNewInstance(it) } + instrumentation + .filterIsInstance() + .groupBy { it.methodId.classId } + .forEach { (classId, methodMocks) -> mockFrameworkManager.mockStaticMethodsOfClass(classId, methodMocks) } + + if (generateWarningsForStaticMocking && forceStaticMocking == ForceStaticMocking.FORCE) { + // warn user about forced using static mocks + multilineComment(forceStaticMocking.warningMessage) + } } } 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 eca33c5b77..97ab11c995 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 @@ -27,6 +27,7 @@ import org.utbot.framework.codegen.model.visitor.importUtilMethodDependencies import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.UtMethodTestSet +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.util.description import org.utbot.framework.plugin.api.util.kClass import kotlin.reflect.KClass diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/util/ConstructorUtils.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/util/ConstructorUtils.kt index 021e0bccca..d2102adf0c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/util/ConstructorUtils.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/util/ConstructorUtils.kt @@ -14,18 +14,6 @@ import org.utbot.framework.codegen.model.util.isAccessibleFrom import org.utbot.framework.fields.ArrayElementAccess import org.utbot.framework.fields.FieldAccess import org.utbot.framework.fields.FieldPath -import org.utbot.framework.plugin.api.BuiltinClassId -import org.utbot.framework.plugin.api.BuiltinMethodId -import org.utbot.framework.plugin.api.ClassId -import org.utbot.framework.plugin.api.ConstructorId -import org.utbot.framework.plugin.api.ExecutableId -import org.utbot.framework.plugin.api.MethodId -import org.utbot.framework.plugin.api.UtArrayModel -import org.utbot.framework.plugin.api.UtExecution -import org.utbot.framework.plugin.api.UtModel -import org.utbot.framework.plugin.api.UtNullModel -import org.utbot.framework.plugin.api.UtPrimitiveModel -import org.utbot.framework.plugin.api.WildcardTypeParameter import org.utbot.framework.plugin.api.util.booleanClassId import org.utbot.framework.plugin.api.util.byteClassId import org.utbot.framework.plugin.api.util.charClassId @@ -44,6 +32,18 @@ import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentSet import org.utbot.framework.codegen.model.tree.CgAllocateInitializedArray import org.utbot.framework.codegen.model.tree.CgArrayInitializer +import org.utbot.framework.plugin.api.BuiltinClassId +import org.utbot.framework.plugin.api.BuiltinMethodId +import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.ConstructorId +import org.utbot.framework.plugin.api.ExecutableId +import org.utbot.framework.plugin.api.MethodId +import org.utbot.framework.plugin.api.UtArrayModel +import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtModel +import org.utbot.framework.plugin.api.UtNullModel +import org.utbot.framework.plugin.api.UtPrimitiveModel +import org.utbot.framework.plugin.api.WildcardTypeParameter import org.utbot.framework.plugin.api.util.arrayLikeName internal data class EnvironmentFieldStateCache( diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/fields/ExecutionStateAnalyzer.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/fields/ExecutionStateAnalyzer.kt index d5ea151257..cf2b3c1c32 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/fields/ExecutionStateAnalyzer.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/fields/ExecutionStateAnalyzer.kt @@ -16,9 +16,11 @@ import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.UtNullModel import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtReferenceModel +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtVoidModel import org.utbot.framework.util.UtModelVisitor import org.utbot.framework.util.hasThisInstance +import org.utbot.fuzzer.UtFuzzedExecution class ExecutionStateAnalyzer(val execution: UtExecution) { fun findModifiedFields(): StateModificationInfo { @@ -29,14 +31,24 @@ class ExecutionStateAnalyzer(val execution: UtExecution) { } private fun StateModificationInfo.analyzeThisInstance(): StateModificationInfo { - if (!execution.hasThisInstance()) { - return this + when (execution) { + is UtSymbolicExecution -> { + if (!execution.hasThisInstance()) { + return this + } + val thisInstanceBefore = execution.stateBefore.thisInstance!! + val thisInstanceAfter = execution.stateAfter.thisInstance!! + val info = analyzeModelStates(thisInstanceBefore, thisInstanceAfter) + val modifiedFields = getModifiedFields(info) + return this.copy(thisInstance = modifiedFields) + } + is UtFuzzedExecution -> { + return this + } + else -> { + return this + } } - val thisInstanceBefore = execution.stateBefore.thisInstance!! - val thisInstanceAfter = execution.stateAfter.thisInstance!! - val info = analyzeModelStates(thisInstanceBefore, thisInstanceAfter) - val modifiedFields = getModifiedFields(info) - return this.copy(thisInstance = modifiedFields) } private fun StateModificationInfo.analyzeParameters(): StateModificationInfo { @@ -52,25 +64,35 @@ class ExecutionStateAnalyzer(val execution: UtExecution) { } private fun StateModificationInfo.analyzeStatics(): StateModificationInfo { - if (execution.stateAfter == MissingState) return this - - val staticsBefore = execution.stateBefore.statics - val staticsAfter = execution.stateAfter.statics - - val staticFieldsByClass = execution.staticFields.groupBy { it.declaringClass } - val modificationsByClass = mutableMapOf() - for ((classId, fields) in staticFieldsByClass) { - val staticFieldModifications = mutableListOf() - for (field in fields) { - val before = staticsBefore[field]!! - val after = staticsAfter[field]!! - val path = FieldPath() + FieldAccess(field) - val info = analyzeModelStates(before, after, path) - staticFieldModifications += getModifiedFields(info) + when (execution) { + is UtSymbolicExecution -> { + if (execution.stateAfter == MissingState) return this + + val staticsBefore = execution.stateBefore.statics + val staticsAfter = execution.stateAfter.statics + + val staticFieldsByClass = execution.staticFields.groupBy { it.declaringClass } + val modificationsByClass = mutableMapOf() + for ((classId, fields) in staticFieldsByClass) { + val staticFieldModifications = mutableListOf() + for (field in fields) { + val before = staticsBefore[field]!! + val after = staticsAfter[field]!! + val path = FieldPath() + FieldAccess(field) + val info = analyzeModelStates(before, after, path) + staticFieldModifications += getModifiedFields(info) + } + modificationsByClass[classId] = staticFieldModifications + } + return this.copy(staticFields = modificationsByClass) + } + is UtFuzzedExecution -> { + return this + } + else -> { + return this } - modificationsByClass[classId] = staticFieldModifications } - return this.copy(staticFields = modificationsByClass) } private fun analyzeModelStates( @@ -90,11 +112,11 @@ class ExecutionStateAnalyzer(val execution: UtExecution) { // therefore, AssembleModelGenerator won't be able to transform the given composite model val reason = if (before is UtAssembleModel && after is UtCompositeModel) { - "ModelBefore is an AssembleModel and ModelAfter " + - "is a CompositeModel, but modelBefore doesn't have an origin model." + "ModelBefore is an AssembleModel and ModelAfter " + + "is a CompositeModel, but modelBefore doesn't have an origin model." } else { - "The model before and the model after have different types: " + - "model before is ${before::class}, but model after is ${after::class}." + "The model before and the model after have different types: " + + "model before is ${before::class}, but model after is ${after::class}." } error("Cannot analyze fields modification. $reason") diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt index b1b0eead6c..78850acc31 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt @@ -19,6 +19,7 @@ import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtStatementModel import org.utbot.framework.plugin.api.UtVoidModel + /** * Minimizes [executions] in each test suite independently. Test suite is computed with [executionToTestSuite] function. * diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/util/EngineUtils.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/util/EngineUtils.kt index 8d04ac748f..cd86c08cfe 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/util/EngineUtils.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/util/EngineUtils.kt @@ -4,7 +4,7 @@ import org.utbot.common.Reflection import org.utbot.engine.ValueConstructor import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.MissingState -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.UtMethodTestSet import org.utbot.framework.plugin.api.UtMethodValueTestSet @@ -74,14 +74,14 @@ val instanceCounter = AtomicInteger(0) fun nextModelName(base: String): String = "$base${instanceCounter.incrementAndGet()}" fun UtMethodTestSet.toValueTestCase(): UtMethodValueTestSet<*> { - val valueExecutions = executions.map { ValueConstructor().construct(it) } + val valueExecutions = executions.map { ValueConstructor().construct(it) } // TODO: make something about UTExecution return UtMethodValueTestSet(method, valueExecutions, errors) } fun UtModel.isUnit(): Boolean = this is UtVoidModel -fun UtExecution.hasThisInstance(): Boolean = when { +fun UtSymbolicExecution.hasThisInstance(): Boolean = when { stateBefore.thisInstance == null && stateAfter.thisInstance == null -> false stateBefore.thisInstance != null && stateAfter.thisInstance != null -> true stateAfter == MissingState -> false diff --git a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt index 4c8d23254a..4442243664 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt @@ -11,9 +11,10 @@ import org.utbot.framework.plugin.api.UtExecutionFailure import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.framework.plugin.api.UtImplicitlyThrownException import org.utbot.framework.plugin.api.UtMethod +import org.utbot.framework.plugin.api.UtMethodTestSet import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.UtOverflowFailure -import org.utbot.framework.plugin.api.UtMethodTestSet +import org.utbot.framework.plugin.api.UtSymbolicExecution /** * Used for the SARIF report creation by given test cases and generated tests code. @@ -336,15 +337,21 @@ class SarifReport( * Returns the number of the last line in the execution path. */ private fun getLastLineNumber(utExecution: UtExecution): Int? { - val lastPathLine = try { - utExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber - } catch (t: Throwable) { - null - } // if for some reason we can't extract the last line from the path val lastCoveredInstruction = utExecution.coverage?.coveredInstructions?.lastOrNull()?.lineNumber - return lastPathLine ?: lastCoveredInstruction + + return if (utExecution is UtSymbolicExecution) { + val lastPathLine = try { + utExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber + } catch (t: Throwable) { + null + } + + lastPathLine ?: lastCoveredInstruction + } else { + lastCoveredInstruction + } } private fun shouldProcessExecutionResult(result: UtExecutionResult): Boolean { diff --git a/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt b/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt index 2c45672ae9..0df89e0be1 100644 --- a/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt +++ b/utbot-framework/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt @@ -2,13 +2,14 @@ package org.utbot.sarif import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue +import org.junit.Test +import org.mockito.Mockito import org.utbot.framework.plugin.api.UtExecution import org.utbot.framework.plugin.api.UtImplicitlyThrownException import org.utbot.framework.plugin.api.UtMethod import org.utbot.framework.plugin.api.UtPrimitiveModel import org.utbot.framework.plugin.api.UtMethodTestSet -import org.junit.Test -import org.mockito.Mockito +import org.utbot.framework.plugin.api.UtSymbolicExecution class SarifReportTest { @@ -236,8 +237,8 @@ class SarifReportTest { fun testMinimizationDoesNotRemoveResultsWithDifferentLocations() { mockUtMethodNames() - val mockUtExecution1 = Mockito.mock(UtExecution::class.java, Mockito.RETURNS_DEEP_STUBS) - val mockUtExecution2 = Mockito.mock(UtExecution::class.java, Mockito.RETURNS_DEEP_STUBS) + val mockUtExecution1 = Mockito.mock(UtSymbolicExecution::class.java, Mockito.RETURNS_DEEP_STUBS) + val mockUtExecution2 = Mockito.mock(UtSymbolicExecution::class.java, Mockito.RETURNS_DEEP_STUBS) // the same ruleId's Mockito.`when`(mockUtExecution1.result).thenReturn(UtImplicitlyThrownException(NullPointerException(), false)) @@ -300,7 +301,7 @@ class SarifReportTest { private val mockUtMethod = Mockito.mock(UtMethod::class.java, Mockito.RETURNS_DEEP_STUBS) - private val mockUtExecution = Mockito.mock(UtExecution::class.java, Mockito.RETURNS_DEEP_STUBS) + private val mockUtExecution = Mockito.mock(UtSymbolicExecution::class.java, Mockito.RETURNS_DEEP_STUBS) private val testSet = UtMethodTestSet(mockUtMethod, listOf(mockUtExecution)) diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/UtFuzzedExecution.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/UtFuzzedExecution.kt new file mode 100644 index 0000000000..211ec0fcfb --- /dev/null +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/UtFuzzedExecution.kt @@ -0,0 +1,58 @@ +package org.utbot.fuzzer + +import org.utbot.framework.plugin.api.Coverage +import org.utbot.framework.plugin.api.DocStatement +import org.utbot.framework.plugin.api.EnvironmentModels +import org.utbot.framework.plugin.api.FieldId +import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtExecutionResult + +/** + * Fuzzed execution. + * + * Contains: + * - execution parameters, including thisInstance; + * - result; + * - static fields changed during execution; + * - coverage information (instructions) if this execution was obtained from the concrete execution. + * - comments, method names and display names created by utbot-summary module. + */ +class UtFuzzedExecution( + stateBefore: EnvironmentModels, + stateAfter: EnvironmentModels, + result: UtExecutionResult, + coverage: Coverage? = null, + summary: List? = null, + testMethodName: String? = null, + displayName: String? = null, + val fuzzingValues: List? = null, + val fuzzedMethodDescription: FuzzedMethodDescription? = null +) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName) { + /** + * By design the 'before' and 'after' states contain info about the same fields. + * It means that it is not possible for a field to be present at 'before' and to be absent at 'after'. + * The reverse is also impossible. + */ + val staticFields: Set + get() = stateBefore.statics.keys // TODO: should we keep it for the Fuzzed Execution? + + override fun toString(): String = buildString { + append("UtFuzzedExecution(") + appendLine() + + append(":") + appendLine() + append(stateBefore) + appendLine() + + append(":") + appendLine() + append(stateAfter) + appendLine() + + append(":") + appendLine() + append(result) + append(")") + } +} \ No newline at end of file diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt index 27d6cf7f9a..05caad94ae 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt @@ -27,16 +27,8 @@ import org.utbot.framework.codegen.ForceStaticMocking import org.utbot.framework.codegen.StaticsMocking import org.utbot.framework.codegen.junitByVersion import org.utbot.framework.codegen.model.CodeGenerator -import org.utbot.framework.plugin.api.CodegenLanguage -import org.utbot.framework.plugin.api.MockStrategyApi -import org.utbot.framework.plugin.api.TestCaseGenerator -import org.utbot.framework.plugin.api.UtError -import org.utbot.framework.plugin.api.UtExecution -import org.utbot.framework.plugin.api.UtMethod -import org.utbot.framework.plugin.api.UtMethodTestSet import org.utbot.framework.plugin.api.util.UtContext import org.utbot.framework.plugin.api.util.id -import org.utbot.framework.plugin.api.util.jClass import org.utbot.framework.plugin.api.util.utContext import org.utbot.framework.plugin.api.util.withUtContext import org.utbot.instrumentation.ConcreteExecutor @@ -62,6 +54,13 @@ import kotlin.reflect.jvm.javaConstructor import kotlin.reflect.jvm.javaGetter import kotlin.reflect.jvm.javaMethod import org.utbot.common.filterWhen +import org.utbot.framework.plugin.api.CodegenLanguage +import org.utbot.framework.plugin.api.MockStrategyApi +import org.utbot.framework.plugin.api.TestCaseGenerator +import org.utbot.framework.plugin.api.UtError +import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtMethod +import org.utbot.framework.plugin.api.UtMethodTestSet import org.utbot.framework.util.isKnownSyntheticMethod internal const val junitVersion = 4 diff --git a/utbot-summary/build.gradle b/utbot-summary/build.gradle index 66eaae3682..b0c3c7dfdf 100644 --- a/utbot-summary/build.gradle +++ b/utbot-summary/build.gradle @@ -3,6 +3,7 @@ apply from: "${parent.projectDir}/gradle/include/jvm-project.gradle" dependencies { implementation "com.github.UnitTestBot:soot:${soot_commit_hash}" api project(':utbot-framework-api') + api project(':utbot-fuzzers') compile(project(':utbot-instrumentation')) implementation group: 'io.github.microutils', name: 'kotlin-logging', version: kotlin_logging_version diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt index 87366d516f..b247d9c978 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/Summarization.kt @@ -3,9 +3,8 @@ package org.utbot.summary import com.github.javaparser.ast.body.MethodDeclaration import org.utbot.framework.UtSettings import org.utbot.framework.plugin.api.UtClusterInfo -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtExecutionCluster -import org.utbot.framework.plugin.api.UtExecutionCreator import org.utbot.framework.plugin.api.UtMethodTestSet import org.utbot.instrumentation.instrumentation.instrumenter.Instrumenter import org.utbot.summary.SummarySentenceConstants.NEW_LINE @@ -24,6 +23,11 @@ import java.io.File import java.nio.file.Path import java.nio.file.Paths import mu.KotlinLogging +import org.utbot.fuzzer.FuzzedMethodDescription +import org.utbot.fuzzer.FuzzedValue +import org.utbot.fuzzer.UtFuzzedExecution +import org.utbot.summary.fuzzer.names.MethodBasedNameSuggester +import org.utbot.summary.fuzzer.names.ModelBasedNameSuggester import soot.SootMethod private val logger = KotlinLogging.logger {} @@ -73,18 +77,25 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List() + val updatedExecutions = mutableListOf() val clustersToReturn = mutableListOf() // handles tests produced by fuzzing - val executionsProducedByFuzzer = testSet.executions.filter { it.createdBy == UtExecutionCreator.FUZZER } + val executionsProducedByFuzzer = testSet.executions.filterIsInstance() if (executionsProducedByFuzzer.isNotEmpty()) { - executionsProducedByFuzzer.forEach { - logger.info { - "Test is created by Fuzzing. The path for test ${it.testMethodName} " + - "for method ${testSet.method.clazz.qualifiedName} is empty and summaries could not be generated." + executionsProducedByFuzzer.forEach { utExecution -> + + val nameSuggester = sequenceOf(ModelBasedNameSuggester(), MethodBasedNameSuggester()) + val testMethodName = try { + nameSuggester.flatMap { it.suggest(utExecution.fuzzedMethodDescription as FuzzedMethodDescription, utExecution.fuzzingValues as List, utExecution.result) }.firstOrNull() + } catch (t: Throwable) { + logger.error(t) { "Cannot create suggested test name for $utExecution" } // TODO: add better explanation or default behavoiur + null } + + utExecution.testMethodName = testMethodName?.testName + utExecution.displayName = testMethodName?.displayName } clustersToReturn.add( @@ -189,7 +200,7 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List().filter { it.path.isNotEmpty() } return UtMethodTestSet( method = testSet.method, @@ -201,7 +212,7 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List().filter { it.path.isEmpty() } /* * asts of invokes also included @@ -233,14 +244,16 @@ class Summarization(val sourceFile: File?, val invokeDescriptions: List() + + val maxDepth = symbolicExecutions.flatMap { it.path }.maxOfOrNull { it.depth } ?: 0 if (maxDepth > 0) { logger.info { "Recursive function, max recursion: $maxDepth" } return } - var diversity = percentageDiverseExecutions(testSet.executions) + var diversity = percentageDiverseExecutions(symbolicExecutions) if (diversity >= 50) { logger.info { "Diversity execution path percentage: $diversity" } return @@ -248,8 +261,8 @@ private fun makeDiverseExecutions(testSet: UtMethodTestSet) { for (depth in 1..2) { logger.info { "Depth to add: $depth" } - stepsUpToDepth(testSet.executions, depth) - diversity = percentageDiverseExecutions(testSet.executions) + stepsUpToDepth(symbolicExecutions, depth) + diversity = percentageDiverseExecutions(symbolicExecutions) if (diversity >= 50) { logger.info { "Diversity execution path percentage: $diversity" } @@ -258,8 +271,8 @@ private fun makeDiverseExecutions(testSet: UtMethodTestSet) { } } -private fun invokeDescriptions(testSet: UtMethodTestSet, seachDirectory: Path): List { - val sootInvokes = testSet.executions.flatMap { it.path.invokeJimpleMethods() }.toSet() +private fun invokeDescriptions(testSet: UtMethodTestSet, searchDirectory: Path): List { + val sootInvokes = testSet.executions.filterIsInstance().flatMap { it.path.invokeJimpleMethods() }.toSet() return sootInvokes //TODO(SAT-1170) .filterNot { "\$lambda" in it.declaringClass.name } @@ -267,7 +280,7 @@ private fun invokeDescriptions(testSet: UtMethodTestSet, seachDirectory: Path): val methodFile = Instrumenter.computeSourceFileByClass( sootMethod.declaringClass.name, sootMethod.declaringClass.javaPackageName.replace(".", File.separator), - seachDirectory + searchDirectory ) val ast = methodFile?.let { SourceCodeParser(sootMethod, it).methodAST diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/TagGenerator.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/TagGenerator.kt index b757c70ecf..b4bbcace54 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/TagGenerator.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/TagGenerator.kt @@ -2,7 +2,7 @@ package org.utbot.summary import org.utbot.framework.plugin.api.Step import org.utbot.framework.plugin.api.UtConcreteExecutionFailure -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.framework.plugin.api.UtExecutionSuccess import org.utbot.framework.plugin.api.UtExplicitlyThrownException @@ -80,7 +80,7 @@ class TagGenerator { /** * @return list of TraceTag created from executions and splitsSteps */ -private fun generateExecutionTags(executions: List, splitSteps: SplitSteps): List = +private fun generateExecutionTags(executions: List, splitSteps: SplitSteps): List = executions.map { TraceTag(it, splitSteps) } /** @@ -95,7 +95,7 @@ private fun generateExecutionTags(executions: List, splitSteps: Spl * @return clustered executions */ private fun toClusterExecutions(testSet: UtMethodTestSet): List { - val methodExecutions = testSet.executions + val methodExecutions = testSet.executions.filterIsInstance() val clusters = mutableListOf() val commentPostfix = "for method ${testSet.method.displayName}" @@ -157,18 +157,18 @@ private fun UtExecutionResult.clusterKind() = when (this) { /** * Structure used to represent execution cluster with header */ -private sealed class ExecutionCluster(var header: String, val executions: List) +private sealed class ExecutionCluster(var header: String, val executions: List) /** * Represents successful execution cluster */ -private class SuccessfulExecutionCluster(header: String, executions: List) : +private class SuccessfulExecutionCluster(header: String, executions: List) : ExecutionCluster(header, executions) /** * Represents failed execution cluster */ -private class FailedExecutionCluster(header: String, executions: List) : +private class FailedExecutionCluster(header: String, executions: List) : ExecutionCluster(header, executions) /** diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/Util.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/Util.kt index ef5720412d..c7c3b7e334 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/Util.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/Util.kt @@ -1,7 +1,7 @@ package org.utbot.summary import org.utbot.framework.plugin.api.Step -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtMethod import org.utbot.summary.tag.BasicTypeTag import org.utbot.summary.tag.getBasicTypeTag @@ -36,7 +36,7 @@ fun List.invokeJimpleMethods(): List = it.invokeExpr.method } -fun stepsUpToDepth(executions: List, depth: Int) { +fun stepsUpToDepth(executions: List, depth: Int) { for (execution in executions) { execution.path.clear() execution.path.addAll(execution.fullPath.filter { it.depth <= depth }) @@ -46,13 +46,13 @@ fun stepsUpToDepth(executions: List, depth: Int) { /* * from 0 to 100 * */ -fun percentageDiverseExecutions(executions: List): Int { +fun percentageDiverseExecutions(executions: List): Int { if (executions.isEmpty()) return 100 val diverseExecutions = numberDiverseExecutionsBasedOnPaths(executions) return 100 * diverseExecutions.size / executions.size } -fun numberDiverseExecutionsBasedOnPaths(executions: List) = executions.filter { current -> +fun numberDiverseExecutionsBasedOnPaths(executions: List) = executions.filter { current -> executions.filter { it != current }.any { other -> current.path.isEqualPath(other.path) }.not() diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/clustering/MatrixUniqueness.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/clustering/MatrixUniqueness.kt index 7b722f1bbb..e354d920b3 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/clustering/MatrixUniqueness.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/clustering/MatrixUniqueness.kt @@ -1,14 +1,14 @@ package org.utbot.summary.clustering import org.utbot.framework.plugin.api.Step -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.summary.UtSummarySettings import org.utbot.summary.clustering.dbscan.DBSCANTrainer import org.utbot.summary.clustering.dbscan.neighbor.LinearRangeQuery -class MatrixUniqueness(executions: List) { +class MatrixUniqueness(executions: List) { - private var methodExecutions: List = executions + private var methodExecutions: List = executions private val allSteps = mutableListOf() private val matrix: List @@ -80,10 +80,10 @@ class MatrixUniqueness(executions: List) { companion object { /** Returns map: cluster identifier, List. */ fun dbscanClusterExecutions( - methodExecutions: List, + methodExecutions: List, minPts: Int = UtSummarySettings.MIN_EXEC_DBSCAN, radius: Float = UtSummarySettings.RADIUS_DBSCAN - ): Map> { + ): Map> { val executionPaths = methodExecutions.map { it.path.asIterable() }.toTypedArray() diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/MethodBasedNameSuggester.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt similarity index 92% rename from utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/MethodBasedNameSuggester.kt rename to utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt index 7dc6dbaa10..80583f7cce 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/MethodBasedNameSuggester.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/MethodBasedNameSuggester.kt @@ -1,4 +1,4 @@ -package org.utbot.fuzzer.names +package org.utbot.summary.fuzzer.names import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.fuzzer.FuzzedMethodDescription diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/ModelBasedNameSuggester.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/ModelBasedNameSuggester.kt similarity index 97% rename from utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/ModelBasedNameSuggester.kt rename to utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/ModelBasedNameSuggester.kt index 4c254a49d9..e3b6050f00 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/ModelBasedNameSuggester.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/ModelBasedNameSuggester.kt @@ -1,4 +1,4 @@ -package org.utbot.fuzzer.names +package org.utbot.summary.fuzzer.names import org.utbot.framework.plugin.api.UtExecutionFailure import org.utbot.framework.plugin.api.UtExecutionResult @@ -29,10 +29,12 @@ class ModelBasedNameSuggester( return emptySequence() } - return sequenceOf(TestSuggestedInfo( + return sequenceOf( + TestSuggestedInfo( testName = createTestName(description, values, result), displayName = createDisplayName(description, values, result) - )) + ) + ) } /** diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/NameSuggester.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/NameSuggester.kt similarity index 82% rename from utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/NameSuggester.kt rename to utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/NameSuggester.kt index 33300f7c31..3c9dfd35ed 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/NameSuggester.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/NameSuggester.kt @@ -1,4 +1,4 @@ -package org.utbot.fuzzer.names +package org.utbot.summary.fuzzer.names import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.fuzzer.FuzzedMethodDescription @@ -6,11 +6,9 @@ import org.utbot.fuzzer.FuzzedValue /** * Name suggester generates a sequence of suggested test information such as: - * - test name - * - display test name. + * - method test name. + * - display name. */ interface NameSuggester { - fun suggest(description: FuzzedMethodDescription, values: List, result: UtExecutionResult?): Sequence - } \ No newline at end of file diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/SingleModelNameSuggester.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/SingleModelNameSuggester.kt similarity index 98% rename from utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/SingleModelNameSuggester.kt rename to utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/SingleModelNameSuggester.kt index 11339a87d4..5df9841484 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/SingleModelNameSuggester.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/SingleModelNameSuggester.kt @@ -1,4 +1,4 @@ -package org.utbot.fuzzer.names +package org.utbot.summary.fuzzer.names import org.utbot.framework.plugin.api.UtArrayModel import org.utbot.framework.plugin.api.UtPrimitiveModel diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/TestSuggestedInfo.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/TestSuggestedInfo.kt similarity index 79% rename from utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/TestSuggestedInfo.kt rename to utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/TestSuggestedInfo.kt index 45f212a321..e7b47c7ed1 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/names/TestSuggestedInfo.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/fuzzer/names/TestSuggestedInfo.kt @@ -1,4 +1,4 @@ -package org.utbot.fuzzer.names +package org.utbot.summary.fuzzer.names /** * Information that can be used to generate test names. diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTag.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTag.kt index 7fc15d7fab..f002310c99 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTag.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTag.kt @@ -1,11 +1,11 @@ package org.utbot.summary.tag -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.summary.SummarySentenceConstants.NEW_LINE import org.utbot.summary.clustering.SplitSteps -class TraceTag(val execution: UtExecution, splitSteps: SplitSteps) : TraceTagWithoutExecution(execution, splitSteps) { +class TraceTag(val execution: UtSymbolicExecution, splitSteps: SplitSteps) : TraceTagWithoutExecution(execution, splitSteps) { override fun toString(): String { return "${NEW_LINE}Input params:${execution.stateBefore.parameters} Output: $result${NEW_LINE} ${rootStatementTag.toString()}" } diff --git a/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTagWithoutExecution.kt b/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTagWithoutExecution.kt index 87ef7e7cd7..cd3b99e12c 100644 --- a/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTagWithoutExecution.kt +++ b/utbot-summary/src/main/kotlin/org/utbot/summary/tag/TraceTagWithoutExecution.kt @@ -1,7 +1,7 @@ package org.utbot.summary.tag import org.utbot.framework.plugin.api.Step -import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtSymbolicExecution import org.utbot.framework.plugin.api.UtExecutionResult import org.utbot.summary.clustering.SplitSteps import soot.jimple.Stmt @@ -19,7 +19,7 @@ open class TraceTagWithoutExecution(val path: List, val result: UtExecutio val noIterationCall = mutableListOf>() var returnsToNumber: Map? = null - constructor(execution: UtExecution, splitSteps: SplitSteps) : this(execution.path, execution.result, splitSteps) + constructor(execution: UtSymbolicExecution, splitSteps: SplitSteps) : this(execution.path, execution.result, splitSteps) /* * If stmt is already contained in the previously registered iteration, it is not registered a second time.