aboutsummaryrefslogtreecommitdiff
path: root/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
diff options
context:
space:
mode:
Diffstat (limited to 'agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt')
-rw-r--r--agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt112
1 files changed, 73 insertions, 39 deletions
diff --git a/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt b/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
index 15c88f4c..f2cf2f08 100644
--- a/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
+++ b/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
@@ -14,12 +14,37 @@
package com.code_intelligence.jazzer.instrumentor
+import com.code_intelligence.jazzer.instrumentor.PatchTestUtils.bytecodeToClass
+import com.code_intelligence.jazzer.instrumentor.PatchTestUtils.classToBytecode
import org.junit.Test
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
import java.io.File
import kotlin.test.assertEquals
+/**
+ * Amends the instrumentation performed by [strategy] to call the map's public static void method
+ * updated() after every update to coverage counters.
+ */
+private fun makeTestable(strategy: EdgeCoverageStrategy): EdgeCoverageStrategy =
+ object : EdgeCoverageStrategy by strategy {
+ override fun instrumentControlFlowEdge(
+ mv: MethodVisitor,
+ edgeId: Int,
+ variable: Int,
+ coverageMapInternalClassName: String
+ ) {
+ strategy.instrumentControlFlowEdge(mv, edgeId, variable, coverageMapInternalClassName)
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, coverageMapInternalClassName, "updated", "()V", false)
+ }
+ }
+
private fun applyInstrumentation(bytecode: ByteArray): ByteArray {
- return EdgeCoverageInstrumentor(0, MockCoverageMap::class.java).instrument(bytecode)
+ return EdgeCoverageInstrumentor(
+ makeTestable(ClassInstrumentor.defaultEdgeCoverageStrategy),
+ MockCoverageMap::class.java,
+ 0
+ ).instrument(bytecode)
}
private fun getOriginalInstrumentationTargetInstance(): DynamicTestContract {
@@ -41,26 +66,34 @@ private fun assertControlFlow(expectedLocations: List<Int>) {
assertEquals(expectedLocations, MockCoverageMap.locations.toList())
}
+@Suppress("unused")
class CoverageInstrumentationTest {
private val constructorReturn = 0
- private val ifFirstBranch = 1
- @Suppress("unused")
- private val ifSecondBranch = 2
- private val ifEnd = 3
- private val outerForCondition = 4
- private val innerForBodyIfFirstRun = 6
- private val innerForBodyIfSecondRun = 5
- private val innerForIncrementCounter = 7
- private val outerForIncrementCounter = 8
- private val afterFooInvocation = 9
- private val beforeReturn = 10
- private val fooAfterBarInvocation = 11
- private val fooBeforeReturn = 12
- private val barAfterMapPutInvocation = 13
- private val barBeforeReturn = 14
- @Suppress("unused")
- private val bazReturn = 15
+
+ private val mapConstructor = 1
+ private val addFor0 = 2
+ private val addFor1 = 3
+ private val addFor2 = 4
+ private val addFor3 = 5
+ private val addFor4 = 6
+ private val addFoobar = 7
+
+ private val ifTrueBranch = 8
+ private val addBlock1 = 9
+ private val ifFalseBranch = 10
+ private val ifEnd = 11
+
+ private val outerForCondition = 12
+ private val innerForCondition = 13
+ private val innerForBodyIfTrueBranch = 14
+ private val innerForBodyIfFalseBranch = 15
+ private val innerForBodyPutInvocation = 16
+ private val outerForIncrementCounter = 17
+
+ private val afterFooInvocation = 18
+ private val fooAfterBarInvocation = 19
+ private val barAfterPutInvocation = 20
@Test
fun testOriginal() {
@@ -72,31 +105,32 @@ class CoverageInstrumentationTest {
MockCoverageMap.clear()
assertSelfCheck(getInstrumentedInstrumentationTargetInstance())
- val innerForFirstRunControlFlow = mutableListOf<Int>().apply {
+ val mapControlFlow = listOf(mapConstructor, addFor0, addFor1, addFor2, addFor3, addFor4, addFoobar)
+ val ifControlFlow = listOf(ifTrueBranch, addBlock1, ifEnd)
+ val forFirstRunControlFlow = mutableListOf<Int>().apply {
+ add(outerForCondition)
repeat(5) {
- addAll(listOf(innerForBodyIfFirstRun, innerForIncrementCounter))
+ addAll(listOf(innerForCondition, innerForBodyIfFalseBranch, innerForBodyPutInvocation))
}
+ add(outerForIncrementCounter)
}.toList()
- val innerForSecondRunControlFlow = mutableListOf<Int>().apply {
+ val forSecondRunControlFlow = mutableListOf<Int>().apply {
+ add(outerForCondition)
repeat(5) {
- addAll(listOf(innerForBodyIfSecondRun, innerForIncrementCounter))
+ addAll(listOf(innerForCondition, innerForBodyIfTrueBranch, innerForBodyPutInvocation))
}
+ add(outerForIncrementCounter)
}.toList()
- val outerForControlFlow =
- listOf(outerForCondition) +
- innerForFirstRunControlFlow +
- listOf(outerForIncrementCounter, outerForCondition) +
- innerForSecondRunControlFlow +
- listOf(outerForIncrementCounter)
-
+ val forControlFlow = forFirstRunControlFlow + forSecondRunControlFlow
+ val fooCallControlFlow = listOf(
+ barAfterPutInvocation, fooAfterBarInvocation, afterFooInvocation
+ )
assertControlFlow(
- listOf(constructorReturn, ifFirstBranch, ifEnd) +
- outerForControlFlow +
- listOf(
- barAfterMapPutInvocation, barBeforeReturn,
- fooAfterBarInvocation, fooBeforeReturn,
- afterFooInvocation, beforeReturn
- )
+ listOf(constructorReturn) +
+ mapControlFlow +
+ ifControlFlow +
+ forControlFlow +
+ fooCallControlFlow
)
}
@@ -109,17 +143,17 @@ class CoverageInstrumentationTest {
// The constructor of the target is run only once.
val takenOnceEdge = constructorReturn
// Control flows through the first if branch once per run.
- val takenOnEveryRunEdge = ifFirstBranch
+ val takenOnEveryRunEdge = ifTrueBranch
var lastCounter = 0.toUByte()
for (i in 1..600) {
assertSelfCheck(target)
- assertEquals(1, MockCoverageMap.mem[takenOnceEdge])
+ assertEquals(1, MockCoverageMap.counters[takenOnceEdge])
// Verify that the counter increments, but is never zero.
val expectedCounter = (lastCounter + 1U).toUByte().takeUnless { it == 0.toUByte() }
?: (lastCounter + 2U).toUByte()
lastCounter = expectedCounter
- val actualCounter = MockCoverageMap.mem[takenOnEveryRunEdge].toUByte()
+ val actualCounter = MockCoverageMap.counters[takenOnEveryRunEdge].toUByte()
assertEquals(expectedCounter, actualCounter, "After $i runs:")
}
}