Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Add Tool.USVM in ContestEstimator, implement runUsvmGeneration
  • Loading branch information
IlyaMuravjov committed Oct 27, 2023
commit 0695ab55294dc3c0b822f4c14159d2d8863d924d
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ commonsLoggingVersion=1.2
commonsIOVersion=2.11.0
javaxVersion=2.2
jakartaVersion=3.1.0
jacoDbVersion=1.3.0

# use latest Java 8 compaitable Spring and Spring Boot versions
springVersion=5.3.28
Expand Down
4 changes: 4 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,8 @@ if (projectType == ultimateEdition) {
}

include("utbot-light")

include("utbot-intellij-main")

// TODO usvm-sbft-merge: add if here if we want merge contest it into main
includeBuild("../usvm")
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ abstract class UtExecution(
val executableToCall get() = stateBefore.executableToCall
}

interface UtExecutionWithInstrumentation {
val instrumentation: List<UtInstrumentation>
}

/**
* Symbolic execution.
*
Expand All @@ -163,15 +167,15 @@ class UtSymbolicExecution(
stateBefore: EnvironmentModels,
stateAfter: EnvironmentModels,
result: UtExecutionResult,
val instrumentation: List<UtInstrumentation>,
override 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,
/** Convenient view of the full symbolic path */ val symbolicSteps: List<SymbolicStep> = listOf(),
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName) {
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName), UtExecutionWithInstrumentation {
/**
* 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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import org.utbot.framework.plugin.api.UtExecution
import org.utbot.framework.plugin.api.UtExecutionFailure
import org.utbot.framework.plugin.api.UtExecutionResult
import org.utbot.framework.plugin.api.UtExecutionSuccess
import org.utbot.framework.plugin.api.UtExecutionWithInstrumentation
import org.utbot.framework.plugin.api.UtExplicitlyThrownException
import org.utbot.framework.plugin.api.UtLambdaModel
import org.utbot.framework.plugin.api.UtModel
Expand Down Expand Up @@ -201,8 +202,7 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte

protected fun setupInstrumentation() {
val instrumentation = when (val execution = currentExecution) {
is UtSymbolicExecution -> execution.instrumentation
is UtFuzzedExecution -> execution.instrumentation
is UtExecutionWithInstrumentation -> execution.instrumentation
else -> return
}
if (instrumentation.isEmpty()) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class UtFuzzedExecution(
displayName: String? = null,
val fuzzingValues: List<FuzzedValue>? = null,
val fuzzedMethodDescription: FuzzedMethodDescription? = null,
val instrumentation: List<UtInstrumentation> = emptyList(),
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName) {
override val instrumentation: List<UtInstrumentation> = emptyList(),
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName), UtExecutionWithInstrumentation {
/**
* 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 Down
9 changes: 9 additions & 0 deletions utbot-junit-contest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ dependencies {
implementation group: 'org.mockito', name: 'mockito-core', version: mockitoVersion
implementation group: 'org.mockito', name: 'mockito-inline', version: mockitoInlineVersion
implementation 'junit:junit:4.13.2'

implementation('org.usvm:usvm-core')
implementation('org.usvm:usvm-jvm')
implementation('org.usvm:usvm-jvm-instrumentation')

implementation group: "org.jacodb", name: "jacodb-core", version: jacoDbVersion
implementation group: "org.jacodb", name: "jacodb-analysis", version: jacoDbVersion
implementation group: "org.jacodb", name: "jacodb-approximations", version: jacoDbVersion

testImplementation fileTree(dir: 'src/main/resources/projects/', include: '*/*.jar')
testImplementation files('src/main/resources/evosuite/evosuite-1.2.0.jar')
testImplementation files('src/main/resources/evosuite/evosuite-standalone-runtime-1.2.0.jar')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ fun runGeneration(
statsForClass
}

private fun prepareClass(javaClazz: Class<*>, methodNameFilter: String?): List<ExecutableId> {
fun prepareClass(javaClazz: Class<*>, methodNameFilter: String?): List<ExecutableId> {
//1. all methods from cut
val methods = javaClazz.declaredMethods
.filterNot { it.isAbstract }
Expand Down Expand Up @@ -491,11 +491,13 @@ internal fun File.toUrl(): URL = toURI().toURL()

internal fun testMethodName(name: String, num: Int): String = "test${name.capitalize()}$num"

// TODO usvm-sbft: does SBFT allow to generate tests for private methods and constructors
// If no, add more filtering here
internal val Method.isVisibleFromGeneratedTest: Boolean
get() = (this.modifiers and Modifier.ABSTRACT) == 0
&& (this.modifiers and Modifier.NATIVE) == 0

private fun StatsForClass.updateCoverage(newCoverage: Coverage, isNewClass: Boolean, fromFuzzing: Boolean) {
fun StatsForClass.updateCoverage(newCoverage: Coverage, isNewClass: Boolean, fromFuzzing: Boolean) {
coverage.update(newCoverage, isNewClass)
// other coverage type updates by empty coverage to respect new class
val emptyCoverage = newCoverage.copy(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.utbot.contest.Paths.evosuiteReportFile
import org.utbot.contest.Paths.jarsDir
import org.utbot.contest.Paths.moduleTestDir
import org.utbot.contest.Paths.outputDir
import org.utbot.contest.usvm.runUsvmGeneration
import org.utbot.features.FeatureExtractorFactoryImpl
import org.utbot.features.FeatureProcessorWithStatesRepetitionFactory
import org.utbot.framework.PathSelectorType
Expand Down Expand Up @@ -125,10 +126,20 @@ object Paths {
}

@Suppress("unused")
enum class Tool {
UtBot {
@OptIn(ObsoleteCoroutinesApi::class)
@Suppress("EXPERIMENTAL_API_USAGE")
interface Tool {
abstract class UtBotBasedTool : Tool {
abstract fun runGeneration(
project: ProjectToEstimate,
cut: ClassUnderTest,
timeLimit: Long,
fuzzingRatio: Double,
methodNameFilter: String?,
statsForProject: StatsForProject,
compiledTestDir: File,
classFqn: String,
expectedExceptions: ExpectedExceptionsForClass
) : StatsForClass

override fun run(
project: ProjectToEstimate,
cut: ClassUnderTest,
Expand All @@ -142,19 +153,21 @@ enum class Tool {
) = withUtContext(ContextManager.createNewContext(project.classloader)) {
val classStats: StatsForClass = try {
runGeneration(
project.name,
project,
cut,
timeLimit,
fuzzingRatio,
project.sootClasspathString,
runFromEstimator = true,
expectedExceptions,
methodNameFilter
methodNameFilter,
statsForProject,
compiledTestDir,
classFqn,
expectedExceptions
)
} catch (e: CancellationException) {
logger.info { "[$classFqn] finished with CancellationException" }
return
} catch (e: Throwable) {
logger.error(e) { "ISOLATION: $e" }
logger.info { "ISOLATION: $e" }
logger.info { "continue without compilation" }
return
Expand Down Expand Up @@ -198,8 +211,61 @@ enum class Tool {
override fun moveProducedFilesIfNeeded() {
// don't do anything
}
},
EvoSuite {
}

object UtBot : UtBotBasedTool() {
@OptIn(ObsoleteCoroutinesApi::class)
@Suppress("EXPERIMENTAL_API_USAGE")
override fun runGeneration(
project: ProjectToEstimate,
cut: ClassUnderTest,
timeLimit: Long,
fuzzingRatio: Double,
methodNameFilter: String?,
statsForProject: StatsForProject,
compiledTestDir: File,
classFqn: String,
expectedExceptions: ExpectedExceptionsForClass
): StatsForClass {
return runGeneration(
project.name,
cut,
timeLimit,
fuzzingRatio,
project.sootClasspathString,
runFromEstimator = true,
expectedExceptions,
methodNameFilter
)
}
}

object USVM : UtBotBasedTool() {
@OptIn(ObsoleteCoroutinesApi::class)
@Suppress("EXPERIMENTAL_API_USAGE")
override fun runGeneration(
project: ProjectToEstimate,
cut: ClassUnderTest,
timeLimit: Long,
fuzzingRatio: Double,
methodNameFilter: String?,
statsForProject: StatsForProject,
compiledTestDir: File,
classFqn: String,
expectedExceptions: ExpectedExceptionsForClass
): StatsForClass = runUsvmGeneration(
project.name,
cut,
timeLimit,
fuzzingRatio,
project.sootClasspathString,
runFromEstimator = true,
expectedExceptions,
methodNameFilter
)
}

object EvoSuite : Tool {
override fun run(
project: ProjectToEstimate,
cut: ClassUnderTest,
Expand Down Expand Up @@ -272,7 +338,7 @@ enum class Tool {
}
};

abstract fun run(
fun run(
project: ProjectToEstimate,
cut: ClassUnderTest,
timeLimit: Long,
Expand All @@ -284,7 +350,7 @@ enum class Tool {
expectedExceptions: ExpectedExceptionsForClass
)

abstract fun moveProducedFilesIfNeeded()
fun moveProducedFilesIfNeeded()
}

fun main(args: Array<String>) {
Expand All @@ -295,7 +361,7 @@ fun main(args: Array<String>) {
val tools: List<Tool>

// very special case when you run your project directly from IntellijIDEA omitting command line arguments
if (args.isEmpty() && System.getProperty("os.name")?.run { contains("win", ignoreCase = true) } == true) {
if (args.isEmpty()) {
processedClassesThreshold = 9999 //change to change number of classes to run
val timeLimit = 20 // increase if you want to debug something
val fuzzingRatio = 0.1 // sets fuzzing ratio to total test generation
Expand All @@ -319,7 +385,8 @@ fun main(args: Array<String>) {
// config for SBST 2022
methodFilter = null
projectFilter = listOf("fastjson-1.2.50", "guava-26.0", "seata-core-0.5.0", "spoon-core-7.0.0")
tools = listOf(Tool.UtBot)
// TODO usvm-sbft-merge: add if here if we want merge contest it into main
tools = listOf(Tool.USVM)

estimatorArgs = arrayOf(
classesLists,
Expand All @@ -339,7 +406,8 @@ fun main(args: Array<String>) {
processedClassesThreshold = 9999
methodFilter = null
projectFilter = null
tools = listOf(Tool.UtBot)
// TODO usvm-sbft-merge: add if here if we want merge contest it into main
tools = listOf(Tool.USVM)
}

JdkInfoService.jdkInfoProvider = ContestEstimatorJdkInfoProvider(javaHome)
Expand Down
Loading