use run all approach to dispose app and detect memory leaks in tests

GitOrigin-RevId: b95c4d54ab32fb1577729c3894e118ac38901334
This commit is contained in:
Vladimir Krivosheev
2019-12-05 12:38:14 +00:00
committed by intellij-monorepo-bot
parent def4ab5500
commit 8254a47327
20 changed files with 216 additions and 282 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2018 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.
// Copyright 2000-2019 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.ide.util.gotoByName
import com.intellij.ide.actions.searcheverywhere.ActionSearchEverywhereContributor
@@ -9,7 +9,6 @@ import com.intellij.ide.ui.search.OptionDescription
import com.intellij.ide.util.gotoByName.GotoActionModel.ActionWrapper
import com.intellij.ide.util.gotoByName.GotoActionModel.MatchMode
import com.intellij.ide.util.gotoByName.GotoActionModel.MatchedValue
import com.intellij.idea.IdeaTestApplication
import com.intellij.java.navigation.ChooseByNameTest
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.application.ApplicationManager
@@ -17,6 +16,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.TestApplicationManager
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
import com.intellij.util.CollectConsumer
import gnu.trove.Equality
@@ -25,7 +25,8 @@ import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import java.awt.Component
import java.awt.*
import java.util.List
import java.util.concurrent.TimeUnit
/**
@@ -310,7 +311,7 @@ class GotoActionTest extends LightJavaCodeInsightFixtureTestCase {
}
private static <T> T computeWithCustomDataProvider(passHiddenFlag, Computable<T> task) {
IdeaTestApplication.getInstance().setDataProvider(new DataProvider() {
TestApplicationManager.getInstance().setDataProvider(new DataProvider() {
@Override
Object getData(@NotNull @NonNls String dataId) {
if (SHOW_HIDDEN_KEY.is(dataId) && passHiddenFlag) return Boolean.TRUE
@@ -322,7 +323,7 @@ class GotoActionTest extends LightJavaCodeInsightFixtureTestCase {
return task.compute()
}
finally {
IdeaTestApplication.getInstance().setDataProvider(null)
TestApplicationManager.getInstance().setDataProvider(null)
}
}
@@ -6,7 +6,6 @@ import com.intellij.find.editorHeaderActions.RemoveOccurrenceAction;
import com.intellij.find.editorHeaderActions.ToggleSelectionOnlyAction;
import com.intellij.ide.DataManager;
import com.intellij.ide.impl.HeadlessDataManager;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.application.Application;
@@ -15,6 +14,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.testFramework.ServiceContainerUtil;
import com.intellij.testFramework.TestApplicationManager;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -30,7 +30,7 @@ import java.util.function.Function;
public class FindInEditorFunctionalTest extends AbstractFindInEditorTest {
@Override
protected void setUp() throws Exception {
IdeaTestApplication.getInstance();
TestApplicationManager.getInstance();
Application application = ApplicationManager.getApplication();
// Necessary to properly update button states
ServiceContainerUtil.replaceService(application, DataManager.class, new HeadlessDataManager() {
@@ -1,11 +1,11 @@
// Copyright 2000-2019 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.util.concurrency;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.testFramework.TestApplicationManager;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.concurrency.AsyncPromise;
@@ -35,7 +35,7 @@ import static javax.swing.SwingUtilities.isEventDispatchThread;
*/
public class InvokerTest {
@SuppressWarnings("unused")
private static final IdeaTestApplication application = IdeaTestApplication.getInstance();
private static final TestApplicationManager application = TestApplicationManager.getInstance();
private final List<Promise<?>> futures = Collections.synchronizedList(new ArrayList<>());
private final Disposable parent = Disposer.newDisposable();
@@ -19,7 +19,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.rt.execution.junit.MapSerializerUtil;
import com.intellij.testFramework.HeavyPlatformTestCase;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.TestApplicationManagerKt;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ref.GCUtil;
@@ -82,7 +82,7 @@ public class _LastInSuiteTest extends TestCase {
List<Object> alive = ContainerUtil.mapNotNull(references, WeakReference::get);
if (!alive.isEmpty()) {
String aliveExtensions = StringUtil.join(alive, o -> o.getClass().getName(), "\n");
System.out.printf("##teamcity[%s name='%s' message='%s']%n", MapSerializerUtil.TEST_FAILED, testName,
System.out.printf("##teamcity[%s name='%s' message='%s']%n", MapSerializerUtil.TEST_FAILED, testName,
escape("Not unloaded extensions:\n" + aliveExtensions + "\n\n" + "See testDynamicExtensions output to find a heapDump"));
System.out.flush();
failed.set(true);
@@ -131,7 +131,7 @@ public class _LastInSuiteTest extends TestCase {
}
}
collectForArea(area, useWhiteList, extensions);
return extensions;
}
@@ -168,15 +168,7 @@ public class _LastInSuiteTest extends TestCase {
return;
}
PlatformTestUtil.disposeApplicationAndCheckForProjectLeaks();
try {
Disposer.assertIsEmpty(true);
}
catch (AssertionError | Exception e) {
PlatformTestUtil.captureMemorySnapshot();
throw e;
}
TestApplicationManagerKt.disposeApplicationAndCheckForLeaks();
}
public void testStatistics() {
@@ -3,7 +3,6 @@ package com.intellij.testFramework
import com.intellij.ide.highlighter.ProjectFileType
import com.intellij.ide.impl.OpenProjectTask
import com.intellij.idea.IdeaTestApplication
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.AppUIExecutor
import com.intellij.openapi.application.ApplicationManager
@@ -51,7 +50,7 @@ open class ApplicationRule : ExternalResource() {
}
public final override fun before() {
IdeaTestApplication.getInstance()
TestApplicationManager.getInstance()
TestRunnerUtil.replaceIdeEventQueueSafely()
(PersistentFS.getInstance() as PersistentFSImpl).cleanPersistedContents()
}
@@ -121,7 +120,7 @@ class ProjectRule(val projectDescriptor: LightProjectDescriptor = LightProjectDe
get() {
var result = sharedProject
if (result == null) {
synchronized(IdeaTestApplication.getInstance()) {
synchronized(TestApplicationManager.getInstance()) {
result = sharedProject
if (result == null) {
result = createLightProject()
@@ -8,8 +8,6 @@ import com.intellij.ide.impl.OpenProjectTask;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.idea.IdeaLogger;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.idea.IdeaTestApplicationKt;
import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataProvider;
@@ -105,7 +103,7 @@ import static com.intellij.testFramework.RunAll.runAll;
*/
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace"})
public abstract class HeavyPlatformTestCase extends UsefulTestCase implements DataProvider {
private static IdeaTestApplication ourTestAppManager;
private static TestApplicationManager ourTestAppManager;
private static boolean ourReportedLeakedProjects;
protected Project myProject;
protected Module myModule;
@@ -162,7 +160,7 @@ public abstract class HeavyPlatformTestCase extends UsefulTestCase implements Da
protected void initApplication() throws Exception {
boolean firstTime = ourTestAppManager == null;
ourTestAppManager = IdeaTestApplication.getInstance();
ourTestAppManager = TestApplicationManager.getInstance();
ourTestAppManager.setDataProvider(this);
if (firstTime) {
@@ -539,7 +537,7 @@ public abstract class HeavyPlatformTestCase extends UsefulTestCase implements Da
protected void tearDown() throws Exception {
Project project = myProject;
if (project != null && !project.isDisposed()) {
IdeaTestApplicationKt.waitForProjectLeakingThreads(project);
TestApplicationManagerKt.waitForProjectLeakingThreads(project);
}
// don't use method references here to make stack trace reading easier
@@ -9,8 +9,6 @@ import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.ide.startup.StartupManagerEx;
import com.intellij.idea.IdeaLogger;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.idea.IdeaTestApplicationKt;
import com.intellij.lang.Language;
import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
@@ -74,7 +72,9 @@ import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import com.intellij.workspace.legacyBridge.intellij.LegacyBridgeProjectLifecycleListener;
import junit.framework.TestCase;
import org.jetbrains.annotations.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
@@ -91,7 +91,6 @@ import static com.intellij.testFramework.RunAll.runAll;
* @author yole
*/
public abstract class LightPlatformTestCase extends UsefulTestCase implements DataProvider {
private static IdeaTestApplication ourTestAppManager;
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
private static Project ourProject;
private static Module ourModule;
@@ -137,21 +136,12 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
}
@NotNull
public static IdeaTestApplication initApplication() {
ourTestAppManager = IdeaTestApplication.getInstance();
return ourTestAppManager;
public static TestApplicationManager initApplication() {
return TestApplicationManager.getInstance();
}
@TestOnly
static void disposeApplication() {
if (ourTestAppManager != null) {
ourTestAppManager.disposeApp();
ourTestAppManager = null;
}
}
public static IdeaTestApplication getApplication() {
return ourTestAppManager;
public static TestApplicationManager getApplication() {
return TestApplicationManager.getInstanceIfCreated();
}
@SuppressWarnings("UseOfSystemOutOrSystemErr")
@@ -244,12 +234,12 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
Timings.getStatistics();
}
initApplication();
TestApplicationManager testAppManager = initApplication();
EdtTestUtil.runInEdtAndWait(() -> {
super.setUp();
ourTestAppManager.setDataProvider(this);
testAppManager.setDataProvider(this);
LightProjectDescriptor descriptor = getProjectDescriptor();
doSetup(descriptor, configureLocalInspectionTools(), getTestRootDisposable());
InjectedLanguageManagerImpl.pushInjectors(getProject());
@@ -382,8 +372,8 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
InplaceRefactoring.checkCleared();
},
() -> {
if (project != null && ourTestAppManager != null) {
doTearDown(project, ourTestAppManager);
if (project != null) {
doTearDown(project, null);
}
},
() -> {
@@ -421,17 +411,16 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
);
}
public static void doTearDown(@NotNull Project project, @NotNull IdeaTestApplication testAppManager) {
public static void doTearDown(@NotNull Project project, @Nullable TestApplicationManager testAppManager) {
try {
IdeaTestApplicationKt.tearDownProjectAndApp(project, testAppManager);
TestApplicationManagerKt.tearDownProjectAndApp(project, testAppManager);
}
finally {
ourTestCase = null;
}
}
@ApiStatus.Internal
public static void checkAssertions() throws Exception {
static void checkAssertions() throws Exception {
if (!ourAssertionsInTestDetected) {
if (IdeaLogger.ourErrorsOccurred != null) {
throw IdeaLogger.ourErrorsOccurred;
@@ -439,8 +428,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
}
}
@ApiStatus.Internal
public static void tearDownSourceRoot(@NotNull Project project) {
static void tearDownSourceRoot(@NotNull Project project) {
WriteCommandAction.runWriteCommandAction(project, () -> {
if (ourSourceRoot != null) {
try {
@@ -14,7 +14,6 @@ import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.process.CapturingProcessAdapter;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessIOExecutorService;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
@@ -30,11 +29,9 @@ import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.AbstractTreeUi;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -903,38 +900,6 @@ public class PlatformTestUtil {
ourProjectCleanups.clear();
}
/**
* Disposes the application (it also stops some application-related threads)
* and checks for project leaks.
*/
public static void disposeApplicationAndCheckForProjectLeaks() {
EdtTestUtil.runInEdtAndWait(() -> {
cleanupAllProjects();
UIUtil.dispatchAllInvocationEvents();
ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
if (application != null) {
System.out.println(application.writeActionStatistics());
}
System.out.println(ActionUtil.ActionPauses.STAT.statistics());
System.out.println(((AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService()).statistics());
System.out.println("ProcessIOExecutorService threads created: " + ((ProcessIOExecutorService)ProcessIOExecutorService.INSTANCE).getThreadCounter());
try {
LeakHunter.checkNonDefaultProjectLeak();
}
catch (AssertionError | Exception e) {
captureMemorySnapshot();
ExceptionUtil.rethrow(e);
}
finally {
LightPlatformTestCase.disposeApplication();
UIUtil.dispatchAllInvocationEvents();
}
});
}
public static void captureMemorySnapshot() {
try {
@SuppressWarnings("SpellCheckingInspection") String className = "com.jetbrains.performancePlugin.profilers.YourKitProfilerHandler";
@@ -1,5 +1,5 @@
// Copyright 2000-2019 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.idea
package com.intellij.testFramework
import com.intellij.ReviseWhenPortedToJDK
import com.intellij.application.options.CodeStyle
@@ -10,6 +10,7 @@ import com.intellij.codeInsight.hint.HintManagerImpl
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory
import com.intellij.diagnostic.ThreadDumper
import com.intellij.execution.process.ProcessIOExecutorService
import com.intellij.ide.DataManager
import com.intellij.ide.GeneratedSourceFileChangeTracker
import com.intellij.ide.GeneratedSourceFileChangeTrackerImpl
@@ -20,8 +21,10 @@ import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.ide.structureView.StructureViewFactory
import com.intellij.ide.structureView.impl.StructureViewFactoryImpl
import com.intellij.idea.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.DataProvider
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.WriteAction
@@ -48,17 +51,16 @@ import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.EmptyRunnable
import com.intellij.psi.PsiManager
import com.intellij.psi.impl.PsiManagerImpl
import com.intellij.psi.templateLanguages.TemplateDataLanguageMappings
import com.intellij.testFramework.HeavyPlatformTestCase
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.UsefulTestCase
import com.intellij.ui.IconManager
import com.intellij.ui.UiInterceptors
import com.intellij.util.ReflectionUtil
import com.intellij.util.concurrency.AppExecutorUtil
import com.intellij.util.concurrency.AppScheduledExecutorService
import com.intellij.util.lang.CompoundRuntimeException
import com.intellij.util.ref.GCUtil
import com.intellij.util.ui.UIUtil
@@ -80,10 +82,10 @@ import java.util.function.Supplier
import javax.swing.SwingUtilities
import javax.swing.Timer
class IdeaTestApplication private constructor() {
class TestApplicationManager private constructor() {
companion object {
@Volatile
private var ourInstance: IdeaTestApplication? = null
private var ourInstance: TestApplicationManager? = null
@Volatile
private var bootstrapError: RuntimeException? = null
private val isBootstrappingAppNow = AtomicBoolean()
@@ -92,7 +94,7 @@ class IdeaTestApplication private constructor() {
get() = ApplicationManager.getApplication().getComponent(DataManager::class.java) as HeadlessDataManager
@JvmStatic
fun getInstance(): IdeaTestApplication {
fun getInstance(): TestApplicationManager {
var result = ourInstance
if (result == null) {
try {
@@ -107,8 +109,11 @@ class IdeaTestApplication private constructor() {
return result
}
@JvmStatic
fun getInstanceIfCreated() = ourInstance
@Synchronized
private fun createInstance(): IdeaTestApplication {
private fun createInstance(): TestApplicationManager {
var result = ourInstance
if (result != null) {
return result
@@ -125,22 +130,10 @@ class IdeaTestApplication private constructor() {
HeavyPlatformTestCase.doAutodetectPlatformPrefix()
loadTestApp()
isBootstrappingAppNow.set(false)
result = IdeaTestApplication()
result = TestApplicationManager()
ourInstance = result
return result
}
@Synchronized
@JvmStatic
private fun disposeInstance() {
if (ourInstance == null) {
return
}
val app = ApplicationManager.getApplication() as ApplicationImpl
// `ApplicationManager#ourApplication` will be automatically set to `null`
app.disposeContainer()
ourInstance = null
}
}
fun setDataProvider(provider: DataProvider?) {
@@ -153,14 +146,13 @@ class IdeaTestApplication private constructor() {
fun getData(dataId: String) = dataManager.dataContext.getData(dataId)
fun disposeApp() {
ApplicationManager.getApplication().invokeAndWait {
disposeInstance()
}
}
fun dispose() {
disposeInstance()
val app = ApplicationManager.getApplication() as ApplicationImpl? ?: return
runInEdtAndWait {
// `ApplicationManager#ourApplication` will be automatically set to `null`
app.disposeContainer()
ourInstance = null
}
}
}
@@ -172,11 +164,11 @@ private fun loadTestApp() {
IdeaForkJoinWorkerThreadFactory.setupForkJoinCommonPool(true)
val loadedPluginFuture = CompletableFuture.supplyAsync(Supplier {
PluginManagerCore.getLoadedPlugins(IdeaTestApplication::class.java.classLoader)
PluginManagerCore.getLoadedPlugins(TestApplicationManager::class.java.classLoader)
}, AppExecutorUtil.getAppExecutorService())
if (EventQueue.isDispatchThread()) {
StartupUtil.replaceSystemEventQueue(logger<IdeaTestApplication>())
StartupUtil.replaceSystemEventQueue(logger<TestApplicationManager>())
}
else {
replaceIdeEventQueueSafely()
@@ -244,7 +236,7 @@ private var testCounter = 0
// Kotlin allows to easily debug code and to get clear and short stack traces
@ApiStatus.Internal
fun tearDownProjectAndApp(project: Project, appManager: IdeaTestApplication) {
fun tearDownProjectAndApp(project: Project, appManager: TestApplicationManager? = null) {
val isLightProject = ProjectManagerImpl.isLight(project)
val l = mutableListOf<Throwable>()
@@ -324,7 +316,7 @@ fun tearDownProjectAndApp(project: Project, appManager: IdeaTestApplication) {
l.run { (ProjectManager.getInstance() as ProjectManagerImpl).forceCloseProject(project, !isLightProject) }
l.run { appManager.setDataProvider(null) }
l.run { (appManager ?: TestApplicationManager.getInstanceIfCreated())?.setDataProvider(null) }
l.run { UiInterceptors.clear() }
l.run { CompletionProgressIndicator.cleanupForNextTest() }
l.run {
@@ -338,6 +330,62 @@ fun tearDownProjectAndApp(project: Project, appManager: IdeaTestApplication) {
CompoundRuntimeException.throwIfNotEmpty(l)
}
/**
* Disposes the application (it also stops some application-related threads)
* and checks for project leaks.
*/
fun disposeApplicationAndCheckForLeaks() {
val l = mutableListOf<Throwable>()
runInEdtAndWait {
l.run { PlatformTestUtil.cleanupAllProjects() }
l.run { UIUtil.dispatchAllInvocationEvents() }
l.run {
val app = ApplicationManager.getApplication() as? ApplicationImpl
if (app != null) {
println(app.writeActionStatistics())
}
println(ActionUtil.ActionPauses.STAT.statistics())
println((AppExecutorUtil.getAppScheduledExecutorService() as AppScheduledExecutorService).statistics())
println("ProcessIOExecutorService threads created: ${(ProcessIOExecutorService.INSTANCE as ProcessIOExecutorService).threadCounter}")
}
l.run {
try {
LeakHunter.checkNonDefaultProjectLeak()
}
catch (e: AssertionError) {
PlatformTestUtil.captureMemorySnapshot()
throw e
}
catch (e: Exception) {
PlatformTestUtil.captureMemorySnapshot()
throw e
}
}
l.run { TestApplicationManager.getInstanceIfCreated()?.dispose() }
l.run { UIUtil.dispatchAllInvocationEvents() }
}
l.run {
try {
Disposer.assertIsEmpty(true)
}
catch (e: AssertionError) {
PlatformTestUtil.captureMemorySnapshot()
throw e
}
catch (e: Exception) {
PlatformTestUtil.captureMemorySnapshot()
throw e
}
}
CompoundRuntimeException.throwIfNotEmpty(l)
}
@ReviseWhenPortedToJDK("9")
private fun checkJavaSwingTimersAreDisposed() {
val timerQueueClass = Class.forName("javax.swing.TimerQueue")
@@ -1,8 +1,6 @@
// Copyright 2000-2019 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.idea.IdeaTestApplicationKt;
/**
* @author yole
*/
@@ -11,6 +9,6 @@ public final class TestRunnerUtil {
}
public static void replaceIdeEventQueueSafely() {
IdeaTestApplicationKt.replaceIdeEventQueueSafely();
TestApplicationManagerKt.replaceIdeEventQueueSafely();
}
}
@@ -39,7 +39,6 @@ import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
import com.intellij.ide.util.scopeChooser.ScopeDescriptor;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.injected.editor.VirtualFileWindow;
@@ -1179,7 +1178,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
public void setUp() throws Exception {
super.setUp();
IdeaTestApplication.getInstance();
TestApplicationManager.getInstance();
EdtTestUtil.runInEdtAndWait(() -> {
myProjectFixture.setUp();
myTempDirFixture.setUp();
@@ -5,8 +5,6 @@ package com.intellij.testFramework.fixtures.impl;
import com.intellij.ProjectTopics;
import com.intellij.ide.IdeView;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.idea.IdeaTestApplicationKt;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -59,7 +57,7 @@ final class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTes
private Project myProject;
private volatile Module myModule;
private final Set<Path> myFilesToDelete = new HashSet<>();
private IdeaTestApplication myTestAppManager;
private TestApplicationManager myTestAppManager;
private final Set<ModuleFixtureBuilder<?>> myModuleFixtureBuilders = new LinkedHashSet<>();
private EditorListenerTracker myEditorListenerTracker;
private ThreadTracker myThreadTracker;
@@ -101,7 +99,7 @@ final class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTes
runAll = runAll
.append(
() -> {
IdeaTestApplicationKt.tearDownProjectAndApp(myProject, myTestAppManager);
TestApplicationManagerKt.tearDownProjectAndApp(myProject, myTestAppManager);
myProject = null;
},
() -> {
@@ -201,7 +199,7 @@ final class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTes
}
private void initApplication() {
myTestAppManager = IdeaTestApplication.getInstance();
myTestAppManager = TestApplicationManager.getInstance();
myTestAppManager.setDataProvider(new MyDataProvider());
}
@@ -3,8 +3,6 @@ package com.intellij.testFramework.fixtures.impl;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.idea.IdeaTestApplicationKt;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.impl.StartMarkAction;
@@ -37,7 +35,7 @@ public final class LightIdeaTestFixtureImpl extends BaseFixture implements Light
public void setUp() throws Exception {
super.setUp();
IdeaTestApplication application = LightPlatformTestCase.initApplication();
TestApplicationManager application = LightPlatformTestCase.initApplication();
Pair<Project, Module> setup = LightPlatformTestCase.doSetup(myProjectDescriptor, LocalInspectionTool.EMPTY_ARRAY, getTestRootDisposable());
myProject = setup.getFirst();
myModule = setup.getSecond();
@@ -70,7 +68,7 @@ public final class LightIdeaTestFixtureImpl extends BaseFixture implements Light
})
.append(() -> {
if (project != null) {
IdeaTestApplicationKt.waitForProjectLeakingThreads(project);
TestApplicationManagerKt.waitForProjectLeakingThreads(project);
}
})
.append(() -> super.tearDown()) // call all disposables' dispose() while the project is still open
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 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.execution.junit;
import com.intellij.execution.Location;
@@ -22,7 +8,6 @@ import com.intellij.execution.junit2.PsiMemberParameterizedLocation;
import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.execution.testframework.JavaTestLocator;
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
@@ -31,6 +16,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.TestApplicationManager;
import com.intellij.testFramework.TestDataProvider;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NonNls;
@@ -87,7 +73,7 @@ public class JUnitRerunFailedTestsTest extends LightJavaCodeInsightFixtureTestCa
"@RunWith(Parameterized.class)\n" +
"public class MyTest {\n" +
" @Test\n" +
" public void testName1() throws Exception {}\n" +
" public void testName1() {}\n" +
"}");
final Project project = getProject();
@@ -190,7 +176,7 @@ public class JUnitRerunFailedTestsTest extends LightJavaCodeInsightFixtureTestCa
public void testMultipleClassesInOneFile() {
myFixture.configureByText("a.java", "public class Test1 {<caret>} public class Test2 {}");
final IdeaTestApplication testApplication = IdeaTestApplication.getInstance();
TestApplicationManager testApplication = TestApplicationManager.getInstance();
try {
testApplication.setDataProvider(new TestDataProvider(myFixture.getProject()) {
@Override
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 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.junit4;
import com.intellij.execution.actions.ConfigurationContext;
@@ -20,7 +6,6 @@ import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.junit.JUnitConfiguration;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.idea.Bombed;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.java.execution.AbstractTestFrameworkCompilingIntegrationTest;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -32,6 +17,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.rt.execution.junit.RepeatCount;
import com.intellij.testFramework.MapDataContext;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.TestApplicationManager;
import com.intellij.testFramework.TestDataProvider;
import com.intellij.util.containers.ContainerUtil;
import jetbrains.buildServer.messages.serviceMessages.BaseTestMessage;
@@ -58,7 +44,7 @@ public class JUnit5IntegrationTest extends AbstractTestFrameworkCompilingIntegra
@Override
protected void setupModule() throws Exception {
super.setupModule();
ModuleRootModificationUtil.updateModel(myModule,
ModuleRootModificationUtil.updateModel(myModule,
model -> model.addContentEntry(getTestContentRoot()).addSourceFolder(getTestContentRoot() + "/test1", true));
final ArtifactRepositoryManager repoManager = getRepoManager();
addMavenLibs(myModule, new JpsMavenRepositoryLibraryDescriptor("org.junit.jupiter", "junit-jupiter-api", "5.3.0"), repoManager);
@@ -74,7 +60,7 @@ public class JUnit5IntegrationTest extends AbstractTestFrameworkCompilingIntegra
}
public void testSelectedMethods() throws Exception {
final IdeaTestApplication testApplication = IdeaTestApplication.getInstance();
final TestApplicationManager testApplication = TestApplicationManager.getInstance();
try {
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
GlobalSearchScope scope = GlobalSearchScope.projectScope(myProject);
@@ -119,7 +105,7 @@ public class JUnit5IntegrationTest extends AbstractTestFrameworkCompilingIntegra
}
public void testPatternConfiguration() throws Exception {
final IdeaTestApplication testApplication = IdeaTestApplication.getInstance();
final TestApplicationManager testApplication = TestApplicationManager.getInstance();
try {
JUnitConfiguration configuration = new JUnitConfiguration("pattern", getProject());
JUnitConfiguration.Data data = configuration.getPersistentData();
@@ -177,7 +163,7 @@ public class JUnit5IntegrationTest extends AbstractTestFrameworkCompilingIntegra
RunConfiguration configuration = createConfiguration(aClass);
((JUnitConfiguration)configuration).setRepeatMode(RepeatCount.N);
((JUnitConfiguration)configuration).setRepeatCount(2);
ProcessOutput processOutput = doStartTestsProcess(configuration);
String systemOutput = processOutput.sys.toString(); //command line
@@ -209,7 +195,7 @@ public class JUnit5IntegrationTest extends AbstractTestFrameworkCompilingIntegra
assertEmpty(processOutput.out);
assertEmpty(processOutput.err);
assertEquals(1, processOutput.messages.stream().filter(TestStarted.class::isInstance).count());
}
@Bombed(month = Calendar.AUGUST, day = 31, user = "Timur Yuldashev", description = "IDEA-174534")
@@ -8,7 +8,6 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupEx;
import com.intellij.find.findUsages.CustomUsageSearcher;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
@@ -151,7 +150,7 @@ public abstract class PyTestCase extends UsefulTestCase {
}
private static void initApplication() {
IdeaTestApplication.getInstance();
TestApplicationManager.getInstance();
}
/**
@@ -1,8 +1,8 @@
// Copyright 2000-2019 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.jetbrains.python.tools
import com.intellij.idea.IdeaTestApplication
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.testFramework.TestApplicationManager
import com.intellij.util.io.Compressor
import com.jetbrains.python.sdk.PythonSdkUtil
import com.jetbrains.python.sdk.skeletons.DefaultPregeneratedSkeletonsProvider
@@ -13,15 +13,11 @@ import java.io.File
import kotlin.math.abs
import kotlin.system.exitProcess
/**
* @author traff
*/
const val PYCHARM_PYTHONS: String = "PYCHARM_PYTHONS"
internal const val PYCHARM_PYTHONS = "PYCHARM_PYTHONS"
fun main() {
println("Starting build process")
val app = IdeaTestApplication.getInstance()
val app = TestApplicationManager.getInstance()
println("App started: ${app}")
try {
@@ -1,11 +1,11 @@
// Copyright 2000-2019 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.jetbrains.python.tools
import com.intellij.idea.IdeaTestApplication
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.TestApplicationManager
import com.intellij.util.PlatformUtils
import com.intellij.util.io.ZipUtil
import java.io.File
@@ -14,13 +14,13 @@ import java.io.File
* @author Aleksey.Rostovskiy
*/
open class PyGeneratorBase {
protected val app: IdeaTestApplication by lazy {
protected val app by lazy {
System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, PlatformUtils.PYCHARM_CE_PREFIX)
System.setProperty(PathManager.PROPERTY_PLUGINS_PATH, FileUtil.createTempDirectory("pystubs", "plugins").absolutePath)
System.setProperty(PathManager.PROPERTY_SYSTEM_PATH, FileUtil.createTempDirectory("pystubs", "system").absolutePath)
System.setProperty(PathManager.PROPERTY_CONFIG_PATH, FileUtil.createTempDirectory("pystubs", "config").absolutePath)
//Thread.currentThread().contextClassLoader = BootstrapClassLoaderUtil.initClassLoader()
IdeaTestApplication.getInstance()
TestApplicationManager.getInstance()
}
protected fun rootFiles(root: String): ArrayList<VirtualFile>{
@@ -51,7 +51,7 @@ open class PyGeneratorBase {
}
protected fun tearDown() {
app.disposeApp()
app.dispose()
FileUtil.delete(File(System.getProperty(PathManager.PROPERTY_PLUGINS_PATH)))
FileUtil.delete(File(System.getProperty(PathManager.PROPERTY_SYSTEM_PATH)))
}
@@ -2,18 +2,14 @@
package org.jetbrains.index.stubs
import com.google.common.hash.HashCode
import com.intellij.idea.IdeaTestApplication
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.project.ex.ProjectManagerEx
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.impl.DebugUtil
import com.intellij.psi.stubs.*
import com.intellij.testFramework.TestApplicationManager
import com.intellij.util.indexing.FileBasedIndexExtension
import com.intellij.util.indexing.FileContentImpl
import com.intellij.util.io.PersistentHashMap
@@ -72,97 +68,84 @@ private fun writeStubsVersionFile(stubsStorageFilePath: String, stubsVersion: St
}
fun mergeStubs(paths: List<String>, stubsFilePath: String, stubsFileName: String, projectPath: String, stubsVersion: String) {
val app = IdeaTestApplication.getInstance()
val project = ProjectManager.getInstance().loadAndOpenProject(projectPath)!!
TestApplicationManager.getInstance()
ProjectManager.getInstance().loadAndOpenProject(projectPath)!!
// we don't need a project here, but I didn't find a better way to wait until indices and components are initialized
try {
val stubExternalizer = FullStubExternalizer()
val stubExternalizer = FullStubExternalizer()
val storageFile = File(stubsFilePath, "$stubsFileName.input")
if (storageFile.exists()) {
storageFile.delete()
}
val storage = PersistentHashMap<HashCode, SerializedStubTree>(storageFile,
HashCodeDescriptor.instance, stubExternalizer)
val stringEnumeratorFile = File(stubsFilePath, "$stubsFileName.names")
if (stringEnumeratorFile.exists()) {
stringEnumeratorFile.delete()
}
val newSerializationManager = SerializationManagerImpl(stringEnumeratorFile, false)
val map = HashMap<HashCode, Int>()
println("Writing results to ${storageFile.absolutePath}")
for (path in paths) {
println("Reading stubs from $path")
var count = 0
val fromStorageFile = File(path, "$stubsFileName.input")
val fromStorage = PersistentHashMap<HashCode, SerializedStubTree>(fromStorageFile,
HashCodeDescriptor.instance, stubExternalizer)
val serializationManager = SerializationManagerImpl(File(path, "$stubsFileName.names"), true)
try {
fromStorage.processKeysWithExistingMapping { key ->
count++
val value = fromStorage.get(key)
// re-serialize stub tree to correctly enumerate strings in the new string enumerator
val newStubTree = value.reSerialize(serializationManager, newSerializationManager, STUB_EXTERNALIZER, STUB_EXTERNALIZER)
if (storage.containsMapping(key)) {
if (newStubTree != storage.get(key)) { // TODO: why are they slightly different???
storage.get(key).getStub(false, newSerializationManager)
val stub = value.getStub(false, serializationManager)
val newStubTree2 = SerializedStubTree(stub, newSerializationManager, STUB_EXTERNALIZER)
TestCase.assertTrue(newStubTree == newStubTree2) // wtf!!! why are they equal now???
}
map[key] = map[key]!! + 1
}
else {
storage.put(key, newStubTree)
map[key] = 1
}
true
}
}
finally {
fromStorage.close()
Disposer.dispose(serializationManager)
}
println("Items in ${fromStorageFile.absolutePath}: $count")
}
storage.close()
Disposer.dispose(newSerializationManager)
val total = map.size
println("Total items in storage: $total")
writeStubsVersionFile(stringEnumeratorFile.nameWithoutExtension, stubsVersion)
for (i in 2..paths.size) {
val count = map.entries.stream().filter { e -> e.value == i }.count()
println("Intersection between $i: ${"%.2f".format(if (total > 0) 100.0 * count / total else 0.0)}%")
}
val storageFile = File(stubsFilePath, "$stubsFileName.input")
if (storageFile.exists()) {
storageFile.delete()
}
finally {
ApplicationManager.getApplication().invokeAndWait(Runnable {
ProjectManagerEx.getInstanceEx().forceCloseProject(project)
WriteAction.run<Throwable> {
app.dispose()
val storage = PersistentHashMap<HashCode, SerializedStubTree>(storageFile, HashCodeDescriptor.instance, stubExternalizer)
val stringEnumeratorFile = File(stubsFilePath, "$stubsFileName.names")
if (stringEnumeratorFile.exists()) {
stringEnumeratorFile.delete()
}
val newSerializationManager = SerializationManagerImpl(stringEnumeratorFile, false)
val map = HashMap<HashCode, Int>()
println("Writing results to ${storageFile.absolutePath}")
for (path in paths) {
println("Reading stubs from $path")
var count = 0
val fromStorageFile = File(path, "$stubsFileName.input")
val fromStorage = PersistentHashMap<HashCode, SerializedStubTree>(fromStorageFile, HashCodeDescriptor.instance, stubExternalizer)
val serializationManager = SerializationManagerImpl(File(path, "$stubsFileName.names"), true)
try {
fromStorage.processKeysWithExistingMapping { key ->
count++
val value = fromStorage.get(key)
// re-serialize stub tree to correctly enumerate strings in the new string enumerator
val newStubTree = value.reSerialize(serializationManager, newSerializationManager, STUB_EXTERNALIZER, STUB_EXTERNALIZER)
if (storage.containsMapping(key)) {
if (newStubTree != storage.get(key)) { // TODO: why are they slightly different???
storage.get(key).getStub(false, newSerializationManager)
val stub = value.getStub(false, serializationManager)
val newStubTree2 = SerializedStubTree(stub, newSerializationManager, STUB_EXTERNALIZER)
TestCase.assertTrue(newStubTree == newStubTree2) // wtf!!! why are they equal now???
}
map[key] = map[key]!! + 1
}
else {
storage.put(key, newStubTree)
map[key] = 1
}
true
}
}, ModalityState.NON_MODAL)
}
finally {
fromStorage.close()
Disposer.dispose(serializationManager)
}
println("Items in ${fromStorageFile.absolutePath}: $count")
}
storage.close()
Disposer.dispose(newSerializationManager)
val total = map.size
println("Total items in storage: $total")
writeStubsVersionFile(stringEnumeratorFile.nameWithoutExtension, stubsVersion)
for (i in 2..paths.size) {
val count = map.entries.stream().filter { e -> e.value == i }.count()
println("Intersection between $i: ${"%.2f".format(if (total > 0) 100.0 * count / total else 0.0)}%")
}
exitProcess(0)
@@ -1,7 +1,6 @@
// Copyright 2000-2019 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 org.jetbrains.index.stubs
import com.intellij.idea.IdeaTestApplication
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.module.Module
@@ -11,6 +10,7 @@ import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.TestApplicationManager
import com.intellij.util.ui.UIUtil
import java.io.File
import kotlin.system.exitProcess
@@ -27,7 +27,7 @@ abstract class ProjectSdkStubsGenerator {
private val stubsFileName = "sdk-stubs"
fun buildStubs(baseDir: String) {
IdeaTestApplication.getInstance()
TestApplicationManager.getInstance()
try {
for (python in File(root).listFiles()!!) {
if (python.name.startsWith(".")) {