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 492681bdb72..66164ecbc96 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 @@ -4,6 +4,7 @@ import org.gradle.api.logging.LogLevel import org.gradle.api.logging.configuration.WarningMode import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated +import org.jetbrains.kotlin.gradle.testbase.NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED import org.jetbrains.kotlin.gradle.testbase.TestVersions import org.jetbrains.kotlin.gradle.tooling.BuildKotlinToolingMetadataTask import org.jetbrains.kotlin.gradle.util.* @@ -694,7 +695,7 @@ open class KotlinAndroid70GradleIT : KotlinAndroid36GradleIT() { project.build(":app:testDebugUnitTest", options = options) { assertSuccessful() - assertNotContains("Non-incremental compilation will be performed") + assertNotContains(NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED) } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildCacheIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildCacheIT.kt index 2d06e4b3e3d..c265ffc40af 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildCacheIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildCacheIT.kt @@ -160,7 +160,7 @@ class BuildCacheIT : KGPBaseTest() { bKtSourceFile.modify { it.replace("fun b() {}", "fun b() {}\nfun b2() {}") } build("assemble", buildOptions = defaultBuildOptions.copy(useICClasspathSnapshot = true, logLevel = LogLevel.DEBUG)) { - assertOutputDoesNotContain("[KOTLIN] [IC] Non-incremental compilation will be performed") + assertOutputDoesNotContain(NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED) assertOutputContains("Incremental compilation with ABI snapshot enabled") assertCompiledKotlinSources(setOf(bKtSourceFile).map { it.relativeTo(projectPath)}, output) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt index 36d34e0fde8..4df2a75825c 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.gradle import org.gradle.testkit.runner.BuildResult import org.gradle.util.GradleVersion import org.jetbrains.kotlin.build.report.metrics.BuildAttribute +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.util.checkedReplace import org.junit.jupiter.api.DisplayName @@ -648,6 +649,35 @@ abstract class BaseIncrementalCompilationMultiProjectIT : IncrementalCompilation } } + @DisplayName("Test compilation when incremental state is missing") + @GradleTest + fun testMissingIncrementalState(gradleVersion: GradleVersion) { + defaultProject(gradleVersion) { + // Perform the first non-incremental build without using Kotlin daemon so that incremental state is not produced + build( + ":lib:compileKotlin", + "-Pkotlin.compiler.execution.strategy=${KotlinCompilerExecutionStrategy.IN_PROCESS.propertyValue}" + ) { + assert(projectPath.resolve("lib/build/kotlin/${compileKotlinTaskName}/classpath-snapshot").listDirectoryEntries().isEmpty()) + } + + // Perform the next build using Kotlin daemon without making a change and check that tasks are up-to-date. This is to ensure + // that the `kotlin.compiler.execution.strategy` property used above is not an input to the KotlinCompile task; otherwise the + // test in the next build would not be effective. + build(":lib:compileKotlin") { + assertTasksUpToDate(":lib:$compileKotlinTaskName") + } + + // Make a change in the source code + changeMethodSignatureInLib() + + // In the next build, compilation should be non-incremental as incremental state is missing + build(":lib:compileKotlin") { + assertNonIncrementalCompilation(BuildAttribute.INCREMENTAL_COMPILATION_FAILED) + } + } + } + @DisplayName("Test handling of failures caused by user errors") @GradleTest fun testFailureHandling_UserError(gradleVersion: GradleVersion) { @@ -666,7 +696,7 @@ abstract class BaseIncrementalCompilationMultiProjectIT : IncrementalCompilation buildAndFail(":lib:compileKotlin") { assertTasksFailed(":lib:$compileKotlinTaskName") assertOutputContains("Compilation error. See log for more details") - assertOutputDoesNotContain("Non-incremental compilation will be performed: ${BuildAttribute.INCREMENTAL_COMPILATION_FAILED.name}") + assertOutputDoesNotContain(NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED) } // Fix the compile error in the source code @@ -704,7 +734,7 @@ abstract class BaseIncrementalCompilationMultiProjectIT : IncrementalCompilation // In the next build, compilation should be incremental and fail, then fall back to non-incremental compilation and succeed build(":lib:compileKotlin") { - assertOutputContains("Non-incremental compilation will be performed: ${BuildAttribute.INCREMENTAL_COMPILATION_FAILED.name}") + assertNonIncrementalCompilation(BuildAttribute.INCREMENTAL_COMPILATION_FAILED) // Also check that the output is not deleted (regression test for KT-49780) assertFileExists(lookupFile) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/compilationAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/compilationAssertions.kt index f66dc751f23..d000ae54426 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/compilationAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/compilationAssertions.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.testbase import org.gradle.api.logging.LogLevel import org.gradle.testkit.runner.BuildResult import org.intellij.lang.annotations.Language +import org.jetbrains.kotlin.build.report.metrics.BuildAttribute import java.io.File import java.nio.file.Path import java.nio.file.Paths @@ -89,9 +90,12 @@ fun assertCompiledKotlinSources( * * Note: Log level of output must be set to [LogLevel.DEBUG]. */ -@Suppress("unused") -fun BuildResult.assertNonIncrementalCompilation() { - assertOutputContains("Non-incremental compilation will be performed") +fun BuildResult.assertNonIncrementalCompilation(reason: BuildAttribute? = null) { + if (reason != null) { + assertOutputContains("$NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED: ${reason.name}") + } else { + assertOutputContains(NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED) + } } /** @@ -102,8 +106,10 @@ fun BuildResult.assertNonIncrementalCompilation() { * Note: Log level of output must be set to [LogLevel.DEBUG]. */ fun BuildResult.assertIncrementalCompilation(expectedCompiledKotlinFiles: Iterable) { - assertOutputDoesNotContain("Non-incremental compilation will be performed") + assertOutputDoesNotContain(NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED) val actualCompiledKotlinFiles = extractCompiledKotlinFiles(output) assertSameFiles(expectedCompiledKotlinFiles, actualCompiledKotlinFiles, "Compiled Kotlin files differ:\n") } + +const val NON_INCREMENTAL_COMPILATION_WILL_BE_PERFORMED = "Non-incremental compilation will be performed"