From 2c78f1fe85a89d3d45a99aa75b39d551ed6a40d2 Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Wed, 11 Sep 2019 16:37:25 -0700 Subject: [PATCH] debug information test: instantiate a single thread for all tests under same test class --- .../debugInformation/AbstractSteppingTest.kt | 197 ++++++++++-------- 1 file changed, 105 insertions(+), 92 deletions(-) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt index ef7d785e817..06d30b3e6c9 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/debugInformation/AbstractSteppingTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.codegen.debugInformation +import com.intellij.openapi.util.SystemInfo import com.intellij.util.PathUtil import com.intellij.util.SystemProperties 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.TestProcessServer 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.lang.IllegalStateException import java.net.URLClassLoader @@ -32,88 +37,99 @@ import kotlin.properties.Delegates abstract class AbstractSteppingTest : CodegenTestCase() { - private companion object { - private const val DEBUG_ADDRESS = "127.0.0.1" - private const val MAIN_CLASS = "org.jetbrains.kotlin.test.clientserver.TestProcessServer" - private const val TEST_CLASS = "TestKt" - private const val BOX_METHOD = "box" - private const val LINENUMBER_PREFIX = "// LINENUMBERS" + companion object { + const val DEBUG_ADDRESS = "127.0.0.1" + const val MAIN_CLASS = "org.jetbrains.kotlin.test.clientserver.TestProcessServer" + const val TEST_CLASS = "TestKt" + const val BOX_METHOD = "box" + const val LINENUMBER_PREFIX = "// LINENUMBERS" + var proxyPort = 0 + lateinit var process: Process + lateinit var virtualMachine: VirtualMachine + + @BeforeClass + @JvmStatic + fun setUpTest() { + val debugPort = startDebuggeeProcess() + virtualMachine = attachDebugger(debugPort) + setUpVM(virtualMachine) + + val reader = process.inputStream.bufferedReader() + reader.readLine() + proxyPort = reader.readLine() + .split("port ") + .last() + .trim() + .toInt() + reader.close() + } + + private fun setUpVM(virtualMachine: VirtualMachine) { + val manager = virtualMachine.eventRequestManager() + + val methodEntryReq = manager.createMethodEntryRequest() + methodEntryReq.addClassFilter(TEST_CLASS) + methodEntryReq.setSuspendPolicy(SUSPEND_ALL) + methodEntryReq.enable() + + val methodExitReq = manager.createMethodExitRequest() + methodExitReq.addClassFilter(TEST_CLASS) + methodExitReq.setSuspendPolicy(SUSPEND_NONE) + methodExitReq.enable() + } + + private fun startDebuggeeProcess(): Int { + val classpath = listOf( + PathUtil.getJarPathForClass(TestProcessServer::class.java), + PathUtil.getJarPathForClass(Delegates::class.java) // Add Kotlin runtime JAR + ) + + val javaExecutablePath = findJavaExecutable().absolutePath + val command = arrayOf( + if (SystemInfo.isWindows) "\"$javaExecutablePath\"" else javaExecutablePath, + "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:0", + "-ea", + "-classpath", classpath.joinToString(File.pathSeparator), + MAIN_CLASS, + TestProcessServer.DEBUG_TEST + ) + + process = ProcessBuilder(*command).start() + return process.inputStream.bufferedReader().readLine() + .split("address:") + .last() + .trim() + .toInt() + } + + private fun attachDebugger(port: Int): VirtualMachine { + val connector = SocketAttachingConnector() + return connector.attach(connector.defaultArguments().toMutableMap().apply { + getValue("port").setValue("$port") + getValue("hostname").setValue(DEBUG_ADDRESS) + }) + } + + 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()) } + } + + @AfterClass + @JvmStatic + fun tearDownTest() { + process.destroy() + } } - private var proxyPort = 0 - - private var process: Process? = null - - private var virtualMachine: VirtualMachine? = null - - override fun setUp() { - val debugPort = startDebuggeeProcess() - virtualMachine = attachDebugger(debugPort) - setUpVM(virtualMachine!!) - - val reader = process!!.inputStream.bufferedReader() - reader.readLine() - proxyPort = reader.readLine() - .split("port ") - .last() - .trim() - .toInt() - reader.close() - + @Before + public override fun setUp() { super.setUp() } - open fun setUpVM(virtualMachine: VirtualMachine) { - val manager = virtualMachine.eventRequestManager() - - val methodEntryReq = manager.createMethodEntryRequest() - methodEntryReq.addClassFilter(TEST_CLASS) - methodEntryReq.setSuspendPolicy(SUSPEND_ALL) - methodEntryReq.enable() - - val methodExitReq = manager.createMethodExitRequest() - methodExitReq.addClassFilter(TEST_CLASS) - methodExitReq.setSuspendPolicy(SUSPEND_NONE) - methodExitReq.enable() - } - - private fun startDebuggeeProcess(): Int{ - val classpath = listOf( - System.getProperty("java.class.path"), - PathUtil.getJarPathForClass(Delegates::class.java) // Add Kotlin runtime JAR - ) - - val command = arrayOf( - findJavaExecutable().absolutePath, - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:0", - "-ea", - "-classpath", classpath.joinToString(File.pathSeparator), - MAIN_CLASS, - TestProcessServer.DEBUG_TEST - ) - - process = ProcessBuilder(*command).start() - return process!!.inputStream.bufferedReader().readLine() - .split("address:") - .last() - .trim() - .toInt() - } - - private fun attachDebugger(port: Int): VirtualMachine { - val connector = SocketAttachingConnector() - return connector.attach(connector.defaultArguments().toMutableMap().apply { - getValue("port").setValue("$port") - getValue("hostname").setValue(DEBUG_ADDRESS) - }) - } - - override fun tearDown() { - try { - process!!.destroy() - } finally { - - } + @After + public override fun tearDown() { super.tearDown() } @@ -146,9 +162,9 @@ abstract class AbstractSteppingTest : CodegenTestCase() { classFileFactory.writeAllTo(classesDir) try { - doTest(lineNumbers, classesDir, virtualMachine!!, classBuilderFactory, classFileFactory, generationState) + doTest(lineNumbers, classesDir, virtualMachine, classBuilderFactory, classFileFactory, generationState) } finally { - //process.destroy() + } } finally { tempDirForTest.deleteRecursively() @@ -200,18 +216,20 @@ abstract class AbstractSteppingTest : CodegenTestCase() { is VMDeathEvent, is VMDisconnectEvent -> { 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 MethodEntryEvent -> { if (!shouldRecordSteps && event.location().method().name() == BOX_METHOD) { - val stepReq = manager.createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_INTO) - stepReq.setSuspendPolicy(SUSPEND_NONE) - stepReq.addClassExclusionFilter("java.*") - stepReq.addClassExclusionFilter("sun.*") - stepReq.addClassExclusionFilter("kotlin.*") - stepReq.enable() + if (manager.stepRequests().isEmpty()) { + val stepReq = manager.createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_INTO) + stepReq.setSuspendPolicy(SUSPEND_NONE) + stepReq.addClassExclusionFilter("java.*") + stepReq.addClassExclusionFilter("sun.*") + stepReq.addClassExclusionFilter("kotlin.*") + } + manager.stepRequests().map { it.enable() } shouldRecordSteps = true loggedEvents.add(event) } @@ -227,6 +245,7 @@ abstract class AbstractSteppingTest : CodegenTestCase() { } is MethodExitEvent -> { if (event.location().method().name() == BOX_METHOD) { + manager.stepRequests().map { it.disable() } break@vmLoop } } @@ -244,12 +263,6 @@ abstract class AbstractSteppingTest : CodegenTestCase() { 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 get() = relativePath.substringBeforeLast(".class")