Fix Process.waitFor freeze on windows when gradle daemon is stopped during tests
This commit is contained in:
+11
-43
@@ -2,11 +2,12 @@ package org.jetbrains.kotlin.gradle
|
||||
|
||||
import com.google.common.io.Files
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.jetbrains.kotlin.gradle.util.createGradleCommand
|
||||
import org.jetbrains.kotlin.gradle.util.runProcess
|
||||
import org.junit.After
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Before
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import kotlin.test.*
|
||||
|
||||
private val SYSTEM_LINE_SEPARATOR = System.getProperty("line.separator")
|
||||
@@ -42,29 +43,12 @@ abstract class BaseGradleIT {
|
||||
ranDaemonVersions.clear()
|
||||
}
|
||||
|
||||
fun createGradleCommand(tailParameters: List<String>): List<String> {
|
||||
return if (isWindows())
|
||||
listOf("cmd", "/C", "gradlew.bat") + tailParameters
|
||||
else
|
||||
listOf("/bin/bash", "./gradlew") + tailParameters
|
||||
}
|
||||
|
||||
fun isWindows(): Boolean {
|
||||
return System.getProperty("os.name")!!.contains("Windows")
|
||||
}
|
||||
|
||||
fun stopDaemon(ver: String) {
|
||||
println("Stopping gradle daemon v$ver")
|
||||
val wrapperDir = File(resourcesRootFile, "GradleWrapper-$ver")
|
||||
val cmd = createGradleCommand(arrayListOf("-stop"))
|
||||
createProcess(cmd, wrapperDir).waitFor()
|
||||
}
|
||||
|
||||
fun createProcess(cmd: List<String>, projectDir: File): Process {
|
||||
val builder = ProcessBuilder(cmd)
|
||||
builder.directory(projectDir)
|
||||
builder.redirectErrorStream(true)
|
||||
return builder.start()
|
||||
val result = runProcess(cmd, wrapperDir)
|
||||
assert(result.isSuccessful) { "Could not stop daemon: $result" }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -98,8 +82,9 @@ abstract class BaseGradleIT {
|
||||
val kotlinSourcesListRegex = Regex("\\[KOTLIN\\] compile iteration: ([^\\r\\n]*)")
|
||||
val javaSourcesListRegex = Regex("\\[DEBUG\\] \\[[^\\]]*JavaCompiler\\] Compiler arguments: ([^\\r\\n]*)")
|
||||
}
|
||||
val compiledKotlinSources : Iterable<File> by lazy { kotlinSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(", ").map { File(project.projectDir, it).canonicalFile } } }
|
||||
val compiledJavaSources : Iterable<File> by lazy { javaSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(" ").filter { it.endsWith(".java", ignoreCase = true) }.map { File(it).canonicalFile } } }
|
||||
|
||||
val compiledKotlinSources: Iterable<File> by lazy { kotlinSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(", ").map { File(project.projectDir, it).canonicalFile } } }
|
||||
val compiledJavaSources: Iterable<File> by lazy { javaSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(" ").filter { it.endsWith(".java", ignoreCase = true) }.map { File(it).canonicalFile } } }
|
||||
}
|
||||
|
||||
fun Project.build(vararg tasks: String, options: BuildOptions = defaultBuildOptions(), check: CompiledProject.() -> Unit) {
|
||||
@@ -116,13 +101,12 @@ abstract class BaseGradleIT {
|
||||
|
||||
private fun Project.runAndCheck(cmd: List<String>, check: CompiledProject.() -> Unit) {
|
||||
val projectDir = File(workingDir, projectName)
|
||||
if (!projectDir.exists())
|
||||
if (!projectDir.exists()) {
|
||||
setupWorkingDir()
|
||||
}
|
||||
|
||||
val process = createProcess(cmd, projectDir)
|
||||
|
||||
val (output, resultCode) = readOutput(process)
|
||||
CompiledProject(this, output, resultCode).check()
|
||||
val result = runProcess(cmd, projectDir)
|
||||
CompiledProject(this, result.output, result.exitCode).check()
|
||||
}
|
||||
|
||||
fun CompiledProject.assertSuccessful(): CompiledProject {
|
||||
@@ -221,22 +205,6 @@ abstract class BaseGradleIT {
|
||||
|
||||
private fun String.normalize() = this.lineSequence().joinToString(SYSTEM_LINE_SEPARATOR)
|
||||
|
||||
private fun readOutput(process: Process): Pair<String, Int> {
|
||||
fun InputStream.readFully(): String {
|
||||
val text = reader().readText()
|
||||
close()
|
||||
return text
|
||||
}
|
||||
|
||||
val stdout = process.inputStream!!.readFully()
|
||||
System.out.println(stdout)
|
||||
val stderr = process.errorStream!!.readFully()
|
||||
System.err.println(stderr)
|
||||
|
||||
val result = process.waitFor()
|
||||
return stdout to result
|
||||
}
|
||||
|
||||
fun copyRecursively(source: File, target: File) {
|
||||
assertTrue(target.isDirectory)
|
||||
val targetFile = File(target, source.name)
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package org.jetbrains.kotlin.gradle.util
|
||||
|
||||
import java.io.File
|
||||
|
||||
class ProcessRunResult(
|
||||
private val cmd: List<String>,
|
||||
private val workingDir: File,
|
||||
val exitCode: Int,
|
||||
val output: String
|
||||
) {
|
||||
val isSuccessful: Boolean
|
||||
get() = exitCode == 0
|
||||
|
||||
override fun toString(): String = """
|
||||
Executing process was ${if (isSuccessful) "successful" else "unsuccessful"}
|
||||
Command: ${cmd.joinToString()}
|
||||
Working directory: ${workingDir.absolutePath}
|
||||
Exit code: $exitCode
|
||||
Output: $output
|
||||
"""
|
||||
}
|
||||
|
||||
fun runProcess(cmd: List<String>, workingDir: File): ProcessRunResult {
|
||||
val builder = ProcessBuilder(cmd)
|
||||
builder.directory(workingDir)
|
||||
// redirectErrorStream merges stdout and stderr, so it can be get from process.inputStream
|
||||
builder.redirectErrorStream(true)
|
||||
|
||||
val process = builder.start()
|
||||
// important to read inputStream, otherwise the process may hang on some systems
|
||||
val output = process.inputStream!!.bufferedReader().readText()
|
||||
System.out.println(output)
|
||||
val exitCode = process.waitFor()
|
||||
|
||||
return ProcessRunResult(cmd, workingDir, exitCode, output)
|
||||
}
|
||||
|
||||
fun createGradleCommand(tailParameters: List<String>): List<String> {
|
||||
return if (isWindows())
|
||||
listOf("cmd", "/C", "gradlew.bat") + tailParameters
|
||||
else
|
||||
listOf("/bin/bash", "./gradlew") + tailParameters
|
||||
}
|
||||
|
||||
private fun isWindows(): Boolean = System.getProperty("os.name")!!.contains("Windows")
|
||||
Reference in New Issue
Block a user