add local variable test. This test runs box() method and checks local variable types and names avaiable at every step.
This commit is contained in:
committed by
Ilmir Usmanov
parent
6b73ef4b0b
commit
6454cfad87
+8
-4
@@ -11,7 +11,7 @@ import com.intellij.util.SystemProperties
|
||||
import com.sun.jdi.VirtualMachine
|
||||
import com.sun.jdi.event.*
|
||||
import com.sun.jdi.request.EventRequest
|
||||
import com.sun.jdi.request.EventRequest.SUSPEND_NONE
|
||||
import com.sun.jdi.request.EventRequest.SUSPEND_ALL
|
||||
import com.sun.jdi.request.StepRequest
|
||||
import com.sun.tools.jdi.SocketAttachingConnector
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||
@@ -53,7 +53,7 @@ abstract class AbstractDebugTest : CodegenTestCase() {
|
||||
|
||||
val methodExitReq = manager.createMethodExitRequest()
|
||||
methodExitReq.addClassFilter(TEST_CLASS)
|
||||
methodExitReq.setSuspendPolicy(EventRequest.SUSPEND_NONE)
|
||||
methodExitReq.setSuspendPolicy(EventRequest.SUSPEND_ALL)
|
||||
methodExitReq.enable()
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ abstract class AbstractDebugTest : CodegenTestCase() {
|
||||
var inBoxMethod = false
|
||||
vmLoop@
|
||||
while (true) {
|
||||
val eventSet = virtualMachine.eventQueue().remove()
|
||||
val eventSet = virtualMachine.eventQueue().remove(100)
|
||||
for (event in eventSet) {
|
||||
when (event) {
|
||||
is VMDeathEvent, is VMDisconnectEvent -> {
|
||||
@@ -192,7 +192,7 @@ abstract class AbstractDebugTest : CodegenTestCase() {
|
||||
if (!inBoxMethod && event.location().method().name() == BOX_METHOD) {
|
||||
if (manager.stepRequests().isEmpty()) {
|
||||
val stepReq = manager.createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_INTO)
|
||||
stepReq.setSuspendPolicy(SUSPEND_NONE)
|
||||
stepReq.setSuspendPolicy(SUSPEND_ALL)
|
||||
stepReq.addClassExclusionFilter("java.*")
|
||||
stepReq.addClassExclusionFilter("sun.*")
|
||||
stepReq.addClassExclusionFilter("kotlin.*")
|
||||
@@ -206,17 +206,21 @@ abstract class AbstractDebugTest : CodegenTestCase() {
|
||||
is StepEvent -> {
|
||||
// Handle the case where an Exception causing program to exit without MethodExitEvent.
|
||||
if (inBoxMethod && event.location().method().name() == "run") {
|
||||
virtualMachine.resume()
|
||||
break@vmLoop
|
||||
}
|
||||
if (inBoxMethod) {
|
||||
storeStep(loggedItems, event)
|
||||
}
|
||||
virtualMachine.resume()
|
||||
}
|
||||
is MethodExitEvent -> {
|
||||
if (event.location().method().name() == BOX_METHOD) {
|
||||
manager.stepRequests().map { it.disable() }
|
||||
virtualMachine.resume()
|
||||
break@vmLoop
|
||||
}
|
||||
virtualMachine.resume()
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("event not handled: $event")
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.jetbrains.kotlin.codegen.debugInformation
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
|
||||
abstract class AbstractIrLocalVariableTest : AbstractLocalVariableTest() {
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
configuration.put(JVMConfigurationKeys.IR, true)
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package org.jetbrains.kotlin.codegen.debugInformation
|
||||
|
||||
import com.sun.jdi.LocalVariable
|
||||
import com.sun.jdi.StackFrame
|
||||
import com.sun.jdi.VirtualMachine
|
||||
import com.sun.jdi.event.Event
|
||||
import com.sun.jdi.event.LocatableEvent
|
||||
import junit.framework.TestCase
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractLocalVariableTest : AbstractDebugTest() {
|
||||
|
||||
override val virtualMachine: VirtualMachine = Companion.virtualMachine
|
||||
override val proxyPort: Int = Companion.proxyPort
|
||||
|
||||
companion object {
|
||||
const val LOCAL_VARIABLES = "// LOCAL VARIABLES"
|
||||
var proxyPort = 0
|
||||
lateinit var process: Process
|
||||
lateinit var virtualMachine: VirtualMachine
|
||||
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun setUpTest() {
|
||||
val (process, port) = startDebuggeeProcess()
|
||||
this.process = process
|
||||
virtualMachine = attachDebugger(port)
|
||||
setUpVM(virtualMachine)
|
||||
|
||||
proxyPort = getProxyPort(process)
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@JvmStatic
|
||||
fun tearDownTest() {
|
||||
process.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
override fun storeStep(loggedItems: ArrayList<Any>, event: Event) {
|
||||
waitUntil { (event as LocatableEvent).thread().isSuspended }
|
||||
val visibleVars = (event as LocatableEvent)
|
||||
.thread()
|
||||
.frame(0)
|
||||
.visibleVariables()
|
||||
.map { variable -> toRecord(event.thread().frame(0), variable) }
|
||||
.joinToString(", ")
|
||||
loggedItems.add("${event.location()}: $visibleVars".trim())
|
||||
}
|
||||
|
||||
override fun checkResult(wholeFile: File, loggedItems: List<Any>) {
|
||||
val expectedLocalVariables = wholeFile
|
||||
.readLines()
|
||||
.dropWhile { !it.startsWith(LOCAL_VARIABLES) }
|
||||
.drop(1)
|
||||
.map { it.drop(3) }
|
||||
.joinToString("\n")
|
||||
val actualLocalVariables = loggedItems.joinToString("\n")
|
||||
|
||||
TestCase.assertEquals(expectedLocalVariables, actualLocalVariables)
|
||||
}
|
||||
|
||||
private fun toRecord(frame: StackFrame, variable: LocalVariable): String {
|
||||
return "${variable.name()}:${frame.getValue(variable)?.type()?.name() ?: "null"}"
|
||||
}
|
||||
|
||||
private fun waitUntil(condition: () -> Boolean) {
|
||||
while (!condition()) {
|
||||
Thread.sleep(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user