Skip to content
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

Add branch coverage #2486

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,11 @@ object UtSettings : AbstractSettings(logger, defaultKeyForSettingsPath, defaultS
*/
var useBytecodeTransformation by getBooleanProperty(false)

/**
* Type of trace instrumentation.
*/
var traceInstrumentationType by getEnumProperty(TraceInstrumentationType.INSTRUCTION)

/**
* Limit for number of generated tests per method (in each region)
*/
Expand Down Expand Up @@ -756,3 +761,16 @@ enum class ExploreThrowableDepth {
*/
EXPLORE_ALL_STATEMENTS
}

enum class TraceInstrumentationType {

/**
* Insert probes before each bytecode instruction.
*/
INSTRUCTION,

/**
* Insert probes into the [control flow graph](https://www.eclemma.org/jacoco/trunk/doc/flow.html).
*/
BRANCH
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package org.utbot.framework.coverage

import kotlinx.coroutines.runBlocking
import org.utbot.framework.plugin.api.ExecutableId
import org.utbot.framework.plugin.api.UtValueExecution
import org.utbot.framework.plugin.api.util.jClass
import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.instrumentation.coverage.CoverageInfo
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.util.StaticEnvironment
import kotlinx.coroutines.runBlocking

fun methodCoverage(executable: ExecutableId, executions: List<UtValueExecution<*>>, classpath: String): Coverage {
val methodSignature = executable.signature
val classId = executable.classId
return ConcreteExecutor(CoverageInstrumentation.Factory, classpath).let { executor ->
return ConcreteExecutor(InstructionCoverageInstrumentation.Factory, classpath).let { executor ->
for (execution in executions) {
val args = execution.stateBefore.params.map { it.value }.toMutableList()
val caller = execution.stateBefore.caller
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.utbot.examples

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.utbot.examples.samples.ExampleClass
import org.utbot.examples.samples.et.ClassSimpleCatch
import org.utbot.examples.statics.substitution.StaticSubstitution
import org.utbot.examples.statics.substitution.StaticSubstitutionExamples
import org.utbot.framework.plugin.api.util.fieldId
import org.utbot.framework.plugin.api.util.signature
import org.utbot.instrumentation.execute
import org.utbot.instrumentation.instrumentation.coverage.BranchCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.util.StaticEnvironment
import org.utbot.instrumentation.withInstrumentation

class TestBranchCoverageInstrumentation {
lateinit var utContext: AutoCloseable

@Test
fun testIfBranches() {
withInstrumentation(
BranchCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
) { executor ->
val testObject = ExampleClass()

executor.execute(ExampleClass::bar, arrayOf(testObject, 2))
val coverageInfo1 = executor.collectCoverage(ExampleClass::class.java)

assertEquals(2, coverageInfo1.visitedInstrs.size)
assertEquals(1..3, coverageInfo1.methodToInstrRange[ExampleClass::bar.signature])

executor.execute(ExampleClass::bar, arrayOf(testObject, 0))
val coverageInfo2 = executor.collectCoverage(ExampleClass::class.java)

assertEquals(2, coverageInfo2.visitedInstrs.size)
assertEquals(1..3, coverageInfo2.methodToInstrRange[ExampleClass::bar.signature])
}
}

@Test
fun testTryCatch() {
withInstrumentation(
BranchCoverageInstrumentation.Factory,
ClassSimpleCatch::class.java.protectionDomain.codeSource.location.path
) { executor ->
executor.execute(ClassSimpleCatch::A_catches, emptyArray())
val coverageInfo1 = executor.collectCoverage(ClassSimpleCatch::class.java)

assertEquals(2, coverageInfo1.visitedInstrs.size)
assertEquals(3..5, coverageInfo1.methodToInstrRange[ClassSimpleCatch::A_catches.signature])

executor.execute(ClassSimpleCatch::A_catchesWrongException, emptyArray())
val coverageInfo2 = executor.collectCoverage(ClassSimpleCatch::class.java)

assertEquals(0, coverageInfo2.visitedInstrs.size)
assertEquals(7..9, coverageInfo2.methodToInstrRange[ClassSimpleCatch::A_catchesWrongException.signature])
}
}

@Test
fun testTernaryOperator() {
withInstrumentation(
BranchCoverageInstrumentation.Factory,
StaticSubstitutionExamples::class.java.protectionDomain.codeSource.location.path
) { executor ->
val testObject = StaticSubstitutionExamples()

val emptyStaticEnvironment = StaticEnvironment()

val res1 = executor.execute(
StaticSubstitutionExamples::lessThanZero,
arrayOf(testObject),
parameters = emptyStaticEnvironment
)

val staticEnvironment = StaticEnvironment(
StaticSubstitution::mutableValue.fieldId to -1
)
val res2 = executor.execute(
StaticSubstitutionExamples::lessThanZero,
arrayOf(testObject),
parameters = staticEnvironment
)
val coverageInfo = executor.collectCoverage(StaticSubstitutionExamples::class.java)

assertEquals(res1.getOrNull(), 5)
assertEquals(res2.getOrNull(), 0)
assertEquals(coverageInfo.visitedInstrs, (1..3).toList())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.utbot.framework.plugin.api.util.signature
import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.execute
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.instrumentation.et.ExecutionTraceInstrumentation
import org.utbot.instrumentation.instrumentation.et.convert
Expand Down Expand Up @@ -86,7 +86,7 @@ class TestConstructors {
@Test
fun testCoverageConstructor() {
withInstrumentation(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
CLASSPATH
) { executor ->
val constructors = ClassWithMultipleConstructors::class.constructors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.utbot.framework.plugin.api.util.fieldId
import org.utbot.framework.plugin.api.util.signature
import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.execute
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.util.InstrumentedProcessError
import org.utbot.instrumentation.util.StaticEnvironment
Expand All @@ -18,13 +18,13 @@ import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class TestCoverageInstrumentation {
class TestInstructionCoverageInstrumentation {
lateinit var utContext: AutoCloseable

@Test
fun testCatchTargetException() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand All @@ -41,7 +41,7 @@ class TestCoverageInstrumentation {
@Test
fun testIfBranches() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand All @@ -63,7 +63,7 @@ class TestCoverageInstrumentation {
@Test
fun testWrongArgumentsException() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand All @@ -86,7 +86,7 @@ class TestCoverageInstrumentation {
@Test
fun testMultipleRunsInsideCoverage() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand Down Expand Up @@ -121,7 +121,7 @@ class TestCoverageInstrumentation {
@Test
fun testSameResult() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand All @@ -143,7 +143,7 @@ class TestCoverageInstrumentation {
@Test
fun testResult() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand All @@ -160,7 +160,7 @@ class TestCoverageInstrumentation {
@Test
fun testEmptyMethod() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = ExampleClass()
Expand All @@ -176,7 +176,7 @@ class TestCoverageInstrumentation {
@Test
fun testTernaryOperator() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
StaticSubstitutionExamples::class.java.protectionDomain.codeSource.location.path
).use {
val testObject = StaticSubstitutionExamples()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.utbot.examples.samples.staticenvironment.StaticExampleClass
import org.utbot.framework.plugin.api.util.signature
import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.execute
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
Expand All @@ -17,7 +17,7 @@ class TestStaticMethods {
@Test
fun testStaticMethodCall() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
StaticExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val res1 = it.execute(StaticExampleClass::inc, arrayOf())
Expand All @@ -44,7 +44,7 @@ class TestStaticMethods {
@Test
fun testNullableMethod() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
StaticExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val res1 = it.execute(
Expand Down Expand Up @@ -75,7 +75,7 @@ class TestStaticMethods {
@Test
fun testNullableMethodWithoutAnnotations() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
StaticExampleClass::class.java.protectionDomain.codeSource.location.path
).use {
val res1 = it.execute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.utbot.examples.samples.staticenvironment.StaticExampleClass
import org.utbot.framework.plugin.api.util.signature
import org.utbot.instrumentation.execute
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.withInstrumentation
import kotlin.reflect.full.declaredMembers
Expand All @@ -20,7 +20,7 @@ class TestWithInstrumentation {
@Test
fun testStaticMethodCall() {
withInstrumentation(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
StaticExampleClass::class.java.protectionDomain.codeSource.location.path
) { executor ->
val res1 = executor.execute(StaticExampleClass::inc, arrayOf())
Expand Down Expand Up @@ -70,7 +70,7 @@ class TestWithInstrumentation {
@Test
fun testInnerClasses() {
withInstrumentation(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
ClassWithInnerClasses::class.java.protectionDomain.codeSource.location.path
) { executor ->
val innerClazz = ClassWithInnerClasses.InnerClass::class.java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.utbot.examples.benchmark

import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.util.Isolated
import kotlin.system.measureNanoTime
Expand All @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
fun getBasicCoverageTime(count: Int): Double {
var time: Long
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
Repeater::class.java.protectionDomain.codeSource.location.path
).use { executor ->
val dc0 = Repeater(", ")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import org.utbot.framework.plugin.api.util.UtContext
import org.utbot.framework.plugin.api.util.withUtContext
import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.collectCoverage
import org.utbot.instrumentation.util.Isolated
import kotlin.system.measureNanoTime

fun getBasicCoverageTime_fib(count: Int): Double {
var time: Long
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
Fibonacci::class.java.protectionDomain.codeSource.location.path
).use {
val fib = Isolated(Fibonacci::calc, it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.utbot.examples.samples.benchmark.Fibonacci
import org.utbot.instrumentation.ConcreteExecutor
import org.utbot.instrumentation.execute
import org.utbot.instrumentation.instrumentation.InvokeInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.CoverageInstrumentation
import org.utbot.instrumentation.instrumentation.coverage.InstructionCoverageInstrumentation
import java.math.BigInteger
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Disabled
Expand All @@ -18,7 +18,7 @@ class TestBenchmarkClasses {
@Disabled("Ask Sergey to check")
fun testRepeater() {
ConcreteExecutor(
CoverageInstrumentation.Factory,
InstructionCoverageInstrumentation.Factory,
Repeater::class.java.protectionDomain.codeSource.location.path
).use {
val dc0 = Repeater(", ")
Expand Down
Loading