mirror of https://github.com/sbt/sbt.git
Add ability to timeout ClientTest cases
It is possible for the test cases in ClientTest to block indefinitely. To avoid that, we can instead run them on a background thread and cancel the thread if that happens.
This commit is contained in:
parent
e3731994de
commit
8a23f1e440
|
|
@ -59,6 +59,7 @@ import Serialization.{
|
|||
setTerminalAttributes,
|
||||
}
|
||||
import NetworkClient.Arguments
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
trait ConsoleInterface {
|
||||
def appendLog(level: Level.Value, message: => String): Unit
|
||||
|
|
@ -799,7 +800,10 @@ class NetworkClient(
|
|||
val json = s"""{"query":"$query","level":1}"""
|
||||
val execId = sendJson("sbt/completion", json)
|
||||
pendingCompletions.put(execId, result.put)
|
||||
val response = result.poll(30, TimeUnit.SECONDS)
|
||||
val response = result.poll(30, TimeUnit.SECONDS) match {
|
||||
case null => throw new TimeoutException("no response from server within 30 seconds")
|
||||
case r => r
|
||||
}
|
||||
def fillCompletions(label: String, regex: String, command: String): Seq[String] = {
|
||||
def updateCompletions(): Seq[String] = {
|
||||
errorStream.println()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
package testpkg
|
||||
|
||||
import java.io.{ InputStream, OutputStream, PrintStream }
|
||||
import java.util.concurrent.{ LinkedBlockingQueue, TimeUnit, TimeoutException }
|
||||
import sbt.internal.client.NetworkClient
|
||||
import sbt.internal.util.Util
|
||||
import scala.collection.mutable
|
||||
|
|
@ -41,27 +42,47 @@ object ClientTest extends AbstractServerTest {
|
|||
} else -1
|
||||
}
|
||||
}
|
||||
private def client(args: String*) =
|
||||
NetworkClient.client(
|
||||
testPath.toFile,
|
||||
args.toArray,
|
||||
NullInputStream,
|
||||
NullPrintStream,
|
||||
NullPrintStream,
|
||||
false
|
||||
private[this] def background[R](f: => R): R = {
|
||||
val result = new LinkedBlockingQueue[R]
|
||||
val thread = new Thread("client-bg-thread") {
|
||||
setDaemon(true)
|
||||
start()
|
||||
override def run(): Unit = result.put(f)
|
||||
}
|
||||
result.poll(1, TimeUnit.MINUTES) match {
|
||||
case null =>
|
||||
thread.interrupt()
|
||||
thread.join(5000)
|
||||
throw new TimeoutException
|
||||
case r => r
|
||||
}
|
||||
}
|
||||
private def client(args: String*): Int = {
|
||||
background(
|
||||
NetworkClient.client(
|
||||
testPath.toFile,
|
||||
args.toArray,
|
||||
NullInputStream,
|
||||
NullPrintStream,
|
||||
NullPrintStream,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
// This ensures that the completion command will send a tab that triggers
|
||||
// sbt to call definedTestNames or discoveredMainClasses if there hasn't
|
||||
// been a necessary compilation
|
||||
def tabs = new FixedInputStream('\t', '\t')
|
||||
private def complete(completionString: String): Seq[String] = {
|
||||
val cps = new CachingPrintStream
|
||||
NetworkClient.complete(
|
||||
testPath.toFile,
|
||||
Array(s"--completions=sbtn $completionString"),
|
||||
false,
|
||||
tabs,
|
||||
cps
|
||||
background(
|
||||
NetworkClient.complete(
|
||||
testPath.toFile,
|
||||
Array(s"--completions=sbtn $completionString"),
|
||||
false,
|
||||
tabs,
|
||||
cps
|
||||
)
|
||||
)
|
||||
cps.lines
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue