Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,31 +135,50 @@ 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<UtInstrumentation>,
val path: MutableList<Step>,
val fullPath: List<Step>,
val coverage: Coverage? = null,
val createdBy: UtExecutionCreator? = null,
var summary: List<DocStatement>? = 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.
* - the engine type that created this execution.
* - comments, method names and display names created by utbot-summary module.
*/
class UtSymbolicExecution(
stateBefore: EnvironmentModels,
stateAfter: EnvironmentModels,
result: UtExecutionResult,
val instrumentation: List<UtInstrumentation>,
val path: MutableList<Step>,
val fullPath: List<Step>,
coverage: Coverage? = null,
summary: List<DocStatement>? = 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'.
Expand All @@ -169,7 +188,7 @@ data class UtExecution(
get() = stateBefore.statics.keys

override fun toString(): String = buildString {
append("UtExecution(")
append("UtSymbolicExecution(")
appendLine()

append("<State before>:")
Expand All @@ -190,6 +209,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(
Expand All @@ -209,7 +243,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,
Expand Down Expand Up @@ -553,12 +587,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"
}

}

Expand Down Expand Up @@ -1034,7 +1068,7 @@ class BuiltinMethodId(

open class TypeParameters(val parameters: List<ClassId> = emptyList())

class WildcardTypeParameter: TypeParameters(emptyList())
class WildcardTypeParameter : TypeParameters(emptyList())

interface CodeGenerationSettingItem {
val displayName: String
Expand Down Expand Up @@ -1164,6 +1198,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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,7 +31,7 @@ data class Edge(val src: Stmt, val dst: Stmt, val decisionNum: Int)
* [INTERMEDIATE] is a label for an intermediate state which is suitable for further symbolic analysis.
*
* [TERMINAL] is a label for a terminal state from which we might (or might not) execute concretely and construct
* [UtExecution]. This state represents the final state of the program execution, that is a throw or return from the outer
* [UtSymbolicExecution]. This state represents the final state of the program execution, that is a throw or return from the outer
* method.
*
* [CONCRETE] is a label for a state which is not suitable for further symbolic analysis, and it is also not a terminal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,41 +58,16 @@ import org.utbot.framework.UtSettings.useDebugVisualization
import org.utbot.framework.concrete.UtConcreteExecutionData
import org.utbot.framework.concrete.UtConcreteExecutionResult
import org.utbot.framework.concrete.UtExecutionInstrumentation
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.ConcreteExecutionFailureException
import org.utbot.framework.plugin.api.EnvironmentModels
import org.utbot.framework.plugin.api.Instruction
import org.utbot.framework.plugin.api.MissingState
import org.utbot.framework.plugin.api.*
import org.utbot.framework.plugin.api.Step
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.onSuccess
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.Trie
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.*
import org.utbot.fuzzer.providers.ObjectModelProvider
import org.utbot.instrumentation.ConcreteExecutor
import soot.jimple.Stmt
Expand Down Expand Up @@ -298,15 +273,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)

Expand Down Expand Up @@ -486,32 +460,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
)
)
}
Expand All @@ -524,11 +481,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)
Expand Down Expand Up @@ -562,14 +515,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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import org.utbot.framework.plugin.api.UtConcreteValue
import org.utbot.framework.plugin.api.UtDirectSetFieldModel
import org.utbot.framework.plugin.api.UtEnumConstantModel
import org.utbot.framework.plugin.api.UtExecutableCallModel
import org.utbot.framework.plugin.api.UtExecution
import org.utbot.framework.plugin.api.UtSymbolicExecution
import org.utbot.framework.plugin.api.UtExecutionFailure
import org.utbot.framework.plugin.api.UtExecutionResult
import org.utbot.framework.plugin.api.UtExecutionSuccess
Expand Down Expand Up @@ -118,7 +118,7 @@ class ValueConstructor {
/**
* Constructs value based execution from model based.
*/
fun construct(execution: UtExecution): UtValueExecution<*> {
fun construct(execution: UtSymbolicExecution): UtValueExecution<*> {
val (stateBefore, mocks) = constructState(execution.stateBefore)
val (stateAfter, _) = constructState(execution.stateAfter)
val returnValue = execution.result.map { construct(listOf(it)).single().value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -54,6 +44,7 @@ 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.*
import org.utbot.framework.plugin.api.util.id
import org.utbot.framework.plugin.api.util.isCheckedException
import org.utbot.framework.plugin.api.util.isSubtypeOf
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down
Loading