From 74130d0a52e33b967e9adee689a49b2ad44c6f70 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 2 Oct 2017 18:42:39 +0300 Subject: [PATCH] refactor sdk leak code to work in Kotlin tests with their absence of JdkTable --- .../testFramework/LightPlatformTestCase.java | 7 ++- .../testFramework/PlatformTestCase.java | 8 ++-- .../testFramework/SdkLeakTracker.java | 47 +++++++++++++++++++ .../impl/HeavyIdeaTestFixtureImpl.java | 8 ++-- .../impl/LightIdeaTestFixtureImpl.java | 8 ++-- 5 files changed, 60 insertions(+), 18 deletions(-) create mode 100644 platform/testFramework/src/com/intellij/testFramework/SdkLeakTracker.java diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index a00bd3bbfaed..17ef6f35813d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -59,7 +59,6 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.project.impl.ProjectImpl; import com.intellij.openapi.project.impl.ProjectManagerImpl; -import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderRootType; @@ -130,7 +129,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da private static TestCase ourTestCase; public static Thread ourTestThread; private static LightProjectDescriptor ourProjectDescriptor; - private static Sdk[] myOldSdks; + private static SdkLeakTracker myOldSdks; private ThreadTracker myThreadTracker; @@ -296,7 +295,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da IdeaLogger.ourErrorsOccurred = null; ApplicationManager.getApplication().assertIsDispatchThread(); - myOldSdks = ProjectJdkTable.getInstance().getAllJdks(); + myOldSdks = new SdkLeakTracker(); boolean reusedProject = true; if (ourProject == null || ourProjectDescriptor == null || !ourProjectDescriptor.equals(descriptor)) { @@ -383,7 +382,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da this::checkForSettingsDamage, () -> doTearDown(project, ourApplication), () -> checkEditorsReleased(), - () -> checkForJdkTableLeaks(myOldSdks), + () -> myOldSdks.checkForJdkTableLeaks(), super::tearDown, () -> myThreadTracker.checkLeak(), () -> InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project), diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 237d793a873e..86d6dc500bf7 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -127,7 +127,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro private static boolean ourPlatformPrefixInitialized; private static Set ourEternallyLivingFilesCache; - private Sdk[] myOldSdks; + private SdkLeakTracker myOldSdks; private VirtualFilePointerTracker myVirtualFilePointerTracker; /** @@ -148,7 +148,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro cleanPersistedVFSContent(); } // try to remember old sdks as soon as possible after the app instantiation - myOldSdks = ProjectJdkTable.getInstance().getAllJdks(); + myOldSdks = new SdkLeakTracker(); } private static final String[] PREFIX_CANDIDATES = { @@ -210,7 +210,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro initApplication(); if (myOldSdks == null) { // some bastard's overridden initApplication completely - myOldSdks = ProjectJdkTable.getInstance().getAllJdks(); + myOldSdks = new SdkLeakTracker(); } myEditorListenerTracker = new EditorListenerTracker(); @@ -522,7 +522,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } }) .append(LightPlatformTestCase::checkEditorsReleased) - .append(() -> UsefulTestCase.checkForJdkTableLeaks(myOldSdks)) + .append(() -> myOldSdks.checkForJdkTableLeaks()) .append(() -> myVirtualFilePointerTracker.assertPointersAreDisposed()) .append(() -> { myProjectManager = null; diff --git a/platform/testFramework/src/com/intellij/testFramework/SdkLeakTracker.java b/platform/testFramework/src/com/intellij/testFramework/SdkLeakTracker.java new file mode 100644 index 000000000000..458c5968a841 --- /dev/null +++ b/platform/testFramework/src/com/intellij/testFramework/SdkLeakTracker.java @@ -0,0 +1,47 @@ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.testFramework; + +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.Sdk; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; +import org.junit.Assert; + +import java.util.Arrays; +import java.util.Set; + +@TestOnly +public class SdkLeakTracker { + @NotNull + private final Sdk[] oldSdks; + public SdkLeakTracker() { + ProjectJdkTable table = ProjectJdkTable.getInstance(); + oldSdks = table == null ? new Sdk[0] : table.getAllJdks(); + } + + public void checkForJdkTableLeaks() { + ProjectJdkTable table = ProjectJdkTable.getInstance(); + if (table != null) { + Sdk[] jdks = table.getAllJdks(); + if (jdks.length != 0) { + Set leaked = new THashSet<>(Arrays.asList(jdks)); + Set old = new THashSet<>(Arrays.asList(oldSdks)); + leaked.removeAll(old); + + try { + if (!leaked.isEmpty()) { + Assert.fail("Leaked SDKs: " + leaked); + } + } + finally { + for (Sdk jdk : leaked) { + WriteAction.run(()-> table.removeJdk(jdk)); + } + } + } + } + } + +} diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java index 7be89052172b..11fdccfbc99d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java @@ -34,8 +34,6 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; -import com.intellij.openapi.projectRoots.ProjectJdkTable; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -79,7 +77,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu private EditorListenerTracker myEditorListenerTracker; private ThreadTracker myThreadTracker; private final String myName; - private Sdk[] myOldSdks; + private SdkLeakTracker myOldSdks; HeavyIdeaTestFixtureImpl(@NotNull String name) { myName = name; @@ -100,7 +98,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu myEditorListenerTracker = new EditorListenerTracker(); myThreadTracker = new ThreadTracker(); InjectedLanguageManagerImpl.pushInjectors(getProject()); - myOldSdks = ProjectJdkTable.getInstance().getAllJdks(); + myOldSdks = new SdkLeakTracker(); } @Override @@ -143,7 +141,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu .append(() -> myEditorListenerTracker.checkListenersLeak()) .append(() -> myThreadTracker.checkLeak()) .append(LightPlatformTestCase::checkEditorsReleased) - .append(() -> UsefulTestCase.checkForJdkTableLeaks(myOldSdks)) + .append(() -> myOldSdks.checkForJdkTableLeaks()) .append(() -> PlatformTestCase.cleanupApplicationCaches(null)) // project is disposed by now, no point in passing it .run(); } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java index b9094c70f5f6..a2b714a8d17a 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightIdeaTestFixtureImpl.java @@ -21,8 +21,6 @@ import com.intellij.idea.IdeaTestApplication; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.ProjectJdkTable; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.psi.codeStyle.CodeStyleSchemes; import com.intellij.psi.codeStyle.CodeStyleSettings; @@ -38,7 +36,7 @@ import com.intellij.testFramework.fixtures.LightIdeaTestFixture; public class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTestFixture { private final LightProjectDescriptor myProjectDescriptor; private CodeStyleSettings myOldCodeStyleSettings; - private Sdk[] myOldSdks; + private SdkLeakTracker myOldSdks; public LightIdeaTestFixtureImpl(LightProjectDescriptor projectDescriptor) { myProjectDescriptor = projectDescriptor; @@ -56,7 +54,7 @@ public class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTe myOldCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA); application.setDataProvider(new TestDataProvider(getProject())); - myOldSdks = ProjectJdkTable.getInstance().getAllJdks(); + myOldSdks = new SdkLeakTracker(); } @Override @@ -71,7 +69,7 @@ public class LightIdeaTestFixtureImpl extends BaseFixture implements LightIdeaTe .append(() -> LightPlatformTestCase.doTearDown(project, LightPlatformTestCase.getApplication())) .append(super::tearDown) .append(() -> LightPlatformTestCase.checkEditorsReleased()) - .append(() -> UsefulTestCase.checkForJdkTableLeaks(myOldSdks)) + .append(() -> myOldSdks.checkForJdkTableLeaks()) .append(() -> InjectedLanguageManagerImpl.checkInjectorsAreDisposed(project)) .append(() -> PersistentFS.getInstance().clearIdCache()) .append(() -> PlatformTestCase.cleanupApplicationCaches(project))