From 857d8aa8ae21e3df5d0c404d8fd4fd98a6d22d14 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Wed, 6 Jul 2022 21:54:00 +0300 Subject: [PATCH] [MPP] Fix Android test-on-main dependencies Add dependencies from associated compilations conventionally for Android, as it's done for all other multiplatform targets. It used to work unintentionally before because of the configuration name clash between test compilation and its default source set. KT-35916 KT-49877 --- .../AbstractKotlinAndroidGradleTests.kt | 25 +++++++++++++++++ .../jetbrains/kotlin/gradle/BaseGradleIT.kt | 1 + .../testProject/kt-49877/build.gradle.kts | 27 +++++++++++++++++++ .../testProject/kt-49877/settings.gradle.kts | 1 + .../src/androidAndroidTest/kotlin/aTest.kt | 3 +++ .../kt-49877/src/androidMain/kotlin/aMain.kt | 3 +++ .../src/commonMain/kotlin/pkg/test.kt | 3 +++ .../kt-49877/src/main/AndroidManifest.xml | 1 + .../kt-49877/src/test/kotlin/aTest.kt | 3 +++ .../gradle/plugin/mpp/CompilationDetails.kt | 27 ++++++++++++++++--- 10 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/settings.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidAndroidTest/kotlin/aTest.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidMain/kotlin/aMain.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/commonMain/kotlin/pkg/test.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/main/AndroidManifest.xml create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/test/kotlin/aTest.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt index f4fe4ecd421..492681bdb72 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt @@ -784,6 +784,31 @@ open class KotlinAndroid71GradleIT : KotlinAndroid70GradleIT() { } } } + + @Test + fun `test associate compilation dependencies are passed correctly to android test compilations`() { + with(Project("kt-49877")) { + build("allTests") { + assertSuccessful() + assertTasksExecuted( + ":compileDebugKotlinAndroid", + ":compileReleaseKotlinAndroid", + ":compileDebugUnitTestKotlinAndroid", + ":compileReleaseUnitTestKotlinAndroid", + ":testDebugUnitTest", + ":testReleaseUnitTest", + ) + } + + // instrumented tests don't work without a device, so we only compile them + build("packageDebugAndroidTest") { + assertSuccessful() + assertTasksExecuted( + ":compileDebugAndroidTestKotlinAndroid", + ) + } + } + } } abstract class KotlinAndroid3GradleIT : AbstractKotlinAndroidGradleTests() { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt index e5f953b725e..c01e0493b5d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt @@ -955,6 +955,7 @@ Finished executing task ':$taskName'| options.androidHome?.let { sdkDir -> sdkDir.parentFile.mkdirs() put("ANDROID_HOME", sdkDir.canonicalPath) + put("ANDROID_SDK_ROOT", sdkDir.canonicalPath) } options.javaHome?.let { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/build.gradle.kts new file mode 100644 index 00000000000..4934fedc981 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + kotlin("multiplatform") + id("com.android.library") +} + +repositories { + mavenLocal() + mavenCentral() + google() +} + +android { + compileSdk = 30 +} + +kotlin { + android() + linuxX64() + + sourceSets { + getByName("commonMain") { + dependencies { + implementation("com.squareup.okio:okio:3.2.0") + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/settings.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/settings.gradle.kts new file mode 100644 index 00000000000..049b3d5325c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "kt-49877" diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidAndroidTest/kotlin/aTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidAndroidTest/kotlin/aTest.kt new file mode 100644 index 00000000000..5cee5cbeb7b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidAndroidTest/kotlin/aTest.kt @@ -0,0 +1,3 @@ +private fun test() { + val sink: okio.Sink = null!! +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidMain/kotlin/aMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidMain/kotlin/aMain.kt new file mode 100644 index 00000000000..5cee5cbeb7b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/androidMain/kotlin/aMain.kt @@ -0,0 +1,3 @@ +private fun test() { + val sink: okio.Sink = null!! +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/commonMain/kotlin/pkg/test.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/commonMain/kotlin/pkg/test.kt new file mode 100644 index 00000000000..5cee5cbeb7b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/commonMain/kotlin/pkg/test.kt @@ -0,0 +1,3 @@ +private fun test() { + val sink: okio.Sink = null!! +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/main/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..b6961a87161 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/test/kotlin/aTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/test/kotlin/aTest.kt new file mode 100644 index 00000000000..5cee5cbeb7b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-49877/src/test/kotlin/aTest.kt @@ -0,0 +1,3 @@ +private fun test() { + val sink: okio.Sink = null!! +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt index e5573dd18c3..bfb4a073ea7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt @@ -251,7 +251,7 @@ open class DefaultCompilationDetails( * Adds `allDependencies` of configurations mentioned in `configurationNames` to configuration named [this] in * a lazy manner */ - private fun String.addAllDependenciesFromOtherConfigurations(project: Project, vararg configurationNames: String) { + protected fun String.addAllDependenciesFromOtherConfigurations(project: Project, vararg configurationNames: String) { project.configurations.named(this).configure { receiverConfiguration -> receiverConfiguration.dependencies.addAllLater( project.objects.listProperty(Dependency::class.java).apply { @@ -528,10 +528,29 @@ class AndroidCompilationDetails( override val friendArtifacts: FileCollection get() = target.project.files(super.friendArtifacts, compilation.testedVariantArtifacts) + /* + * Example of how multiplatform dependencies from common would get to Android test classpath: + * commonMainImplementation -> androidDebugImplementation -> debugImplementation -> debugAndroidTestCompileClasspath + * After the fix for KT-35916 MPP compilation configurations receive a 'compilation' postfix for disambiguation. + * androidDebugImplementation remains a source set configuration, but no longer contains compilation dependencies. + * Therefore, it doesn't get dependencies from common source sets. + * We now explicitly add associate compilation dependencies to the Kotlin test compilation configurations (test classpaths). + * This helps, because the Android test classpath configurations extend from the Kotlin test compilations' directly. + */ override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) { - if ((other as? KotlinJvmAndroidCompilation)?.androidVariant != getTestedVariantData(androidVariant)) { - super.addAssociateCompilationDependencies(other) - } // otherwise, do nothing: the Android Gradle plugin adds these dependencies for us, we don't need to add them to the classpath + compilation.compileDependencyConfigurationName.addAllDependenciesFromOtherConfigurations( + project, + other.apiConfigurationName, + other.implementationConfigurationName, + other.compileOnlyConfigurationName + ) + + compilation.runtimeDependencyConfigurationName.addAllDependenciesFromOtherConfigurations( + project, + other.apiConfigurationName, + other.implementationConfigurationName, + other.runtimeOnlyConfigurationName + ) } override val kotlinDependenciesHolder: HasKotlinDependencies