Skip to content

Commit

Permalink
Fix: #4370
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaTP committed Sep 25, 2018
1 parent 550c068 commit 15d11f8
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 25 deletions.
43 changes: 29 additions & 14 deletions main/src/main/scala/sbt/MainLoop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,36 @@ object MainLoop {
val channelName = exec.source map (_.channelName)
StandardMain.exchange publishEventMessage
ExecStatusEvent("Processing", channelName, exec.execId, Vector())
val newState = Command.process(exec.commandLine, state)
val doneEvent = ExecStatusEvent(
"Done",
channelName,
exec.execId,
newState.remainingCommands.toVector map (_.commandLine),
exitCode(newState, state),
)
if (doneEvent.execId.isDefined) { // send back a response or error
import sbt.protocol.codec.JsonProtocol._
StandardMain.exchange publishEvent doneEvent
} else { // send back a notification
StandardMain.exchange publishEventMessage doneEvent

try {
val newState = Command.process(exec.commandLine, state)
val doneEvent = ExecStatusEvent(
"Done",
channelName,
exec.execId,
newState.remainingCommands.toVector map (_.commandLine),
exitCode(newState, state),
)
if (doneEvent.execId.isDefined) { // send back a response or error
import sbt.protocol.codec.JsonProtocol._
StandardMain.exchange publishEvent doneEvent
} else { // send back a notification
StandardMain.exchange publishEventMessage doneEvent
}
newState
} catch {
case err: Throwable =>
val errorEvent = ExecStatusEvent(
"Error",
channelName,
exec.execId,
Vector(),
ExitCode(ErrorCodes.UnknownError),
)
import sbt.protocol.codec.JsonProtocol._
StandardMain.exchange publishEvent errorEvent
throw err
}
newState
}

def logFullException(e: Throwable, log: Logger): Unit = State.logFullException(e, log)
Expand Down
2 changes: 2 additions & 0 deletions sbt/src/server-test/events/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

commands += Command.command("hello") { state => ??? }
8 changes: 4 additions & 4 deletions sbt/src/test/scala/sbt/RunFromSourceMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@

package sbt

import scala.util.Try
import sbt.util.LogExchange
import scala.annotation.tailrec
import buildinfo.TestBuildInfo
import xsbti._
import scala.sys.process.Process

object RunFromSourceMain {
private val sbtVersion = "1.1.4" // TestBuildInfo.version
private val scalaVersion = "2.12.6"

def fork(workingDirectory: File): Try[Unit] = {
def fork(workingDirectory: File): Process = {
val fo = ForkOptions()
.withOutputStrategy(OutputStrategy.StdoutOutput)
fork(fo, workingDirectory)
}

def fork(fo0: ForkOptions, workingDirectory: File): Try[Unit] = {
def fork(fo0: ForkOptions, workingDirectory: File): Process = {
val fo = fo0
.withWorkingDirectory(workingDirectory)
implicit val runner = new ForkRun(fo)
Expand All @@ -32,7 +32,7 @@ object RunFromSourceMain {
}
val options = Vector(workingDirectory.toString)
val log = LogExchange.logger("RunFromSourceMain.fork", None, None)
Run.run("sbt.RunFromSourceMain", cp, options, log)
runner.fork("sbt.RunFromSourceMain", cp, options, log)
}

def main(args: Array[String]): Unit = args match {
Expand Down
33 changes: 26 additions & 7 deletions sbt/src/test/scala/testpkg/ServerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import java.io.File
import sbt.io.syntax._
import sbt.io.IO
import sbt.RunFromSourceMain
import scala.concurrent.ExecutionContext
import java.util.concurrent.ForkJoinPool

class ServerSpec extends AsyncFreeSpec with Matchers {
"server" - {
Expand All @@ -36,10 +38,22 @@ class ServerSpec extends AsyncFreeSpec with Matchers {
s contains """"id":3"""
})
}

"report task failures in case of exceptions" in withTestServer("events") { p =>
p.writeLine(
"""{ "jsonrpc": "2.0", "id": 11, "method": "sbt/exec", "params": { "commandLine": "hello" } }"""
)
assert(p.waitForString(10) { s =>
(s contains """"id":11""") && (s contains """"error":""")
})
}
}
}

object TestServer {
// The test server instance will be executed in a Thread pool separated from the tests
implicit val ec = ExecutionContext.fromExecutor(new ForkJoinPool())

private val serverTestBase: File = new File(".").getAbsoluteFile / "sbt" / "src" / "server-test"

def withTestServer(testBuild: String)(f: TestServer => Future[Assertion]): Future[Assertion] = {
Expand All @@ -54,7 +68,7 @@ object TestServer {
try {
f(testServer)
} finally {
testServer.bye()
try { testServer.bye() } finally {}
}
}

Expand All @@ -63,7 +77,7 @@ object TestServer {
}
}

case class TestServer(baseDirectory: File) {
case class TestServer(baseDirectory: File)(implicit ec: ExecutionContext) {
import TestServer.hostLog

val readBuffer = new Array[Byte](4096)
Expand All @@ -73,11 +87,11 @@ case class TestServer(baseDirectory: File) {
private val RetByte = '\r'.toByte

hostLog("fork to a new sbt instance")
import scala.concurrent.ExecutionContext.Implicits.global
Future {
RunFromSourceMain.fork(baseDirectory)
()
}
val process =
Future {
RunFromSourceMain.fork(baseDirectory)
}

lazy val portfile = baseDirectory / "project" / "target" / "active.json"

hostLog("wait 30s until the server is ready to respond")
Expand Down Expand Up @@ -114,6 +128,11 @@ case class TestServer(baseDirectory: File) {
sendJsonRpc(
"""{ "jsonrpc": "2.0", "id": 9, "method": "sbt/exec", "params": { "commandLine": "exit" } }"""
)
for {
p <- process
} {
p.destroy()
}
}

def sendJsonRpc(message: String): Unit = {
Expand Down

0 comments on commit 15d11f8

Please sign in to comment.