Migrate KotlinDaemonIT tests to new test dsl.
^KT-45745 In Progress
This commit is contained in:
+109
-70
@@ -16,100 +16,139 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle
|
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.compilerRunner.*
|
import org.jetbrains.kotlin.compilerRunner.*
|
||||||
import org.junit.Assert
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.junit.Test
|
import org.junit.jupiter.api.DisplayName
|
||||||
import java.io.File
|
import java.nio.file.Paths
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
// todo: test client file creation/deletion
|
// todo: test client file creation/deletion
|
||||||
// todo: test daemon start (does not start every build)
|
// todo: test daemon start (does not start every build)
|
||||||
// todo: test daemon shutdown when gradle daemon dies
|
// todo: test daemon shutdown when gradle daemon dies
|
||||||
class KotlinDaemonIT : BaseGradleIT() {
|
@DisplayName("Kotlin daemon base behaviour")
|
||||||
|
class KotlinDaemonIT : KGPDaemonsBaseTest() {
|
||||||
|
|
||||||
@Test
|
override val defaultBuildOptions: BuildOptions = super.defaultBuildOptions
|
||||||
fun testDaemonMultiproject() {
|
.copy(
|
||||||
fun String.findAllStringsPrefixed(prefix: String): Array<String> {
|
logLevel = LogLevel.DEBUG
|
||||||
val result = arrayListOf<String>()
|
)
|
||||||
val regex = ("$prefix([^\\r\\n]*)").toRegex()
|
|
||||||
for (match in regex.findAll(this)) {
|
|
||||||
result.add(match.groupValues[1])
|
|
||||||
}
|
|
||||||
return result.toTypedArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
val project = Project("multiprojectWithDependency")
|
@DisplayName("Kotlin daemon is reused in multiproject")
|
||||||
val strategyCLIArg = "-Dkotlin.compiler.execution.strategy=daemon"
|
@GradleTest
|
||||||
|
fun testDaemonMultiproject(gradleVersion: GradleVersion) {
|
||||||
fun checkAfterNonIncrementalBuild(output: String) {
|
project("multiprojectWithDependency", gradleVersion) {
|
||||||
val createdSessions = output.findAllStringsPrefixed(CREATED_SESSION_FILE_PREFIX)
|
gradleProperties.append(
|
||||||
assert(createdSessions.size == 1) { "Created multiple sessions per build ${createdSessions.joinToString()}" }
|
"\nkotlin.compiler.execution.strategy=daemon"
|
||||||
|
|
||||||
val existingSessions = output.findAllStringsPrefixed(EXISTING_SESSION_FILE_PREFIX)
|
|
||||||
Assert.assertArrayEquals(
|
|
||||||
"Existing sessions don't match created sessions for two module projects",
|
|
||||||
createdSessions,
|
|
||||||
existingSessions
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val deletedSessions = output.findAllStringsPrefixed(DELETED_SESSION_FILE_PREFIX)
|
build("build") {
|
||||||
Assert.assertArrayEquals("Deleted sessions don't match created sessions", createdSessions, deletedSessions)
|
assertOutputDoesNotContain(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE)
|
||||||
}
|
assertKotlinDaemonReusesOnlyOneSession()
|
||||||
|
}
|
||||||
|
|
||||||
project.build("build", strategyCLIArg) {
|
build("clean", "build") {
|
||||||
assertNotContains(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE)
|
assertOutputDoesNotContain(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE)
|
||||||
checkAfterNonIncrementalBuild(output)
|
assertKotlinDaemonReusesOnlyOneSession()
|
||||||
}
|
}
|
||||||
|
|
||||||
project.build("clean", "build", strategyCLIArg) {
|
build("build") {
|
||||||
assertNotContains(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE)
|
assert(output.findAllStringsPrefixed(CREATED_SESSION_FILE_PREFIX).isEmpty()) {
|
||||||
checkAfterNonIncrementalBuild(output)
|
"Sessions should not be created (incremental build)"
|
||||||
}
|
}
|
||||||
|
|
||||||
project.build("build", strategyCLIArg) {
|
assert(output.findAllStringsPrefixed(EXISTING_SESSION_FILE_PREFIX).isEmpty()) {
|
||||||
val createdSessions = output.findAllStringsPrefixed(CREATED_SESSION_FILE_PREFIX)
|
"Sessions should not be existing (incremental build)"
|
||||||
Assert.assertArrayEquals("Sessions should not be created (incremental build)", createdSessions, emptyArray())
|
}
|
||||||
|
|
||||||
val existingSessions = output.findAllStringsPrefixed(EXISTING_SESSION_FILE_PREFIX)
|
assert(output.findAllStringsPrefixed(DELETED_SESSION_FILE_PREFIX).isEmpty()) {
|
||||||
Assert.assertArrayEquals("Sessions should not be existing (incremental build)", existingSessions, emptyArray())
|
"Sessions should not be deleted (incremental build)"
|
||||||
|
}
|
||||||
val deletedSessions = output.findAllStringsPrefixed(DELETED_SESSION_FILE_PREFIX)
|
|
||||||
Assert.assertArrayEquals("Sessions should not be deleted (incremental build)", deletedSessions, emptyArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testClientFileIsDeletedOnExit() {
|
|
||||||
val project = Project("kotlinProject")
|
|
||||||
val options = defaultBuildOptions().copy(withDaemon = false)
|
|
||||||
|
|
||||||
project.build("assemble", options = options) {
|
|
||||||
val regex = Regex("(?m)($CREATED_CLIENT_FILE_PREFIX|$EXISTING_CLIENT_FILE_PREFIX)(.+)$")
|
|
||||||
val clientFiles = regex.findAll(output).toList().map { File(it.groupValues[2]) }
|
|
||||||
assert(clientFiles.isNotEmpty()) { "No client files in log" }
|
|
||||||
clientFiles.forEach { clientFile ->
|
|
||||||
assert(!clientFile.exists()) { "Client file $clientFile is expected to be deleted!" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Client file is deleted on exit")
|
||||||
fun testGradleBuildClasspathShouldNotBeLeakedIntoDaemonClasspath() {
|
@GradleTest
|
||||||
val testProject = Project("kotlinProject")
|
fun testClientFileIsDeletedOnExit(gradleVersion: GradleVersion) {
|
||||||
testProject.setupWorkingDir()
|
project("kotlinProject", gradleVersion) {
|
||||||
|
build("assemble") {
|
||||||
|
val regex = "(?m)($CREATED_CLIENT_FILE_PREFIX|$EXISTING_CLIENT_FILE_PREFIX)(.+)$".toRegex()
|
||||||
|
val clientFiles = regex.findAll(output).map { Paths.get(it.groupValues[2]) }.toList()
|
||||||
|
assert(clientFiles.isNotEmpty()) { "No client files in log" }
|
||||||
|
|
||||||
testProject.build("assemble") {
|
// Stop daemons
|
||||||
assertGradleClasspathNotLeaked()
|
ConnectorServices.reset()
|
||||||
|
Thread.sleep(2000) // Kotlin daemon stops itself after 1 sec of Gradle daemon
|
||||||
|
clientFiles.forEach { clientFile ->
|
||||||
|
assertFileNotExists(clientFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompiledProject.assertGradleClasspathNotLeaked() {
|
@DisplayName("Gradle build classpath should not leak into Kotlin daemon")
|
||||||
assertContains("Kotlin compiler classpath:")
|
@GradleTest
|
||||||
val daemonClasspath = output.lineSequence().find {
|
fun testGradleBuildClasspathShouldNotBeLeakedIntoDaemonClasspath(gradleVersion: GradleVersion) {
|
||||||
it.contains("Kotlin compiler classpath:")
|
project("kotlinProject", gradleVersion) {
|
||||||
}!!
|
build("assemble") {
|
||||||
|
assertGradleClasspathNotLeaked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun BuildResult.assertGradleClasspathNotLeaked() {
|
||||||
|
assertOutputContains("Kotlin compiler classpath:")
|
||||||
|
val daemonClasspath = output
|
||||||
|
.lineSequence()
|
||||||
|
.first {
|
||||||
|
it.contains("Kotlin compiler classpath:")
|
||||||
|
}
|
||||||
assertTrue("Daemon classpath contains embeddable daemon jar leaked from Gradle dist classpath: $daemonClasspath") {
|
assertTrue("Daemon classpath contains embeddable daemon jar leaked from Gradle dist classpath: $daemonClasspath") {
|
||||||
!daemonClasspath.contains(".gradle/wrapper/dists")
|
!daemonClasspath.contains(".gradle/wrapper/dists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun BuildResult.assertKotlinDaemonReusesOnlyOneSession() {
|
||||||
|
val createdSessions = output.findAllStringsPrefixed(CREATED_SESSION_FILE_PREFIX)
|
||||||
|
assert(createdSessions.size == 1) {
|
||||||
|
"""
|
||||||
|
|${printBuildOutput()}
|
||||||
|
|
|
||||||
|
|Created multiple sessions per build: ${createdSessions.joinToString()}
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
|
||||||
|
val existingSessions = output.findAllStringsPrefixed(EXISTING_SESSION_FILE_PREFIX)
|
||||||
|
assert(createdSessions == createdSessions) {
|
||||||
|
"""
|
||||||
|
|${printBuildOutput()}
|
||||||
|
|
|
||||||
|
|Existing sessions don't match created sessions for two module projects.
|
||||||
|
|Created sessions:
|
||||||
|
|${createdSessions.joinToString(separator = "\n")}
|
||||||
|
|Existing sessions:
|
||||||
|
|${existingSessions.joinToString(separator = "\n")}
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
|
||||||
|
val deletedSessions = output.findAllStringsPrefixed(DELETED_SESSION_FILE_PREFIX)
|
||||||
|
assert(createdSessions == deletedSessions) {
|
||||||
|
"""
|
||||||
|
|${printBuildOutput()}
|
||||||
|
|
|
||||||
|
|Deleted sessions don't match created sessions.
|
||||||
|
|Created sessions:
|
||||||
|
|${createdSessions.joinToString(separator = "\n")}
|
||||||
|
|Deleted sessions:
|
||||||
|
|${deletedSessions.joinToString(separator = "\n")}
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.findAllStringsPrefixed(prefix: String): List<String> =
|
||||||
|
("$prefix([^\\r\\n]*)").toRegex().findAll(this).map { it.groupValues[1] }.toList()
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user