From 40cd480d901d1c2526a205f55ae8f96ff2d98535 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Tue, 15 Feb 2022 09:20:02 +0100 Subject: [PATCH] [KPM] kotlin-gradle-plugin-idea: Implement ProxyUtil.kt KT-51262 KT-51220 --- .../src/test/kotlin/ProxyUtil.kt | 14 ++++++ ...ckwardsCompatibilityDeserializationTest.kt | 49 +++++++++---------- 2 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/ProxyUtil.kt diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/ProxyUtil.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/ProxyUtil.kt new file mode 100644 index 00000000000..e37f622d9d4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/ProxyUtil.kt @@ -0,0 +1,14 @@ +import org.gradle.tooling.internal.adapter.ProtocolToModelAdapter + +/* + * 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. + */ + +inline fun createProxyInstance(obj: Any): T { + return ProtocolToModelAdapter().adapt(T::class.java, obj) +} + +fun unwrapProxyInstance(obj: Any): Any { + return ProtocolToModelAdapter().unpack(obj) +} diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/BackwardsCompatibilityDeserializationTest.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/BackwardsCompatibilityDeserializationTest.kt index f1d9270cedf..730d5281485 100644 --- a/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/BackwardsCompatibilityDeserializationTest.kt +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/test/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/BackwardsCompatibilityDeserializationTest.kt @@ -7,12 +7,13 @@ package org.jetbrains.kotlin.gradle.kpm.idea +import createProxyInstance +import deserialize 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.internal.adapter.ProtocolToModelAdapter import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.kpm.KotlinExternalModelKey import org.jetbrains.kotlin.gradle.kpm.KotlinExternalModelSerializer.Companion.serializable @@ -24,7 +25,10 @@ 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 serialize +import unwrapProxyInstance +import java.io.File +import java.io.Serializable import java.net.URLClassLoader import kotlin.test.* @@ -61,17 +65,17 @@ class BackwardsCompatibilityDeserializationTest { val model = buildModel(project) val deserializedModel = deserializeModelWithBackwardsCompatibleClasses(model) - /* Use reflection magic (aka ProtocolToModelAdapter) to proxy the deserialized model */ + /* Use proxy instances to assert the deserialized model */ run { - val adaptedDeserializedModel = ProtocolToModelAdapter().adapt(IdeaKotlinProjectModel::class.java, deserializedModel) + val deserializedModelProxy = createProxyInstance(deserializedModel) - val mainModule = adaptedDeserializedModel.modules.firstOrNull { it.moduleIdentifier.moduleClassifier == null } + val deserializedMainModuleProxy = deserializedModelProxy.modules.firstOrNull { it.moduleIdentifier.moduleClassifier == null } ?: fail("Missing main module") - val testModule = adaptedDeserializedModel.modules.firstOrNull { it.moduleIdentifier.moduleClassifier == "test" } + val deserializedTestModuleProxy = deserializedModelProxy.modules.firstOrNull { it.moduleIdentifier.moduleClassifier == "test" } ?: fail("Missing test module") - listOf(mainModule, testModule).forEach { module -> + listOf(deserializedMainModuleProxy, deserializedTestModuleProxy).forEach { module -> assertEquals( model.modules.flatMap { it.fragments }.map { it.name }.toSet(), module.fragments.map { it.name }.toSet(), @@ -100,17 +104,21 @@ class BackwardsCompatibilityDeserializationTest { val model = buildModel(project) val deserializedModel = deserializeModelWithBackwardsCompatibleClasses(model) - val adaptedDeserializedModel = ProtocolToModelAdapter().adapt(IdeaKotlinProjectModel::class.java, deserializedModel) + val deserializedModelProxy = createProxyInstance(deserializedModel) - val mainModule = adaptedDeserializedModel.modules.find { it.moduleIdentifier.moduleClassifier == null } + val deserializedMainModuleProxy = deserializedModelProxy.modules.find { it.moduleIdentifier.moduleClassifier == null } ?: fail("Missing main module") - val commonFragment = mainModule.fragments.find { it.name == "common" } + val deserializedCommonFragmentProxy = deserializedMainModuleProxy.fragments.find { it.name == "common" } ?: fail("Missing common fragment") - assertEquals(1, commonFragment.external.ids.size) - assertEquals(RetainedModel(2411), commonFragment.external[retainedModelKey]) - assertNull(commonFragment.external[unretainedModelKey]) + run { + val deserializedCommonFragment = unwrapProxyInstance(deserializedCommonFragmentProxy) + val external = deserializedCommonFragment.serialize().deserialize().external + assertEquals(1, external.ids.size) + assertEquals(RetainedModel(2411), external[retainedModelKey]) + assertNull(external[unretainedModelKey]) + } } } @@ -133,21 +141,12 @@ private fun buildModel(project: Project): IdeaKotlinProjectModel { } private fun deserializeModelWithBackwardsCompatibleClasses(model: IdeaKotlinProjectModel): Any { - val serializedModel = ByteArrayOutputStream().run { - ObjectOutputStream(this).use { stream -> stream.writeObject(model) } - toByteArray() - } + val backwardsCompatibilityClassLoader = getClassLoaderForBackwardsCompatibilityTest() + val backwardsCompatibilityModel = model.serialize().deserialize(backwardsCompatibilityClassLoader) - val backwardsCompatibilityTestClassLoader = getClassLoaderForBackwardsCompatibilityTest() - val backwardsCompatibilityObjectInputStream = object : ObjectInputStream(ByteArrayInputStream(serializedModel)) { - override fun resolveClass(desc: ObjectStreamClass): Class<*> { - return backwardsCompatibilityTestClassLoader.loadClass(desc.name) - } - } - val backwardsCompatibilityModel = backwardsCompatibilityObjectInputStream.use { it.readObject() } assertSame( backwardsCompatibilityModel.javaClass.classLoader, - backwardsCompatibilityTestClassLoader, + backwardsCompatibilityClassLoader, "Expected deserialized model being loaded by 'backwardsCompatibilityTestClassLoader'" )