Skip to content

Commit

Permalink
Merge branch 'master' into mocks
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdullinAM authored Apr 30, 2024
2 parents 74ebec6 + f1279a1 commit f172330
Show file tree
Hide file tree
Showing 47 changed files with 1,366 additions and 152 deletions.
2 changes: 1 addition & 1 deletion kex-boolector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<version>3.2.5</version>
<configuration>
<systemPropertyVariables>
<!--suppress UnresolvedMavenProperty -->
Expand Down
2 changes: 1 addition & 1 deletion kex-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<version>3.2.5</version>
<configuration>
<argLine>${test.jvm.params}</argLine>
<systemPropertyVariables>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ class SymbolicTraceInstrumenter(
)
)
)
add(resetCollector())
}
inst.insertBefore(instrumented.mapLocation())
}
Expand Down Expand Up @@ -864,6 +865,11 @@ class SymbolicTraceInstrumenter(
)
}

private fun resetCollector(): Instruction {
val resetMethod = collectorClass.getMethod("resetConverter", types.voidType)
return collectorClass.interfaceCall(resetMethod, traceCollector, listOf())
}

private fun addNullityConstraint(inst: Instruction, value: Value): List<Instruction> = buildList {
if (inst.parent.method.isConstructor && value is ThisRef) return@buildList

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import java.nio.file.Path
object RuntimeConfig : Config() {
private val options = mutableMapOf<String, MutableMap<String, String>>()

fun setValue(section: String, name: String, value: String) =
options.getOrPut(section) { mutableMapOf() }.set(name, value)
fun setValue(section: String, name: String, value: String?) {
when {
value != null -> options.getOrPut(section) { mutableMapOf() }[name] = value
else -> options.getOrPut(section) { mutableMapOf() }.remove(name)
}
}

fun setValue(section: String, name: String, value: Path) =
options.getOrPut(section) { mutableMapOf() }.set(name, value.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import org.vorpal.research.kex.util.StringInfoContext
import org.vorpal.research.kfg.ClassManager
import org.vorpal.research.kfg.ir.Class
import org.vorpal.research.kfg.ir.Method
import org.vorpal.research.kfg.ir.value.*
import org.vorpal.research.kthelper.assert.unreachable
import org.vorpal.research.kthelper.logging.error
import org.vorpal.research.kthelper.logging.log
import org.vorpal.research.kthelper.tryOrNull
import ru.spbstu.wheels.joinToString
import org.vorpal.research.kthelper.toBoolean
import kotlin.random.Random

sealed class Descriptor(term: Term, type: KexType) {
Expand Down Expand Up @@ -212,6 +214,8 @@ sealed class ConstantDescriptor(term: Term, type: KexType) : Descriptor(term, ty
if (other !is Int) return false
return this.value == other.value
}

fun toBool() = Bool(value.toBoolean())
}

class Long(val value: kotlin.Long) : ConstantDescriptor(term { generate(KexLong) }, KexLong) {
Expand Down Expand Up @@ -894,6 +898,19 @@ open class DescriptorBuilder : StringInfoContext() {
is Double -> ConstantDescriptor.Double(number)
else -> unreachable { log.error("Unknown number $number") }
}

fun const(constant: Constant) = when (constant) {
is BoolConstant -> ConstantDescriptor.Bool(constant.value)
is ByteConstant -> ConstantDescriptor.Byte(constant.value)
is ShortConstant -> ConstantDescriptor.Short(constant.value)
is IntConstant -> ConstantDescriptor.Int(constant.value)
is LongConstant -> ConstantDescriptor.Long(constant.value)
is CharConstant -> ConstantDescriptor.Char(constant.value)
is FloatConstant -> ConstantDescriptor.Float(constant.value)
is DoubleConstant -> ConstantDescriptor.Double(constant.value)
is StringConstant -> string(constant.value)
else -> ConstantDescriptor.Null
}

fun const(type: KexType, value: String): Descriptor = descriptor {
when (type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.vorpal.research.kex.parameters

import org.vorpal.research.kex.descriptor.ConstantDescriptor
import org.vorpal.research.kex.descriptor.Descriptor
import org.vorpal.research.kex.descriptor.ObjectDescriptor
import org.vorpal.research.kex.descriptor.descriptor
import org.vorpal.research.kex.ktype.KexClass
import org.vorpal.research.kex.state.term.ArgumentTerm
import org.vorpal.research.kex.trace.symbolic.protocol.ExceptionResult
import org.vorpal.research.kex.trace.symbolic.protocol.ExecutionCompletedResult
import org.vorpal.research.kex.trace.symbolic.protocol.ExecutionResult
import org.vorpal.research.kex.trace.symbolic.protocol.SuccessResult
import org.vorpal.research.kfg.ir.Method
import org.vorpal.research.kfg.ir.value.Constant
import org.vorpal.research.kfg.ir.value.instruction.ReturnInst
import org.vorpal.research.kfg.type.BoolType
import org.vorpal.research.kfg.type.SystemTypeNames
import org.vorpal.research.kthelper.assert.asserted

class FinalParameters<T> private constructor(
val instance: T?,
val args: List<T>,
val returnValueUnsafe: T?,
val exceptionTypeUnsafe: String?
) {
val isException: Boolean
get() = exceptionTypeUnsafe != null
val isSuccess: Boolean
get() = !isException
val hasReturnValue: Boolean
get() = returnValueUnsafe != null

val exceptionType: String
get() = asserted(isException) { exceptionTypeUnsafe!! }
val returnValue: T
get() = asserted(hasReturnValue) { returnValueUnsafe!! }
val asList: List<T>
get() = listOfNotNull(instance) + args + listOfNotNull(returnValueUnsafe)

constructor(instance: T?, args: List<T>, exceptionType: String) :
this(instance, args, null, exceptionType)

constructor(instance: T?, args: List<T>, returnValue: T?) :
this(instance, args, returnValue, null)

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as FinalParameters<*>

if (instance != other.instance) return false
if (args != other.args) return false
if (returnValueUnsafe != other.returnValueUnsafe) return false
if (exceptionTypeUnsafe != other.exceptionTypeUnsafe) return false

return true
}

override fun hashCode(): Int {
var result = instance?.hashCode() ?: 0
result = 31 * result + args.hashCode()
result = 31 * result + (returnValueUnsafe?.hashCode() ?: 0)
result = 31 * result + (exceptionTypeUnsafe?.hashCode() ?: 0)
return result
}

override fun toString(): String = buildString {
append("FinalParameters(instance=")
append(instance)
append(", args=")
append(args)
append(", returnValueUnsafe=")
append(returnValueUnsafe)
append(", exceptionTypeUnsafe=")
append(exceptionTypeUnsafe)
append(")")
}
}

val <T> FinalParameters<T>?.isSuccessOrFalse: Boolean get() = this?.isSuccess ?: false
val <T> FinalParameters<T>?.isExceptionOrFalse: Boolean get() = this?.isException ?: false
val <T> FinalParameters<T>?.hasReturnValueOrFalse: Boolean get() = this?.hasReturnValue ?: false

fun Parameters<Descriptor>.extractFinalParameters(exceptionJavaName: String): FinalParameters<Descriptor> =
FinalParameters(instance, arguments, exceptionJavaName)

fun Parameters<Descriptor>.extractFinalParameters(returnValueDescriptor: Descriptor?) =
FinalParameters(instance, arguments, returnValueDescriptor)

fun extractFinalParameters(executionResult: ExecutionResult, method: Method): FinalParameters<Descriptor>? =
when (executionResult) {
is ExecutionCompletedResult -> {
val instance = executionResult.symbolicState.concreteValues.entries
.firstOrNull { it.key.name == "this" }?.value?.deepCopy()
val args = executionResult.symbolicState.concreteValues
.filterKeys { it is ArgumentTerm }.map { it.value.deepCopy() }

when (executionResult) {
is ExceptionResult -> {
var exceptionDescriptor = executionResult.cause as ObjectDescriptor
val exceptionType = KexClass(SystemTypeNames.throwableClass)
while (exceptionDescriptor.fields["target" to exceptionType] as? ObjectDescriptor != null) {
exceptionDescriptor = exceptionDescriptor.fields["target" to exceptionType] as ObjectDescriptor
}
val exceptionClassName = exceptionDescriptor.type.javaName
if ("org.vorpal.research.kex" in exceptionClassName) {
throw IllegalArgumentException("Exception $exceptionDescriptor is from kex package")
}
FinalParameters(instance, args, exceptionClassName)
}

is SuccessResult -> {
val retInst = method.body.bodyBlocks
.flatten()
.filterIsInstance<ReturnInst>()
.firstOrNull()
val retValue = when (retInst?.hasReturnValue) {
true -> retInst.returnValue
else -> null
}
val retDescriptor = when (retValue) {
is Constant -> descriptor { const(retValue) }

else -> {
val retTerm = executionResult.symbolicState.termMap.entries.firstOrNull {
it.value.value == retValue && it.value.depth == 0
}?.key
val descriptor = executionResult.symbolicState.concreteValues[retTerm]
when (method.returnType) {
is BoolType -> (descriptor as? ConstantDescriptor.Int)?.toBool()
else -> descriptor
}
}
}

FinalParameters(instance, args, retDescriptor)
}
}
}

else -> null
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ interface InstructionTraceCollector {

fun track(value: String, concreteValue: Any?)

fun resetConverter()

fun methodEnter(
className: String,
methodName: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.vorpal.research.kthelper.collection.stackOf
import org.vorpal.research.kthelper.logging.log
import org.vorpal.research.kthelper.toInt
import org.vorpal.research.kthelper.`try`
import java.util.*

class SymbolicTraceException(message: String, cause: Throwable) : KtException(message, cause) {
override fun toString() = "SymbolicTraceException: $message: ${cause?.message}"
Expand Down Expand Up @@ -78,7 +79,7 @@ class SymbolicTraceBuilder(
* mutable backing fields for required fields
*/
private val cm get() = ctx.cm
private val converter = Object2DescriptorConverter()
private var converter = Object2DescriptorConverter()
private val stateBuilder = arrayListOf<Clause>()
private val traceBuilder = arrayListOf<Instruction>()
private val pathBuilder = arrayListOf<PathClause>()
Expand Down Expand Up @@ -1435,4 +1436,8 @@ class SymbolicTraceBuilder(
lengthChecked += to
}
}

override fun resetConverter() {
converter = Object2DescriptorConverter()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ private class EmptyTraceCollector : InstructionTraceCollector {

override fun track(value: String, concreteValue: Any?) {}

override fun resetConverter() {}

override fun methodEnter(
className: String,
methodName: String,
Expand Down
14 changes: 9 additions & 5 deletions kex-core/src/test/kotlin/org/vorpal/research/kex/KexTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class KexTest(testDirectoryName: String) {
kexConfig.initLog("kex-test.log")

jarPath = "$rootDir/kex-test/target/kex-test-$version-jar-with-dependencies.jar"
jar = Paths.get(jarPath).asContainer(`package`)!!
jar = Paths.get(jarPath).asContainer()!!

val jars = listOfNotNull(jar, getRuntime(), getKexRuntime(), getIntrinsics())
loader = jars.first().classLoader
Expand All @@ -56,11 +56,15 @@ abstract class KexTest(testDirectoryName: String) {
return psa
}

inline fun withConfigOption(section: String, option: String, value: String, body: () -> Unit) =
withConfigOptions(listOf(Triple(section, option, value)), body)

inline fun withConfigOption(section: String, option: String, value: String, body: () -> Unit) {
val oldValue = kexConfig.getStringValue(section, option)
RuntimeConfig.setValue(section, option, value)
inline fun withConfigOptions(options: List<Triple<String, String, String>>, body: () -> Unit) {
val oldValues = options.associateWith { (section, option, _) -> kexConfig.getStringValue(section, option) }
options.forEach { (section, option, value) -> RuntimeConfig.setValue(section, option, value) }
body()
RuntimeConfig.setValue(section, option, oldValue.toString())
oldValues.forEach { (section, option, _), oldValue ->
RuntimeConfig.setValue(section, option, oldValue.toString())
}
}
}
4 changes: 2 additions & 2 deletions kex-executor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<version>3.2.5</version>
<configuration>
<systemPropertyVariables>
<!--suppress UnresolvedMavenProperty -->
Expand Down Expand Up @@ -128,7 +128,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.7.1</version>
<configuration>
<archive>
<manifest>
Expand Down
Loading

0 comments on commit f172330

Please sign in to comment.