diff --git a/utbot-junit-contest/build.gradle b/utbot-junit-contest/build.gradle index 07462c678a..6b473ef491 100644 --- a/utbot-junit-contest/build.gradle +++ b/utbot-junit-contest/build.gradle @@ -22,6 +22,7 @@ configurations { usvmApproximationsApi usvmInstrumentationCollector usvmInstrumentationRunner + generatedTestCompile } def approximationsRepo = "com.github.UnitTestBot.java-stdlib-approximations" @@ -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 @@ -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 @@ -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 + } + } + } +} diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt index b4098a2415..22deb062a6 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt @@ -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 @@ -107,20 +109,29 @@ fun main(args: Array) { 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}") @@ -138,7 +149,8 @@ fun main(args: Array) { 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, @@ -146,6 +158,7 @@ fun main(args: Array) { classpathString, runFromEstimator = false, expectedExceptions = ExpectedExceptionsForClass(), + tmpDir = tmpDir, methodNameFilter = null ) @@ -153,7 +166,7 @@ fun main(args: Array) { compiledClassFileDir.mkdirs() compileClassAndRemoveUncompilableTests( testDir = compiledClassFileDir.absolutePath, - classPath = classpathString, + classPath = classpathStringForTestCompile, testClass = cut.generatedTestFile.absolutePath ) compiledClassFileDir.deleteRecursively() @@ -161,7 +174,9 @@ fun main(args: Array) { println("${ContestMessage.READY}") } } + ConcreteExecutor.defaultPool.close() + JcContainer.close() } fun setOptions() { diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/ContestEstimator.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/ContestEstimator.kt index d0b75c78f1..e618ce46b6 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/ContestEstimator.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/ContestEstimator.kt @@ -312,8 +312,9 @@ interface Tool { fuzzingRatio, project.sootClasspathString, runFromEstimator = true, - expectedExceptions, - methodNameFilter + expectedExceptions = expectedExceptions, + tmpDir = File("."), + methodNameFilter = methodNameFilter ) override fun close() { diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt index 6bd5b81249..cdba54815c 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt @@ -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() @@ -87,6 +88,7 @@ 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 @@ -94,7 +96,7 @@ fun runUsvmGeneration( 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 diff --git a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/jc/JcContainer.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/jc/JcContainer.kt index bd615852e4..cbd6823c20 100644 --- a/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/jc/JcContainer.kt +++ b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/jc/JcContainer.kt @@ -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, machineOptions: UMachineOptions, builder: JcSettings.() -> Unit, @@ -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 } @@ -83,6 +84,7 @@ class JcContainer private constructor( operator fun invoke( usePersistence: Boolean, + persistenceDir: File, classpath: List, machineOptions: UMachineOptions, builder: JcSettings.() -> Unit, @@ -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 } } } diff --git a/utbot-junit-contest/usvm-runtool b/utbot-junit-contest/usvm-runtool new file mode 100755 index 0000000000..e811620e93 --- /dev/null +++ b/utbot-junit-contest/usvm-runtool @@ -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