[KPM] Implement BackwardsCompatibilityDeserializationTest
KT-51262
This commit is contained in:
committed by
Space
parent
0460de870a
commit
55448943af
@@ -1,9 +1,36 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("gradle-plugin-common-configuration")
|
kotlin("jvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.sourceSets.configureEach {
|
||||||
|
languageSettings.apiVersion = "1.4"
|
||||||
|
languageSettings.languageVersion = "1.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlinStdlib())
|
implementation(kotlinStdlib())
|
||||||
|
testImplementation(gradleApi())
|
||||||
|
testImplementation(gradleKotlinDsl())
|
||||||
|
testImplementation(project(":kotlin-gradle-plugin"))
|
||||||
|
testImplementation(project(":kotlin-test:kotlin-test-junit"))
|
||||||
}
|
}
|
||||||
|
|
||||||
publish()
|
publish()
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
/* Setup for backwards compatibility test */
|
||||||
|
val minimalBackwardsCompatibleVersion = "1.7.0-dev-1825"
|
||||||
|
val minimalBackwardsCompatibleVersionTestClasspath by configurations.creating
|
||||||
|
dependencies {
|
||||||
|
minimalBackwardsCompatibleVersionTestClasspath("org.jetbrains.kotlin:kotlin-gradle-plugin-idea:$minimalBackwardsCompatibleVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependsOn(minimalBackwardsCompatibleVersionTestClasspath)
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
systemProperty(
|
||||||
|
"backwardsCompatibilityClasspath",
|
||||||
|
minimalBackwardsCompatibleVersionTestClasspath.files.joinToString(";") { it.absolutePath }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:OptIn(InternalKotlinGradlePluginApi::class)
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.kpm.idea
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
|
import org.gradle.configurationcache.extensions.serviceOf
|
||||||
|
import org.gradle.kotlin.dsl.create
|
||||||
|
import org.gradle.testfixtures.ProjectBuilder
|
||||||
|
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPm20PluginWrapper
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinIosX64Variant
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinLinuxX64Variant
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.jvm
|
||||||
|
import org.junit.Test
|
||||||
|
import java.io.*
|
||||||
|
import java.net.URLClassLoader
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
import kotlin.test.assertSame
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test is designed to test if serialized models can still be deserialized with a older (minimal supported)
|
||||||
|
* version of this module.
|
||||||
|
*
|
||||||
|
* The test will
|
||||||
|
* - Build a representative 'sample' model
|
||||||
|
* - Serialize this model
|
||||||
|
* - Deserialize this model with the older version of the classes (using a custom class loader)
|
||||||
|
* - Assert the deserialized model is healthy
|
||||||
|
*/
|
||||||
|
class BackwardsCompatibilityDeserializationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - simple project`() {
|
||||||
|
val project = ProjectBuilder.builder().build() as ProjectInternal
|
||||||
|
project.plugins.apply(KotlinPm20PluginWrapper::class.java)
|
||||||
|
|
||||||
|
/* Setup example project */
|
||||||
|
val kotlinExtension = project.extensions.getByType(KotlinPm20ProjectExtension::class.java)
|
||||||
|
kotlinExtension.mainAndTest {
|
||||||
|
jvm
|
||||||
|
val native = fragments.create("native")
|
||||||
|
val linux = fragments.create<KotlinLinuxX64Variant>("linuxX64")
|
||||||
|
val ios = fragments.create<KotlinIosX64Variant>("iosX64")
|
||||||
|
native.refines(common)
|
||||||
|
linux.refines(native)
|
||||||
|
ios.refines(native)
|
||||||
|
}
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
|
testDeserializeCompatibility(buildModel(project))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildModel(project: Project): IdeaKotlinProjectModel {
|
||||||
|
return project.serviceOf<ToolingModelBuilderRegistry>().getBuilder(IdeaKotlinProjectModel::class.java.name)
|
||||||
|
.buildAll(IdeaKotlinProjectModel::class.java.name, project) as IdeaKotlinProjectModel
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testDeserializeCompatibility(model: IdeaKotlinProjectModel) {
|
||||||
|
val serializedModel = ByteArrayOutputStream().run {
|
||||||
|
ObjectOutputStream(this).use { stream -> stream.writeObject(model) }
|
||||||
|
toByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
val backwardsCompatibilityTestClassLoader = getClassLoaderForBackwardsCompatibilityTest()
|
||||||
|
val backwardsCompatibilityObjectInputStream = object : ObjectInputStream(ByteArrayInputStream(serializedModel)) {
|
||||||
|
override fun resolveClass(desc: ObjectStreamClass): Class<*> {
|
||||||
|
return backwardsCompatibilityTestClassLoader.loadClass(desc.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val backwardsCompatibilityModel = backwardsCompatibilityObjectInputStream.readObject()
|
||||||
|
assertSame(
|
||||||
|
backwardsCompatibilityModel.javaClass.classLoader,
|
||||||
|
backwardsCompatibilityTestClassLoader,
|
||||||
|
"Expected deserialized model being loaded by 'backwardsCompatibilityTestClassLoader'"
|
||||||
|
)
|
||||||
|
|
||||||
|
assertNotEquals<Class<*>>(
|
||||||
|
model.javaClass, backwardsCompatibilityModel.javaClass,
|
||||||
|
"Expected deserialized model java class to be different from origin"
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
model.javaClass.name, backwardsCompatibilityModel.javaClass.name,
|
||||||
|
"Expected deserialized model to be same java class as origin"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClassLoaderForBackwardsCompatibilityTest(): ClassLoader {
|
||||||
|
val uris = getClasspathForBackwardsCompatibilityTest().map { file -> file.toURI().toURL() }.toTypedArray()
|
||||||
|
return URLClassLoader.newInstance(uris, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClasspathForBackwardsCompatibilityTest(): List<File> {
|
||||||
|
val backwardsCompatibilityClasspathString = System.getProperty("backwardsCompatibilityClasspath")
|
||||||
|
?: error("Missing backwardsCompatibilityClasspath system property")
|
||||||
|
|
||||||
|
return backwardsCompatibilityClasspathString.split(";").map { path -> File(path) }
|
||||||
|
.onEach { file -> if (!file.exists()) println("[WARNING] Missing $file") }
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user