[Gradle] Test that source set have own Cinterop configurations

It is necessary to prevent leaking dependencies in source set hierarchy
i.e. if linuxMain depends on some project with cinterops and
nativeMain also have the same set of underlying targets it is important
that nativeMain should not see any dependencies from linuxMain!

And vice versa, if linuxMain should see own + parents dependencies.

^KT-63338
This commit is contained in:
Anton Lakotka
2023-11-14 11:10:22 +01:00
committed by Space Team
parent d865a44c94
commit 645d263474
@@ -7,14 +7,24 @@
package org.jetbrains.kotlin.gradle.unitTests package org.jetbrains.kotlin.gradle.unitTests
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.dependencies
import org.jetbrains.kotlin.commonizer.CommonizerTarget import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.identityString import org.jetbrains.kotlin.commonizer.identityString
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.commonMain
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.linuxMain
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.ReadyForExecution
import org.jetbrains.kotlin.gradle.plugin.await
import org.jetbrains.kotlin.gradle.targets.native.internal.CommonizerTargetAttribute import org.jetbrains.kotlin.gradle.targets.native.internal.CommonizerTargetAttribute
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCommonizedCInteropDependencyConfiguration
import org.jetbrains.kotlin.gradle.util.*
import org.jetbrains.kotlin.gradle.utils.markConsumable import org.jetbrains.kotlin.gradle.utils.markConsumable
import org.jetbrains.kotlin.gradle.utils.markResolvable import org.jetbrains.kotlin.gradle.utils.markResolvable
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.tooling.core.UnsafeApi
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.fail import kotlin.test.fail
@@ -114,4 +124,72 @@ class CInteropCommonizerConfigurationTests {
val resolved = resolvedDependencies.single() val resolved = resolvedDependencies.single()
assertEquals(consumableSpecific.name, resolved.configuration) assertEquals(consumableSpecific.name, resolved.configuration)
} }
@Test
fun `test - KT-63338 - source sets have own cinterop configurations`() {
val rootProject = buildProject()
val producerAProject = buildProjectWithMPP(
projectBuilder = { withParent(rootProject).withName("producer-a") }
) {
kotlin {
linuxX64().compilations.main.cinterops.create("myInterop")
linuxArm64().compilations.main.cinterops.create("myInterop")
}
}
val producerBProject = buildProjectWithMPP(
projectBuilder = { withParent(rootProject).withName("producer-b") }
) {
kotlin {
linuxX64().compilations.main.cinterops.create("myInterop")
linuxArm64().compilations.main.cinterops.create("myInterop")
}
}
val consumerProject = buildProjectWithMPP(
projectBuilder = { withParent(rootProject).withName("consumer") }
) {
kotlin {
linuxX64()
linuxArm64()
sourceSets.commonMain.dependencies {
implementation(project(":producer-a"))
}
sourceSets.linuxMain.dependencies {
implementation(project(":producer-b"))
}
}
}
producerAProject.evaluate()
consumerProject.runLifecycleAwareTest {
val commonMain = consumerProject.multiplatformExtension.sourceSets.commonMain
val linuxMain = consumerProject.multiplatformExtension.sourceSets.linuxMain
@OptIn(UnsafeApi::class)
val commonMainCinterop = consumerProject.locateOrCreateCommonizedCInteropDependencyConfiguration(commonMain.get())!!
@OptIn(UnsafeApi::class)
val linuxMainCinterop = consumerProject.locateOrCreateCommonizedCInteropDependencyConfiguration(linuxMain.get())!!
if (linuxMainCinterop == commonMainCinterop)
fail("Expected different source sets have different resolvable Cinterop configurations")
fun Configuration.allProjectDependencies() = allDependencies
.filterIsInstance<ProjectDependency>()
.map { it.dependencyProject }
.toSet()
if (commonMainCinterop.allProjectDependencies() != setOf(producerAProject))
fail("commonMain Cinterop configuration should depend only on `producer-a` project")
if (linuxMainCinterop.allProjectDependencies() != setOf(producerAProject, producerBProject))
fail("linuxMain Cinterop configuration should depend on both `producer-a` and `producer-b` projects")
}
}
} }