From b4e64d37dbd4e095da8da4ef38a4e532eacb4296 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Wed, 15 Aug 2012 09:41:31 +0100 Subject: [PATCH] Various fork in Test fixes. Closes #512 #515. --- main/actions/ForkTests.scala | 56 +++++++++++-------- sbt/src/sbt-test/tests/fork2/build.sbt | 3 + .../sbt-test/tests/fork2/changes/Test.scala | 8 +++ sbt/src/sbt-test/tests/fork2/test | 8 +++ testing/agent/src/main/java/sbt/ForkMain.java | 7 ++- 5 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 sbt/src/sbt-test/tests/fork2/build.sbt create mode 100644 sbt/src/sbt-test/tests/fork2/changes/Test.scala create mode 100644 sbt/src/sbt-test/tests/fork2/test diff --git a/main/actions/ForkTests.scala b/main/actions/ForkTests.scala index 8583633c65..b7c7d38316 100755 --- a/main/actions/ForkTests.scala +++ b/main/actions/ForkTests.scala @@ -33,18 +33,24 @@ private[sbt] object ForkTests { }.toMap std.TaskExtra.task { - val server = new ServerSocket(0) - object Acceptor extends Runnable { - val results = collection.mutable.Map.empty[String, TestResult.Value] - def output = (overall(results.values), results.toMap) - def run = { - val socket = server.accept() + if (!tests.isEmpty) { + val server = new ServerSocket(0) + object Acceptor extends Runnable { + val resultsAcc = collection.mutable.Map.empty[String, TestResult.Value] + lazy val result = (overall(resultsAcc.values), resultsAcc.toMap) + def run: Unit = { + val socket = + try { + server.accept() + } catch { + case _: java.net.SocketException => return + } val os = new ObjectOutputStream(socket.getOutputStream) val is = new ObjectInputStream(socket.getInputStream) import ForkTags._ @annotation.tailrec def react: Unit = is.readObject match { - case `Done` => os.writeObject(Done); + case `Done` => os.writeObject(Done); os.flush() case Array(`Error`, s: String) => log.error(s); react case Array(`Warn`, s: String) => log.warn(s); react case Array(`Info`, s: String) => log.info(s); react @@ -55,7 +61,7 @@ private[sbt] object ForkTests { val event = TestEvent(tEvents) listeners.foreach(_ testEvent event) val result = event.result getOrElse TestResult.Passed - results += group -> result + resultsAcc += group -> result listeners.foreach(_ endGroup (group, result)) react } @@ -73,28 +79,34 @@ private[sbt] object ForkTests { os.writeObject(clazz) os.writeObject(args.toArray) } + os.flush() react } finally { is.close(); os.close(); socket.close() } } - } + } - try { - testListeners.foreach(_.doInit()) - new Thread(Acceptor).start() + try { + testListeners.foreach(_.doInit()) + 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) - } finally { - server.close() - } - val result = Acceptor.output - testListeners.foreach(_.doComplete(result._1)) - result + 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) + val result = + if (ec != 0) + (TestResult.Error, Map("Running java with options " + options.mkString(" ") + " failed with exit code " + ec -> TestResult.Error)) + else + Acceptor.result + testListeners.foreach(_.doComplete(result._1)) + result + } finally { + server.close() + } + } else + (TestResult.Passed, Map.empty[String, TestResult.Value]) } tagw (config.tags: _*) } } diff --git a/sbt/src/sbt-test/tests/fork2/build.sbt b/sbt/src/sbt-test/tests/fork2/build.sbt new file mode 100644 index 0000000000..d142fde457 --- /dev/null +++ b/sbt/src/sbt-test/tests/fork2/build.sbt @@ -0,0 +1,3 @@ +fork := true + +libraryDependencies += "org.scalatest" % "scalatest_2.9.2" % "1.8" % "test" \ No newline at end of file diff --git a/sbt/src/sbt-test/tests/fork2/changes/Test.scala b/sbt/src/sbt-test/tests/fork2/changes/Test.scala new file mode 100644 index 0000000000..19789db2c4 --- /dev/null +++ b/sbt/src/sbt-test/tests/fork2/changes/Test.scala @@ -0,0 +1,8 @@ +import org.scalatest.FlatSpec +import org.scalatest.matchers.MustMatchers + +class Test extends FlatSpec with MustMatchers { + "A simple equation" must "hold" in { + Int.MaxValue must equal (Int.MaxValue) + } +} diff --git a/sbt/src/sbt-test/tests/fork2/test b/sbt/src/sbt-test/tests/fork2/test new file mode 100644 index 0000000000..7ccfe7768f --- /dev/null +++ b/sbt/src/sbt-test/tests/fork2/test @@ -0,0 +1,8 @@ +> test + +$ copy-file changes/Test.scala src/test/scala/Test.scala + +> test + +> 'set javaOptions += "-Xno-opt"' +-> test \ No newline at end of file diff --git a/testing/agent/src/main/java/sbt/ForkMain.java b/testing/agent/src/main/java/sbt/ForkMain.java index 8c51dbc9fa..b92ed1c5e5 100755 --- a/testing/agent/src/main/java/sbt/ForkMain.java +++ b/testing/agent/src/main/java/sbt/ForkMain.java @@ -89,6 +89,7 @@ boolean matches(Fingerprint f1, Fingerprint f2) { void write(ObjectOutputStream os, Object obj) { try { os.writeObject(obj); + os.flush(); } catch (IOException e) { System.err.println("Cannot write to socket"); } @@ -109,8 +110,10 @@ void run(ObjectInputStream is, final ObjectOutputStream os) throws Exception { final ForkTestDefinition[] tests = (ForkTestDefinition[]) is.readObject(); int nFrameworks = is.readInt(); for (int i = 0; i < nFrameworks; i++) { - final Framework framework; final String implClassName = (String) is.readObject(); + final String[] frameworkArgs = (String[]) is.readObject(); + + final Framework framework; try { framework = (Framework) Class.forName(implClassName).newInstance(); } catch (ClassNotFoundException e) { @@ -118,8 +121,6 @@ void run(ObjectInputStream is, final ObjectOutputStream os) throws Exception { continue; } - final String[] frameworkArgs = (String[]) is.readObject(); - ArrayList filteredTests = new ArrayList(); for (Fingerprint testFingerprint : framework.tests()) { for (ForkTestDefinition test : tests) {