[IC] Smoke tests for KMP IC, part 1.5

Refactorings: rework testData to better reflect usages of declarations,
clean up internal test methods.

Merge-request: KT-MR-13232
Merged-by: Evgenii Mazhukin <evgenii.mazhukin@jetbrains.com>
This commit is contained in:
Evgenii Mazhukin
2023-11-29 13:28:26 +00:00
committed by Space Team
parent 35cf9cb0c4
commit 3f8505a090
59 changed files with 120 additions and 81 deletions
@@ -11,8 +11,14 @@ import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.testbase.relativizeTo
import java.nio.file.Path
import java.util.concurrent.atomic.AtomicInteger
import kotlin.io.path.appendText
/**
* KmpIncrementalITBase is used as a "limited scope" for experimental test utils.
* If some of them can be reused widely, consider moving them to KGPBaseTest
* or the appropriate util package. //TODO: KT-63876
*/
abstract class KmpIncrementalITBase : KGPBaseTest() {
override val defaultBuildOptions: BuildOptions
@@ -38,10 +44,13 @@ abstract class KmpIncrementalITBase : KGPBaseTest() {
)
}
protected open fun TestProject.touchAndGet(subproject: String, srcDir: String, name: String): Path {
val path = subProject(subproject).kotlinSourcesDir(srcDir).resolve(name)
path.appendText("private val nothingMuch = 24")
return path
protected fun TestProject.resolvePath(subproject: String, srcDir: String, name: String): Path {
return subProject(subproject).kotlinSourcesDir(srcDir).resolve(name)
}
protected fun Path.addPrivateVal(): Path {
this@addPrivateVal.appendText("private val nothingMuch${changeCounter.incrementAndGet()} = 24")
return this@addPrivateVal
}
protected open fun BuildResult.assertSuccessOrUTD(allTasks: Set<String>, executedTasks: Set<String>) {
@@ -61,4 +70,8 @@ abstract class KmpIncrementalITBase : KGPBaseTest() {
assertions()
}
}
companion object {
private val changeCounter = AtomicInteger(0)
}
}
@@ -10,6 +10,9 @@ import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
/**
* Basic smoke tests assert that the baseline IC is reasonable: if we do a local change, only a local rebuild is performed.
*/
@DisplayName("Basic incremental scenarios with KMP - K2")
@MppGradlePluginTests
open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
@@ -24,7 +27,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("app", "commonMain", "PlainPublicClass.kt"),
incrementalPath = resolvePath("app", "commonMain", "Unused.kt").addPrivateVal(),
executedTasks = setOf(
":app:compileKotlinJvm",
":app:compileKotlinJs",
@@ -36,7 +39,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
* Step 2: touch app:jvm, no abi change
*/
val appJvmClassKt = touchAndGet("app", "jvmMain", "PlainPublicClassJvm.kt")
val appJvmClassKt = resolvePath("app", "jvmMain", "UnusedJvm.kt").addPrivateVal()
testCase(
incrementalPath = null, //TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
executedTasks = setOf(":app:compileKotlinJvm")
@@ -49,7 +52,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("app", "jsMain", "PlainPublicClassJs.kt"),
incrementalPath = resolvePath("app", "jsMain", "UnusedJs.kt").addPrivateVal(),
executedTasks = setOf(":app:compileKotlinJs"),
)
@@ -57,7 +60,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
* Step 4: touch app:native, no abi change
*/
touchAndGet("app", "nativeMain", "PlainPublicClassNative.kt")
resolvePath("app", "nativeMain", "UnusedNative.kt").addPrivateVal()
testCase(
incrementalPath = null, // no native incremental compilation - see KT-62824
executedTasks = setOf(":app:compileKotlinNative"),
@@ -68,7 +71,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("lib", "commonMain", "CommonUtil.kt"),
incrementalPath = resolvePath("lib", "commonMain", "UsedInLibPlatformTests.kt").addPrivateVal(),
executedTasks = mainCompileTasks // TODO: KT-62642 - bad compile avoidance here
)
@@ -76,7 +79,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
* Step 6: touch lib:jvm, no abi change
*/
val libJvmUtilKt = touchAndGet("lib", "jvmMain", "libJvmPlatformUtil.kt")
val libJvmUtilKt = resolvePath("lib", "jvmMain", "UsedInAppJvmAndLibTests.kt").addPrivateVal()
testCase(
incrementalPath = null, //TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
executedTasks = setOf(":app:compileKotlinJvm", ":lib:compileKotlinJvm"),
@@ -89,7 +92,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("lib", "jsMain", "libJsPlatformUtil.kt"),
incrementalPath = resolvePath("lib", "jsMain", "UsedInAppJsAndLibTests.kt").addPrivateVal(),
executedTasks = setOf(":app:compileKotlinJs", ":lib:compileKotlinJs"),
)
@@ -97,7 +100,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
* Step 8: touch lib:native, no abi change
*/
touchAndGet("lib", "nativeMain", "libNativePlatformUtil.kt")
resolvePath("lib", "nativeMain", "UsedInAppNativeAndLibTests.kt").addPrivateVal()
testCase(
incrementalPath = null,
executedTasks = setOf(":app:compileKotlinNative", ":lib:compileKotlinNative"),
@@ -46,7 +46,7 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("lib", "commonMain", "CommonUtil.kt"),
incrementalPath = resolvePath("lib", "commonMain", "UsedInLibPlatformTests.kt").addPrivateVal(),
executedTasks = mainCompileTasks,
)
@@ -55,7 +55,7 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("app", "commonMain", "PlainPublicClass.kt"),
incrementalPath = resolvePath("app", "commonMain", "Unused.kt").addPrivateVal(),
executedTasks = setOf(
":app:compileTestKotlinJvm",
":app:compileTestKotlinNative",
@@ -70,7 +70,7 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
* Step 3 - touch app/jvm, affect jvm tests in app
*/
val touchedAppJvm = touchAndGet("app", "jvmMain", "PlainPublicClassJvm.kt")
val touchedAppJvm = resolvePath("app", "jvmMain", "UnusedJvm.kt").addPrivateVal()
testCase(
incrementalPath = null,
executedTasks = setOf(
@@ -86,7 +86,7 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
*/
testCase(
incrementalPath = touchAndGet("app", "jsMain", "PlainPublicClassJs.kt"),
incrementalPath = resolvePath("app", "jsMain", "UnusedJs.kt").addPrivateVal(),
executedTasks = setOf(
":app:compileTestKotlinJs",
":app:jsTest",
@@ -97,7 +97,7 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
* Step 5 - touch app/native, affect native tests in app
*/
touchAndGet("app", "nativeMain", "PlainPublicClassNative.kt")
resolvePath("app", "nativeMain", "UnusedNative.kt").addPrivateVal()
testCase(
incrementalPath = null,
executedTasks = setOf(
@@ -33,9 +33,9 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
build("assemble")
listOf(
kotlinSourcesDir("jvmMain").resolve("FooJvm.kt"),
kotlinSourcesDir("nativeMain").resolve("FooNative.kt"),
kotlinSourcesDir("jsMain").resolve("FooJs.kt")
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
kotlinSourcesDir("nativeMain").resolve("ActualFunFoo.kt"),
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt")
).forEach {
it.replaceFirst("\"foo", "\"bar")
}
@@ -44,9 +44,9 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
assertIncrementalCompilation(
listOf(
kotlinSourcesDir("jvmMain").resolve("FooJvm.kt"),
kotlinSourcesDir("jsMain").resolve("FooJs.kt"),
kotlinSourcesDir("commonMain").resolve("Foo.kt")
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt"),
kotlinSourcesDir("commonMain").resolve("ExpectFunFoo.kt")
).relativizeTo(projectPath)
)
}
@@ -59,8 +59,8 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
build("assemble")
val valueKtPath = kotlinSourcesDir("commonMain").resolve("Value.kt")
valueKtPath.replaceFirst(
val unusedKtPath = kotlinSourcesDir("commonMain").resolve("Unused.kt")
unusedKtPath.replaceFirst(
"val secret = 1",
"val secret = \"k2\""
)
@@ -69,10 +69,10 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
assertIncrementalCompilation(
listOf(
kotlinSourcesDir("jvmMain").resolve("FooJvm.kt"),
kotlinSourcesDir("jsMain").resolve("FooJs.kt"),
kotlinSourcesDir("commonMain").resolve("Foo.kt"),
valueKtPath
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt"),
kotlinSourcesDir("commonMain").resolve("ExpectFunFoo.kt"),
unusedKtPath
).relativizeTo(projectPath)
)
}
@@ -85,13 +85,17 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
build("assemble")
kotlinSourcesDir("commonMain").resolve("Bar.kt").appendText("val irrelevant = 2")
kotlinSourcesDir("commonMain").resolve("ExpectClassBar.kt").appendText("val irrelevant = 2")
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
assertIncrementalCompilation(listOf("commonMain", "jvmMain", "jsMain").map { sourceSet ->
kotlinSourcesDir(sourceSet).resolve("Bar.kt")
}.relativizeTo(projectPath))
assertIncrementalCompilation(
listOf(
kotlinSourcesDir("jvmMain").resolve("ActualClassBar.kt"),
kotlinSourcesDir("jsMain").resolve("ActualClassBar.kt"),
kotlinSourcesDir("commonMain").resolve("ExpectClassBar.kt")
).relativizeTo(projectPath)
)
}
}
}
@@ -4,14 +4,10 @@ plugins {
kotlin {
jvm()
js()
<SingleNativeTarget>("native")
}
kotlin {
js {
js() {
nodejs()
}
<SingleNativeTarget>("native")
sourceSets {
val commonMain by getting {
@@ -0,0 +1,3 @@
fun appCommonFunDependingOnLibCommon() {
println("you're ${libCommonFunForAppCommon()} years old!")
}
@@ -1,10 +1,10 @@
import kotlin.test.Test
import kotlin.test.assertEquals
class TrivialTest {
class AppCommonTest {
@Test
fun sayYesSaysYes() {
assertEquals("Yes", sayYes())
assertEquals("Yes", appCommonFunForAppPlatformAndAppCommonTest())
}
}
@@ -0,0 +1,3 @@
class AppJsUnusedClassWithDependencies {
val line = appCommonFunForAppPlatformAndAppCommonTest()
}
@@ -0,0 +1,3 @@
class AppJsUnusedChildClass(length: Int, builder: String) : LibCommonClassForAppPlatform(length, builder) {
fun price() = length * builder.length * 300
}
@@ -0,0 +1,3 @@
class AppJvmUnusedClassWithDependencies {
val line = appCommonFunForAppPlatformAndAppCommonTest()
}
@@ -0,0 +1,3 @@
class AppJvmUnusedChildClass(length: Int, builder: String) : LibCommonClassForAppPlatform(length, builder) {
fun price() = length * builder.length * 300
}
@@ -0,0 +1,3 @@
class AppNativeUnusedClassWithDependencies {
val line = appCommonFunForAppPlatformAndAppCommonTest()
}
@@ -0,0 +1,3 @@
class AppNativeUnusedChildClass(length: Int, builder: String) : LibCommonClassForAppPlatform(length, builder) {
fun price() = length * builder.length * 300
}
@@ -4,14 +4,10 @@ plugins {
kotlin {
jvm()
js()
<SingleNativeTarget>("native")
}
kotlin {
js {
js() {
nodejs()
}
<SingleNativeTarget>("native")
sourceSets {
val commonTest by getting {
@@ -1 +1 @@
expect fun calc(expression: String): Double
expect fun expectActualCalc(expression: String): Double
@@ -0,0 +1,5 @@
open class LibCommonClassForAppPlatform(
val length: Int,
val builder: String,
) {
}
@@ -1,3 +1,3 @@
actual fun calc(expression: String): Double {
actual fun expectActualCalc(expression: String): Double {
return Double.NaN
}
@@ -1,7 +1,7 @@
import kotlin.test.Test
import kotlin.test.assertEquals
class AdvancedTest {
class LibJsTest {
@Test
fun jsUtilReturns0() {
@@ -10,6 +10,6 @@ class AdvancedTest {
@Test
fun commonUtilTest() {
assertEquals(2, multiplyByTwo(1))
assertEquals(2, libCommonFunForLibPlatformTests(1))
}
}
@@ -1,3 +1,3 @@
actual fun calc(expression: String): Double {
actual fun expectActualCalc(expression: String): Double {
return expression.toDoubleOrNull()?.let { it * 2 } ?: 0.0
}
@@ -1,7 +1,7 @@
import kotlin.test.Test
import kotlin.test.assertEquals
class AdvancedTest {
class LibJvmTest {
@Test
fun jvmUtilReturns400() {
@@ -10,6 +10,6 @@ class AdvancedTest {
@Test
fun commonUtilTest() {
assertEquals(2, multiplyByTwo(1))
assertEquals(2, libCommonFunForLibPlatformTests(1))
}
}
@@ -1,3 +1,3 @@
actual fun calc(expression: String): Double {
actual fun expectActualCalc(expression: String): Double {
return 15.0
}
@@ -1,7 +1,7 @@
import kotlin.test.Test
import kotlin.test.assertEquals
class AdvancedTest {
class LibNativeTest {
@Test
fun nativeUtilReturns800() {
@@ -10,6 +10,6 @@ class AdvancedTest {
@Test
fun commonUtilTest() {
assertEquals(2, multiplyByTwo(1))
assertEquals(2, libCommonFunForLibPlatformTests(1))
}
}