debug information test: instantiate a single thread for all tests under same test class

This commit is contained in:
Jiaxiang Chen
2019-09-11 16:37:25 -07:00
committed by max-kammerer
parent 0a2812f83b
commit 2c78f1fe85
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.codegen.debugInformation package org.jetbrains.kotlin.codegen.debugInformation
import com.intellij.openapi.util.SystemInfo
import com.intellij.util.PathUtil import com.intellij.util.PathUtil
import com.intellij.util.SystemProperties import com.intellij.util.SystemProperties
import com.sun.jdi.VirtualMachine import com.sun.jdi.VirtualMachine
@@ -25,6 +26,10 @@ import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.clientserver.getGeneratedClass import org.jetbrains.kotlin.test.clientserver.getGeneratedClass
import org.jetbrains.kotlin.test.clientserver.TestProcessServer import org.jetbrains.kotlin.test.clientserver.TestProcessServer
import org.jetbrains.kotlin.test.clientserver.TestProxy import org.jetbrains.kotlin.test.clientserver.TestProxy
import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import java.io.File import java.io.File
import java.lang.IllegalStateException import java.lang.IllegalStateException
import java.net.URLClassLoader import java.net.URLClassLoader
@@ -32,26 +37,24 @@ import kotlin.properties.Delegates
abstract class AbstractSteppingTest : CodegenTestCase() { abstract class AbstractSteppingTest : CodegenTestCase() {
private companion object { companion object {
private const val DEBUG_ADDRESS = "127.0.0.1" const val DEBUG_ADDRESS = "127.0.0.1"
private const val MAIN_CLASS = "org.jetbrains.kotlin.test.clientserver.TestProcessServer" const val MAIN_CLASS = "org.jetbrains.kotlin.test.clientserver.TestProcessServer"
private const val TEST_CLASS = "TestKt" const val TEST_CLASS = "TestKt"
private const val BOX_METHOD = "box" const val BOX_METHOD = "box"
private const val LINENUMBER_PREFIX = "// LINENUMBERS" const val LINENUMBER_PREFIX = "// LINENUMBERS"
} var proxyPort = 0
lateinit var process: Process
lateinit var virtualMachine: VirtualMachine
private var proxyPort = 0 @BeforeClass
@JvmStatic
private var process: Process? = null fun setUpTest() {
private var virtualMachine: VirtualMachine? = null
override fun setUp() {
val debugPort = startDebuggeeProcess() val debugPort = startDebuggeeProcess()
virtualMachine = attachDebugger(debugPort) virtualMachine = attachDebugger(debugPort)
setUpVM(virtualMachine!!) setUpVM(virtualMachine)
val reader = process!!.inputStream.bufferedReader() val reader = process.inputStream.bufferedReader()
reader.readLine() reader.readLine()
proxyPort = reader.readLine() proxyPort = reader.readLine()
.split("port ") .split("port ")
@@ -59,11 +62,9 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
.trim() .trim()
.toInt() .toInt()
reader.close() reader.close()
super.setUp()
} }
open fun setUpVM(virtualMachine: VirtualMachine) { private fun setUpVM(virtualMachine: VirtualMachine) {
val manager = virtualMachine.eventRequestManager() val manager = virtualMachine.eventRequestManager()
val methodEntryReq = manager.createMethodEntryRequest() val methodEntryReq = manager.createMethodEntryRequest()
@@ -79,12 +80,13 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
private fun startDebuggeeProcess(): Int { private fun startDebuggeeProcess(): Int {
val classpath = listOf( val classpath = listOf(
System.getProperty("java.class.path"), PathUtil.getJarPathForClass(TestProcessServer::class.java),
PathUtil.getJarPathForClass(Delegates::class.java) // Add Kotlin runtime JAR PathUtil.getJarPathForClass(Delegates::class.java) // Add Kotlin runtime JAR
) )
val javaExecutablePath = findJavaExecutable().absolutePath
val command = arrayOf( val command = arrayOf(
findJavaExecutable().absolutePath, if (SystemInfo.isWindows) "\"$javaExecutablePath\"" else javaExecutablePath,
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:0", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:0",
"-ea", "-ea",
"-classpath", classpath.joinToString(File.pathSeparator), "-classpath", classpath.joinToString(File.pathSeparator),
@@ -93,7 +95,7 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
) )
process = ProcessBuilder(*command).start() process = ProcessBuilder(*command).start()
return process!!.inputStream.bufferedReader().readLine() return process.inputStream.bufferedReader().readLine()
.split("address:") .split("address:")
.last() .last()
.trim() .trim()
@@ -108,12 +110,26 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
}) })
} }
override fun tearDown() { private fun findJavaExecutable(): File {
try { val javaBin = File(SystemProperties.getJavaHome(), "bin")
process!!.destroy() return File(javaBin, "java.exe").takeIf { it.exists() }
} finally { ?: File(javaBin, "java").also { assert(it.exists()) }
} }
@AfterClass
@JvmStatic
fun tearDownTest() {
process.destroy()
}
}
@Before
public override fun setUp() {
super.setUp()
}
@After
public override fun tearDown() {
super.tearDown() super.tearDown()
} }
@@ -146,9 +162,9 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
classFileFactory.writeAllTo(classesDir) classFileFactory.writeAllTo(classesDir)
try { try {
doTest(lineNumbers, classesDir, virtualMachine!!, classBuilderFactory, classFileFactory, generationState) doTest(lineNumbers, classesDir, virtualMachine, classBuilderFactory, classFileFactory, generationState)
} finally { } finally {
//process.destroy()
} }
} finally { } finally {
tempDirForTest.deleteRecursively() tempDirForTest.deleteRecursively()
@@ -200,18 +216,20 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
is VMDeathEvent, is VMDisconnectEvent -> { is VMDeathEvent, is VMDisconnectEvent -> {
break@vmLoop break@vmLoop
} }
// We start VM with option suspend=n, in case VMStartEvent is still received, discard. // We start VM with option 'suspend=n', in case VMStartEvent is still received, discard.
is VMStartEvent -> { is VMStartEvent -> {
} }
is MethodEntryEvent -> { is MethodEntryEvent -> {
if (!shouldRecordSteps && event.location().method().name() == BOX_METHOD) { if (!shouldRecordSteps && event.location().method().name() == BOX_METHOD) {
if (manager.stepRequests().isEmpty()) {
val stepReq = manager.createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_INTO) val stepReq = manager.createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_INTO)
stepReq.setSuspendPolicy(SUSPEND_NONE) stepReq.setSuspendPolicy(SUSPEND_NONE)
stepReq.addClassExclusionFilter("java.*") stepReq.addClassExclusionFilter("java.*")
stepReq.addClassExclusionFilter("sun.*") stepReq.addClassExclusionFilter("sun.*")
stepReq.addClassExclusionFilter("kotlin.*") stepReq.addClassExclusionFilter("kotlin.*")
stepReq.enable() }
manager.stepRequests().map { it.enable() }
shouldRecordSteps = true shouldRecordSteps = true
loggedEvents.add(event) loggedEvents.add(event)
} }
@@ -227,6 +245,7 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
} }
is MethodExitEvent -> { is MethodExitEvent -> {
if (event.location().method().name() == BOX_METHOD) { if (event.location().method().name() == BOX_METHOD) {
manager.stepRequests().map { it.disable() }
break@vmLoop break@vmLoop
} }
} }
@@ -244,12 +263,6 @@ abstract class AbstractSteppingTest : CodegenTestCase() {
TestCase.assertEquals(expectedLineNumbers, actualLineNumbers.joinToString(" ")) TestCase.assertEquals(expectedLineNumbers, actualLineNumbers.joinToString(" "))
} }
private fun findJavaExecutable(): File {
val javaBin = File(SystemProperties.getJavaHome(), "bin")
return File(javaBin, "java.exe").takeIf { it.exists() }
?: File(javaBin, "java").also { assert(it.exists()) }
}
internal val OutputFile.internalName internal val OutputFile.internalName
get() = relativePath.substringBeforeLast(".class") get() = relativePath.substringBeforeLast(".class")