[coroutine debugger] IDEA-362750 Add packet number test

GitOrigin-RevId: 922a2419f082afe91c14785a84f0cc8a50c3a1b3
This commit is contained in:
Maksim Zuev
2024-11-25 17:00:46 +00:00
committed by intellij-monorepo-bot
parent ea4a8a7f6d
commit 4bdaf94437
12 changed files with 430 additions and 0 deletions
@@ -105,6 +105,7 @@ import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
@@ -165,6 +166,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
private Job otherThreadsJob;
private int myOtherThreadsReachBreakpointNumber = 0;
private final AtomicInteger myMethodInvocations = new AtomicInteger();
protected DebugProcessImpl(Project project) {
this.project = project;
@@ -1403,6 +1405,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
int invokePolicy = getInvokePolicy(context);
invocationWatcherRef.set(myThreadBlockedMonitor.startInvokeWatching(invokePolicy, thread, context));
myMethodInvocations.incrementAndGet();
result.set(invokeMethod(thread.getThreadReference(), invokePolicy, myMethod, myArgs));
}
finally {
@@ -2925,4 +2928,10 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
public void logError(@NotNull String message, @NotNull Throwable e) {
LOG.error(message, e, DebuggerDiagnosticsUtil.getAttachments(this));
}
@ApiStatus.Internal
@TestOnly
public int getMethodInvocationsCount() {
return myMethodInvocations.get();
}
}
@@ -16,6 +16,7 @@ import com.intellij.debugger.impl.*;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.settings.ViewsGeneralSettings;
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
@@ -34,12 +35,14 @@ import com.intellij.execution.target.TargetedCommandLineBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
@@ -650,4 +653,19 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
}
});
}
protected void setUpPacketsMeasureTest() {
ApplicationManagerEx.setInStressTest(true);
setRegistryPropertyForTest("debugger.track.instrumentation", "false");
setRegistryPropertyForTest("debugger.evaluate.single.threaded.timeout", "-1");
boolean dfa = ViewsGeneralSettings.getInstance().USE_DFA_ASSIST;
boolean dfaGray = ViewsGeneralSettings.getInstance().USE_DFA_ASSIST_GRAY_OUT;
ViewsGeneralSettings.getInstance().USE_DFA_ASSIST = false;
ViewsGeneralSettings.getInstance().USE_DFA_ASSIST_GRAY_OUT = false;
Disposer.register(getTestRootDisposable(), () -> {
ViewsGeneralSettings.getInstance().USE_DFA_ASSIST = dfa;
ViewsGeneralSettings.getInstance().USE_DFA_ASSIST_GRAY_OUT = dfaGray;
});
}
}
@@ -0,0 +1,13 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.debugger.test.cases
import org.jetbrains.kotlin.config.JvmClosureGenerationScheme
import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode
import org.jetbrains.kotlin.idea.debugger.test.AbstractKotlinSteppingPacketsNumberTest
abstract class AbstractK2IdeK2CodeKotlinSteppingPacketsNumberTest : AbstractKotlinSteppingPacketsNumberTest() {
override fun lambdasGenerationScheme() = JvmClosureGenerationScheme.INDY
override val compileWithK2 = true
override val pluginMode: KotlinPluginMode
get() = KotlinPluginMode.K2
}
@@ -0,0 +1,42 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.k2.debugger.test.cases;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode;
import org.jetbrains.kotlin.idea.base.test.TestRoot;
import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.idea.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
/**
* This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}.
* DO NOT MODIFY MANUALLY.
*/
@SuppressWarnings("all")
@TestRoot("jvm-debugger/test/k2")
@TestDataPath("$CONTENT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../testData/stepping/packets")
public class K2IdeK2CodeKotlinSteppingPacketsNumberTestGenerated extends AbstractK2IdeK2CodeKotlinSteppingPacketsNumberTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K2;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doCustomTest, this, testDataFilePath);
}
@TestMetadata("coroutineStepping.kt")
public void testCoroutineStepping() throws Exception {
runTest("../testData/stepping/packets/coroutineStepping.kt");
}
@TestMetadata("veryLongCoroutineStack.kt")
public void testVeryLongCoroutineStack() throws Exception {
runTest("../testData/stepping/packets/veryLongCoroutineStack.kt");
}
}
@@ -0,0 +1,40 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.debugger.test
import com.intellij.debugger.engine.SuspendContextImpl
import com.intellij.execution.process.ProcessOutputTypes
import com.jetbrains.jdi.VirtualMachineImpl
import org.jetbrains.kotlin.config.JvmClosureGenerationScheme
import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode
import java.util.concurrent.atomic.AtomicInteger
abstract class AbstractKotlinSteppingPacketsNumberTest : AbstractIrKotlinSteppingTest() {
private val packets = AtomicInteger()
private val methods = AtomicInteger()
private var firstAccessSkipped = false
override fun setUp() {
super.setUp()
setUpPacketsMeasureTest()
}
override fun extraPrintContext(context: SuspendContextImpl) {
val totalPacketsNumber = (context.virtualMachineProxy.virtualMachine as VirtualMachineImpl).waitPacketsNumber
val totalMethodsNumber = context.debugProcess.methodInvocationsCount
val previousPacketsNumber = packets.getAndSet(totalPacketsNumber)
val previousMethodsNumber = methods.getAndSet(totalMethodsNumber)
if (!firstAccessSkipped) {
firstAccessSkipped = true
return
}
val stepPacketNumber = totalPacketsNumber - previousPacketsNumber
val stepMethodNumber = totalMethodsNumber - previousMethodsNumber
println("Packets sent: $stepPacketNumber, methods called: $stepMethodNumber", ProcessOutputTypes.SYSTEM)
}
}
abstract class AbstractK1IdeK2CodeKotlinSteppingPacketsNumberTest : AbstractKotlinSteppingPacketsNumberTest() {
override fun lambdasGenerationScheme() = JvmClosureGenerationScheme.INDY
override val compileWithK2 = true
override val pluginMode: KotlinPluginMode
get() = KotlinPluginMode.K1
}
@@ -0,0 +1,42 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.debugger.test;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode;
import org.jetbrains.kotlin.idea.base.test.TestRoot;
import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.idea.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
/**
* This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}.
* DO NOT MODIFY MANUALLY.
*/
@SuppressWarnings("all")
@TestRoot("jvm-debugger/test")
@TestDataPath("$CONTENT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("testData/stepping/packets")
public class K1IdeK2CodeKotlinSteppingPacketsNumberTestGenerated extends AbstractK1IdeK2CodeKotlinSteppingPacketsNumberTest {
@java.lang.Override
@org.jetbrains.annotations.NotNull
public final KotlinPluginMode getPluginMode() {
return KotlinPluginMode.K1;
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doCustomTest, this, testDataFilePath);
}
@TestMetadata("coroutineStepping.kt")
public void testCoroutineStepping() throws Exception {
runTest("testData/stepping/packets/coroutineStepping.kt");
}
@TestMetadata("veryLongCoroutineStack.kt")
public void testVeryLongCoroutineStack() throws Exception {
runTest("testData/stepping/packets/veryLongCoroutineStack.kt");
}
}
@@ -0,0 +1,27 @@
package coroutineStepping
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
// ATTACH_LIBRARY: maven(org.jetbrains.kotlinx:kotlinx-coroutines-debug:1.3.8)-javaagent
// ATTACH_LIBRARY: maven(org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4)
fun main(): Unit = runBlocking {
launch {
launch {
launch {
launch {
//Breakpoint!
println()
for (i in 1..5) {
yield()
}
}
}
}
}
}
// STEP_OVER: 10
@@ -0,0 +1,27 @@
LineBreakpoint created at coroutineStepping.kt:17
Run Java
Connected to the target VM
coroutineStepping.kt:17
coroutineStepping.kt:18
Packets sent: 76, methods called: 18
coroutineStepping.kt:19
Packets sent: 68, methods called: 17
coroutineStepping.kt:18
Packets sent: 80, methods called: 18
coroutineStepping.kt:19
Packets sent: 70, methods called: 17
coroutineStepping.kt:18
Packets sent: 77, methods called: 18
coroutineStepping.kt:19
Packets sent: 70, methods called: 17
coroutineStepping.kt:18
Packets sent: 77, methods called: 18
coroutineStepping.kt:19
Packets sent: 70, methods called: 17
coroutineStepping.kt:18
Packets sent: 77, methods called: 18
coroutineStepping.kt:19
Packets sent: 70, methods called: 17
Disconnected from the target VM
Process finished with exit code 0
@@ -0,0 +1,23 @@
package veryLongCoroutineStack
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.delay
// ATTACH_LIBRARY: maven(org.jetbrains.kotlinx:kotlinx-coroutines-debug:1.3.8)-javaagent
// ATTACH_LIBRARY: maven(org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4)
suspend fun foo(n: Int) {
if (n == 0) {
delay(1)
} else {
foo(n - 1)
}
val n1 = 42 // to prevent stackFrame to collapse
}
fun main(): Unit = runBlocking {
//Breakpoint!
foo(20)
}
// STEP_INTO: 100
@@ -0,0 +1,181 @@
LineBreakpoint created at veryLongCoroutineStack.kt:20
Run Java
Connected to the target VM
veryLongCoroutineStack.kt:20
veryLongCoroutineStack.kt:10
Packets sent: 80, methods called: 18
veryLongCoroutineStack.kt:13
Packets sent: 64, methods called: 17
veryLongCoroutineStack.kt:10
Packets sent: 73, methods called: 20
veryLongCoroutineStack.kt:13
Packets sent: 72, methods called: 20
veryLongCoroutineStack.kt:10
Packets sent: 82, methods called: 23
veryLongCoroutineStack.kt:13
Packets sent: 81, methods called: 23
veryLongCoroutineStack.kt:10
Packets sent: 91, methods called: 26
veryLongCoroutineStack.kt:13
Packets sent: 90, methods called: 26
veryLongCoroutineStack.kt:10
Packets sent: 100, methods called: 29
veryLongCoroutineStack.kt:13
Packets sent: 99, methods called: 29
veryLongCoroutineStack.kt:10
Packets sent: 109, methods called: 32
veryLongCoroutineStack.kt:13
Packets sent: 108, methods called: 32
veryLongCoroutineStack.kt:10
Packets sent: 118, methods called: 35
veryLongCoroutineStack.kt:13
Packets sent: 117, methods called: 35
veryLongCoroutineStack.kt:10
Packets sent: 127, methods called: 38
veryLongCoroutineStack.kt:13
Packets sent: 126, methods called: 38
veryLongCoroutineStack.kt:10
Packets sent: 137, methods called: 41
veryLongCoroutineStack.kt:13
Packets sent: 136, methods called: 41
veryLongCoroutineStack.kt:10
Packets sent: 147, methods called: 44
veryLongCoroutineStack.kt:13
Packets sent: 146, methods called: 44
veryLongCoroutineStack.kt:10
Packets sent: 157, methods called: 47
veryLongCoroutineStack.kt:13
Packets sent: 156, methods called: 47
veryLongCoroutineStack.kt:10
Packets sent: 167, methods called: 50
veryLongCoroutineStack.kt:13
Packets sent: 166, methods called: 50
veryLongCoroutineStack.kt:10
Packets sent: 177, methods called: 53
veryLongCoroutineStack.kt:13
Packets sent: 176, methods called: 53
veryLongCoroutineStack.kt:10
Packets sent: 187, methods called: 56
veryLongCoroutineStack.kt:13
Packets sent: 186, methods called: 56
veryLongCoroutineStack.kt:10
Packets sent: 197, methods called: 59
veryLongCoroutineStack.kt:13
Packets sent: 196, methods called: 59
veryLongCoroutineStack.kt:10
Packets sent: 207, methods called: 62
veryLongCoroutineStack.kt:13
Packets sent: 206, methods called: 62
veryLongCoroutineStack.kt:10
Packets sent: 217, methods called: 65
veryLongCoroutineStack.kt:13
Packets sent: 216, methods called: 65
veryLongCoroutineStack.kt:10
Packets sent: 227, methods called: 68
veryLongCoroutineStack.kt:13
Packets sent: 226, methods called: 68
veryLongCoroutineStack.kt:10
Packets sent: 237, methods called: 71
veryLongCoroutineStack.kt:13
Packets sent: 236, methods called: 71
veryLongCoroutineStack.kt:10
Packets sent: 247, methods called: 74
veryLongCoroutineStack.kt:13
Packets sent: 245, methods called: 74
veryLongCoroutineStack.kt:10
Packets sent: 257, methods called: 77
veryLongCoroutineStack.kt:11
Packets sent: 256, methods called: 77
veryLongCoroutineStack.kt:11
Packets sent: 255, methods called: 78
veryLongCoroutineStack.kt:16
Packets sent: 241, methods called: 77
veryLongCoroutineStack.kt:15
Packets sent: 236, methods called: 74
veryLongCoroutineStack.kt:16
Packets sent: 231, methods called: 74
veryLongCoroutineStack.kt:15
Packets sent: 226, methods called: 71
veryLongCoroutineStack.kt:16
Packets sent: 223, methods called: 71
veryLongCoroutineStack.kt:15
Packets sent: 217, methods called: 68
veryLongCoroutineStack.kt:16
Packets sent: 215, methods called: 68
veryLongCoroutineStack.kt:15
Packets sent: 208, methods called: 65
veryLongCoroutineStack.kt:16
Packets sent: 205, methods called: 65
veryLongCoroutineStack.kt:15
Packets sent: 199, methods called: 62
veryLongCoroutineStack.kt:16
Packets sent: 197, methods called: 62
veryLongCoroutineStack.kt:15
Packets sent: 190, methods called: 59
veryLongCoroutineStack.kt:16
Packets sent: 187, methods called: 59
veryLongCoroutineStack.kt:15
Packets sent: 181, methods called: 56
veryLongCoroutineStack.kt:16
Packets sent: 179, methods called: 56
veryLongCoroutineStack.kt:15
Packets sent: 172, methods called: 53
veryLongCoroutineStack.kt:16
Packets sent: 169, methods called: 53
veryLongCoroutineStack.kt:15
Packets sent: 163, methods called: 50
veryLongCoroutineStack.kt:16
Packets sent: 161, methods called: 50
veryLongCoroutineStack.kt:15
Packets sent: 154, methods called: 47
veryLongCoroutineStack.kt:16
Packets sent: 152, methods called: 47
veryLongCoroutineStack.kt:15
Packets sent: 145, methods called: 44
veryLongCoroutineStack.kt:16
Packets sent: 143, methods called: 44
veryLongCoroutineStack.kt:15
Packets sent: 136, methods called: 41
veryLongCoroutineStack.kt:16
Packets sent: 133, methods called: 41
veryLongCoroutineStack.kt:15
Packets sent: 127, methods called: 38
veryLongCoroutineStack.kt:16
Packets sent: 125, methods called: 38
veryLongCoroutineStack.kt:15
Packets sent: 118, methods called: 35
veryLongCoroutineStack.kt:16
Packets sent: 116, methods called: 35
veryLongCoroutineStack.kt:15
Packets sent: 109, methods called: 32
veryLongCoroutineStack.kt:16
Packets sent: 106, methods called: 32
veryLongCoroutineStack.kt:15
Packets sent: 100, methods called: 29
veryLongCoroutineStack.kt:16
Packets sent: 98, methods called: 29
veryLongCoroutineStack.kt:15
Packets sent: 91, methods called: 26
veryLongCoroutineStack.kt:16
Packets sent: 89, methods called: 26
veryLongCoroutineStack.kt:15
Packets sent: 82, methods called: 23
veryLongCoroutineStack.kt:16
Packets sent: 80, methods called: 23
veryLongCoroutineStack.kt:15
Packets sent: 73, methods called: 20
veryLongCoroutineStack.kt:16
Packets sent: 71, methods called: 20
veryLongCoroutineStack.kt:15
Packets sent: 64, methods called: 17
veryLongCoroutineStack.kt:16
Packets sent: 62, methods called: 17
veryLongCoroutineStack.kt:21
Packets sent: 64, methods called: 16
veryLongCoroutineStack.kt:18
Packets sent: 3, methods called: 1
veryLongCoroutineStack.kt:21
Packets sent: 0, methods called: 0
Disconnected from the target VM
Process finished with exit code 0
@@ -262,6 +262,10 @@ private fun assembleWorkspace(): TWorkspace = workspace(KotlinPluginMode.K1) {
}
}
testClass<AbstractK1IdeK2CodeKotlinSteppingPacketsNumberTest> {
model("stepping/packets", isRecursive = false, pattern = KT_WITHOUT_DOTS, testMethodName = "doCustomTest")
}
testClass<AbstractSmartStepIntoTest> {
model("smartStepInto")
}
@@ -61,6 +61,10 @@ internal fun MutableTWorkspace.generateK2DebuggerTests() {
}
}
testClass<AbstractK2IdeK2CodeKotlinSteppingPacketsNumberTest> {
model("stepping/packets", isRecursive = false, pattern = KT_WITHOUT_DOTS, testMethodName = "doCustomTest")
}
testClass<AbstractK2SmartStepIntoTest> {
model("smartStepInto")
}