workaround for blinking tests because of JVMTI_ERROR_WRONG_PHASE(112)

This commit is contained in:
Egor.Ushakov
2017-02-21 11:57:11 +03:00
parent 527777d4fd
commit 8e4de4c726
3 changed files with 65 additions and 13 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@ import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
@@ -55,6 +56,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
@@ -67,10 +69,14 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCase {
public static final int DEFAULT_ADDRESS = 3456;
protected DebuggerSession myDebuggerSession;
protected final AtomicInteger myRestart = new AtomicInteger();
private static final int MAX_RESTARTS = 3;
private volatile TestDisposable myTestRootDisposable;
@Override
protected void initApplication() throws Exception {
@@ -93,10 +99,42 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
assertNull(DebuggerManagerEx.getInstanceEx(myProject).getDebugProcess(getDebugProcess().getProcessHandler()));
myDebuggerSession = null;
}
if (getChecker().contains("JVMTI_ERROR_WRONG_PHASE(112)")) {
myRestart.incrementAndGet();
if (needsRestart()) {
return;
}
} else {
myRestart.set(0);
}
throwExceptionsIfAny();
checkTestOutput();
}
private boolean needsRestart() {
int restart = myRestart.get();
return restart > 0 && restart <= MAX_RESTARTS;
}
@Override
protected void runBareRunnable(ThrowableRunnable<Throwable> runnable) throws Throwable {
myTestRootDisposable = new TestDisposable();
super.runBareRunnable(runnable);
while (needsRestart()) {
assert (myTestRootDisposable.isDisposed());
myTestRootDisposable = new TestDisposable();
super.runBareRunnable(runnable);
}
}
@NotNull
@Override
public Disposable getTestRootDisposable() {
return myTestRootDisposable;
}
protected void checkTestOutput() throws Exception {
getChecker().checkValid(getTestProjectJdk());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -157,6 +157,10 @@ public class OutputChecker {
}
}
public boolean contains(String str) {
return buildOutputString().contains(str);
}
private synchronized String buildOutputString() {
final StringBuilder result = new StringBuilder();
for (Key key : OUTPUT_ORDER) {
@@ -88,16 +88,7 @@ public abstract class UsefulTestCase extends TestCase {
}
@NotNull
private final Disposable myTestRootDisposable = new Disposable() {
@Override
public void dispose() { }
@Override
public String toString() {
String testName = getTestName(false);
return UsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
}
};
private final Disposable myTestRootDisposable = new TestDisposable();
static String ourPathToKeep;
private final List<String> myPathsToKeep = new ArrayList<>();
@@ -307,7 +298,7 @@ public abstract class UsefulTestCase extends TestCase {
}
@NotNull
public final Disposable getTestRootDisposable() {
public Disposable getTestRootDisposable() {
return myTestRootDisposable;
}
@@ -1000,4 +991,23 @@ public abstract class UsefulTestCase extends TestCase {
@Deprecated
public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.roots.IdeaModifiableModelsProvider";
//</editor-fold>
public class TestDisposable implements Disposable {
private volatile boolean myDisposed;
@Override
public void dispose() {
myDisposed = true;
}
public boolean isDisposed() {
return myDisposed;
}
@Override
public String toString() {
String testName = getTestName(false);
return UsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
}
}
}