[Gradle] Add integration tests for JVM compilation via the Build Tools API
This commit is contained in:
committed by
Space Team
parent
419381af7f
commit
754f4830b9
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.internals.asFinishLogMessage
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
|
||||
import org.jetbrains.kotlin.gradle.tasks.USING_JVM_INCREMENTAL_COMPILATION_MESSAGE
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@DisplayName("JVM compilation via the Build Tools API")
|
||||
@JvmGradlePluginTests
|
||||
class BuildToolsApiJvmCompilationIT : KGPBaseTest() {
|
||||
override val defaultBuildOptions = super.defaultBuildOptions.copy(runViaBuildToolsApi = true)
|
||||
|
||||
@GradleTest
|
||||
@Disabled
|
||||
@DisplayName("Simple project non-incremental in-process compilation")
|
||||
fun compileJvmInProcessNonIncremental(gradleVersion: GradleVersion) = testSimpleProject(
|
||||
gradleVersion, defaultBuildOptions.copy(
|
||||
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.IN_PROCESS,
|
||||
incremental = false,
|
||||
)
|
||||
) {
|
||||
assertOutputContains(KotlinCompilerExecutionStrategy.IN_PROCESS.asFinishLogMessage)
|
||||
assertOutputDoesNotContain(USING_JVM_INCREMENTAL_COMPILATION_MESSAGE)
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@Disabled
|
||||
@DisplayName("Simple project incremental in-process compilation")
|
||||
fun compileJvmInProcessIncremental(gradleVersion: GradleVersion) = testSimpleProject(
|
||||
gradleVersion, defaultBuildOptions.copy(
|
||||
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.IN_PROCESS,
|
||||
incremental = false,
|
||||
)
|
||||
) {
|
||||
assertOutputContains(KotlinCompilerExecutionStrategy.IN_PROCESS.asFinishLogMessage)
|
||||
assertOutputContains(USING_JVM_INCREMENTAL_COMPILATION_MESSAGE)
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@Disabled
|
||||
@DisplayName("Simple project non-incremental compilation within the daemon")
|
||||
fun compileJvmNonIncrementalWithinDaemon(gradleVersion: GradleVersion) = testSimpleProject(
|
||||
gradleVersion, defaultBuildOptions.copy(
|
||||
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.DAEMON,
|
||||
incremental = false,
|
||||
)
|
||||
) {
|
||||
assertOutputContains(KotlinCompilerExecutionStrategy.DAEMON.asFinishLogMessage)
|
||||
assertOutputDoesNotContain(USING_JVM_INCREMENTAL_COMPILATION_MESSAGE)
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@Disabled
|
||||
@DisplayName("Simple project incremental compilation within the daemon")
|
||||
fun compileJvmIncrementalWithinDaemon(gradleVersion: GradleVersion) = testSimpleProject(
|
||||
gradleVersion, defaultBuildOptions.copy(
|
||||
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.DAEMON,
|
||||
incremental = true,
|
||||
)
|
||||
) {
|
||||
assertOutputContains(KotlinCompilerExecutionStrategy.DAEMON.asFinishLogMessage)
|
||||
assertOutputContains(USING_JVM_INCREMENTAL_COMPILATION_MESSAGE)
|
||||
}
|
||||
|
||||
private fun testSimpleProject(gradleVersion: GradleVersion, buildOptions: BuildOptions, assertions: BuildResult.() -> Unit) {
|
||||
project("simpleProject", gradleVersion, buildOptions = buildOptions) {
|
||||
build("assemble", "compileDeployKotlin") {
|
||||
assertFileExists(kotlinClassesDir("main").resolve("demo/KotlinGreetingJoiner.class"))
|
||||
assertFileExists(javaClassesDir("main").resolve("demo/Greeter.class"))
|
||||
assertFileExists(javaClassesDir("main").resolve("demo/HelloWorld.class"))
|
||||
assertFileExists(kotlinClassesDir("deploy").resolve("demo/ExampleSource.class"))
|
||||
assertions()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-16
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.internals.asFinishLogMessage
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
||||
@@ -99,15 +100,17 @@ abstract class ExecutionStrategyIT : KGPDaemonsBaseTest() {
|
||||
project(
|
||||
projectName = "kotlinBuiltins",
|
||||
gradleVersion = gradleVersion,
|
||||
addHeapDumpOptions = false
|
||||
addHeapDumpOptions = false,
|
||||
buildOptions = defaultBuildOptions.copy(
|
||||
useDaemonFallbackStrategy = false,
|
||||
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.DAEMON,
|
||||
)
|
||||
) {
|
||||
setupProject(this)
|
||||
|
||||
buildAndFail(
|
||||
"build",
|
||||
"-Pkotlin.compiler.execution.strategy=${KotlinCompilerExecutionStrategy.DAEMON}",
|
||||
"-Pkotlin.daemon.jvmargs=-Xmxqwerty",
|
||||
"-Pkotlin.daemon.useFallbackStrategy=false"
|
||||
) {
|
||||
assertOutputContains("Failed to compile with Kotlin daemon. Fallback strategy (compiling without Kotlin daemon) is turned off.")
|
||||
}
|
||||
@@ -200,26 +203,28 @@ abstract class ExecutionStrategyIT : KGPDaemonsBaseTest() {
|
||||
projectName = "kotlinBuiltins",
|
||||
gradleVersion = gradleVersion,
|
||||
addHeapDumpOptions = addHeapDumpOptions,
|
||||
buildOptions = defaultBuildOptions.copy(useDaemonFallbackStrategy = testFallbackStrategy)
|
||||
buildOptions = defaultBuildOptions.copy(
|
||||
useDaemonFallbackStrategy = testFallbackStrategy,
|
||||
compilerExecutionStrategy = if (shouldConfigureStrategyViaGradleProperty) {
|
||||
executionStrategy
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
) {
|
||||
setupProject(this)
|
||||
additionalProjectConfiguration()
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
val args = buildList {
|
||||
if (shouldConfigureStrategyViaGradleProperty) {
|
||||
add("-Pkotlin.compiler.execution.strategy=${executionStrategy.propertyValue}")
|
||||
}
|
||||
if (testFallbackStrategy) {
|
||||
// add jvm option that JVM fails to parse
|
||||
add("-Pkotlin.daemon.jvmargs=-Xmxqwerty")
|
||||
}
|
||||
}.toTypedArray()
|
||||
val args = if (testFallbackStrategy) {
|
||||
arrayOf("-Pkotlin.daemon.jvmargs=-Xmxqwerty")
|
||||
} else {
|
||||
emptyArray()
|
||||
}
|
||||
val expectedFinishStrategy = if (testFallbackStrategy) KotlinCompilerExecutionStrategy.OUT_OF_PROCESS else executionStrategy
|
||||
val finishMessage = "Finished executing kotlin compiler using $expectedFinishStrategy strategy"
|
||||
val finishMessage = expectedFinishStrategy.asFinishLogMessage
|
||||
|
||||
build("build", *args) {
|
||||
assertOutputContains(finishMessage)
|
||||
assertOutputContains(expectedFinishStrategy.asFinishLogMessage)
|
||||
checkOutput(this@project)
|
||||
assertNoBuildWarnings()
|
||||
|
||||
|
||||
+3
-1
@@ -880,7 +880,9 @@ abstract class BaseIncrementalCompilationMultiProjectIT : IncrementalCompilation
|
||||
// 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}"
|
||||
buildOptions = defaultBuildOptions.copy(
|
||||
compilerExecutionStrategy = KotlinCompilerExecutionStrategy.IN_PROCESS,
|
||||
),
|
||||
) {
|
||||
projectPath.resolve("lib/build/kotlin/${compileKotlinTaskName}/classpath-snapshot").let {
|
||||
assert(!it.exists() || it.listDirectoryEntries().isEmpty())
|
||||
|
||||
+11
@@ -11,6 +11,7 @@ import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties.COMPILE_INCREMENTAL_WITH_ARTIFACT_TRANSFORM
|
||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
|
||||
import org.jetbrains.kotlin.gradle.report.BuildReportType
|
||||
import org.junit.jupiter.api.condition.OS
|
||||
import java.util.*
|
||||
@@ -44,6 +45,8 @@ data class BuildOptions(
|
||||
val useDaemonFallbackStrategy: Boolean = false,
|
||||
val verboseDiagnostics: Boolean = true,
|
||||
val nativeOptions: NativeOptions = NativeOptions(),
|
||||
val compilerExecutionStrategy: KotlinCompilerExecutionStrategy? = null,
|
||||
val runViaBuildToolsApi: Boolean? = null,
|
||||
) {
|
||||
val safeAndroidVersion: String
|
||||
get() = androidVersion ?: error("AGP version is expected to be set")
|
||||
@@ -176,6 +179,14 @@ data class BuildOptions(
|
||||
arguments.add("-Pkotlin.internal.verboseDiagnostics=$verboseDiagnostics")
|
||||
}
|
||||
|
||||
if (compilerExecutionStrategy != null) {
|
||||
arguments.add("-Pkotlin.compiler.execution.strategy=${compilerExecutionStrategy.propertyValue}")
|
||||
}
|
||||
|
||||
if (runViaBuildToolsApi != null) {
|
||||
arguments.add("-Pkotlin.compiler.runViaBuildToolsApi=$runViaBuildToolsApi")
|
||||
}
|
||||
|
||||
arguments.addAll(freeArgs)
|
||||
|
||||
return arguments.toList()
|
||||
|
||||
+4
-1
@@ -227,8 +227,11 @@ private fun createLoggingMessageCollector(log: KotlinLogger): MessageCollector =
|
||||
}
|
||||
}
|
||||
|
||||
internal val KotlinCompilerExecutionStrategy.asFinishLogMessage: String
|
||||
get() = "Finished executing kotlin compiler using $this strategy"
|
||||
|
||||
internal fun KotlinLogger.logFinish(strategy: KotlinCompilerExecutionStrategy) {
|
||||
debug("Finished executing kotlin compiler using $strategy strategy")
|
||||
debug(strategy.asFinishLogMessage)
|
||||
}
|
||||
|
||||
internal fun exitCodeFromProcessExitCode(log: KotlinLogger, code: Int): ExitCode {
|
||||
|
||||
+5
@@ -5,11 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internals
|
||||
|
||||
import org.jetbrains.kotlin.compilerRunner.asFinishLogMessage
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.DIAGNOSTIC_SEPARATOR
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.parseKotlinSourceSetMetadataFromJson
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
|
||||
|
||||
fun parseKotlinSourceSetMetadataFromJson(json: String): KotlinProjectStructureMetadata = parseKotlinSourceSetMetadataFromJson(json)
|
||||
|
||||
@@ -18,3 +20,6 @@ const val MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME = MULTIPLATFORM_PROJECT_
|
||||
const val KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS_PROPERTY = KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS
|
||||
|
||||
const val VERBOSE_DIAGNOSTIC_SEPARATOR = DIAGNOSTIC_SEPARATOR
|
||||
|
||||
val KotlinCompilerExecutionStrategy.asFinishLogMessage: String
|
||||
get() = this.asFinishLogMessage
|
||||
Reference in New Issue
Block a user