From 9e2d1f5e508f4e40c9cde9d35cd66aa337b1ca69 Mon Sep 17 00:00:00 2001 From: Valentyn Sobol Date: Thu, 30 Nov 2023 02:05:29 +0300 Subject: [PATCH 1/4] utbot-usvm runtool distribution --- utbot-junit-contest/build.gradle | 56 +++++++++++++++++++ .../main/kotlin/org/utbot/contest/Contest.kt | 26 ++++++--- .../org/utbot/contest/ContestEstimator.kt | 5 +- .../org/utbot/contest/usvm/ContestUsvm.kt | 2 + .../org/utbot/contest/usvm/jc/JcContainer.kt | 7 ++- utbot-junit-contest/usvm-runtool | 20 +++++++ 6 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 utbot-junit-contest/usvm-runtool diff --git a/utbot-junit-contest/build.gradle b/utbot-junit-contest/build.gradle index 07462c678a..c0d5a1c558 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,8 @@ jar { attributes 'JAR-Type': 'Fat JAR' } + processResources.exclude("*") + version '1.0' dependsOn configurations.runtimeClasspath @@ -296,3 +303,52 @@ task run(type: JavaExec) { if (javaHome.endsWith(jreSuffix)) javaHome = javaHome.dropRight(jreSuffix.length()) environment "JAVA_HOME", javaHome } + +tasks.register("generateRuntool") { + dependsOn(jar, usvmInstrumentationRunnerJar) + + 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..fdff1331bc 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,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.newSingleThreadContext import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeoutOrNull +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 +108,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.parentFile + 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 +148,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 +157,7 @@ fun main(args: Array) { classpathString, runFromEstimator = false, expectedExceptions = ExpectedExceptionsForClass(), + tmpDir = tmpDir, methodNameFilter = null ) @@ -153,7 +165,7 @@ fun main(args: Array) { compiledClassFileDir.mkdirs() compileClassAndRemoveUncompilableTests( testDir = compiledClassFileDir.absolutePath, - classPath = classpathString, + classPath = classpathStringForTestCompile, testClass = cut.generatedTestFile.absolutePath ) compiledClassFileDir.deleteRecursively() @@ -161,7 +173,7 @@ fun main(args: Array) { println("${ContestMessage.READY}") } } - ConcreteExecutor.defaultPool.close() +// ConcreteExecutor.defaultPool.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..b17959d436 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 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 100644 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 From 9970a2be457d68515e089f84b70dbd35f7e248bb Mon Sep 17 00:00:00 2001 From: Valentyn Sobol Date: Thu, 30 Nov 2023 11:02:24 +0300 Subject: [PATCH 2/4] Minor fixes --- utbot-junit-contest/build.gradle | 4 +++- .../src/main/kotlin/org/utbot/contest/Contest.kt | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/utbot-junit-contest/build.gradle b/utbot-junit-contest/build.gradle index c0d5a1c558..336bfecd6a 100644 --- a/utbot-junit-contest/build.gradle +++ b/utbot-junit-contest/build.gradle @@ -221,7 +221,9 @@ jar { attributes 'JAR-Type': 'Fat JAR' } - processResources.exclude("*") + processResources.exclude("classes/**") + processResources.exclude("projects/**") + processResources.exclude("evosuite/**") version '1.0' 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 fdff1331bc..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,7 @@ 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.* @@ -109,7 +110,7 @@ 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.parentFile + val tmpDir = outputDir.resolveSibling("data") val cpEntries = classpathString.split(File.pathSeparator).map { File(it) } val classLoader = URLClassLoader(cpEntries.map { it.toUrl() }.toTypedArray()) @@ -173,7 +174,9 @@ fun main(args: Array) { println("${ContestMessage.READY}") } } -// ConcreteExecutor.defaultPool.close() + + ConcreteExecutor.defaultPool.close() + JcContainer.close() } fun setOptions() { From 5e18ef4cb047063974a857c09ff259081ec4b4ff Mon Sep 17 00:00:00 2001 From: Valentyn Sobol Date: Thu, 30 Nov 2023 11:56:58 +0300 Subject: [PATCH 3/4] Minor fixes --- utbot-junit-contest/build.gradle | 74 ++++++++++--------- .../org/utbot/contest/usvm/ContestUsvm.kt | 2 +- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/utbot-junit-contest/build.gradle b/utbot-junit-contest/build.gradle index 336bfecd6a..6b473ef491 100644 --- a/utbot-junit-contest/build.gradle +++ b/utbot-junit-contest/build.gradle @@ -309,48 +309,50 @@ task run(type: JavaExec) { tasks.register("generateRuntool") { dependsOn(jar, usvmInstrumentationRunnerJar) - 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" } - } + doLast { + def distDir = buildDir.toPath().resolve("utbot-usvm-runtool").toFile() + copy { + from jar.outputs + into distDir + rename { "utbot-usvm-tool.jar" } + } - copy { - from configurations.approximations.resolvedConfiguration.files.find() - into distDir - rename { "usvm-approximations.jar" } - } + copy { + from configurations.usvmApproximationsApi.resolvedConfiguration.files.find() + into distDir + rename { "usvm-api.jar" } + } - copy { - from configurations.usvmInstrumentationCollector.resolvedConfiguration.files.find() - into distDir - rename { "usvm-jvm-collectors.jar" } - } + copy { + from configurations.approximations.resolvedConfiguration.files.find() + into distDir + rename { "usvm-approximations.jar" } + } - copy { - from usvmInstrumentationRunnerJar.outputs - into distDir - rename { "usvm-jvm-instrumentation.jar" } - } + copy { + from configurations.usvmInstrumentationCollector.resolvedConfiguration.files.find() + into distDir + rename { "usvm-jvm-collectors.jar" } + } - copy { - from projectDir.toPath().resolve("usvm-runtool") - into distDir - rename { "runtool" } - } + copy { + from usvmInstrumentationRunnerJar.outputs + into distDir + rename { "usvm-jvm-instrumentation.jar" } + } - def libsDir = distDir.toPath().resolve("lib").toFile() - configurations.generatedTestCompile.resolvedConfiguration.files.forEach {f -> copy { - from f - into libsDir + 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/usvm/ContestUsvm.kt b/utbot-junit-contest/src/main/kotlin/org/utbot/contest/usvm/ContestUsvm.kt index b17959d436..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 @@ -96,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 From f1603ec98397976cd67cf552970cfc6cde5463ed Mon Sep 17 00:00:00 2001 From: Valentyn Sobol Date: Thu, 30 Nov 2023 13:34:28 +0300 Subject: [PATCH 4/4] Mark as executable --- utbot-junit-contest/usvm-runtool | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 utbot-junit-contest/usvm-runtool diff --git a/utbot-junit-contest/usvm-runtool b/utbot-junit-contest/usvm-runtool old mode 100644 new mode 100755