Skip to content

Usvm distribution for the contest #2704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all 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
60 changes: 60 additions & 0 deletions utbot-junit-contest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ configurations {
usvmApproximationsApi
usvmInstrumentationCollector
usvmInstrumentationRunner
generatedTestCompile
}

def approximationsRepo = "com.github.UnitTestBot.java-stdlib-approximations"
Expand Down Expand Up @@ -170,6 +171,10 @@ dependencies {
implementation group: 'org.mockito', name: 'mockito-inline', version: mockitoInlineVersion
implementation 'junit:junit:4.13.2'

generatedTestCompile group: 'org.mockito', name: 'mockito-core', version: mockitoVersion
generatedTestCompile group: 'org.mockito', name: 'mockito-inline', version: mockitoInlineVersion
generatedTestCompile 'junit:junit:4.13.2'

implementation "org.burningwave:core:12.62.7"

implementation group: "org.usvm", name: "usvm-core", version: usvmVersion
Expand Down Expand Up @@ -216,6 +221,10 @@ jar {
attributes 'JAR-Type': 'Fat JAR'
}

processResources.exclude("classes/**")
processResources.exclude("projects/**")
processResources.exclude("evosuite/**")

version '1.0'

dependsOn configurations.runtimeClasspath
Expand Down Expand Up @@ -296,3 +305,54 @@ task run(type: JavaExec) {
if (javaHome.endsWith(jreSuffix)) javaHome = javaHome.dropRight(jreSuffix.length())
environment "JAVA_HOME", javaHome
}

tasks.register("generateRuntool") {
dependsOn(jar, usvmInstrumentationRunnerJar)

doLast {
def distDir = buildDir.toPath().resolve("utbot-usvm-runtool").toFile()
copy {
from jar.outputs
into distDir
rename { "utbot-usvm-tool.jar" }
}

copy {
from configurations.usvmApproximationsApi.resolvedConfiguration.files.find()
into distDir
rename { "usvm-api.jar" }
}

copy {
from configurations.approximations.resolvedConfiguration.files.find()
into distDir
rename { "usvm-approximations.jar" }
}

copy {
from configurations.usvmInstrumentationCollector.resolvedConfiguration.files.find()
into distDir
rename { "usvm-jvm-collectors.jar" }
}

copy {
from usvmInstrumentationRunnerJar.outputs
into distDir
rename { "usvm-jvm-instrumentation.jar" }
}

copy {
from projectDir.toPath().resolve("usvm-runtool")
into distDir
rename { "runtool" }
}

def libsDir = distDir.toPath().resolve("lib").toFile()
configurations.generatedTestCompile.resolvedConfiguration.files.forEach { f ->
copy {
from f
into libsDir
}
}
}
}
27 changes: 21 additions & 6 deletions utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeoutOrNull
import org.utbot.contest.usvm.jc.JcContainer
import org.utbot.contest.usvm.runUsvmGeneration
import org.utbot.framework.SummariesGenerationType
import org.utbot.framework.codegen.domain.*
import org.utbot.framework.codegen.generator.CodeGenerator
Expand Down Expand Up @@ -107,20 +109,29 @@ fun main(args: Array<String>) {

println("Started UtBot Contest, classfileDir = $classfileDir, classpathString=$classpathString, outputDir=$outputDir, mocks=$mockStrategyApi")

// TODO: tmp hack to retrieve tmp dir wrt contest rules
val tmpDir = outputDir.resolveSibling("data")

val cpEntries = classpathString.split(File.pathSeparator).map { File(it) }
val classLoader = URLClassLoader(cpEntries.map { it.toUrl() }.toTypedArray())
val context = UtContext(classLoader)

val testCompileCp = System.getenv("UTBOT_CONTEST_TEST_COMPILE_CP")
var classpathStringForTestCompile = classpathString
if (!testCompileCp.isNullOrBlank()) {
classpathStringForTestCompile = "$classpathStringForTestCompile${File.pathSeparator}$testCompileCp"
}

withUtContext(context) {
// Initialize the soot before a contest is started.
// This saves the time budget for real work instead of soot initialization.
TestCaseGenerator(listOf(classfileDir), classpathString, dependencyPath, JdkInfoService.provide())

logger.info().measureTime({ "warmup: kotlin reflection :: init" }) {
prepareClass(ConcreteExecutorPool::class.java, "")
prepareClass(Warmup::class.java, "")
}
// TODO usvm-sbft-merge: utbot instrumentation not used in usvm
// logger.info().measureTime({ "warmup: kotlin reflection :: init" }) {
// prepareClass(ConcreteExecutorPool::class.java, "")
// prepareClass(Warmup::class.java, "")
// }

println("${ContestMessage.INIT}")

Expand All @@ -138,30 +149,34 @@ fun main(args: Array<String>) {
val timeBudgetSec = cmd[2].toLong()
val cut = ClassUnderTest(classLoader.loadClass(classUnderTestName).id, outputDir, classfileDir.toFile())

runGeneration(
// TODO usvm-sbft-merge: usvm generator use different entrypoint
runUsvmGeneration(
project = "Contest",
cut,
timeBudgetSec,
fuzzingRatio = 0.1,
classpathString,
runFromEstimator = false,
expectedExceptions = ExpectedExceptionsForClass(),
tmpDir = tmpDir,
methodNameFilter = null
)

val compiledClassFileDir = File(outputDir.absolutePath, "compiledClassFiles")
compiledClassFileDir.mkdirs()
compileClassAndRemoveUncompilableTests(
testDir = compiledClassFileDir.absolutePath,
classPath = classpathString,
classPath = classpathStringForTestCompile,
testClass = cut.generatedTestFile.absolutePath
)
compiledClassFileDir.deleteRecursively()

println("${ContestMessage.READY}")
}
}

ConcreteExecutor.defaultPool.close()
JcContainer.close()
}

fun setOptions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,9 @@ interface Tool {
fuzzingRatio,
project.sootClasspathString,
runFromEstimator = true,
expectedExceptions,
methodNameFilter
expectedExceptions = expectedExceptions,
tmpDir = File("."),
methodNameFilter = methodNameFilter
)

override fun close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fun runUsvmGeneration(
classpathString: String,
runFromEstimator: Boolean,
expectedExceptions: ExpectedExceptionsForClass,
tmpDir: File,
methodNameFilter: String? = null // For debug purposes you can specify method name
): StatsForClass = runBlocking {
ErrorCountingLoggerAppender.resetOccurrenceCounter()
Expand All @@ -87,14 +88,15 @@ fun runUsvmGeneration(
val jcContainer by lazy {
JcContainer(
usePersistence = true,
persistenceDir = tmpDir,
classpath = classpathFiles,
machineOptions = UMachineOptions(
// TODO usvm-sbft: if we have less than CONTEST_TEST_EXECUTION_TIMEOUT time left, we should try execute
// with smaller timeout, but instrumentation currently doesn't allow to change timeout for individual runs
timeout = generationTimeoutMillisWithoutCodegen.milliseconds - CONTEST_TEST_EXECUTION_TIMEOUT,
pathSelectionStrategies = listOf(PathSelectionStrategy.CLOSEST_TO_UNCOVERED_RANDOM),
pathSelectorFairnessStrategy = PathSelectorFairnessStrategy.COMPLETELY_FAIR,
solverType = SolverType.YICES,
solverType = SolverType.Z3, // TODO: usvm-ksmt: Yices doesn't work on old linux
)
) {
// TODO usvm-sbft: we may want to tune these JcSettings for contest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ private val logger = KotlinLogging.logger {}
// TODO usvm-sbft-refactoring: copied from `usvm/usvm-jvm/test`, extract this class back to USVM project
class JcContainer private constructor(
usePersistence: Boolean,
persistenceDir: File,
classpath: List<File>,
machineOptions: UMachineOptions,
builder: JcSettings.() -> Unit,
Expand All @@ -38,7 +39,7 @@ class JcContainer private constructor(
* 2. Faster analysis for classes from the same cp
* */
val persistenceLocation = if (usePersistence) {
"jcdb-persistence-${cpPath.hashCode()}"
persistenceDir.resolve("jcdb-persistence-${cpPath.hashCode()}").absolutePath
} else {
null
}
Expand Down Expand Up @@ -83,6 +84,7 @@ class JcContainer private constructor(

operator fun invoke(
usePersistence: Boolean,
persistenceDir: File,
classpath: List<File>,
machineOptions: UMachineOptions,
builder: JcSettings.() -> Unit,
Expand All @@ -92,7 +94,8 @@ class JcContainer private constructor(
// TODO usvm-sbft: right now max cache size is 1, do we need to increase it?
logger.info { "JcContainer cache miss" }
close()
JcContainer(usePersistence, classpath, machineOptions, builder).also { cache[cacheKey] = it }
JcContainer(usePersistence, persistenceDir, classpath, machineOptions, builder)
.also { cache[cacheKey] = it }
}
}

Expand Down
20 changes: 20 additions & 0 deletions utbot-junit-contest/usvm-runtool
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

# switch to environment JVM as needed
JAVA_HOME=/usr

export JAVA_HOME=$JAVA_HOME

# Resolve tool absolute path
TOOL_DIR="$(dirname -- "$(readlink -f "${BASH_SOURCE}")")"

# Create test compile classpath from all files in `lib` directory
LIB_DIR="$TOOL_DIR/lib"
export UTBOT_CONTEST_TEST_COMPILE_CP="$(find $LIB_DIR -type f -exec realpath {} \; | tr '\n' ':' | sed 's/:$//')"

TOOL="$TOOL_DIR/utbot-usvm-tool.jar"
env usvm.jvm.api.jar.path="$TOOL_DIR/usvm-api.jar" \
usvm.jvm.approximations.jar.path="$TOOL_DIR/usvm-approximations.jar" \
usvm-jvm-collectors-jar="$TOOL_DIR/usvm-jvm-collectors.jar" \
usvm-jvm-instrumentation-jar="$TOOL_DIR/usvm-jvm-instrumentation.jar" \
$JAVA_HOME/bin/java -cp $TOOL sbst.runtool.Main