From 5f22bcd03b3619f13a15d51b9fd14211b5c83dc1 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Tue, 18 Jan 2022 13:51:24 +0100 Subject: [PATCH] Migrated ExecutionStrategyIT tests to new DSL ^KT-45745 In Progress --- .../kotlin/gradle/ExecutionStrategyIT.kt | 200 +++++++++++------- .../kotlin/gradle/Kotlin2JsGradlePluginIT.kt | 14 +- .../kotlin/gradle/KotlinDaemonJvmArgsTest.kt | 25 --- .../gradle/testbase/outputAssertions.kt | 25 +++ .../kotlinBuiltins/app/build.gradle | 8 +- .../testProject/kotlinBuiltins/build.gradle | 9 - .../kotlin/compilerRunner/reportUtils.kt | 1 - 7 files changed, 163 insertions(+), 119 deletions(-) delete mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/build.gradle diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt index b0b22e94b4d..697f0271118 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt @@ -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) } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt index 1b0b7b149b3..dda4bf9a7cb 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt @@ -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() ) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinDaemonJvmArgsTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinDaemonJvmArgsTest.kt index f20b49487a2..2073560c184 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinDaemonJvmArgsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinDaemonJvmArgsTest.kt @@ -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 - ) { - 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" - } - } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt index 3a85ec8be46..91cb4e80082 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt @@ -190,3 +190,28 @@ fun BuildResult.assertIncrementalCompilation( """.trimMargin() } } + +/** + * Asserts compilation is running via Kotlin daemon with given jvm arguments. + */ +fun BuildResult.assertKotlinDaemonJvmOptions( + expectedJvmArgs: List +) { + 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" + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/app/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/app/build.gradle index 2a8815ebd3e..d7bad4b04e3 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/app/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/app/build.gradle @@ -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" -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/build.gradle deleted file mode 100644 index b1b941981c6..00000000000 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinBuiltins/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -buildscript { - repositories { - mavenLocal() - mavenCentral() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt index 2ccb713d78c..32a9328a652 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt @@ -141,7 +141,6 @@ private fun writeArgumentsToFile(directory: File, argsArray: Array): 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 }