[Gradle] Implement IdeaKotlinDependencyBackwardsCompatibilityTest

KT-54825
This commit is contained in:
Sebastian Sellmair
2022-11-11 10:14:06 +01:00
committed by Space Team
parent 31b7fd9a1f
commit 66cb2b3ad8
4 changed files with 132 additions and 8 deletions
@@ -4,7 +4,7 @@
* Version of kotlin-gradle-plugin-idea module that should be resolved for compatibility tests
* This version can be treated as 'minimal guaranteed backwards compatible version' of the module.
*/
val testedVersion = "1.8.20-dev-2192"
val testedVersion = "1.8.20-dev-2237"
val isSnapshotTest = properties.contains("kgp-idea.snapshot_test")
val resolvedTestedVersion = if (isSnapshotTest) properties["defaultSnapshotVersion"].toString() else testedVersion
@@ -12,16 +12,13 @@ val resolvedTestedVersion = if (isSnapshotTest) properties["defaultSnapshotVersi
//region Download and prepare classpath for specified tested version
repositories {
maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap")
maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies")
}
if (isSnapshotTest) {
repositories {
clear()
if (isSnapshotTest) {
mavenLocal()
mavenCentral()
}
maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap")
maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies")
}
val classpathDestination = layout.buildDirectory.dir("classpath")
@@ -58,6 +58,7 @@ run {
artifacts.add(binaryValidationApiElements.name, binaryValidationApiJar)
}
/* Setup protoc */
tasks.register<Exec>("protoc") {
val protoSources = file("src/main/proto")
val javaOutput = file("src/generated/java/")
@@ -87,3 +88,25 @@ tasks.register<Exec>("protoc") {
.map { it.path },
)
}
/* Setup backwards compatibility tests */
run {
val compatibilityTestClasspath by configurations.creating {
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
}
dependencies {
compatibilityTestClasspath(project(":kotlin-gradle-plugin-idea-for-compatibility-tests"))
}
tasks.test {
dependsOn(compatibilityTestClasspath)
inputs.files(compatibilityTestClasspath)
doFirst { systemProperty("compatibilityTestClasspath", compatibilityTestClasspath.files.joinToString(";") { it.absolutePath }) }
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2022 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 org.jetbrains.kotlin.gradle.idea.proto
import java.io.File
import java.net.URLClassLoader
fun classLoaderForBackwardsCompatibleClasses(): ClassLoader {
val uris = classpathForBackwardsCompatibleClasses().map { file -> file.toURI().toURL() }.toTypedArray()
return URLClassLoader.newInstance(uris, null)
}
fun classpathForBackwardsCompatibleClasses(): List<File> {
val compatibilityTestClasspath = System.getProperty("compatibilityTestClasspath")
?: error("Missing compatibilityTestClasspath system property")
return compatibilityTestClasspath.split(";").map { path -> File(path) }
.onEach { file -> if (!file.exists()) println("[WARNING] Missing $file") }
.flatMap { file -> if (file.isDirectory) file.listFiles().orEmpty().toList() else listOf(file) }
}
@@ -0,0 +1,81 @@
/*
* Copyright 2010-2022 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 org.jetbrains.kotlin.gradle.idea.proto.tcs
import org.jetbrains.kotlin.gradle.idea.proto.classLoaderForBackwardsCompatibleClasses
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationLogger
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinUnresolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.TestIdeaKotlinDependencySerializer
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.TestIdeaKotlinInstances
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.copy
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertSame
class IdeaKotlinDependencyBackwardsCompatibilityTest {
@Test
fun `test - simple unresolved binary dependency`() {
val dependency = TestIdeaKotlinInstances.simpleUnresolvedBinaryDependency
val binary = TestIdeaKotlinDependencySerializer().serialize(dependency)
val deserialized = deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(binary)
val deserializedCopied = deserialized.copy<IdeaKotlinUnresolvedBinaryDependency>()
assertEquals(dependency.cause, deserializedCopied.cause)
assertEquals(dependency.coordinates, deserializedCopied.coordinates)
assertEquals(dependency.extras, deserializedCopied.extras)
}
@Test
fun `test - simple resolved binary dependency`() {
val dependency = TestIdeaKotlinInstances.simpleResolvedBinaryDependency
val binary = TestIdeaKotlinDependencySerializer().serialize(dependency)
val deserialized = deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(binary)
val deserializedCopied = deserialized.copy<IdeaKotlinResolvedBinaryDependency>()
assertEquals(dependency.coordinates, deserializedCopied.coordinates)
assertEquals(dependency.binaryType, deserializedCopied.binaryType)
assertEquals(dependency.binaryFile, deserializedCopied.binaryFile)
assertEquals(dependency.extras, deserializedCopied.extras)
}
@Test
fun `test - simple source dependency`() {
val dependency = TestIdeaKotlinInstances.simpleSourceDependency
val binary = TestIdeaKotlinDependencySerializer().serialize(dependency)
val deserialized = deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(binary)
val deserializedCopied = deserialized.copy<IdeaKotlinSourceDependency>()
assertEquals(dependency.type, deserializedCopied.type)
assertEquals(dependency.coordinates, deserializedCopied.coordinates)
assertEquals(dependency.extras, deserializedCopied.extras)
}
}
private fun deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(project: ByteArray): Any {
val classLoader = classLoaderForBackwardsCompatibleClasses()
val serializer = TestIdeaKotlinDependencySerializer(classLoader)
val deserialized = assertNotNull(
serializer.deserialize(project),
"Failed to deserialize dependency: ${serializer.reports}"
)
assertEquals(
0, serializer.reports.count { it.severity > IdeaKotlinSerializationLogger.Severity.WARNING },
"Expected no severe deserialization reports. Found ${serializer.reports}"
)
assertSame(
classLoader, deserialized::class.java.classLoader,
"Expected model do be deserialized in with old classes"
)
return deserialized
}