use kotlin coroutines instead of fork-join pool and completable future (part 16 - fix gradle tests)

GitOrigin-RevId: 54152b2b364a82ee1f3ec6465bdad59dc168a2a9
This commit is contained in:
Vladimir Krivosheev
2022-07-13 10:22:28 +00:00
committed by intellij-monorepo-bot
parent f817e4b1fb
commit 2bc51f6d67
5 changed files with 54 additions and 52 deletions
@@ -56,13 +56,17 @@ abstract class ProjectManagerEx : ProjectManager() {
/**
* The project and the app settings will be not saved.
*/
abstract fun forceCloseProject(project: Project): Boolean
@TestOnly
fun forceCloseProject(project: Project): Boolean = forceCloseProject(project, save = false)
@TestOnly
abstract fun forceCloseProject(project: Project, save: Boolean): Boolean
@Internal
abstract suspend fun forceCloseProjectAsync(project: Project): Boolean
abstract suspend fun forceCloseProjectAsync(project: Project, save: Boolean = false): Boolean
@Internal
abstract fun saveAndForceCloseProject(project: Project): Boolean
fun saveAndForceCloseProject(project: Project): Boolean = forceCloseProject(project, save = true)
// return true if successful
abstract fun closeAndDisposeAllProjects(checkCanClose: Boolean): Boolean
@@ -296,23 +296,20 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable {
return closeProject(project = project, saveProject = true, dispose = false, checkCanClose = true)
}
override fun forceCloseProject(project: Project): Boolean {
return closeProject(project = project, saveProject = false, dispose = true, checkCanClose = false)
override fun forceCloseProject(project: Project, save: Boolean): Boolean {
return closeProject(project = project, saveProject = save, dispose = true, checkCanClose = false)
}
override suspend fun forceCloseProjectAsync(project: Project): Boolean {
return withContext(Dispatchers.EDT) {
override suspend fun forceCloseProjectAsync(project: Project, save: Boolean): Boolean {
// ModalityState.NON_MODAL for write-safe context
return withContext(Dispatchers.EDT + ModalityState.NON_MODAL.asContextElement()) {
if (project.isDisposed) {
return@withContext false
}
closeProject(project = project, saveProject = false, dispose = true, checkCanClose = false)
closeProject(project = project, saveProject = save, dispose = true, checkCanClose = false)
}
}
override fun saveAndForceCloseProject(project: Project): Boolean {
return closeProject(project = project, saveProject = true, dispose = true, checkCanClose = false)
}
// return true if successful
override fun closeAndDisposeAllProjects(checkCanClose: Boolean): Boolean {
var projects = openProjects
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.testFramework.fixtures.impl;
import com.intellij.analysis.AnalysisScope;
@@ -132,6 +132,7 @@ import com.intellij.util.indexing.FindSymbolParameters;
import com.intellij.util.io.ReadOnlyAttributeUtil;
import com.intellij.util.ui.UIUtil;
import junit.framework.ComparisonFailure;
import kotlin.UninitializedPropertyAccessException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -1290,7 +1291,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
try {
project = myProjectFixture.getProject();
}
catch (AssertionError ignore) {
catch (AssertionError | UninitializedPropertyAccessException ignore) {
project = null;
}
@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.gradle.testFramework.fixtures.impl
import com.intellij.ide.impl.ProjectUtil
import com.intellij.openapi.Disposable
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
@@ -13,6 +14,7 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.observable.operations.CompoundParallelOperationTrace
import com.intellij.openapi.observable.operations.ObservableOperationTrace
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ex.ProjectManagerEx
import com.intellij.openapi.project.modules
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vfs.VirtualFile
@@ -20,13 +22,18 @@ import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.SdkTestFixture
import com.intellij.testFramework.runAll
import com.intellij.testFramework.runInEdtAndWait
import kotlinx.coroutines.runBlocking
import org.gradle.util.GradleVersion
import org.jetbrains.concurrency.AsyncPromise
import org.jetbrains.concurrency.asDeferred
import org.jetbrains.plugins.gradle.testFramework.fixtures.FileTestFixture
import org.jetbrains.plugins.gradle.testFramework.fixtures.GradleTestFixture
import org.jetbrains.plugins.gradle.testFramework.fixtures.GradleTestFixtureFactory
import org.jetbrains.plugins.gradle.testFramework.util.*
import org.jetbrains.plugins.gradle.testFramework.util.closeProject
import org.jetbrains.plugins.gradle.testFramework.util.generateWrapper
import org.jetbrains.plugins.gradle.testFramework.util.withSuppressedErrors
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.jetbrains.plugins.gradle.util.getProjectDataLoadPromise
import org.jetbrains.plugins.gradle.util.waitForProjectReload
import java.util.concurrent.TimeUnit
@@ -56,7 +63,7 @@ internal class GradleTestFixtureImpl private constructor(
GradleTestFixtureFactory.getFixtureFactory().createFileTestFixture("GradleTestFixture/$gradleVersion/$projectName") {
configureProject()
withFiles { generateWrapper(it, gradleVersion) }
withFiles { createProjectCaches(it) }
withFiles { runBlocking { createProjectCaches(it) } }
}
)
@@ -69,7 +76,7 @@ internal class GradleTestFixtureImpl private constructor(
installTaskExecutionWatcher()
installProjectReloadWatcher()
_project = openProject(fileFixture.root)
_project = runBlocking { ProjectUtil.openOrImportAsync(fileFixture.root.toNioPath())!! }
}
override fun tearDown() {
@@ -139,12 +146,30 @@ internal class GradleTestFixtureImpl private constructor(
}
}
private fun createProjectCaches(projectRoot: VirtualFile) {
private suspend fun createProjectCaches(projectRoot: VirtualFile) {
val project = openProjectAndWait(projectRoot)
runAll(
{ projectRoot.refreshAndWait() },
{ project.closeProject(save = true) }
)
try {
projectRoot.refreshAndWait()
}
finally {
ProjectManagerEx.getInstanceEx().forceCloseProjectAsync(project = project, save = true)
}
}
}
}
private suspend fun openProjectAndWait(projectRoot: VirtualFile): Project {
val project = ProjectUtil.openOrImportAsync(projectRoot.toNioPath())!!
try {
getProjectDataLoadPromise().asDeferred().await()
}
catch (e: Throwable) {
try {
ProjectManagerEx.getInstanceEx().forceCloseProjectAsync(project)
}
catch (ignore: Throwable) {
}
throw e
}
return project
}
@@ -1,44 +1,19 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.gradle.testFramework.util
import com.intellij.configurationStore.StoreUtil
import com.intellij.ide.impl.ProjectUtil
import com.intellij.openapi.externalSystem.util.runInEdtAndWait
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ex.ProjectManagerEx
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.runAll
import com.intellij.util.createException
import kotlinx.coroutines.runBlocking
import org.jetbrains.plugins.gradle.util.waitForProjectReload
fun openProject(projectRoot: VirtualFile): Project {
return runBlocking { ProjectUtil.openOrImportAsync(projectRoot.toNioPath())!! }
}
fun Project.closeProject(save: Boolean = false) {
runInEdtAndWait {
val projectManager = ProjectManagerEx.getInstanceEx()
runAll(
{ if (save) StoreUtil.saveSettings(this, forceSavingAllSettings = true) },
{ projectManager.forceCloseProject(this) }
)
internal fun Project.closeProject(save: Boolean = false) {
val project = this
runBlocking {
ProjectManagerEx.getInstanceEx().forceCloseProjectAsync(project, save = save)
}
}
fun openProjectAndWait(projectRoot: VirtualFile): Project {
var project: Project? = null
return runCatching {
waitForProjectReload {
project = openProject(projectRoot)
project!!
}
}.onFailureCatching {
project?.closeProject()
}.getOrThrow()
}
fun <T> Result<T>.onFailureCatching(action: (Throwable) -> Unit): Result<T> {
internal fun <T> Result<T>.onFailureCatching(action: (Throwable) -> Unit): Result<T> {
val exception = exceptionOrNull() ?: return this
val secondaryException = runCatching { action(exception) }.exceptionOrNull()
val compound = createException(listOf(exception, secondaryException))!!