From 2741515d441a3c56a29f2991ba660540b9f1843c Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 2 Apr 2012 16:05:56 +0400 Subject: [PATCH] Fixes after review, take 3. --- main/Defaults.scala | 4 +- main/actions/ForkTests.scala | 70 +++++++++---------- main/actions/Tests.scala | 10 +-- testing/agent/src/main/java/sbt/ForkMain.java | 5 +- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/main/Defaults.scala b/main/Defaults.scala index 74340121b..00ec1437a 100755 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -297,7 +297,7 @@ object Defaults extends BuildCommon Tests(frameworkMap, loader, tests, config, s.log) } } - Tests.flatten(results) + Tests.foldTasks(results) }, test <<= (executeTests, streams, resolvedScoped, state) map { (results, s, scoped, st) => @@ -385,7 +385,7 @@ object Defaults extends BuildCommon Tests(frameworks, loader, tests, newConfig, s.log) } } - Tests.flatten(results) map (Tests.showResults(s.log, _, noTestsMessage(scoped))) + Tests.foldTasks(results) map (Tests.showResults(s.log, _, noTestsMessage(scoped))) } } diff --git a/main/actions/ForkTests.scala b/main/actions/ForkTests.scala index 64371b815..44bdb796d 100755 --- a/main/actions/ForkTests.scala +++ b/main/actions/ForkTests.scala @@ -14,7 +14,7 @@ private[sbt] object ForkTests { val opts = config.options.toList val listeners = opts flatMap { case Listeners(ls) => ls - case _ => List.empty + case _ => Nil } val testListeners = listeners flatMap { case tl: TestsListener => Some(tl) @@ -28,11 +28,11 @@ private[sbt] object ForkTests { f => f.implClassName -> opts.flatMap { case Argument(None, args) => args case Argument(Some(`f`), args) => args - case _ => List.empty + case _ => Nil } }.toMap - std.TaskExtra.toTask { + std.TaskExtra.task { val server = new ServerSocket(0) object Acceptor extends Runnable { val results = collection.mutable.Map.empty[String, TestResult.Value] @@ -47,17 +47,6 @@ private[sbt] object ForkTests { val os = new ObjectOutputStream(socket.getOutputStream) val is = new ObjectInputStream(socket.getInputStream) - val testsFiltered = tests.filter(test => filters.forall(_(test.name))).map{ - t => new ForkTestDefinition(t.name, t.fingerprint) - }.toArray - os.writeObject(testsFiltered) - - os.writeInt(frameworks.size) - for ((clazz, args) <- argMap) { - os.writeObject(clazz) - os.writeObject(args.toArray) - } - import Tags._ @annotation.tailrec def react: Unit = is.readObject match { case `Done` => os.writeObject(Done); @@ -77,33 +66,44 @@ private[sbt] object ForkTests { } react } - react + + try { + os.writeBoolean(log.ansiCodesSupported) + + val testsFiltered = tests.filter(test => filters.forall(_(test.name))).map{ + t => new ForkTestDefinition(t.name, t.fingerprint) + }.toArray + os.writeObject(testsFiltered) + + os.writeInt(frameworks.size) + for ((clazz, args) <- argMap) { + os.writeObject(clazz) + os.writeObject(args.toArray) + } + + react + } finally { + is.close() + os.close() + } } } } - () => { - try { - testListeners.foreach(_.doInit()) - val t = new Thread(Acceptor) - t.start() + testListeners.foreach(_.doInit()) + try { + new Thread(Acceptor).start() - val fullCp = classpath ++: Seq(IO.classLocationFile[ForkMain], IO.classLocationFile[Framework]) - val options = javaOpts ++: Seq("-classpath", fullCp mkString File.pathSeparator, classOf[ForkMain].getCanonicalName, server.getLocalPort.toString) - val ec = Fork.java(javaHome, options, StdoutOutput) - if (ec != 0) { - log.error("Running java with options " + options.mkString(" ") + " failed with exit code " + ec) - server.close() - } - - t.join() - val result = Acceptor.output - testListeners.foreach(_.doComplete(result._1)) - result - } finally { - server.close() - } + val fullCp = classpath ++: Seq(IO.classLocationFile[ForkMain], IO.classLocationFile[Framework]) + val options = javaOpts ++: Seq("-classpath", fullCp mkString File.pathSeparator, classOf[ForkMain].getCanonicalName, server.getLocalPort.toString) + val ec = Fork.java(javaHome, options, StdoutOutput) + if (ec != 0) log.error("Running java with options " + options.mkString(" ") + " failed with exit code " + ec) + } finally { + server.close() } + val result = Acceptor.output + testListeners.foreach(_.doComplete(result._1)) + result } } } diff --git a/main/actions/Tests.scala b/main/actions/Tests.scala index 9b8013629..5406d7d68 100644 --- a/main/actions/Tests.scala +++ b/main/actions/Tests.scala @@ -126,10 +126,12 @@ object Tests def processResults(results: Iterable[(String, TestResult.Value)]): (TestResult.Value, Map[String, TestResult.Value]) = (overall(results.map(_._2)), results.toMap) - def flatten(results: Seq[Task[Output]]): Task[Output] = - reduced(results.toIndexedSeq, { - case ((v1, m1), (v2, m2)) => (if (v1.id < v2.id) v2 else v1, m1 ++ m2) - }) + def foldTasks(results: Seq[Task[Output]]): Task[Output] = + (task((TestResult.Passed, Map.empty[String, TestResult.Value])) /: results) { + reducePair(_, _, { + case ((v1, m1), (v2, m2)) => (if (v1.id < v2.id) v2 else v1, m1 ++ m2) + }) + } def overall(results: Iterable[TestResult.Value]): TestResult.Value = (TestResult.Passed /: results) { (acc, result) => if(acc.id < result.id) result else acc } def discover(frameworks: Seq[Framework], analysis: Analysis, log: Logger): (Seq[TestDefinition], Set[String]) = diff --git a/testing/agent/src/main/java/sbt/ForkMain.java b/testing/agent/src/main/java/sbt/ForkMain.java index 6112cd6c2..f109aa860 100755 --- a/testing/agent/src/main/java/sbt/ForkMain.java +++ b/testing/agent/src/main/java/sbt/ForkMain.java @@ -90,9 +90,10 @@ public class ForkMain { return false; } void run(ObjectInputStream is, final ObjectOutputStream os) throws Exception { + final boolean ansiCodesSupported = is.readBoolean(); Logger[] loggers = { new Logger() { - public boolean ansiCodesSupported() { return false; } + public boolean ansiCodesSupported() { return ansiCodesSupported; } void write(Object obj) { try { os.writeObject(obj); @@ -100,7 +101,7 @@ public class ForkMain { System.err.println("Cannot write to socket"); } } - public void error(String s) { write(new Object[]{Tags.Error, s}); } + public void error(String s) { write(new Object[]{Tags.Error, s}); } public void warn(String s) { write(new Object[]{Tags.Warn, s}); } public void info(String s) { write(new Object[]{Tags.Info, s}); } public void debug(String s) { write(new Object[]{Tags.Debug, s}); }