diff --git a/settings.gradle.kts b/settings.gradle.kts index d901f2e15e..7e15d4d126 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -89,3 +89,5 @@ if (projectType == springEdition || projectType == ultimateEdition) { +include("utbot-light") + diff --git a/utbot-analytics/src/main/kotlin/org/utbot/features/UtExpressionStructureCounter.kt b/utbot-analytics/src/main/kotlin/org/utbot/features/UtExpressionStructureCounter.kt index f66c6377fd..b1c5661919 100644 --- a/utbot-analytics/src/main/kotlin/org/utbot/features/UtExpressionStructureCounter.kt +++ b/utbot-analytics/src/main/kotlin/org/utbot/features/UtExpressionStructureCounter.kt @@ -145,6 +145,7 @@ class UtExpressionStructureCounter(private val input: Iterable) : override fun visit(expr: UtAddNoOverflowExpression) = multipleExpressions(expr.left, expr.right) override fun visit(expr: UtSubNoOverflowExpression) = multipleExpressions(expr.left, expr.right) + override fun visit(expr: UtMulNoOverflowExpression)= multipleExpressions(expr.left, expr.right) override fun visit(expr: UtNegExpression): NestStat { val stat = buildState(expr.variable.expr) diff --git a/utbot-api/build.gradle.kts b/utbot-api/build.gradle.kts index 5f02cd7356..e69de29bb2 100644 --- a/utbot-api/build.gradle.kts +++ b/utbot-api/build.gradle.kts @@ -1,12 +0,0 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -plugins { - id("com.github.johnrengelman.shadow") version "7.1.2" -} - -tasks { - withType { - archiveClassifier.set(" ") - minimize() - } -} \ No newline at end of file diff --git a/utbot-core/build.gradle.kts b/utbot-core/build.gradle.kts index 7f957695f4..faada50cce 100644 --- a/utbot-core/build.gradle.kts +++ b/utbot-core/build.gradle.kts @@ -1,5 +1,3 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - val kotlinLoggingVersion: String by rootProject val junit4Version: String by rootProject @@ -12,11 +10,4 @@ dependencies { implementation(group = "net.java.dev.jna", name = "jna-platform", version = "5.5.0") testImplementation(group = "junit", name = "junit", version = junit4Version) -} - -tasks { - withType { - archiveClassifier.set(" ") - minimize() - } } \ No newline at end of file diff --git a/utbot-framework-api/build.gradle.kts b/utbot-framework-api/build.gradle.kts index a1ab2c502a..f94f8a1b7f 100644 --- a/utbot-framework-api/build.gradle.kts +++ b/utbot-framework-api/build.gradle.kts @@ -1,5 +1,3 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - val junit4Version: String by rootProject val sootVersion: String by rootProject val commonsLangVersion: String by rootProject @@ -8,10 +6,6 @@ val rdVersion: String? by rootProject val kryoVersion: String? by rootProject val kryoSerializersVersion: String? by rootProject -plugins { - id("com.github.johnrengelman.shadow") version "7.1.2" -} - dependencies { api(project(":utbot-core")) api(project(":utbot-api")) @@ -30,11 +24,8 @@ dependencies { testImplementation(group = "junit", name = "junit", version = junit4Version) } -tasks { - withType { - archiveClassifier.set(" ") - minimize() - } +java { + withSourcesJar() } tasks { diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt index ea7353a2b0..a41696da54 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt @@ -576,6 +576,13 @@ object UtSettings : AbstractSettings(logger, defaultKeyForSettingsPath, defaultS var maxArraySize by getIntProperty(1024) // endregion + + // region UTBot light related options + // Changes to improve symbolic engine for light version + + var disableUnsatChecking by getBooleanProperty(false) + + // endregion } /** @@ -592,6 +599,11 @@ enum class PathSelectorType { */ INHERITORS_SELECTOR, + /** + * [BFSSelector] + */ + BFS_SELECTOR, + /** * [SubpathGuidedSelector] */ diff --git a/utbot-framework-test/src/main/java/org/utbot/examples/manual/examples/Trivial.java b/utbot-framework-test/src/main/java/org/utbot/examples/manual/examples/Trivial.java index 7bc2779d50..d5aa823325 100644 --- a/utbot-framework-test/src/main/java/org/utbot/examples/manual/examples/Trivial.java +++ b/utbot-framework-test/src/main/java/org/utbot/examples/manual/examples/Trivial.java @@ -2,6 +2,10 @@ public class Trivial { public int aMethod(int a) { - return a; + String s = "a"; + if (a > 1) { + return s.length(); + } + return s.length() + 1; } } diff --git a/utbot-framework-test/src/test/java/org/utbot/examples/manual/UtBotJavaApiTest.java b/utbot-framework-test/src/test/java/org/utbot/examples/manual/UtBotJavaApiTest.java index 71498407e1..c11ce197f0 100644 --- a/utbot-framework-test/src/test/java/org/utbot/examples/manual/UtBotJavaApiTest.java +++ b/utbot-framework-test/src/test/java/org/utbot/examples/manual/UtBotJavaApiTest.java @@ -18,6 +18,7 @@ import org.utbot.examples.manual.examples.customer.C; import org.utbot.examples.manual.examples.customer.Demo9; import org.utbot.external.api.TestMethodInfo; +import org.utbot.external.api.UnitTestBotLight; import org.utbot.external.api.UtBotJavaApi; import org.utbot.external.api.UtModelFactory; import org.utbot.framework.codegen.domain.ForceStaticMocking; @@ -1306,7 +1307,16 @@ public void testFuzzingSimple() { @NotNull private String getClassPath(Class clazz) { - return clazz.getProtectionDomain().getCodeSource().getLocation().getPath(); + try { + return normalizePath(clazz.getProtectionDomain().getCodeSource().getLocation()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @NotNull + private String normalizePath(URL url) throws URISyntaxException { + return new File(url.toURI()).getPath(); } @NotNull @@ -1376,4 +1386,37 @@ public UtCompositeModel createArrayOfComplexArraysModel() { classIdOfArrayOfComplexArraysClass, Collections.singletonMap("array", arrayOfComplexArrayClasses)); } + + @Test + public void testUnitTestBotLight() { + String classpath = getClassPath(Trivial.class); + String dependencyClassPath = getDependencyClassPath(); + + UtCompositeModel model = modelFactory. + produceCompositeModel( + classIdForType(Trivial.class) + ); + + EnvironmentModels environmentModels = new EnvironmentModels( + model, + Collections.singletonList(new UtPrimitiveModel(2)), + Collections.emptyMap() + ); + + Method methodUnderTest = PredefinedGeneratorParameters.getMethodByName( + Trivial.class, + "aMethod", + int.class + ); + + UnitTestBotLight.run( + (engine, state) -> System.err.println("Got a call:" + state.getStmt()), + new TestMethodInfo( + methodUnderTest, + environmentModels + ), + classpath, + dependencyClassPath + ); + } } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionStateListener.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionStateListener.kt new file mode 100644 index 0000000000..9b92984a1b --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionStateListener.kt @@ -0,0 +1,10 @@ +package org.utbot.engine + +import org.utbot.engine.state.ExecutionState + +/** + * [UtBotSymbolicEngine] will fire an event every time it traverses new [ExecutionState]. + */ +fun interface ExecutionStateListener { + fun visit(graph: InterProceduralUnitGraph, state: ExecutionState) +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt index 38c7e71d65..75e319a943 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt @@ -4060,12 +4060,14 @@ class Traverser( val memory = symbolicState.memory val solver = symbolicState.solver - //no need to respect soft constraints in NestedMethod - val holder = solver.check(respectSoft = !environment.state.isInNestedMethod()) + if (!UtSettings.disableUnsatChecking) { + //no need to respect soft constraints in NestedMethod + val holder = solver.check(respectSoft = !environment.state.isInNestedMethod()) - if (holder !is UtSolverStatusSAT) { - logger.trace { "processResult<${environment.method.signature}> UNSAT" } - return + if (holder !is UtSolverStatusSAT) { + logger.trace { "processResult<${environment.method.signature}> UNSAT" } + return + } } val methodResult = MethodResult(symbolicResult) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt index 46d16f234d..5e88f312c6 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt @@ -48,11 +48,14 @@ import org.utbot.instrumentation.ConcreteExecutor import org.utbot.instrumentation.instrumentation.Instrumentation import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult +import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation import org.utbot.taint.* import org.utbot.taint.model.TaintConfiguration import soot.jimple.Stmt import soot.tagkit.ParamNamesTag import java.lang.reflect.Method +import java.util.function.Consumer +import java.util.function.Predicate import kotlin.math.min import kotlin.system.measureTimeMillis @@ -80,6 +83,9 @@ private fun pathSelector(graph: InterProceduralUnitGraph, typeRegistry: TypeRegi PathSelectorType.INHERITORS_SELECTOR -> inheritorsSelector(graph, typeRegistry) { withStepsLimit(pathSelectorStepsLimit) } + PathSelectorType.BFS_SELECTOR -> bfsSelector(graph, StrategyOption.VISIT_COUNTING) { + withStepsLimit(pathSelectorStepsLimit) + } PathSelectorType.SUBPATH_GUIDED_SELECTOR -> subpathGuidedSelector(graph, StrategyOption.DISTANCE) { withStepsLimit(pathSelectorStepsLimit) } @@ -141,6 +147,18 @@ class UtBotSymbolicEngine( mockerContext = applicationContext.mockerContext, ) + private val stateListeners: MutableList = mutableListOf(); + + fun addListener(listener: ExecutionStateListener): UtBotSymbolicEngine { + stateListeners += listener + return this + } + + fun removeListener(listener: ExecutionStateListener): UtBotSymbolicEngine { + stateListeners -= listener + return this + } + fun attachMockListener(mockListener: MockListener) = mocker.mockListenerController?.attach(mockListener) fun detachMockListener(mockListener: MockListener) = mocker.mockListenerController?.detach(mockListener) @@ -216,6 +234,22 @@ class UtBotSymbolicEngine( .onStart { preTraverse() } .onCompletion { postTraverse() } + /** + * Traverse through all states and get results. + * + * This method is supposed to used when calling [traverse] is not suitable, + * e.g. from Java programs. It runs traversing with blocking style using callback + * to provide [UtResult]. + */ + @JvmOverloads + fun traverseAll(consumer: Consumer = Consumer { }) { + runBlocking { + traverse().collect { + consumer.accept(it) + } + } + } + private fun traverseImpl(): Flow = flow { require(trackableResources.isEmpty()) @@ -252,7 +286,7 @@ class UtBotSymbolicEngine( "queue size=${(pathSelector as? NonUniformRandomSearch)?.size ?: -1}" } - if (controller.executeConcretely || statesForConcreteExecution.isNotEmpty()) { + if (UtSettings.useConcreteExecution && (controller.executeConcretely || statesForConcreteExecution.isNotEmpty())) { val state = pathSelector.pollUntilFastSAT() ?: statesForConcreteExecution.pollUntilSat(processUnknownStatesDuringConcreteExecution) ?: break @@ -316,6 +350,14 @@ class UtBotSymbolicEngine( } } + // I am not sure this part works correctly when concrete execution is enabled. + // todo test this part more accurate + try { + fireExecutionStateEvent(state) + } catch (ce: CancellationException) { + break + } + } else { val state = pathSelector.poll() @@ -360,11 +402,27 @@ class UtBotSymbolicEngine( // TODO: think about concise modifying globalGraph in Traverser and UtBotSymbolicEngine globalGraph.visitNode(state) + + try { + fireExecutionStateEvent(state) + } catch (ce: CancellationException) { + break + } } } } } + private fun fireExecutionStateEvent(state: ExecutionState) { + stateListeners.forEach { l -> + try { + l.visit(globalGraph, state) + } catch (t: Throwable) { + logger.error(t) { "$l failed with error" } + } + } + } + /** * Run fuzzing flow. @@ -516,7 +574,11 @@ class UtBotSymbolicEngine( val solver = state.solver val parameters = state.parameters.map { it.value } val symbolicResult = requireNotNull(state.methodResult?.symbolicResult) { "The state must have symbolicResult" } - val holder = requireNotNull(solver.lastStatus as? UtSolverStatusSAT) { "The state must be SAT!" } + val holder = if (UtSettings.disableUnsatChecking) { + (solver.lastStatus as? UtSolverStatusSAT) ?: return + } else { + requireNotNull(solver.lastStatus as? UtSolverStatusSAT) { "The state must be SAT!" } + } val predictedTestName = Predictors.testName.predict(state.path) Predictors.testName.provide(state.path, predictedTestName, "") diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Simplificator.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Simplificator.kt index 5d0d217101..08845205aa 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Simplificator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Simplificator.kt @@ -607,6 +607,12 @@ open class Simplificator( applySimplification(expr.right) ) + override fun visit(expr: UtMulNoOverflowExpression): UtExpression = + UtMulNoOverflowExpression( + applySimplification(expr.left), + applySimplification(expr.right) + ) + // CONFLUENCE:UtBot+Expression+Optimizations#UtBotExpressionOptimizations-negConcrete // Neg (Concrete a) ---> Concrete (-a) override fun visit(expr: UtNegExpression): UtExpression = diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpression.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpression.kt index 2ee9cbdad4..ebd6bcdec5 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpression.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpression.kt @@ -805,6 +805,31 @@ data class UtSubNoOverflowExpression( override fun hashCode() = hashCode } +data class UtMulNoOverflowExpression( + val left: UtExpression, + val right: UtExpression, +) : UtBoolExpression() { + override val hashCode = Objects.hash(left, right) + + override fun accept(visitor: UtExpressionVisitor): TResult = visitor.visit(this) + + override fun toString() = "(mulNoOverflow $left $right)" + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as UtMulNoOverflowExpression + + if (left != other.left) return false + if (right != other.right) return false + + return true + } + + override fun hashCode() = hashCode +} + data class UtNegExpression(val variable: PrimitiveValue) : UtExpression(alignSort(variable.type.toSort())) { override val hashCode = variable.hashCode diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpressionVisitor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpressionVisitor.kt index fac9f9b6f8..4f22095860 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpressionVisitor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtExpressionVisitor.kt @@ -42,4 +42,5 @@ interface UtExpressionVisitor { // Add and Sub with overflow detection fun visit(expr: UtAddNoOverflowExpression): TResult fun visit(expr: UtSubNoOverflowExpression): TResult + fun visit(expr: UtMulNoOverflowExpression): TResult } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3EvaluatorVisitor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3EvaluatorVisitor.kt index 256f219ca5..5ac6df2e16 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3EvaluatorVisitor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3EvaluatorVisitor.kt @@ -210,6 +210,12 @@ class Z3EvaluatorVisitor(private val model: Model, private val translator: Z3Tra } } + override fun visit(expr: UtMulNoOverflowExpression): Expr<*> = expr.run { + translator.withContext { + mkBVMulNoOverflow(eval(expr.left) as BitVecExpr, eval(expr.right) as BitVecExpr , true) + } + } + override fun visit(expr: UtNegExpression): Expr<*> = expr.run { translator.withContext { negate(this, eval(variable.expr).z3Variable(variable.type)) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3TranslatorVisitor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3TranslatorVisitor.kt index 7e238642e4..638ebb1419 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3TranslatorVisitor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/pc/Z3TranslatorVisitor.kt @@ -113,6 +113,10 @@ open class Z3TranslatorVisitor( z3Context.mkBVSubNoOverflow(translate(expr.left) as BitVecExpr, translate(expr.right) as BitVecExpr) // , true) } + override fun visit(expr: UtMulNoOverflowExpression): Expr<*> = expr.run { + z3Context.mkBVMulNoOverflow(translate(expr.left) as BitVecExpr, translate(expr.right) as BitVecExpr , true) + } + override fun visit(expr: UtNegExpression): Expr<*> = expr.run { negate(z3Context, translate(variable.expr).z3Variable(variable.type)) } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/selectors/BasePathSelector.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/selectors/BasePathSelector.kt index 2f7c680f5d..945d903945 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/selectors/BasePathSelector.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/selectors/BasePathSelector.kt @@ -80,7 +80,7 @@ abstract class BasePathSelector( pathLogger.trace { "poll next state (lastStatus=${state.solver.lastStatus}): " + state.prettifiedPathLog() } current = null - if (choosingStrategy.shouldDrop(state) || checkUnsatIfFork(state)) { + if (choosingStrategy.shouldDrop(state) || (!UtSettings.disableUnsatChecking && checkUnsatIfFork(state))) { state.close() continue } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/z3/Z3initializer.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/z3/Z3initializer.kt index b1aa21d7d4..3c6436b5b8 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/z3/Z3initializer.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/z3/Z3initializer.kt @@ -6,7 +6,7 @@ import org.utbot.common.FileUtil import java.io.File abstract class Z3Initializer : AutoCloseable { - protected val context: Context by lazy { + private val contextDelegate = lazy { Context().also { // Global.setParameter("smt.core.minimize", "true") Global.setParameter("rewriter.hi_fp_unspecified", "true") @@ -14,8 +14,13 @@ abstract class Z3Initializer : AutoCloseable { Global.setParameter("parallel.threads.max", "4") } } + protected val context: Context by contextDelegate - override fun close() = context.close() + override fun close() { + if (contextDelegate.isInitialized()) { + context.close() + } + } companion object { private val libraries = listOf("libz3", "libz3java") diff --git a/utbot-framework/src/main/kotlin/org/utbot/external/api/UnitTestBotLight.kt b/utbot-framework/src/main/kotlin/org/utbot/external/api/UnitTestBotLight.kt new file mode 100644 index 0000000000..4faeef7027 --- /dev/null +++ b/utbot-framework/src/main/kotlin/org/utbot/external/api/UnitTestBotLight.kt @@ -0,0 +1,92 @@ +package org.utbot.external.api + +import org.utbot.engine.EngineController +import org.utbot.engine.ExecutionStateListener +import org.utbot.engine.MockStrategy +import org.utbot.engine.UtBotSymbolicEngine +import org.utbot.framework.UtSettings +import org.utbot.framework.context.ApplicationContext +import org.utbot.framework.context.simple.SimpleApplicationContext +import org.utbot.framework.context.simple.SimpleConcreteExecutionContext +import org.utbot.framework.context.simple.SimpleMockerContext +import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.ExecutableId +import org.utbot.framework.plugin.api.MockStrategyApi +import org.utbot.framework.plugin.api.util.UtContext +import org.utbot.framework.plugin.api.util.executableId +import org.utbot.framework.plugin.api.util.withUtContext +import org.utbot.framework.plugin.services.JdkInfoDefaultProvider +import org.utbot.framework.util.SootUtils.runSoot +import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation +import java.io.File +import java.nio.file.Paths + + +@Suppress("unused") +object UnitTestBotLight { + + /** + * Creates an instance of symbolic engine with default values + * w/o specific objects like + * - [ApplicationContext] + * - [UtExecutionInstrumentation] + * - [EngineController] + * - etc. + * + * @return symbolic engine instance + */ + @JvmStatic + fun javaUtBotSymbolicEngine( + methodUnderTest: ExecutableId, + classpath: String, + mockStrategy: MockStrategy, + chosenClassesToMockAlways: Set, + ) = UtBotSymbolicEngine( + controller = EngineController(), + methodUnderTest = methodUnderTest, + classpath = classpath, + dependencyPaths = "", + mockStrategy = mockStrategy, + chosenClassesToMockAlways = chosenClassesToMockAlways, + applicationContext = SimpleApplicationContext(SimpleMockerContext( + mockFrameworkInstalled = true, + staticsMockingIsConfigured = true + )), + concreteExecutionContext = SimpleConcreteExecutionContext(classpath), + solverTimeoutInMillis = UtSettings.checkSolverTimeoutMillis + ) + + @JvmStatic + @JvmOverloads + fun run ( + stateListener: ExecutionStateListener, + methodForAutomaticGeneration: TestMethodInfo, + classpath: String, + dependencyClassPath: String, + mockStrategyApi: MockStrategyApi = MockStrategyApi.OTHER_PACKAGES, + ) { + // init Soot if it is not yet + runSoot(classpath.split(File.pathSeparator).map(Paths::get), classpath, false, JdkInfoDefaultProvider().info) + val classLoader = Thread.currentThread().contextClassLoader + val utContext = UtContext(classLoader) + withUtContext(utContext) { + UtBotSymbolicEngine( + EngineController(), + methodForAutomaticGeneration.methodToBeTestedFromUserInput.executableId, + classpath, + dependencyClassPath, + when (mockStrategyApi) { + MockStrategyApi.NO_MOCKS -> MockStrategy.NO_MOCKS + MockStrategyApi.OTHER_PACKAGES -> MockStrategy.OTHER_PACKAGES + MockStrategyApi.OTHER_CLASSES -> MockStrategy.OTHER_CLASSES + }, + HashSet(), + SimpleApplicationContext(SimpleMockerContext( + mockFrameworkInstalled = true, + staticsMockingIsConfigured = true + )), + SimpleConcreteExecutionContext(classpath) + ).addListener(stateListener).traverseAll() + } + } +} \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/util/SootUtils.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/util/SootUtils.kt index 00faf10a55..9cb09c0ddf 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/util/SootUtils.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/util/SootUtils.kt @@ -16,6 +16,7 @@ import soot.options.Options import soot.toolkits.graph.ExceptionalUnitGraph import java.io.File import java.nio.file.Path +import java.util.function.Consumer object SootUtils { /** @@ -53,6 +54,11 @@ object SootUtils { private var previousClassPath: String? = null } +/** + * This option is only needed to fast changing from other tools. + */ +var sootOptionConfiguration: Consumer = Consumer { _ -> } + /** * Convert code to Jimple */ @@ -67,6 +73,7 @@ private fun initSoot(buildDirs: List, classpath: String?, jdkInfo: JdkInfo // set true to debug. Disabled because of a bug when two different variables // from the source code have the same name in the jimple body. setPhaseOption("jb", "use-original-names:false") + sootOptionConfiguration.accept(this) set_soot_classpath( FileUtil.isolateClassFiles(*classesToLoad).absolutePath + if (!classpath.isNullOrEmpty()) File.pathSeparator + "$classpath" else "" diff --git a/utbot-java-fuzzing/build.gradle.kts b/utbot-java-fuzzing/build.gradle.kts index 8486cf8279..0b4b121ac6 100644 --- a/utbot-java-fuzzing/build.gradle.kts +++ b/utbot-java-fuzzing/build.gradle.kts @@ -1,20 +1,7 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - val sootVersion: String by rootProject val kotlinLoggingVersion: String by rootProject val rgxgenVersion: String by rootProject -plugins { - id("com.github.johnrengelman.shadow") version "7.1.2" -} - -tasks { - withType { - archiveClassifier.set(" ") - minimize() - } -} - dependencies { implementation(project(":utbot-framework-api")) api(project(":utbot-fuzzing")) @@ -24,10 +11,4 @@ dependencies { } implementation(group = "io.github.microutils", name = "kotlin-logging", version = kotlinLoggingVersion) implementation(group = "com.github.curious-odd-man", name = "rgxgen", version = rgxgenVersion) -} - -tasks { - compileJava { - options.compilerArgs = emptyList() - } } \ No newline at end of file diff --git a/utbot-light/build.gradle b/utbot-light/build.gradle new file mode 100644 index 0000000000..daef2295aa --- /dev/null +++ b/utbot-light/build.gradle @@ -0,0 +1,16 @@ +dependencies { + implementation(project(":utbot-framework")) +} + +jar { + dependsOn classes + dependsOn configurations.runtimeClasspath + archiveClassifier.set('') + from { + sourceSets.main.output + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + zip64 = true + // to minimize artifact size some binaries can be excluded from target zip + // exclude 'lib/utbot-*.jar' +} \ No newline at end of file