From 7bc7852865ffbb86c7cfe3bfe16798ae71faf7b0 Mon Sep 17 00:00:00 2001 From: Konstantin Kolosovsky Date: Wed, 28 Jun 2017 14:47:12 +0300 Subject: [PATCH] Fix directory mappings initialization for "CommittedChangesCacheTest" Previous implementation of "ProjectLevelVcsManagerImpl.waitForInitialized" could return when "VcsInitialization" was in IDLE (but not FINISHED) status. In such cases logic relying on active vcses configuration could've been called before active vcses were initialized (in "NewMappings.activateActiveVcses()") which led to errors in tests. --- .../vcs/impl/ProjectLevelVcsManagerImpl.java | 3 +-- .../openapi/vcs/impl/VcsInitialization.java | 22 ++++++++++++++----- .../committed/CommittedChangesCacheTest.java | 3 ++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index 04d05c0e6bc0..ae599868b7a8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -21,7 +21,6 @@ import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.AppLifecycleListener; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; @@ -883,7 +882,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @TestOnly public void waitForInitialized() { - myInitialization.waitForCompletion(); + myInitialization.waitFinished(); } private static class ActionKey { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java index 2b36da508f05..697d54004eb2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java @@ -38,6 +38,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.Future; +import java.util.function.Predicate; public class VcsInitialization implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.impl.VcsInitialization"); @@ -125,29 +126,38 @@ public class VcsInitialization implements Disposable { // dispose happens without prior project close (most likely light project case in tests) // get out of write action and wait there //noinspection SSBasedInspection - SwingUtilities.invokeLater(this::waitForCompletion); + SwingUtilities.invokeLater(this::waitNotRunning); } else { - waitForCompletion(); + waitNotRunning(); } } } - void waitForCompletion() { - LOG.debug("waitForCompletion() status=" + myStatus); + void waitNotRunning() { + waitFor(status -> status != Status.RUNNING); + } + + void waitFinished() { + waitFor(status -> status == Status.FINISHED); + } + + private void waitFor(@NotNull Predicate predicate) { + LOG.debug("waitFor() status=" + myStatus); // have to wait for task completion to avoid running it in background for closed project long start = System.currentTimeMillis(); Status status = null; while (System.currentTimeMillis() < start + 10000) { synchronized (myLock) { - if ((status=myStatus) != Status.RUNNING) { + status = myStatus; + if (predicate.test(status)) { break; } } TimeoutUtil.sleep(10); } if (status == Status.RUNNING) { - LOG.error("Failed to wait for completion of VCS initialization for project "+ myProject, + LOG.error("Failed to wait for completion of VCS initialization for project " + myProject, new Attachment("thread dump", ThreadDumper.dumpThreadsToString())); } } diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/committed/CommittedChangesCacheTest.java b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/committed/CommittedChangesCacheTest.java index da870fd3b31a..91300298b9b5 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/committed/CommittedChangesCacheTest.java +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/committed/CommittedChangesCacheTest.java @@ -62,7 +62,6 @@ public class CommittedChangesCacheTest extends PlatformTestCase { super.setUp(); myVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(getProject()); - myVcsManager.waitForInitialized(); myVcs = new MockAbstractVcs(getProject()); myProvider = new MockCommittedChangesProvider(); @@ -72,6 +71,8 @@ public class CommittedChangesCacheTest extends PlatformTestCase { myVcsManager.registerVcs(myVcs); myVcsManager.setDirectoryMappings(singletonList(new VcsDirectoryMapping("", myVcs.getName()))); + myVcsManager.waitForInitialized(); + assertTrue(myVcsManager.hasActiveVcss()); myCache = CommittedChangesCache.getInstance(getProject()); assertEquals(1, myCache.getCachesHolder().getAllCaches().size());