[Gradle] Implement MppIdeDependencyResolutionIT for platform cinterops and failing cinterops

^KT-56337 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-02-01 11:23:35 +01:00
committed by Space Team
parent fec9f9fe62
commit 1c1b6ff92a
9 changed files with 105 additions and 3 deletions
@@ -11,13 +11,19 @@ import org.jetbrains.kotlin.commonizer.identityString
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinUnresolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.*
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.IdeaKotlinDependencyMatcher
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.util.kotlinNativeDistributionDependencies
import org.jetbrains.kotlin.gradle.util.resolveIdeDependencies
import org.jetbrains.kotlin.konan.target.KonanTarget.*
import org.junit.jupiter.api.DisplayName
import java.nio.ByteBuffer
import java.util.*
import java.util.zip.CRC32
import kotlin.test.assertEquals
import kotlin.test.fail
@@ -184,4 +190,59 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
}
}
}
@GradleTest
fun `test cinterops - are stored in root gradle folder`(gradleVersion: GradleVersion) {
project(projectName = "cinteropImport", gradleVersion = gradleVersion) {
resolveIdeDependencies("dep-with-cinterop") { dependencies ->
/* Check behaviour of platform cinterops on linuxX64Main */
val cinterops = dependencies["linuxX64Main"].filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { !it.isNativeDistribution && it.klibExtra?.isInterop == true }
.ifEmpty { fail("Expected at least one cinterop on linuxX64Main") }
cinterops.forEach { cinterop ->
if (cinterop.classpath.isEmpty()) fail("Missing classpath for $cinterop")
cinterop.classpath.forEach { cinteropFile ->
/* Check file was copied into root .gradle folder */
val expectedParent = projectPath.toFile().resolve(".gradle/kotlin/kotlinCInteropLibraries").canonicalFile
assertEquals(expectedParent, cinteropFile.parentFile.canonicalFile)
/* Check crc in file name */
val crc = CRC32()
crc.update(cinteropFile.readBytes())
val crcValue = crc.value.toInt()
val crcString = Base64.getEncoder().withoutPadding().encodeToString(
ByteBuffer.allocate(4).putInt(crcValue).array()
)
if (!cinteropFile.name.endsWith("-$crcString.klib")) {
fail("Expected crc $crcString to be part of cinterop file name. Found ${cinteropFile.name}")
}
}
}
}
}
}
@GradleTest
fun `test cinterops - with failing cinterop process`(gradleVersion: GradleVersion) {
project(
projectName = "cinterop-withFailingCInteropProcess", gradleVersion = gradleVersion,
/* Adding idea.sync.active to ensure lenient cinterop generation */
buildOptions = defaultBuildOptions.copy(freeArgs = listOf("-Didea.sync.active=true"))
) {
resolveIdeDependencies { dependencies ->
dependencies["commonMain"].assertMatches(
kotlinNativeDistributionDependencies,
binaryCoordinates(Regex("com.example:cinterop-.*-dummy:.*:linux_x64")),
IdeaKotlinDependencyMatcher("Unresolved 'failing' cinterop") { dependency ->
dependency is IdeaKotlinUnresolvedBinaryDependency && dependency.cause.orEmpty().contains(
"cinterop-withFailingCInteropProcess-cinterop-failing.klib"
)
}
)
}
}
}
}
@@ -34,7 +34,7 @@ class MppCompositeBuildIT : KGPBaseTest() {
regularSourceDependency("producerBuild::producerA/commonMain"),
regularSourceDependency("producerBuild::producerA/nativeMain"),
regularSourceDependency("producerBuild::producerA/linuxMain"),
kotilnNativeDistributionDependencies,
kotlinNativeDistributionDependencies,
binaryCoordinates(Regex(".*stdlib-common:.*")) /* KT-56278 */
)
@@ -48,7 +48,7 @@ class MppCompositeBuildIT : KGPBaseTest() {
dependsOnDependency(":consumerA/nativeMain"),
dependsOnDependency(":consumerA/linuxMain"),
projectArtifactDependency(Regular, "producerBuild::producerA", FilePathRegex(".*/linuxX64/main/klib/producerA.klib")),
kotilnNativeDistributionDependencies,
kotlinNativeDistributionDependencies,
)
}
}
@@ -14,6 +14,6 @@ val kotlinStdlibDependencies = binaryCoordinates(Regex(".*kotlin-stdlib.*"))
val jetbrainsAnnotationDependencies = binaryCoordinates(Regex("org\\.jetbrains:annotations:.*"))
val kotilnNativeDistributionDependencies = IdeaKotlinDependencyMatcher("native distribution") { dependency ->
val kotlinNativeDistributionDependencies = IdeaKotlinDependencyMatcher("native distribution") { dependency ->
dependency is IdeaKotlinResolvedBinaryDependency && dependency.isNativeDistribution
}
@@ -0,0 +1,27 @@
plugins {
kotlin("multiplatform")
}
repositories {
mavenLocal()
mavenCentral()
}
kotlin {
linuxX64 {
compilations.getByName("main") {
cinterops {
create("dummy") {
headers("libs/include/dummy.h")
}
create("failing") {
headers("libs/include/failing.h")
}
}
}
}
}
group = "com.example"
version = "1.0"
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package com.lib
import dummy.dummyCFunction
val helloFromLib = "Hello from Lib"
val helloFromCInterop = dummyCFunction()