Skip to content

Remove old fuzzer dependencies from JavaScript module #1900

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
merged 9 commits into from
Mar 9, 2023
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
18 changes: 9 additions & 9 deletions utbot-js/src/main/kotlin/api/JsTestGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import codegen.JsCodeGenerator
import com.google.javascript.rhino.Node
import framework.api.js.JsClassId
import framework.api.js.JsMethodId
import framework.api.js.JsUtFuzzedExecution
import framework.api.js.util.isJsBasic
import framework.api.js.util.jsErrorClassId
import framework.api.js.util.jsUndefinedClassId
Expand All @@ -26,9 +27,8 @@ import org.utbot.framework.plugin.api.UtExecution
import org.utbot.framework.plugin.api.UtExecutionResult
import org.utbot.framework.plugin.api.UtExecutionSuccess
import org.utbot.framework.plugin.api.UtExplicitlyThrownException
import org.utbot.framework.plugin.api.UtModel
import org.utbot.framework.plugin.api.UtTimeoutException
import org.utbot.fuzzer.FuzzedValue
import org.utbot.fuzzer.UtFuzzedExecution
import org.utbot.fuzzing.Control
import org.utbot.fuzzing.utils.Trie
import parser.JsClassAstVisitor
Expand Down Expand Up @@ -187,7 +187,7 @@ class JsTestGenerator(
private fun getUtModelResult(
execId: JsMethodId,
resultData: ResultData,
fuzzedValues: List<FuzzedValue>
fuzzedValues: List<UtModel>
): UtExecutionResult {
if (resultData.isError && resultData.rawString == "Timeout") return UtTimeoutException(
TimeoutException(" Timeout in generating test for ${
Expand All @@ -197,7 +197,7 @@ class JsTestGenerator(
prefix = "${execId.name}(",
separator = ", ",
postfix = ")"
) { (_, value) -> value.model.toString() }
) { (_, value) -> value.toString() }
}")
)
val (returnValue, valueClassId) = resultData.toJsAny(
Expand All @@ -221,11 +221,11 @@ class JsTestGenerator(
val jsDescription = JsMethodDescription(
name = funcNode.getAbstractFunctionName(),
parameters = execId.parameters,
execId.classId,
classId = execId.classId,
concreteValues = fuzzerVisitor.fuzzedConcreteValues,
tracer = Trie(JsStatement::number)
)
val collectedValues = mutableListOf<List<FuzzedValue>>()
val collectedValues = mutableListOf<List<UtModel>>()
// .location field gets us "jsFile:A:B", then we get A and B as ints
val funcLocation = funcNode.firstChild!!.location.substringAfter("jsFile:")
.split(":").map { it.toInt() }
Expand Down Expand Up @@ -265,13 +265,13 @@ class JsTestGenerator(
return@runFuzzing JsFeedback(Control.PASS)
} else if (!currentlyCoveredStmts.containsAll(covData.additionalCoverage)) {
val (thisObject, modelList) = if (!funcNode.parent!!.isClassMembers) {
null to params.map { it.model }
} else params[0].model to params.drop(1).map { it.model }
null to params
} else params[0] to params.drop(1)
val initEnv =
EnvironmentModels(thisObject, modelList, mapOf())
emit(
JsValidExecution(
UtFuzzedExecution(
JsUtFuzzedExecution(
stateBefore = initEnv,
stateAfter = initEnv,
result = result,
Expand Down
6 changes: 2 additions & 4 deletions utbot-js/src/main/kotlin/api/JsUtModelConstructor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ import framework.api.js.JsPrimitiveModel
import framework.api.js.JsUndefinedModel
import framework.api.js.util.jsErrorClassId
import framework.api.js.util.jsUndefinedClassId
import fuzzer.JsIdProvider
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.UtAssembleModel
import org.utbot.framework.plugin.api.UtExecutableCallModel
import org.utbot.framework.plugin.api.UtModel
import org.utbot.fuzzer.ReferencePreservingIntIdGenerator
import org.utbot.instrumentation.instrumentation.execution.constructors.UtModelConstructorInterface

class JsUtModelConstructor : UtModelConstructorInterface {

private val idGenerator = ReferencePreservingIntIdGenerator()

// TODO SEVERE: Requires substantial expansion to other types
@Suppress("NAME_SHADOWING")
override fun construct(value: Any?, classId: ClassId): UtModel {
Expand Down Expand Up @@ -52,7 +50,7 @@ class JsUtModelConstructor : UtModelConstructorInterface {
val values = (value as Map<String, Any>).values.map {
construct(it, JsEmptyClassId())
}
val id = idGenerator.createId()
val id = JsIdProvider.createId()
val instantiationCall = UtExecutableCallModel(null, constructor, values)
return UtAssembleModel(
id = id,
Expand Down
6 changes: 1 addition & 5 deletions utbot-js/src/main/kotlin/framework/api/js/JsApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,7 @@ class JsConstructorId(
get() = 0
}

class JsMultipleClassId(private val jsJoinedName: String) : JsClassId(jsJoinedName) {

val types: Sequence<JsClassId>
get() = jsJoinedName.split('|').map { JsClassId(it) }.asSequence()
}
class JsMultipleClassId(jsJoinedName: String) : JsClassId(jsJoinedName)

open class JsUtModel(
override val classId: JsClassId
Expand Down
11 changes: 11 additions & 0 deletions utbot-js/src/main/kotlin/framework/api/js/JsUtFuzzedExecution.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package framework.api.js

import org.utbot.framework.plugin.api.EnvironmentModels
import org.utbot.framework.plugin.api.UtExecution
import org.utbot.framework.plugin.api.UtExecutionResult

class JsUtFuzzedExecution(
stateBefore: EnvironmentModels,
stateAfter: EnvironmentModels,
result: UtExecutionResult
) : UtExecution(stateBefore, stateAfter, result, null, null, null, null)
57 changes: 40 additions & 17 deletions utbot-js/src/main/kotlin/fuzzer/JsFuzzerApi.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
package fuzzer

import framework.api.js.JsClassId
import framework.api.js.JsUtFuzzedExecution
import framework.api.js.util.isClass
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.UtModel
import org.utbot.framework.plugin.api.UtTimeoutException
import org.utbot.fuzzer.FuzzedConcreteValue
import org.utbot.fuzzer.FuzzedValue
import org.utbot.fuzzer.UtFuzzedExecution
import org.utbot.fuzzing.Control
import org.utbot.fuzzing.Description
import org.utbot.fuzzing.Feedback
import org.utbot.fuzzing.utils.Trie
import java.util.concurrent.atomic.AtomicInteger

sealed interface JsFuzzingExecutionFeedback
class JsValidExecution(val utFuzzedExecution: UtFuzzedExecution) : JsFuzzingExecutionFeedback
class JsValidExecution(val utFuzzedExecution: JsUtFuzzedExecution) : JsFuzzingExecutionFeedback

class JsTimeoutExecution(val utTimeout: UtTimeoutException) : JsFuzzingExecutionFeedback

class JsMethodDescription(
val name: String,
parameters: List<JsClassId>,
val concreteValues: Collection<FuzzedConcreteValue>,
val concreteValues: Collection<JsFuzzedConcreteValue>,
val thisInstance: JsClassId? = null,
val tracer: Trie<JsStatement, *>
) : Description<JsClassId>(parameters) {
Expand All @@ -28,7 +29,7 @@ class JsMethodDescription(
name: String,
parameters: List<JsClassId>,
classId: JsClassId,
concreteValues: Collection<FuzzedConcreteValue>,
concreteValues: Collection<JsFuzzedConcreteValue>,
tracer: Trie<JsStatement, *>
) : this(
name,
Expand All @@ -39,21 +40,43 @@ class JsMethodDescription(
)
}

class JsFeedback(
data class JsFeedback(
override val control: Control = Control.CONTINUE,
val result: Trie.Node<JsStatement> = Trie.emptyNode()
) : Feedback<JsClassId, FuzzedValue> {
) : Feedback<JsClassId, UtModel>

override fun equals(other: Any?): Boolean {
val castOther = other as? JsFeedback
return control == castOther?.control
}
data class JsStatement(
val number: Int
)

data class JsFuzzedConcreteValue(
val classId: ClassId,
val value: Any,
val fuzzedContext: JsFuzzedContext = JsFuzzedContext.Unknown,
)

override fun hashCode(): Int {
return control.hashCode()
enum class JsFuzzedContext {
EQ,
NE,
GT,
GE,
LT,
LE,
Unknown;

fun reverse(): JsFuzzedContext = when (this) {
EQ -> NE
NE -> EQ
GT -> LE
LT -> GE
LE -> GT
GE -> LT
Unknown -> Unknown
}
}

data class JsStatement(
val number: Int
)
object JsIdProvider {
private var id = AtomicInteger(0)

fun createId() = id.incrementAndGet()
}
12 changes: 6 additions & 6 deletions utbot-js/src/main/kotlin/fuzzer/JsFuzzing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fuzzer.providers.BoolValueProvider
import fuzzer.providers.NumberValueProvider
import fuzzer.providers.ObjectValueProvider
import fuzzer.providers.StringValueProvider
import org.utbot.fuzzer.FuzzedValue
import org.utbot.framework.plugin.api.UtModel
import org.utbot.fuzzing.Fuzzing
import org.utbot.fuzzing.Seed
import org.utbot.fuzzing.fuzz
Expand All @@ -18,10 +18,10 @@ fun defaultValueProviders() = listOf(
)

class JsFuzzing(
val exec: suspend (JsMethodDescription, List<FuzzedValue>) -> JsFeedback
) : Fuzzing<JsClassId, FuzzedValue, JsMethodDescription, JsFeedback> {
val exec: suspend (JsMethodDescription, List<UtModel>) -> JsFeedback
) : Fuzzing<JsClassId, UtModel, JsMethodDescription, JsFeedback> {

override fun generate(description: JsMethodDescription, type: JsClassId): Sequence<Seed<JsClassId, FuzzedValue>> {
override fun generate(description: JsMethodDescription, type: JsClassId): Sequence<Seed<JsClassId, UtModel>> {
return defaultValueProviders().asSequence().flatMap { provider ->
if (provider.accept(type)) {
provider.generate(description, type)
Expand All @@ -31,12 +31,12 @@ class JsFuzzing(
}
}

override suspend fun handle(description: JsMethodDescription, values: List<FuzzedValue>): JsFeedback {
override suspend fun handle(description: JsMethodDescription, values: List<UtModel>): JsFeedback {
return exec(description, values)
}
}

suspend fun runFuzzing(
description: JsMethodDescription,
exec: suspend (JsMethodDescription, List<FuzzedValue>) -> JsFeedback
exec: suspend (JsMethodDescription, List<UtModel>) -> JsFeedback
) = JsFuzzing(exec).fuzz(description)
16 changes: 6 additions & 10 deletions utbot-js/src/main/kotlin/fuzzer/providers/BoolValueProvider.kt
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
package fuzzer.providers


import framework.api.js.JsClassId
import framework.api.js.JsPrimitiveModel
import framework.api.js.util.isJsBasic
import fuzzer.JsMethodDescription
import org.utbot.fuzzer.FuzzedValue
import org.utbot.fuzzer.providers.PrimitivesModelProvider.fuzzed
import org.utbot.framework.plugin.api.UtModel
import org.utbot.fuzzing.Seed
import org.utbot.fuzzing.ValueProvider
import org.utbot.fuzzing.seeds.Bool

object BoolValueProvider : ValueProvider<JsClassId, FuzzedValue, JsMethodDescription> {
object BoolValueProvider : ValueProvider<JsClassId, UtModel, JsMethodDescription> {

override fun accept(type: JsClassId): Boolean {
return type.isJsBasic
}

override fun generate(description: JsMethodDescription, type: JsClassId): Sequence<Seed<JsClassId, FuzzedValue>> =
override fun generate(description: JsMethodDescription, type: JsClassId): Sequence<Seed<JsClassId, UtModel>> =
sequence {
yield(Seed.Known(Bool.TRUE()) {
JsPrimitiveModel(true).fuzzed {
summary = "%var% = true"
}
JsPrimitiveModel(true)
})
yield(Seed.Known(Bool.FALSE()) {
JsPrimitiveModel(false).fuzzed {
summary = "%var% = false"
}
JsPrimitiveModel(false)
})
}
}
25 changes: 10 additions & 15 deletions utbot-js/src/main/kotlin/fuzzer/providers/NumberValueProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,25 @@ package fuzzer.providers
import framework.api.js.JsClassId
import framework.api.js.JsPrimitiveModel
import framework.api.js.util.isJsBasic
import fuzzer.JsFuzzedContext.EQ
import fuzzer.JsFuzzedContext.GE
import fuzzer.JsFuzzedContext.GT
import fuzzer.JsFuzzedContext.LE
import fuzzer.JsFuzzedContext.LT
import fuzzer.JsMethodDescription
import org.utbot.fuzzer.FuzzedContext.Comparison.EQ
import org.utbot.fuzzer.FuzzedContext.Comparison.GE
import org.utbot.fuzzer.FuzzedContext.Comparison.GT
import org.utbot.fuzzer.FuzzedContext.Comparison.LE
import org.utbot.fuzzer.FuzzedContext.Comparison.LT
import org.utbot.fuzzer.FuzzedValue
import org.utbot.fuzzer.providers.PrimitivesModelProvider.fuzzed
import org.utbot.framework.plugin.api.UtModel
import org.utbot.fuzzing.Seed
import org.utbot.fuzzing.ValueProvider
import org.utbot.fuzzing.seeds.DefaultFloatBound
import org.utbot.fuzzing.seeds.IEEE754Value

object NumberValueProvider : ValueProvider<JsClassId, FuzzedValue, JsMethodDescription> {
object NumberValueProvider : ValueProvider<JsClassId, UtModel, JsMethodDescription> {

override fun accept(type: JsClassId): Boolean {
return type.isJsBasic
}

override fun generate(description: JsMethodDescription, type: JsClassId): Sequence<Seed<JsClassId, FuzzedValue>> =
override fun generate(description: JsMethodDescription, type: JsClassId): Sequence<Seed<JsClassId, UtModel>> =
sequence {
description.concreteValues.forEach { (_, v, c) ->
if (v is Double) {
Expand All @@ -33,18 +32,14 @@ object NumberValueProvider : ValueProvider<JsClassId, FuzzedValue, JsMethodDescr
}

yield(Seed.Known(IEEE754Value.fromValue(v)) { known ->
JsPrimitiveModel(known.toDouble() + balance).fuzzed {
summary = "%var% = ${known.toDouble() + balance}"
}
JsPrimitiveModel(known.toDouble() + balance)
})
}
}
DefaultFloatBound.values().forEach { bound ->
// All numbers in JavaScript are like Double in Java/Kotlin
yield(Seed.Known(bound(52, 11)) { known ->
JsPrimitiveModel(known.toDouble()).fuzzed {
summary = "%var% = ${known.toDouble()}"
}
JsPrimitiveModel(known.toDouble())
})
}
}
Expand Down
Loading