IDEA-321510 [Gradle|Sync|Test] new: added tests with multiple modules for the phased Gradle sync

GitOrigin-RevId: 52b92b5378a9ea7ee54b53706cdb65849073aebb
This commit is contained in:
Sergei Vorobyov
2024-03-20 23:28:09 +00:00
committed by intellij-monorepo-bot
parent 98f7d7a3c5
commit e29924eb0b
3 changed files with 106 additions and 35 deletions
@@ -42,6 +42,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.testFramework.IndexingTestUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.containers.ContainerUtil;
import org.assertj.core.api.Assertions;
@@ -89,6 +90,10 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
.containsExactlyInAnyOrder(expectedNames);
}
protected void assertModules(List<String> expectedNames) {
assertModules(ArrayUtil.toStringArray(expectedNames));
}
protected void assertContentRoots(String moduleName, String... expectedRoots) {
List<String> actual = new ArrayList<>();
for (ContentEntry e : getContentRoots(moduleName)) {
@@ -22,16 +22,19 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
addProjectModelProviders(disposable, TestPhasedModelProvider(GradleModelFetchPhase.ADDITIONAL_MODEL_PHASE))
whenBuildCompleted(disposable) { resolverContext ->
buildCompletionAssertion.trace {
val buildModel = resolverContext.allBuilds.single()
val projectModel = buildModel.projects.single()
val buildFinishedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.ADDITIONAL_MODEL_PHASE)
val buildFinishedModel = resolverContext.getProjectModel(projectModel, buildFinishedModelClass)
Assertions.assertNotNull(buildFinishedModel) { "Expected BuildFinishedModel on the build completion" }
for (buildModel in resolverContext.allBuilds) {
for (projectModel in buildModel.projects) {
val buildFinishedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.ADDITIONAL_MODEL_PHASE)
val buildFinishedModel = resolverContext.getProjectModel(projectModel, buildFinishedModelClass)
Assertions.assertNotNull(buildFinishedModel) { "Expected BuildFinishedModel on the build completion" }
}
}
}
}
createSettingsFile("")
initMultiModuleProject()
importProject()
assertMultiModuleProjectStructure()
buildCompletionAssertion.assertListenerFailures()
buildCompletionAssertion.assertListenerState(1) { "Build action should be finished only once" }
@@ -48,28 +51,33 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
addProjectModelProviders(disposable, TestPhasedModelProvider(GradleModelFetchPhase.ADDITIONAL_MODEL_PHASE))
whenProjectLoaded(disposable) { resolverContext ->
projectLoadingAssertion.trace {
val buildModel = resolverContext.allBuilds.single()
val projectModel = buildModel.projects.single()
val projectLoadedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.PROJECT_LOADED_PHASE)
val projectLoadedModel = resolverContext.getProjectModel(projectModel, projectLoadedModelClass)
Assertions.assertNotNull(projectLoadedModel) { "Expected ProjectLoadedModel on the project loaded phase" }
for (buildModel in resolverContext.allBuilds) {
for (projectModel in buildModel.projects) {
val projectLoadedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.PROJECT_LOADED_PHASE)
val projectLoadedModel = resolverContext.getProjectModel(projectModel, projectLoadedModelClass)
Assertions.assertNotNull(projectLoadedModel) { "Expected ProjectLoadedModel on the project loaded phase" }
}
}
}
}
whenBuildCompleted(disposable) { resolverContext ->
buildCompletionAssertion.trace {
val buildModel = resolverContext.allBuilds.single()
val projectModel = buildModel.projects.single()
val projectLoadedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.PROJECT_LOADED_PHASE)
val buildFinishedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.ADDITIONAL_MODEL_PHASE)
val projectLoadedModel = resolverContext.getProjectModel(projectModel, projectLoadedModelClass)
val buildFinishedModel = resolverContext.getProjectModel(projectModel, buildFinishedModelClass)
Assertions.assertNotNull(projectLoadedModel) { "Expected ProjectLoadedModel on the build completion" }
Assertions.assertNotNull(buildFinishedModel) { "Expected BuildFinishedModel on the build completion" }
for (buildModel in resolverContext.allBuilds) {
for (projectModel in buildModel.projects) {
val projectLoadedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.PROJECT_LOADED_PHASE)
val buildFinishedModelClass = TestPhasedModel.getModelClass(GradleModelFetchPhase.ADDITIONAL_MODEL_PHASE)
val projectLoadedModel = resolverContext.getProjectModel(projectModel, projectLoadedModelClass)
val buildFinishedModel = resolverContext.getProjectModel(projectModel, buildFinishedModelClass)
Assertions.assertNotNull(projectLoadedModel) { "Expected ProjectLoadedModel on the build completion" }
Assertions.assertNotNull(buildFinishedModel) { "Expected BuildFinishedModel on the build completion" }
}
}
}
}
createSettingsFile("")
initMultiModuleProject()
importProject()
assertMultiModuleProjectStructure()
projectLoadingAssertion.assertListenerFailures()
buildCompletionAssertion.assertListenerFailures()
@@ -94,9 +102,6 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
addProjectModelProviders(disposable, phasedModelProviders)
whenPhaseCompleted(disposable) { resolverContext, phase ->
phaseCompletionAssertion.trace {
val buildModel = resolverContext.allBuilds.single()
val projectModel = buildModel.projects.single()
for (completedPhase in completedPhases) {
Assertions.assertTrue(completedPhase < phase) {
"The $phase should be completed before the $completedPhase.\n" +
@@ -109,13 +114,17 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
"Requested phases = $allPhases\n" +
"Completed phases = $completedPhases"
}
for (completedPhase in completedPhases) {
val phasedModelClass = TestPhasedModel.getModelClass(completedPhase)
val phasedModel = resolverContext.getProjectModel(projectModel, phasedModelClass)
Assertions.assertNotNull(phasedModel) {
"Expected model for the $completedPhase on the $phase completion.\n" +
"Requested phases = $allPhases\n" +
"Completed phases = $completedPhases"
for (buildModel in resolverContext.allBuilds) {
for (projectModel in buildModel.projects) {
for (completedPhase in completedPhases) {
val phasedModelClass = TestPhasedModel.getModelClass(completedPhase)
val phasedModel = resolverContext.getProjectModel(projectModel, phasedModelClass)
Assertions.assertNotNull(phasedModel) {
"Expected model for the $completedPhase on the $phase completion.\n" +
"Requested phases = $allPhases\n" +
"Completed phases = $completedPhases"
}
}
}
}
}
@@ -135,15 +144,16 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
}
}
createSettingsFile("")
initMultiModuleProject()
importProject()
assertMultiModuleProjectStructure()
projectLoadingAssertion.assertListenerFailures()
buildCompletionAssertion.assertListenerFailures()
phaseCompletionAssertion.assertListenerFailures()
phaseCompletionAssertion.assertListenerState(allPhases.size) {
"All requested phases should be completed.\n" +
"Requested phases = $allPhases\n"
"Requested phases = $allPhases\n" +
"Completed phases = $completedPhases"
}
}
@@ -158,7 +168,7 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
throw ProcessCanceledException()
}
createSettingsFile("")
initMultiModuleProject()
importProject(errorHandler = { _, _ ->
isSyncCancelled.set(true)
})
@@ -182,7 +192,7 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
isBuildFinished.set(true)
}
createSettingsFile("")
initMultiModuleProject()
importProject(errorHandler = { _, _ ->
isSyncCancelled.set(true)
})
@@ -232,7 +242,7 @@ class GradlePhasedSyncTest : GradlePhasedSyncTestCase() {
isBuildCompleted.set(true)
}
createSettingsFile("")
initMultiModuleProject()
importProject(errorHandler = { _, _ ->
isSyncCancelled.set(true)
})
@@ -14,6 +14,8 @@ import org.jetbrains.plugins.gradle.model.ProjectImportModelProvider
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension
import org.jetbrains.plugins.gradle.service.project.ProjectResolverContext
import org.jetbrains.plugins.gradle.testFramework.util.createBuildFile
import org.jetbrains.plugins.gradle.testFramework.util.createSettingsFile
import org.junit.jupiter.api.Assertions
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicInteger
@@ -90,6 +92,60 @@ abstract class GradlePhasedSyncTestCase : GradleImportingTestCase() {
})
}
fun initMultiModuleProject() {
if (isGradleAtLeast("8.0")) {
// For old Gradle versions, Idea sync project with build src in two sequent Gradle calls.
// So don't use buildSrc for generic projects with multiple modules.
createBuildFile("buildSrc") {
withPlugin("groovy")
addImplementationDependency(code("gradleApi()"))
addImplementationDependency(code("localGroovy()"))
}
}
createSettingsFile {
setProjectName("project")
include("module")
includeBuild("../includedProject")
}
createBuildFile {
withJavaPlugin()
}
createBuildFile("module") {
withJavaPlugin()
}
createSettingsFile("../includedProject") {
setProjectName("includedProject")
include("module")
}
createBuildFile("../includedProject") {
withJavaPlugin()
}
createBuildFile("../includedProject/module") {
withJavaPlugin()
}
}
fun assertMultiModuleProjectStructure() {
val buildSrcModules = listOf(
"project.buildSrc", "project.buildSrc.main", "project.buildSrc.test"
)
val projectModules = listOf(
"project", "project.main", "project.test",
"project.module", "project.module.main", "project.module.test"
)
val includesProjectModules = listOf(
"includedProject", "includedProject.main", "includedProject.test",
"includedProject.module", "includedProject.module.main", "includedProject.module.test"
)
assertModules(buildList {
if (isGradleAtLeast("8.0")) {
addAll(buildSrcModules)
}
addAll(projectModules)
addAll(includesProjectModules)
})
}
private class TestProjectResolverExtension : AbstractProjectResolverExtension() {
override fun getToolingExtensionsClasses(): Set<Class<*>> {