Skip to content

Commit 557009b

Browse files
committed
Add Tool.USVM in ContestEstimator, implement runUsvmGeneration
1 parent f6bc749 commit 557009b

File tree

16 files changed

+888
-24
lines changed

16 files changed

+888
-24
lines changed

Diff for: gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ commonsLoggingVersion=1.2
9696
commonsIOVersion=2.11.0
9797
javaxVersion=2.2
9898
jakartaVersion=3.1.0
99+
jacoDbVersion=1.3.0
99100

100101
# use latest Java 8 compaitable Spring and Spring Boot versions
101102
springVersion=5.3.28

Diff for: settings.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,8 @@ if (projectType == ultimateEdition) {
9191
}
9292

9393
include("utbot-light")
94+
9495
include("utbot-intellij-main")
96+
97+
// TODO usvm-sbft-merge: add if here if we want merge contest it into main
98+
includeBuild("../usvm")

Diff for: utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ abstract class UtExecution(
148148
val executableToCall get() = stateBefore.executableToCall
149149
}
150150

151+
interface UtExecutionWithInstrumentation {
152+
val instrumentation: List<UtInstrumentation>
153+
}
154+
151155
/**
152156
* Symbolic execution.
153157
*
@@ -163,15 +167,15 @@ class UtSymbolicExecution(
163167
stateBefore: EnvironmentModels,
164168
stateAfter: EnvironmentModels,
165169
result: UtExecutionResult,
166-
val instrumentation: List<UtInstrumentation>,
170+
override val instrumentation: List<UtInstrumentation>,
167171
val path: MutableList<Step>,
168172
val fullPath: List<Step>,
169173
coverage: Coverage? = null,
170174
summary: List<DocStatement>? = null,
171175
testMethodName: String? = null,
172176
displayName: String? = null,
173177
/** Convenient view of the full symbolic path */ val symbolicSteps: List<SymbolicStep> = listOf(),
174-
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName) {
178+
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName), UtExecutionWithInstrumentation {
175179
/**
176180
* By design the 'before' and 'after' states contain info about the same fields.
177181
* It means that it is not possible for a field to be present at 'before' and to be absent at 'after'.

Diff for: utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgMethodConstructor.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ import org.utbot.framework.plugin.api.UtExecution
9999
import org.utbot.framework.plugin.api.UtExecutionFailure
100100
import org.utbot.framework.plugin.api.UtExecutionResult
101101
import org.utbot.framework.plugin.api.UtExecutionSuccess
102+
import org.utbot.framework.plugin.api.UtExecutionWithInstrumentation
102103
import org.utbot.framework.plugin.api.UtExplicitlyThrownException
103104
import org.utbot.framework.plugin.api.UtLambdaModel
104105
import org.utbot.framework.plugin.api.UtModel
@@ -201,8 +202,7 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
201202

202203
protected fun setupInstrumentation() {
203204
val instrumentation = when (val execution = currentExecution) {
204-
is UtSymbolicExecution -> execution.instrumentation
205-
is UtFuzzedExecution -> execution.instrumentation
205+
is UtExecutionWithInstrumentation -> execution.instrumentation
206206
else -> return
207207
}
208208
if (instrumentation.isEmpty()) return

Diff for: utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzer/UtFuzzedExecution.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ class UtFuzzedExecution(
2222
displayName: String? = null,
2323
val fuzzingValues: List<FuzzedValue>? = null,
2424
val fuzzedMethodDescription: FuzzedMethodDescription? = null,
25-
val instrumentation: List<UtInstrumentation> = emptyList(),
26-
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName) {
25+
override val instrumentation: List<UtInstrumentation> = emptyList(),
26+
) : UtExecution(stateBefore, stateAfter, result, coverage, summary, testMethodName, displayName), UtExecutionWithInstrumentation {
2727
/**
2828
* By design the 'before' and 'after' states contain info about the same fields.
2929
* It means that it is not possible for a field to be present at 'before' and to be absent at 'after'.

Diff for: utbot-junit-contest/build.gradle

+9
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ dependencies {
139139
implementation group: 'org.mockito', name: 'mockito-core', version: mockitoVersion
140140
implementation group: 'org.mockito', name: 'mockito-inline', version: mockitoInlineVersion
141141
implementation 'junit:junit:4.13.2'
142+
143+
implementation('org.usvm:usvm-core')
144+
implementation('org.usvm:usvm-jvm')
145+
implementation('org.usvm:usvm-jvm-instrumentation')
146+
147+
implementation group: "org.jacodb", name: "jacodb-core", version: jacoDbVersion
148+
implementation group: "org.jacodb", name: "jacodb-analysis", version: jacoDbVersion
149+
implementation group: "org.jacodb", name: "jacodb-approximations", version: jacoDbVersion
150+
142151
testImplementation fileTree(dir: 'src/main/resources/projects/', include: '*/*.jar')
143152
testImplementation files('src/main/resources/evosuite/evosuite-1.2.0.jar')
144153
testImplementation files('src/main/resources/evosuite/evosuite-standalone-runtime-1.2.0.jar')

Diff for: utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ fun runGeneration(
417417
statsForClass
418418
}
419419

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

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

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

498-
private fun StatsForClass.updateCoverage(newCoverage: Coverage, isNewClass: Boolean, fromFuzzing: Boolean) {
500+
fun StatsForClass.updateCoverage(newCoverage: Coverage, isNewClass: Boolean, fromFuzzing: Boolean) {
499501
coverage.update(newCoverage, isNewClass)
500502
// other coverage type updates by empty coverage to respect new class
501503
val emptyCoverage = newCoverage.copy(

Diff for: utbot-junit-contest/src/main/kotlin/org/utbot/contest/ContestEstimator.kt

+84-16
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.utbot.contest.Paths.evosuiteReportFile
2626
import org.utbot.contest.Paths.jarsDir
2727
import org.utbot.contest.Paths.moduleTestDir
2828
import org.utbot.contest.Paths.outputDir
29+
import org.utbot.contest.usvm.runUsvmGeneration
2930
import org.utbot.features.FeatureExtractorFactoryImpl
3031
import org.utbot.features.FeatureProcessorWithStatesRepetitionFactory
3132
import org.utbot.framework.PathSelectorType
@@ -125,10 +126,20 @@ object Paths {
125126
}
126127

127128
@Suppress("unused")
128-
enum class Tool {
129-
UtBot {
130-
@OptIn(ObsoleteCoroutinesApi::class)
131-
@Suppress("EXPERIMENTAL_API_USAGE")
129+
interface Tool {
130+
abstract class UtBotBasedTool : Tool {
131+
abstract fun runGeneration(
132+
project: ProjectToEstimate,
133+
cut: ClassUnderTest,
134+
timeLimit: Long,
135+
fuzzingRatio: Double,
136+
methodNameFilter: String?,
137+
statsForProject: StatsForProject,
138+
compiledTestDir: File,
139+
classFqn: String,
140+
expectedExceptions: ExpectedExceptionsForClass
141+
) : StatsForClass
142+
132143
override fun run(
133144
project: ProjectToEstimate,
134145
cut: ClassUnderTest,
@@ -142,19 +153,21 @@ enum class Tool {
142153
) = withUtContext(ContextManager.createNewContext(project.classloader)) {
143154
val classStats: StatsForClass = try {
144155
runGeneration(
145-
project.name,
156+
project,
146157
cut,
147158
timeLimit,
148159
fuzzingRatio,
149-
project.sootClasspathString,
150-
runFromEstimator = true,
151-
expectedExceptions,
152-
methodNameFilter
160+
methodNameFilter,
161+
statsForProject,
162+
compiledTestDir,
163+
classFqn,
164+
expectedExceptions
153165
)
154166
} catch (e: CancellationException) {
155167
logger.info { "[$classFqn] finished with CancellationException" }
156168
return
157169
} catch (e: Throwable) {
170+
logger.error(e) { "ISOLATION: $e" }
158171
logger.info { "ISOLATION: $e" }
159172
logger.info { "continue without compilation" }
160173
return
@@ -198,8 +211,61 @@ enum class Tool {
198211
override fun moveProducedFilesIfNeeded() {
199212
// don't do anything
200213
}
201-
},
202-
EvoSuite {
214+
}
215+
216+
object UtBot : UtBotBasedTool() {
217+
@OptIn(ObsoleteCoroutinesApi::class)
218+
@Suppress("EXPERIMENTAL_API_USAGE")
219+
override fun runGeneration(
220+
project: ProjectToEstimate,
221+
cut: ClassUnderTest,
222+
timeLimit: Long,
223+
fuzzingRatio: Double,
224+
methodNameFilter: String?,
225+
statsForProject: StatsForProject,
226+
compiledTestDir: File,
227+
classFqn: String,
228+
expectedExceptions: ExpectedExceptionsForClass
229+
): StatsForClass {
230+
return runGeneration(
231+
project.name,
232+
cut,
233+
timeLimit,
234+
fuzzingRatio,
235+
project.sootClasspathString,
236+
runFromEstimator = true,
237+
expectedExceptions,
238+
methodNameFilter
239+
)
240+
}
241+
}
242+
243+
object USVM : UtBotBasedTool() {
244+
@OptIn(ObsoleteCoroutinesApi::class)
245+
@Suppress("EXPERIMENTAL_API_USAGE")
246+
override fun runGeneration(
247+
project: ProjectToEstimate,
248+
cut: ClassUnderTest,
249+
timeLimit: Long,
250+
fuzzingRatio: Double,
251+
methodNameFilter: String?,
252+
statsForProject: StatsForProject,
253+
compiledTestDir: File,
254+
classFqn: String,
255+
expectedExceptions: ExpectedExceptionsForClass
256+
): StatsForClass = runUsvmGeneration(
257+
project.name,
258+
cut,
259+
timeLimit,
260+
fuzzingRatio,
261+
project.sootClasspathString,
262+
runFromEstimator = true,
263+
expectedExceptions,
264+
methodNameFilter
265+
)
266+
}
267+
268+
object EvoSuite : Tool {
203269
override fun run(
204270
project: ProjectToEstimate,
205271
cut: ClassUnderTest,
@@ -272,7 +338,7 @@ enum class Tool {
272338
}
273339
};
274340

275-
abstract fun run(
341+
fun run(
276342
project: ProjectToEstimate,
277343
cut: ClassUnderTest,
278344
timeLimit: Long,
@@ -284,7 +350,7 @@ enum class Tool {
284350
expectedExceptions: ExpectedExceptionsForClass
285351
)
286352

287-
abstract fun moveProducedFilesIfNeeded()
353+
fun moveProducedFilesIfNeeded()
288354
}
289355

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

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

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

345413
JdkInfoService.jdkInfoProvider = ContestEstimatorJdkInfoProvider(javaHome)

0 commit comments

Comments
 (0)