[JVM+IR] Unify new debugger tests expectations
This commit unifies the expectation format between the stepping and LVT tests in the new debugging test harness. Furthermore, it introduces a compression of runs of locations without linenumbers. These default to showing as bytecode offsets from previous line number, which overspecifies the tests: the bytecodes chosen should not be constrained by a debugging step test.
This commit is contained in:
committed by
max-kammerer
parent
e19ecdfb3d
commit
27fb46712a
+29
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.sun.jdi.AbsentInformationException
|
||||
import com.sun.jdi.Location
|
||||
import com.sun.jdi.VirtualMachine
|
||||
import com.sun.jdi.event.*
|
||||
import com.sun.jdi.request.EventRequest
|
||||
@@ -266,6 +267,34 @@ abstract class AbstractDebugTest : CodegenTestCase() {
|
||||
checkResult(wholeFile, loggedItems)
|
||||
}
|
||||
|
||||
fun Location.formatAsExpectation(): String {
|
||||
val synthetic = if (method().isSynthetic) " (synthetic)" else ""
|
||||
return "${sourceName()}:${lineNumber()} ${method().name()}$synthetic"
|
||||
}
|
||||
|
||||
/*
|
||||
Compresses runs of the same, linenumber-less location in the log:
|
||||
specifically removes locations without linenumber, that would otherwise
|
||||
print as byte offsets. This avoids overspecifying code generation
|
||||
strategy in debug tests.
|
||||
*/
|
||||
fun <T> compressRunsWithoutLinenumber(loggedItems: List<T>, getLocation: (T) -> Location): List<T> {
|
||||
if (loggedItems.isEmpty()) return listOf()
|
||||
|
||||
val logIterator = loggedItems.iterator()
|
||||
var currentItem = logIterator.next()
|
||||
val result = mutableListOf(currentItem)
|
||||
|
||||
for (logItem in logIterator) {
|
||||
if (getLocation(currentItem).lineNumber() != -1 || getLocation(currentItem).formatAsExpectation() != getLocation(logItem).formatAsExpectation()) {
|
||||
result.add(logItem)
|
||||
currentItem = logItem
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
abstract fun storeStep(loggedItems: ArrayList<Any>, event: Event)
|
||||
|
||||
abstract fun checkResult(wholeFile: File, loggedItems: List<Any>)
|
||||
|
||||
+19
-11
@@ -72,19 +72,24 @@ abstract class AbstractLocalVariableTest : AbstractDebugTest() {
|
||||
}
|
||||
}
|
||||
|
||||
data class LVTStep(
|
||||
val location : Location,
|
||||
val visibleVars: Collection<LocalVariableRecord>
|
||||
)
|
||||
|
||||
override fun storeStep(loggedItems: ArrayList<Any>, event: Event) {
|
||||
waitUntil { (event as LocatableEvent).thread().isSuspended }
|
||||
val frame = (event as LocatableEvent).thread().frame(0)
|
||||
try {
|
||||
val visibleVars = frame
|
||||
.visibleVariables()
|
||||
.map { variable -> toRecord(frame, variable) }
|
||||
.joinToString(", ")
|
||||
loggedItems.add("${event.location()}: $visibleVars".trim())
|
||||
val locatableEvent = event as LocatableEvent
|
||||
waitUntil { locatableEvent.thread().isSuspended }
|
||||
val location = locatableEvent.location()
|
||||
if (location.method().isSynthetic) return
|
||||
val frame = locatableEvent.thread().frame(0)
|
||||
val visibleVars = try {
|
||||
frame.visibleVariables().map { variable -> toRecord(frame, variable) }
|
||||
} catch (e: AbsentInformationException) {
|
||||
// LVT Completely absent - not distinguished from an empty table
|
||||
loggedItems.add("${event.location()}:".trim())
|
||||
listOf()
|
||||
}
|
||||
loggedItems.add(LVTStep(location, visibleVars))
|
||||
}
|
||||
|
||||
override fun checkResult(wholeFile: File, loggedItems: List<Any>) {
|
||||
@@ -109,11 +114,14 @@ abstract class AbstractLocalVariableTest : AbstractDebugTest() {
|
||||
continue
|
||||
}
|
||||
if (currentBackend == TargetBackend.ANY || currentBackend == backend) {
|
||||
expectedLocalVariables.add(line.drop(3))
|
||||
expectedLocalVariables.add(line)
|
||||
}
|
||||
}
|
||||
|
||||
val actualLocalVariables = loggedItems.joinToString("\n")
|
||||
val compressedLog = compressRunsWithoutLinenumber(loggedItems as List<LVTStep>, LVTStep::location)
|
||||
val actualLocalVariables = compressedLog.joinToString("\n") {
|
||||
"// ${it.location.formatAsExpectation()}: ${it.visibleVars.joinToString(", ")}".trim()
|
||||
}
|
||||
|
||||
TestCase.assertEquals(expectedLocalVariables.joinToString("\n"), actualLocalVariables)
|
||||
}
|
||||
|
||||
+3
-8
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.debugInformation
|
||||
import com.sun.jdi.VirtualMachine
|
||||
import com.sun.jdi.event.Event
|
||||
import com.sun.jdi.event.LocatableEvent
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.assertEqualsToFile
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.junit.AfterClass
|
||||
@@ -57,18 +56,14 @@ abstract class AbstractSteppingTest : AbstractDebugTest() {
|
||||
val lines = wholeFile.readLines()
|
||||
val forceStepInto = lines.any { it.startsWith(FORCE_STEP_INTO_MARKER) }
|
||||
|
||||
val actualLineNumbers = loggedItems
|
||||
val actualLineNumbers = compressRunsWithoutLinenumber(loggedItems as List<LocatableEvent>, LocatableEvent::location)
|
||||
.filter {
|
||||
val location = (it as LocatableEvent).location()
|
||||
val location = it.location()
|
||||
// Ignore synthetic code with no line number information
|
||||
// unless force step into behavior is requested.
|
||||
forceStepInto || !location.method().isSynthetic
|
||||
}
|
||||
.map { event ->
|
||||
val location = (event as LocatableEvent).location()
|
||||
val synthetic = if (location.method().isSynthetic) " (synthetic)" else ""
|
||||
"// ${location.sourceName()}:${location.lineNumber()} ${location.method().name()}$synthetic"
|
||||
}
|
||||
.map { "// ${it.location().formatAsExpectation()}" }
|
||||
val actualLineNumbersIterator = actualLineNumbers.iterator()
|
||||
|
||||
val lineIterator = lines.iterator()
|
||||
|
||||
Reference in New Issue
Block a user