more robust highlighting tests: execute them with deprioritization disabled to avoid unexpected timeouts

GitOrigin-RevId: ecddcc3493d2c4ff69c7a537f9c7ae4df6fade54
This commit is contained in:
Alexey Kudravtsev
2022-07-20 13:55:45 +00:00
committed by intellij-monorepo-bot
parent 4626607cc9
commit f5af862190
3 changed files with 105 additions and 88 deletions
@@ -2719,8 +2719,17 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately() {
ensureEnoughParallelism();
useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MyInfoAnnotator(), new MySleepyAnnotator(), new MyFastAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately);
}
public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately1() {
ensureEnoughParallelism();
useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MySleepyAnnotator(), new MyInfoAnnotator(), new MyFastAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately);
}
public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately2() {
ensureEnoughParallelism();
useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MySleepyAnnotator(), new MyFastAnnotator(), new MyInfoAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately);
}
public void testAddAnnotationToHolderEntailsCreatingCorrespondingRangeHighlighterMoreOrLessImmediately3() {
ensureEnoughParallelism();
// also check in the opposite order in case the order of annotators is important
useAnnotatorsIn(JavaFileType.INSTANCE.getLanguage(), new MyRecordingAnnotator[]{new MyFastAnnotator(), new MyInfoAnnotator(), new MySleepyAnnotator(), }, this::checkSwearingAnnotationIsVisibleImmediately);
}
@@ -2841,7 +2850,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
}
private static void ensureEnoughParallelism() {
if (ForkJoinPool.commonPool().getParallelism() <= 2) {
if (ForkJoinPool.commonPool().getParallelism() <= 3) {
throw new AssumptionViolatedException("Too low parallelism, I will not even bother, it's hopeless: " + ForkJoinPool.commonPool().getParallelism());
}
}
@@ -41,6 +41,7 @@ import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.impl.CoreProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.DumbServiceImpl;
import com.intellij.openapi.project.Project;
@@ -375,55 +376,66 @@ public final class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implement
fileStatusMap.markFileUpToDate(document, ignoreId);
}
HighlightingSession session = queuePassesCreation(textEditors, passesToIgnore);
((CoreProgressManager)ProgressManager.getInstance()).suppressAllDeprioritizationsDuringLongTestsExecutionIn(() -> {
HighlightingSession session = queuePassesCreation(textEditors, passesToIgnore);
DaemonProgressIndicator progress = getUpdateProgress();
// there can be PCE in FJP during queuePassesCreation
// no PCE guarantees session is not null
progress.checkCanceled();
DaemonProgressIndicator progress = getUpdateProgress();
// there can be PCE in FJP during queuePassesCreation
// no PCE guarantees session is not null
progress.checkCanceled();
try {
long start = System.currentTimeMillis();
while (progress.isRunning() && System.currentTimeMillis() < start + 10*60*1000) {
progress.checkCanceled();
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
try {
long start = System.currentTimeMillis();
while (progress.isRunning() && System.currentTimeMillis() < start + 10 * 60 * 1000) {
progress.checkCanceled();
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
}
waitInOtherThread(50, canChangeDocument);
EDT.dispatchAllInvocationEvents();
Throwable savedException = PassExecutorService.getSavedException(progress);
if (savedException != null) throw savedException;
}
if (progress.isRunning() && !progress.isCanceled()) {
throw new RuntimeException("Highlighting still running after " +
(System.currentTimeMillis() - start) / 1000 +
" seconds." +
" Still submitted passes: " +
myPassExecutorService.getAllSubmittedPasses() +
" ForkJoinPool.commonPool(): " +
ForkJoinPool.commonPool() +
"\n" +
", ForkJoinPool.commonPool() active thread count: " +
ForkJoinPool.commonPool().getActiveThreadCount() +
", ForkJoinPool.commonPool() has queued submissions: " +
ForkJoinPool.commonPool().hasQueuedSubmissions() +
"\n" +
ThreadDumper.dumpThreadsToString());
}
waitInOtherThread(50, canChangeDocument);
EDT.dispatchAllInvocationEvents();
Throwable savedException = PassExecutorService.getSavedException(progress);
if (savedException != null) throw savedException;
}
if (progress.isRunning() && !progress.isCanceled()) {
throw new RuntimeException("Highlighting still running after " +(System.currentTimeMillis()-start)/1000 + " seconds." +
" Still submitted passes: "+myPassExecutorService.getAllSubmittedPasses()+
" ForkJoinPool.commonPool(): "+ForkJoinPool.commonPool()+"\n"+
", ForkJoinPool.commonPool() active thread count: "+ ForkJoinPool.commonPool().getActiveThreadCount()+
", ForkJoinPool.commonPool() has queued submissions: "+ ForkJoinPool.commonPool().hasQueuedSubmissions()+
"\n"+ ThreadDumper.dumpThreadsToString());
}
if (!waitInOtherThread(60000, canChangeDocument)) {
throw new TimeoutException("Unable to complete in 60s. Thread dump:\n"+ThreadDumper.dumpThreadsToString());
if (!waitInOtherThread(60000, canChangeDocument)) {
throw new TimeoutException("Unable to complete in 60s. Thread dump:\n" + ThreadDumper.dumpThreadsToString());
}
((HighlightingSessionImpl)session).waitForHighlightInfosApplied();
EDT.dispatchAllInvocationEvents();
EDT.dispatchAllInvocationEvents();
assert progress.isCanceled() && progress.isDisposed();
}
((HighlightingSessionImpl)session).waitForHighlightInfosApplied();
EDT.dispatchAllInvocationEvents();
EDT.dispatchAllInvocationEvents();
assert progress.isCanceled() && progress.isDisposed();
}
catch (Throwable e) {
Throwable unwrapped = ExceptionUtilRt.unwrapException(e, ExecutionException.class);
if (progress.isCanceled() && progress.isRunning()) {
unwrapped.addSuppressed(new RuntimeException("Daemon progress was canceled unexpectedly: " + progress));
catch (Throwable e) {
Throwable unwrapped = ExceptionUtilRt.unwrapException(e, ExecutionException.class);
if (progress.isCanceled() && progress.isRunning()) {
unwrapped.addSuppressed(new RuntimeException("Daemon progress was canceled unexpectedly: " + progress));
}
ExceptionUtil.rethrow(unwrapped);
}
ExceptionUtil.rethrow(unwrapped);
}
finally {
DaemonProgressIndicator.setDebug(false);
fileStatusMap.allowDirt(true);
progress.cancel();
waitForTermination();
}
finally {
DaemonProgressIndicator.setDebug(false);
fileStatusMap.allowDirt(true);
progress.cancel();
waitForTermination();
}
return null;
});
}
@TestOnly
@@ -84,8 +84,6 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.impl.CoreProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
@@ -259,50 +257,48 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
DaemonCodeAnalyzerSettings settings = DaemonCodeAnalyzerSettings.getInstance();
ProjectInspectionProfileManager.getInstance(project); // avoid "severities changed, restart" event
return ((CoreProgressManager)ProgressManager.getInstance()).suppressAllDeprioritizationsDuringLongTestsExecutionIn(() -> {
ProcessCanceledException exception = null;
int retries = 1000;
for (int i = 0; i < retries; i++) {
int oldDelay = settings.getAutoReparseDelay();
try {
settings.setAutoReparseDelay(0);
List<HighlightInfo> infos = new ArrayList<>();
EdtTestUtil.runInEdtAndWait(() -> {
codeAnalyzer.runPasses(file, editor.getDocument(), Collections.singletonList(textEditor), toIgnore, canChangeDocument, null);
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
if (policy != null) {
policy.waitForHighlighting(project, editor);
}
IdentifierHighlighterPassFactory.waitForIdentifierHighlighting();
infos.addAll(DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), null, project));
if (readEditorMarkupModel) {
MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel();
DaemonCodeAnalyzerEx.processHighlights(markupModel, project, null, 0, editor.getDocument().getTextLength(),
Processors.cancelableCollectProcessor(infos));
}
});
infos.addAll(DaemonCodeAnalyzerEx.getInstanceEx(project).getFileLevelHighlights(project, file));
return infos;
}
catch (ProcessCanceledException e) {
Throwable cause = e.getCause();
if (cause != null && cause.getClass() != Throwable.class) {
// canceled because of an exception, no need to repeat the same
throw e;
ProcessCanceledException exception = null;
int retries = 1000;
for (int i = 0; i < retries; i++) {
int oldDelay = settings.getAutoReparseDelay();
try {
settings.setAutoReparseDelay(0);
List<HighlightInfo> infos = new ArrayList<>();
EdtTestUtil.runInEdtAndWait(() -> {
codeAnalyzer.runPasses(file, editor.getDocument(), Collections.singletonList(textEditor), toIgnore, canChangeDocument, null);
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
if (policy != null) {
policy.waitForHighlighting(project, editor);
}
EdtTestUtil.runInEdtAndWait(() -> {
PsiDocumentManager.getInstance(project).commitAllDocuments();
UIUtil.dispatchAllInvocationEvents();
});
exception = e;
}
finally {
settings.setAutoReparseDelay(oldDelay);
}
IdentifierHighlighterPassFactory.waitForIdentifierHighlighting();
infos.addAll(DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), null, project));
if (readEditorMarkupModel) {
MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel();
DaemonCodeAnalyzerEx.processHighlights(markupModel, project, null, 0, editor.getDocument().getTextLength(),
Processors.cancelableCollectProcessor(infos));
}
});
infos.addAll(DaemonCodeAnalyzerEx.getInstanceEx(project).getFileLevelHighlights(project, file));
return infos;
}
throw new AssertionError("Unable to highlight after " + retries + " retries", exception);
});
catch (ProcessCanceledException e) {
Throwable cause = e.getCause();
if (cause != null && cause.getClass() != Throwable.class) {
// canceled because of an exception, no need to repeat the same
throw e;
}
EdtTestUtil.runInEdtAndWait(() -> {
PsiDocumentManager.getInstance(project).commitAllDocuments();
UIUtil.dispatchAllInvocationEvents();
});
exception = e;
}
finally {
settings.setAutoReparseDelay(oldDelay);
}
}
throw new AssertionError("Unable to highlight after " + retries + " retries", exception);
}
public static void ensureIndexesUpToDate(@NotNull Project project) {