[SDK|Test] cleanup: use inline modifier for functions that define SDK lifecycle

The inline modifier allows using these functions in both threading models (blocking and suspendable)

GitOrigin-RevId: 14bd358a291cdadcee5da9b042813f58302080de
This commit is contained in:
Sergei Vorobyov
2024-03-22 20:09:12 +00:00
committed by intellij-monorepo-bot
parent 3a4f963bd5
commit 9575b17fca
7 changed files with 116 additions and 153 deletions
@@ -2,6 +2,7 @@
package com.intellij.openapi.externalSystem.service.execution
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.SdkLookupProvider
import com.intellij.openapi.roots.ui.configuration.SdkLookupProvider.SdkInfo
import com.intellij.openapi.roots.ui.configuration.SdkLookupProviderImpl
@@ -18,8 +19,10 @@ abstract class ExternalSystemJdkNonblockingUtilTestCase : ExternalSystemJdkUtilT
sdkLookupProvider = SdkLookupProviderImpl()
}
open fun nonblockingResolveJdkInfo(jdkReference: String?) =
sdkLookupProvider.nonblockingResolveJdkInfo(projectSdk, jdkReference)
open fun nonblockingResolveJdkInfo(jdkReference: String?): SdkInfo {
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
return sdkLookupProvider.nonblockingResolveJdkInfo(projectSdk, jdkReference)
}
fun assertSdkInfo(versionString: String, homePath: String, actualJdkReference: String?) {
val actualSdkInfo = nonblockingResolveJdkInfo(actualJdkReference)
@@ -5,13 +5,10 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.externalSystem.util.environment.Environment
import com.intellij.openapi.externalSystem.util.environment.TestEnvironment
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.ProjectJdkTableImpl
import com.intellij.openapi.roots.ui.configuration.SdkTestCase
import com.intellij.openapi.roots.ui.configuration.UnknownSdkResolver
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.use
import com.intellij.testFramework.ExtensionTestUtil
import com.intellij.testFramework.replaceService
@@ -49,50 +46,4 @@ abstract class ExternalSystemJdkUtilTestCase : SdkTestCase() {
override fun dispose() {}
}
companion object {
fun assertUnexpectedSdksRegistration(action: () -> Unit) {
assertNewlyRegisteredSdks({ null }, action = action)
}
fun assertNewlyRegisteredSdks(expectedNewSdk: () -> Sdk?, isAssertSdkName: Boolean = true, action: () -> Unit) {
val projectSdkTable = ProjectJdkTable.getInstance()
val beforeSdks = projectSdkTable.allJdks.toSet()
var throwable = runCatching(action).exceptionOrNull()
val afterSdks = projectSdkTable.allJdks.toSet()
val newSdks = afterSdks - beforeSdks
throwable = throwable ?: runCatching {
assertNewlyRegisteredSdks(expectedNewSdk(), newSdks, isAssertSdkName)
}.exceptionOrNull()
removeSdks(*newSdks.toTypedArray())
if (throwable != null) throw throwable
}
private fun assertNewlyRegisteredSdks(expectedNewSdk: Sdk?, newSdks: Set<Sdk>, isAssertSdkName: Boolean) {
if (expectedNewSdk != null) {
assertTrue("Expected registration of $expectedNewSdk but found $newSdks", newSdks.size == 1)
val newSdk = newSdks.first()
assertSdk(expectedNewSdk, newSdk, isAssertSdkName)
}
else {
assertTrue("Unexpected sdk registration $newSdks", newSdks.isEmpty())
}
}
fun withoutRegisteredSdks(action: () -> Unit) {
assertUnexpectedSdksRegistration(action)
}
fun withRegisteredSdks(vararg sdks: Sdk, action: () -> Unit) {
Disposer.newDisposable().use {
registerSdks(*sdks, parentDisposable = it)
assertUnexpectedSdksRegistration(action)
}
}
}
}
@@ -18,7 +18,7 @@ class TestEnvironment : Environment {
this.variables.putAll(variables)
}
fun <R> withVariables(vararg variables: Pair<String, String?>, action: () -> R): R {
inline fun <R> withVariables(vararg variables: Pair<String, String?>, action: () -> R): R {
val environment = TestEnvironment()
environment.variables(*variables)
val application = ApplicationManager.getApplication()
@@ -3,15 +3,17 @@ package com.intellij.openapi.roots.ui.configuration
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.invokeAndWaitIfNeeded
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.*
import com.intellij.openapi.projectRoots.impl.DependentSdkType
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownload
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.use
import com.intellij.testFramework.LightPlatformTestCase
import org.jdom.Element
import java.io.File
@@ -21,8 +23,6 @@ import javax.swing.JComponent
abstract class SdkTestCase : LightPlatformTestCase() {
val projectSdk get() = ProjectRootManager.getInstance(project).projectSdk
override fun setUp() {
super.setUp()
@@ -50,51 +50,12 @@ abstract class SdkTestCase : LightPlatformTestCase() {
private fun registerSdk(sdk: Sdk, isProjectSdk: Boolean = false) {
registerSdk(sdk, testRootDisposable)
if (isProjectSdk) {
setProjectSdk(sdk)
setProjectSdk(project, sdk, testRootDisposable)
}
}
fun registerSdks(vararg sdks: Sdk) {
registerSdks(*sdks, parentDisposable = testRootDisposable)
}
private fun setProjectSdk(sdk: Sdk?) {
invokeAndWaitIfNeeded {
runWriteAction {
val rootManager = ProjectRootManager.getInstance(project)
rootManager.projectSdk = sdk
}
}
}
fun withProjectSdk(sdk: Sdk, action: () -> Unit) {
val projectSdk = projectSdk
setProjectSdk(sdk)
try {
action()
}
finally {
setProjectSdk(projectSdk)
}
}
fun withRegisteredSdk(sdk: Sdk, isProjectSdk: Boolean = false, action: () -> Unit) {
withRegisteredSdks(sdk) {
when (isProjectSdk) {
true -> withProjectSdk(sdk, action)
else -> action()
}
}
}
fun withRegisteredSdks(vararg sdks: Sdk, action: () -> Unit) {
registerSdks(*sdks)
try {
action()
}
finally {
removeSdks(*sdks)
}
fun <R> withProjectSdk(sdk: Sdk, action: () -> R): R {
return withProjectSdk(project, sdk, action)
}
interface TestSdkType : JavaSdkType, SdkTypeId {
@@ -261,6 +222,36 @@ abstract class SdkTestCase : LightPlatformTestCase() {
}
companion object {
inline fun <R> assertUnexpectedSdksRegistration(action: () -> R): R {
return assertNewlyRegisteredSdks({ null }, action = action)
}
inline fun <R> assertNewlyRegisteredSdks(getExpectedNewSdk: () -> Sdk?, isAssertSdkName: Boolean = true, action: () -> R): R {
val projectSdkTable = ProjectJdkTable.getInstance()
val beforeSdks = projectSdkTable.allJdks.toSet()
val result = runCatching(action)
val afterSdks = projectSdkTable.allJdks.toSet()
val newSdks = afterSdks - beforeSdks
removeSdks(*newSdks.toTypedArray())
result.onSuccess {
val expectedNewSdk = getExpectedNewSdk()
if (expectedNewSdk != null) {
assertTrue("Expected registration of $expectedNewSdk but found $newSdks", newSdks.size == 1)
val newSdk = newSdks.single()
assertSdk(expectedNewSdk, newSdk, isAssertSdkName)
}
else {
assertTrue("Unexpected sdk registration $newSdks", newSdks.isEmpty())
}
}
return result.getOrThrow()
}
fun assertSdk(expected: Sdk?, actual: Sdk?, isAssertSdkName: Boolean = true) {
if (expected != null && actual != null) {
if (isAssertSdkName) {
@@ -275,11 +266,9 @@ abstract class SdkTestCase : LightPlatformTestCase() {
}
fun registerSdk(sdk: Sdk, parentDisposable: Disposable) {
invokeAndWaitIfNeeded {
runWriteAction {
val jdkTable = ProjectJdkTable.getInstance()
jdkTable.addJdk(sdk, parentDisposable)
}
WriteAction.runAndWait<Throwable> {
val jdkTable = ProjectJdkTable.getInstance()
jdkTable.addJdk(sdk, parentDisposable)
}
}
@@ -288,16 +277,41 @@ abstract class SdkTestCase : LightPlatformTestCase() {
}
fun removeSdk(sdk: Sdk) {
invokeAndWaitIfNeeded {
runWriteAction {
val jdkTable = ProjectJdkTable.getInstance()
jdkTable.removeJdk(sdk)
}
WriteAction.runAndWait<Throwable> {
val jdkTable = ProjectJdkTable.getInstance()
jdkTable.removeJdk(sdk)
}
}
fun removeSdks(vararg sdks: Sdk) {
sdks.forEach(::removeSdk)
}
fun setProjectSdk(project: Project, sdk: Sdk?, parentDisposable: Disposable) {
val rootManager = ProjectRootManager.getInstance(project)
val projectSdk = rootManager.projectSdk
WriteAction.runAndWait<Throwable> {
rootManager.projectSdk = sdk
}
Disposer.register(parentDisposable, Disposable {
WriteAction.runAndWait<Throwable> {
rootManager.projectSdk = projectSdk
}
})
}
inline fun <R> withProjectSdk(project: Project, sdk: Sdk, action: () -> R): R {
return Disposer.newDisposable().use { disposable ->
setProjectSdk(project, sdk, parentDisposable = disposable)
action()
}
}
inline fun <R> withRegisteredSdks(vararg sdks: Sdk, action: () -> R): R {
return Disposer.newDisposable().use { disposable ->
registerSdks(*sdks, parentDisposable = disposable)
action()
}
}
}
}
@@ -2,10 +2,9 @@
package org.jetbrains.plugins.gradle.importing
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil.JAVA_HOME
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtilTestCase.Companion.assertNewlyRegisteredSdks
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtilTestCase.Companion.assertUnexpectedSdksRegistration
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtilTestCase.Companion.withRegisteredSdks
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtilTestCase.Companion.withoutRegisteredSdks
import com.intellij.openapi.roots.ui.configuration.SdkTestCase.Companion.assertNewlyRegisteredSdks
import com.intellij.openapi.roots.ui.configuration.SdkTestCase.Companion.assertUnexpectedSdksRegistration
import com.intellij.openapi.roots.ui.configuration.SdkTestCase.Companion.withRegisteredSdks
import com.intellij.openapi.roots.ui.configuration.SdkTestCase.TestSdkGenerator
import org.junit.Test
@@ -31,7 +30,7 @@ class GradleProjectResolverTest : GradleProjectResolverTestCase() {
createGradleSubProject()
environment.withVariables(JAVA_HOME to jdk.homePath) {
withoutRegisteredSdks {
assertUnexpectedSdksRegistration {
assertNewlyRegisteredSdks({ jdk }, isAssertSdkName = false) {
loadProject()
assertSdks(jdk, "project", "project.main", "project.test", isAssertSdkName = false)
@@ -100,28 +100,10 @@ abstract class GradleProjectResolverTestCase : GradleImportingTestCase() {
return ModuleRootManager.getInstance(getModule(moduleName)).sdk
}
private fun setProjectSdk(sdk: Sdk?) {
val projectRootManager = ProjectRootManager.getInstance(myProject)
ApplicationManager.getApplication().invokeAndWait {
runWriteAction {
projectRootManager.projectSdk = sdk
}
}
protected inline fun withProjectSdk(sdk: Sdk, action: () -> Unit) {
SdkTestCase.withProjectSdk(myProject, sdk, action)
}
fun withProjectSdk(sdk: Sdk, action: () -> Unit) {
val projectRootManager = ProjectRootManager.getInstance(myProject)
val projectSdk = projectRootManager.projectSdk
setProjectSdk(sdk)
try {
action()
}
finally {
setProjectSdk(projectSdk)
}
}
fun createGradleSubProject() {
createSettingsFile {
setProjectName("project")
@@ -13,6 +13,7 @@ import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class GradleJdkResolutionTest : GradleJdkResolutionTestCase() {
@Test
fun `test simple gradle jvm resolution`() {
withGradleProperties(externalProjectPath, java = latestSdk) {
@@ -22,18 +23,24 @@ class GradleJdkResolutionTest : GradleJdkResolutionTestCase() {
assertGradleJvmSuggestion(expected = latestSdk, expectsSdkRegistration = true)
}
withRegisteredSdks(earliestSdk, latestSdk, unsupportedSdk) {
withGradleLinkedProject(java = earliestSdk) {
assertGradleJvmSuggestion(expected = earliestSdk)
assertUnexpectedSdksRegistration {
withGradleLinkedProject(java = earliestSdk) {
assertGradleJvmSuggestion(expected = earliestSdk)
}
}
}
withRegisteredSdk(latestSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
withRegisteredSdks(latestSdk) {
withProjectSdk(latestSdk) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
}
environment.withVariables(JAVA_HOME to latestSdk.homePath) {
assertGradleJvmSuggestion(expected = USE_JAVA_HOME)
}
withRegisteredSdks(earliestSdk, latestSdk, unsupportedSdk) {
assertGradleJvmSuggestion(expected = latestSdk)
assertUnexpectedSdksRegistration {
assertGradleJvmSuggestion(expected = latestSdk)
}
}
assertGradleJvmSuggestion(expected = latestSdk, expectsSdkRegistration = true)
}
@@ -48,28 +55,35 @@ class GradleJdkResolutionTest : GradleJdkResolutionTestCase() {
@Test
fun `test gradle jvm resolution (linked project)`() {
registerSdks(earliestSdk, latestSdk, unsupportedSdk)
withGradleLinkedProject(java = earliestSdk) {
assertGradleJvmSuggestion(expected = earliestSdk)
}
withGradleLinkedProject(java = latestSdk) {
assertGradleJvmSuggestion(expected = latestSdk)
}
withGradleLinkedProject(java = unsupportedSdk) {
assertGradleJvmSuggestion(expected = unsupportedSdk)
withRegisteredSdks(earliestSdk, latestSdk, unsupportedSdk) {
withGradleLinkedProject(java = earliestSdk) {
assertGradleJvmSuggestion(expected = earliestSdk)
}
withGradleLinkedProject(java = latestSdk) {
assertGradleJvmSuggestion(expected = latestSdk)
}
withGradleLinkedProject(java = unsupportedSdk) {
assertGradleJvmSuggestion(expected = unsupportedSdk)
}
}
}
@Test
fun `test gradle jvm resolution (project sdk)`() {
withRegisteredSdk(earliestSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
withRegisteredSdks(earliestSdk) {
withProjectSdk(earliestSdk) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
}
withRegisteredSdk(latestSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
withRegisteredSdks(latestSdk) {
withProjectSdk(latestSdk) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
}
withRegisteredSdk(unsupportedSdk, isProjectSdk = true) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
withRegisteredSdks(unsupportedSdk) {
withProjectSdk(unsupportedSdk) {
assertGradleJvmSuggestion(expected = USE_PROJECT_JDK)
}
}
}