Migrated ExecutionStrategyIT tests to new DSL

^KT-45745 In Progress
This commit is contained in:
Yahor Berdnikau
2022-01-18 13:51:24 +01:00
parent 12d8b189a9
commit 5f22bcd03b
7 changed files with 163 additions and 119 deletions
@@ -1,85 +1,140 @@
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.tasks.KotlinCompilerExecutionStrategy
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.util.checkedReplace
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Assert
import org.junit.Test
import java.io.File
import org.junit.jupiter.api.DisplayName
@DisplayName("Kotlin JS compile execution strategy")
class ExecutionStrategyJsIT : ExecutionStrategyIT() {
override fun setupProject(project: Project) {
override fun setupProject(project: TestProject) {
super.setupProject(project)
val buildGradle = File(project.projectDir, "app/build.gradle")
buildGradle.modify {
it.replace("apply plugin: \"kotlin\"", "apply plugin: \"kotlin2js\"") +
"\ncompileKotlin2Js.kotlinOptions.outputFile = \"web/js/out.js\""
project.subProject("app").buildGradle.modify {
it.replace(
"id \"org.jetbrains.kotlin.jvm\"",
"id \"org.jetbrains.kotlin.js\""
) +
"""
|
|afterEvaluate {
| tasks.named('compileKotlinJs') {
| kotlinOptions.outputFile = "${'$'}{project.projectDir}/web/js/out.js"
| }
|}
|
""".trimMargin()
}
}
override fun CompiledProject.checkOutput() {
assertFileExists("web/js/out.js")
override fun BuildResult.checkOutput(project: TestProject) {
project.subProject("app").assertFileInProjectExists("web/js/out.js")
}
override fun CompiledProject.checkOutputAfterChange() {
assertFileExists("web/js/out.js")
override fun BuildResult.checkOutputAfterChange(project: TestProject) {
project.subProject("app").assertFileInProjectExists("web/js/out.js")
}
}
@DisplayName("Kotlin JVM compile execution strategy")
class ExecutionStrategyJvmIT : ExecutionStrategyIT() {
override fun CompiledProject.checkOutput() {
val classesDir = kotlinClassesDir(subproject = "app") + "foo/"
assertFileExists("${classesDir}MainKt.class")
assertFileExists("${classesDir}A.class")
assertFileExists("${classesDir}B.class")
override fun BuildResult.checkOutput(project: TestProject) {
with(project) {
val classesDir = subProject("app").kotlinClassesDir().resolve("foo")
assertFileExists(classesDir.resolve("MainKt.class"))
assertFileExists(classesDir.resolve("A.class"))
assertFileExists(classesDir.resolve("B.class"))
}
}
override fun CompiledProject.checkOutputAfterChange() {
val classesDir = kotlinClassesDir(subproject = "app") + "foo/"
assertFileExists("${classesDir}MainKt.class")
assertFileExists("${classesDir}A.class")
assertNoSuchFile("${classesDir}B.class")
override fun BuildResult.checkOutputAfterChange(project: TestProject) {
with(project) {
val classesDir = subProject("app").kotlinClassesDir().resolve("foo")
assertFileExists(classesDir.resolve("MainKt.class"))
assertFileExists(classesDir.resolve("A.class"))
assertFileNotExists(classesDir.resolve("B.class"))
}
}
}
abstract class ExecutionStrategyIT : BaseGradleIT() {
@Test
fun testDaemon() {
doTestExecutionStrategy(KotlinCompilerExecutionStrategy.DAEMON, addHeapDumpOptions = false)
abstract class ExecutionStrategyIT : KGPDaemonsBaseTest() {
override val defaultBuildOptions: BuildOptions = super.defaultBuildOptions.copy(
logLevel = LogLevel.DEBUG
)
@DisplayName("Compilation via Kotlin daemon")
@GradleTest
fun testDaemon(gradleVersion: GradleVersion) {
doTestExecutionStrategy(
gradleVersion,
KotlinCompilerExecutionStrategy.DAEMON,
addHeapDumpOptions = false
)
}
@Test
fun testDaemonViaSystemProperty() {
doTestExecutionStrategy(KotlinCompilerExecutionStrategy.DAEMON, addHeapDumpOptions = false, viaSystemProperty = true)
@DisplayName("Compilation via Kotlin daemon enabled using system property")
@GradleTest
fun testDaemonViaSystemProperty(gradleVersion: GradleVersion) {
doTestExecutionStrategy(
gradleVersion,
KotlinCompilerExecutionStrategy.DAEMON,
addHeapDumpOptions = false,
viaSystemProperty = true
)
}
@Test
fun testInProcess() {
doTestExecutionStrategy(KotlinCompilerExecutionStrategy.IN_PROCESS)
@DisplayName("Compilation inside Gradle daemon")
@GradleTest
fun testInProcess(gradleVersion: GradleVersion) {
doTestExecutionStrategy(
gradleVersion,
KotlinCompilerExecutionStrategy.IN_PROCESS
)
}
@Test
fun testInProcessViaSystemProperty() {
doTestExecutionStrategy(KotlinCompilerExecutionStrategy.IN_PROCESS, viaSystemProperty = true)
@DisplayName("Compilation inside Gradle daemon enabled using system property")
@GradleTest
fun testInProcessViaSystemProperty(gradleVersion: GradleVersion) {
doTestExecutionStrategy(
gradleVersion,
KotlinCompilerExecutionStrategy.IN_PROCESS,
viaSystemProperty = true
)
}
@Test
fun testOutOfProcess() {
doTestExecutionStrategy(KotlinCompilerExecutionStrategy.OUT_OF_PROCESS)
@DisplayName("Compilation via separate compiler process")
@GradleTest
fun testOutOfProcess(gradleVersion: GradleVersion) {
doTestExecutionStrategy(
gradleVersion,
KotlinCompilerExecutionStrategy.OUT_OF_PROCESS
)
}
@Test
fun testOutOfProcessViaSystemProperty() {
doTestExecutionStrategy(KotlinCompilerExecutionStrategy.OUT_OF_PROCESS, viaSystemProperty = true)
@DisplayName("Compilation via separate compiler process enabled via system property")
@GradleTest
fun testOutOfProcessViaSystemProperty(gradleVersion: GradleVersion) {
doTestExecutionStrategy(
gradleVersion,
KotlinCompilerExecutionStrategy.OUT_OF_PROCESS,
viaSystemProperty = true
)
}
private fun doTestExecutionStrategy(
gradleVersion: GradleVersion,
executionStrategy: KotlinCompilerExecutionStrategy,
addHeapDumpOptions: Boolean = true,
viaSystemProperty: Boolean = false
) {
with(Project("kotlinBuiltins", addHeapDumpOptions = addHeapDumpOptions)) {
project(
projectName = "kotlinBuiltins",
gradleVersion = gradleVersion,
addHeapDumpOptions = addHeapDumpOptions
) {
setupProject(this)
val cliArgPrefix = if (viaSystemProperty) "-D" else "-P"
@@ -87,53 +142,44 @@ abstract class ExecutionStrategyIT : BaseGradleIT() {
val finishMessage = "Finished executing kotlin compiler using $executionStrategy strategy"
build("build", strategyCLIArg) {
assertSuccessful()
assertContains(finishMessage)
checkOutput()
assertNoWarnings()
assertOutputContains(finishMessage)
checkOutput(this@project)
assertNoBuildWarnings()
if (executionStrategy == KotlinCompilerExecutionStrategy.DAEMON) {
checkCompileDaemon()
// 256m is the default value for Gradle 5.0+
assertKotlinDaemonJvmOptions(
listOf("-XX:MaxMetaspaceSize=256m", "-ea")
)
}
}
val classesKt = projectDir.getFileByName("classes.kt")
val classesKt = subProject("app").kotlinSourcesDir().resolve("classes.kt")
classesKt.modify {
it.checkedReplace("class B", "//class B")
}
build("build", strategyCLIArg) {
assertSuccessful()
assertContains(finishMessage)
checkOutputAfterChange()
assertNoWarnings()
assertOutputContains(finishMessage)
checkOutputAfterChange(this@project)
assertNoBuildWarnings()
}
}
}
private fun CompiledProject.checkCompileDaemon() {
val m = "Kotlin compile daemon JVM options: \\[(.*?)\\]".toRegex().find(output)
?: error("Could not find Kotlin compile daemon JVM options in Gradle's output")
val kotlinDaemonJvmArgs = m.groupValues[1].split(",").mapTo(LinkedHashSet()) { it.trim() }
fun assertDaemonArgsContain(arg: String) {
Assert.assertTrue(
"Expected '$arg' in kotlin daemon JVM args, got: $kotlinDaemonJvmArgs",
arg in kotlinDaemonJvmArgs
)
}
// 256m is the default value for Gradle 5.0+
assertDaemonArgsContain("-XX:MaxMetaspaceSize=256m")
assertDaemonArgsContain("-ea")
}
protected open fun setupProject(project: Project) {
project.setupWorkingDir()
File(project.projectDir, "app/build.gradle").appendText(
"\ntasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all { kotlinOptions.allWarningsAsErrors = true }"
protected open fun setupProject(project: TestProject) {
project.subProject("app").buildGradle.append(
//language=Groovy
"""
|
|tasks
| .withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile)
| .configureEach {
| kotlinOptions.allWarningsAsErrors = true
| }
""".trimMargin()
)
}
protected abstract fun CompiledProject.checkOutput()
protected abstract fun CompiledProject.checkOutputAfterChange()
protected abstract fun BuildResult.checkOutput(project: TestProject)
protected abstract fun BuildResult.checkOutputAfterChange(project: TestProject)
}
@@ -224,11 +224,21 @@ class Kotlin2JsGradlePluginIT : AbstractKotlin2JsGradlePluginIT(false) {
project("kotlinBuiltins", gradleVersion) {
subProject("app").buildGradle.modify { originalScript ->
buildString {
append(originalScript.replace("apply plugin: \"kotlin\"", "apply plugin: \"kotlin2js\""))
append(
originalScript.replace(
"id \"org.jetbrains.kotlin.jvm\"",
"id \"org.jetbrains.kotlin.js\""
)
)
append(
"""
|
|compileKotlin2Js.kotlinOptions.outputFile = "out/out.js"
|afterEvaluate {
| tasks.named('compileKotlinJs') {
| kotlinOptions.outputFile = "${'$'}{project.projectDir}/out/out.js"
| }
|}
|
""".trimMargin()
)
}
@@ -6,11 +6,8 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.gradle.testkit.runner.BuildResult
import org.gradle.tooling.internal.consumer.ConnectorServices
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.DisplayName
@DisplayName("Kotlin daemon JVM args")
@@ -171,26 +168,4 @@ class KotlinDaemonJvmArgsTest : KGPDaemonsBaseTest() {
}
}
}
private fun BuildResult.assertKotlinDaemonJvmOptions(
expectedOptions: List<String>
) {
val jvmArgsCommonMessage = "Kotlin compile daemon JVM options: "
assertOutputContains(jvmArgsCommonMessage)
val argsRegex = "\\[.+?]".toRegex()
val argsStrings = output.lineSequence()
.filter { it.contains(jvmArgsCommonMessage) }
.map {
argsRegex.findAll(it).last().value.removePrefix("[").removeSuffix("]").split(", ")
}
val containsArgs = argsStrings.any {
it.containsAll(expectedOptions)
}
assert(containsArgs) {
printBuildOutput()
"${argsStrings.toList()} does not contain expected args: $expectedOptions"
}
}
}
@@ -190,3 +190,28 @@ fun BuildResult.assertIncrementalCompilation(
""".trimMargin()
}
}
/**
* Asserts compilation is running via Kotlin daemon with given jvm arguments.
*/
fun BuildResult.assertKotlinDaemonJvmOptions(
expectedJvmArgs: List<String>
) {
val jvmArgsCommonMessage = "Kotlin compile daemon JVM options: "
assertOutputContains(jvmArgsCommonMessage)
val argsRegex = "\\[.+?]".toRegex()
val argsStrings = output.lineSequence()
.filter { it.contains(jvmArgsCommonMessage) }
.map {
argsRegex.findAll(it).last().value.removePrefix("[").removeSuffix("]").split(", ")
}
val containsArgs = argsStrings.any {
it.containsAll(expectedJvmArgs)
}
assert(containsArgs) {
printBuildOutput()
"${argsStrings.toList()} does not contain expected args: $expectedJvmArgs"
}
}
@@ -1,10 +1,8 @@
apply plugin: "kotlin"
plugins {
id "org.jetbrains.kotlin.jvm"
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
@@ -1,9 +0,0 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@@ -141,7 +141,6 @@ private fun writeArgumentsToFile(directory: File, argsArray: Array<String>): Fil
Files.createTempFile(directory.toPath(), prefix, suffix).toFile()
else
Files.createTempFile(prefix, suffix).toFile()
compilerOptions.deleteOnExit()
compilerOptions.writeText(argsArray.joinToString(" ") { "\"${StringEscapeUtils.escapeJava(it)}\"" })
return compilerOptions
}