[test][debugger] make reading of std{out,err} asynchroneous
- this fix issue on big amount data in stdout or stderr, making program hanging on waiting when appear some room in stdout/stderr buffer [test][debugger] DevToolsSecurity check and stdio/stderr async processing
This commit is contained in:
@@ -51,6 +51,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
|
||||
cli_bc project(path: ':backend.native', configuration: 'cli_bc')
|
||||
def updateTestData = true
|
||||
if (project.hasProperty("kotlinProjectPath")) {
|
||||
|
||||
+1
@@ -15,6 +15,7 @@ object DistProperties {
|
||||
private val konancDriver = if (HostManager.host.family == Family.MINGW) "konanc.bat" else "konanc"
|
||||
val konanc: Path = dist.resolve("bin/$konancDriver")
|
||||
val lldb: Path = Paths.get("lldb")
|
||||
val devToolsSecurity: Path = Paths.get("DevToolsSecurity")
|
||||
val lldbPrettyPrinters: Path = dist.resolve("tools/konan_lldb.py")
|
||||
|
||||
private fun requireProp(name: String): String
|
||||
|
||||
+47
-12
@@ -5,9 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.native.test.debugger
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.cli.bc.K2Native
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.StringReader
|
||||
import java.lang.StringBuilder
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ToolDriver(
|
||||
@@ -31,7 +40,7 @@ class ToolDriver(
|
||||
}
|
||||
|
||||
fun runLldb(program: Path, commands: List<String>): String {
|
||||
val args = listOf("-o", "command script import \"$lldbPrettyPrinters\"") +
|
||||
val args = listOf("-b", "-o", "command script import \"$lldbPrettyPrinters\"") +
|
||||
commands.flatMap { listOf("-o", it) }
|
||||
return subprocess(lldb, program.toString(), "-b", *args.toTypedArray())
|
||||
.thrownIfFailed()
|
||||
@@ -63,15 +72,41 @@ data class ProcessOutput(
|
||||
fun subprocess(program: Path, vararg args: String): ProcessOutput {
|
||||
val start = System.currentTimeMillis()
|
||||
val process = ProcessBuilder(program.toString(), *args).start()
|
||||
val outReader = process.inputStream.bufferedReader()
|
||||
val errReader = process.errorStream.bufferedReader()
|
||||
|
||||
val timeout = 5L
|
||||
if (!process.waitFor(timeout, TimeUnit.MINUTES)) {
|
||||
process.destroy()
|
||||
error("$program is running for more then $timeout minutes")
|
||||
val out = GlobalScope.async(Dispatchers.IO) {
|
||||
readStream(process, process.inputStream.buffered())
|
||||
}
|
||||
val stdout = outReader.readText()
|
||||
val stderr = errReader.readText()
|
||||
return ProcessOutput(program, process, stdout, stderr, System.currentTimeMillis() - start)
|
||||
}
|
||||
|
||||
val err = GlobalScope.async(Dispatchers.IO) {
|
||||
readStream(process, process.errorStream.buffered())
|
||||
}
|
||||
|
||||
return runBlocking {
|
||||
try {
|
||||
val status = process.waitFor(5L, TimeUnit.MINUTES)
|
||||
if (!status) {
|
||||
out.cancel()
|
||||
err.cancel()
|
||||
error("$program timeouted")
|
||||
}
|
||||
}catch (e:Exception) {
|
||||
out.cancel()
|
||||
err.cancel()
|
||||
error(e)
|
||||
}
|
||||
ProcessOutput(program, process, out.await(), err.await(), System.currentTimeMillis() - start)
|
||||
}
|
||||
}
|
||||
|
||||
private fun readStream(process: Process, stream: InputStream): String {
|
||||
var size = 4096
|
||||
val buffer = ByteArray(size) { 0 }
|
||||
val sunk = ByteArrayOutputStream()
|
||||
while (true) {
|
||||
size = stream.read(buffer, 0, buffer.size)
|
||||
if (size < 0 && !process.isAlive)
|
||||
break
|
||||
if (size > 0)
|
||||
sunk.write(buffer, 0, size)
|
||||
}
|
||||
return String(sunk.toByteArray())
|
||||
}
|
||||
|
||||
+18
@@ -62,6 +62,15 @@ fun lldbTest(@Language("kotlin") programText: String, lldbSession: String) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isOsxDevToolsEnabled) {
|
||||
println("""Development tools aren't available.
|
||||
|Please consider to execute:
|
||||
| ${DistProperties.devToolsSecurity} -enable
|
||||
|or
|
||||
| csrutil disable
|
||||
|to run lldb tests""".trimMargin())
|
||||
return
|
||||
}
|
||||
val lldbSessionSpec = LldbSessionSpecification.parse(lldbSession)
|
||||
|
||||
val tmpdir = Files.createTempDirectory("debugger_test")
|
||||
@@ -76,6 +85,15 @@ fun lldbTest(@Language("kotlin") programText: String, lldbSession: String) {
|
||||
lldbSessionSpec.match(result)
|
||||
}
|
||||
|
||||
private val isOsxDevToolsEnabled: Boolean by lazy {
|
||||
//TODO: add OSX checks.
|
||||
val rawStatus = subprocess(DistProperties.devToolsSecurity, "-status")
|
||||
println("> status: $rawStatus")
|
||||
|
||||
val r = Regex("^.*\\ (enabled|disabled).$")
|
||||
r.find(rawStatus.stdout)?.destructured?.component1() == "enabled"
|
||||
}
|
||||
|
||||
private val haveLldb: Boolean by lazy {
|
||||
val lldbVersion = try {
|
||||
subprocess(DistProperties.lldb, "-version")
|
||||
|
||||
Reference in New Issue
Block a user