summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/io/File.scala12
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala1
-rw-r--r--src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala8
-rw-r--r--src/partest/scala/tools/partest/nest/CompileManager.scala3
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunner.scala7
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala46
-rw-r--r--src/partest/scala/tools/partest/nest/NestUI.scala4
-rw-r--r--src/partest/scala/tools/partest/nest/StreamAppender.scala94
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala753
-rw-r--r--test/files/jvm/actor-link-getstate.scala4
-rw-r--r--test/files/res/bug687.check3
-rw-r--r--test/files/run/programmatic-main.scala4
14 files changed, 378 insertions, 565 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index aca34ec3a0..70e540701b 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -158,7 +158,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def logThrowable(t: Throwable): Unit = globalError(throwableAsString(t))
def throwableAsString(t: Throwable): String =
if (opt.richExes) Exceptional(t).force().context()
- else util.stringFromWriter(t printStackTrace _)
+ else util.stackTraceString(t)
// ------------ File interface -----------------------------------------
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 3425c04277..e5bc1cf732 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -1041,7 +1041,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
private def bindUnexceptionally(t: Throwable) = {
quietBind("lastException", classOf[Throwable], t)
- stringFromWriter(t printStackTrace _)
+ stackTraceString(t)
}
/** load and run the code using reflection */
diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala
index eddc9c0de6..284fb81125 100644
--- a/src/compiler/scala/tools/nsc/io/File.scala
+++ b/src/compiler/scala/tools/nsc/io/File.scala
@@ -12,7 +12,7 @@ package io
import java.io.{
FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
- BufferedInputStream, BufferedOutputStream, IOException, PrintStream, File => JFile, Closeable => JCloseable }
+ BufferedInputStream, BufferedOutputStream, IOException, PrintStream, PrintWriter, File => JFile, Closeable => JCloseable }
import java.nio.channels.{ Channel, FileChannel }
import scala.io.Codec
@@ -105,6 +105,9 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w
def bufferedWriter(append: Boolean, codec: Codec): BufferedWriter =
new BufferedWriter(writer(append, codec))
+ def printWriter(): PrintWriter = new PrintWriter(bufferedWriter(), true)
+ def printWriter(append: Boolean): PrintWriter = new PrintWriter(bufferedWriter(append), true)
+
/** Creates a new file and writes all the Strings to it. */
def writeAll(strings: String*): Unit = {
val out = bufferedWriter()
@@ -121,6 +124,13 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w
def appendAll(strings: String*): Unit = {
val out = bufferedWriter(append = true)
try strings foreach (out write _)
+ finally out.close()
+ }
+
+ /** Calls println on each string (so it adds a newline in the PrintWriter fashion.) */
+ def printlnAll(strings: String*): Unit = {
+ val out = printWriter()
+ try strings foreach (out println _)
finally out close
}
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
index 06e4de80f9..03c8603a6d 100644
--- a/src/compiler/scala/tools/nsc/util/package.scala
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -58,4 +58,5 @@ package object util {
ps.close()
bs.toString()
}
+ def stackTraceString(ex: Throwable): String = stringFromWriter(ex printStackTrace _)
}
diff --git a/src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala b/src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala
index 8cebcf1685..3d1cee95c6 100644
--- a/src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala
+++ b/src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala
@@ -83,12 +83,12 @@ object StreamAppender {
class StreamAppender(reader: BufferedReader, writer: PrintWriter) extends Runnable {
override def run() = runAndMap(identity)
private def lines() = Iterator continually reader.readLine() takeWhile (_ != null)
- def closeAll() = {
- reader.close()
- writer.close()
- }
def runAndMap(f: String => String) =
try lines() map f foreach (writer println _)
catch { case e: IOException => e.printStackTrace() }
+ finally {
+ reader.close()
+ writer.close()
+ }
}
diff --git a/src/partest/scala/tools/partest/nest/CompileManager.scala b/src/partest/scala/tools/partest/nest/CompileManager.scala
index cec9d60743..6a30aa32af 100644
--- a/src/partest/scala/tools/partest/nest/CompileManager.scala
+++ b/src/partest/scala/tools/partest/nest/CompileManager.scala
@@ -37,10 +37,11 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
}
def newSettings(out: Option[String]) = {
+ // val settings = new Settings(Console.err println _)
val settings = new Settings(_ => ())
settings.deprecation.value = true
settings.nowarnings.value = false
- settings.encoding.value = "ISO-8859-1" // XXX why?
+ settings.encoding.value = "ISO-8859-1"
val classpathElements = fileManager.LATEST_LIB :: out.toList
settings.classpath.value = ClassPath.join(classpathElements: _*)
diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
index eb5cff4fa5..41ecca7d06 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
@@ -87,7 +87,8 @@ class ConsoleRunner extends DirectRunner {
def argNarrowsTests(x: String) = denotesTestSet(x) || denotesTestFile(x) || denotesTestDir(x)
NestUI._verbose = parsed isSet "--verbose"
- fileManager.showDiff = parsed isSet "--show-diff"
+ fileManager.showDiff = true
+ // parsed isSet "--show-diff"
fileManager.updateCheck = parsed isSet "--update-check"
fileManager.showLog = parsed isSet "--show-log"
fileManager.failed = parsed isSet "--failed"
@@ -205,7 +206,9 @@ class ConsoleRunner extends DirectRunner {
resultsToStatistics(runTestsForFiles(files, kind))
}
- NestUI.verbose("Run sets: "+enabledSets)
+ if (enabledSets.nonEmpty)
+ NestUI.verbose("Run sets: "+enabledSets)
+
val results = runTestsFileLists ::: (enabledSets map runTests)
(results map (_._1) sum, results map (_._2) sum)
diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala
index 589332430a..b0b0c326e4 100644
--- a/src/partest/scala/tools/partest/nest/FileManager.scala
+++ b/src/partest/scala/tools/partest/nest/FileManager.scala
@@ -12,7 +12,7 @@ import java.io.{File, FilenameFilter, IOException, StringWriter,
FileInputStream, FileOutputStream, BufferedReader,
FileReader, PrintWriter, FileWriter}
import java.net.URI
-import scala.tools.nsc.io.{ Path, Directory }
+import scala.tools.nsc.io.{ Path, Directory, File => SFile }
import scala.collection.mutable.HashMap
trait FileManager {
@@ -50,7 +50,9 @@ trait FileManager {
var SCALAC_OPTS = PartestDefaults.scalacOpts
var JAVA_OPTS = PartestDefaults.javaOpts
var timeout = PartestDefaults.timeout
- var oneTestTimeout = 15 * 60 * 1000 // okay, let's try 15
+ // how can 15 minutes not be enough? What are you doing, run/lisp.scala?
+ // You complete in 11 seconds on my machine.
+ var oneTestTimeout = 60 * 60 * 1000
/** Only when --debug is given. */
lazy val testTimings = new HashMap[String, Long]
@@ -64,8 +66,9 @@ trait FileManager {
new LogFile(dir, fileBase + "-" + kind + ".log")
def getLogFile(file: File, kind: String): LogFile = {
- val dir = file.getParentFile
+ val dir = file.getParentFile
val fileBase = basename(file.getName)
+
getLogFile(dir, fileBase, kind)
}
@@ -75,38 +78,27 @@ trait FileManager {
def overwriteFileWith(dest: File, file: File) =
dest.isFile && copyFile(file, dest)
-
def copyFile(from: File, dest: File): Boolean = {
- def copyFile0(from: File, to: File): Boolean =
- try {
- val appender = StreamAppender(from, to)
- appender.run()
- appender.closeAll()
- true
- } catch {
- case _: IOException => false
- }
-
if (from.isDirectory) {
assert(dest.isDirectory, "cannot copy directory to file")
val subDir:Directory = Path(dest) / Directory(from.getName)
subDir.createDirectory()
- from.listFiles.toList.forall(copyFile(_, subDir))
- } else
- copyFile0(from, if (dest.isDirectory) new File(dest, from.getName) else dest)
+ from.listFiles.toList forall (copyFile(_, subDir))
+ }
+ else {
+ val to = if (dest.isDirectory) new File(dest, from.getName) else dest
+
+ try {
+ SFile(to) writeAll SFile(from).slurp()
+ true
+ }
+ catch { case _: IOException => false }
+ }
}
def mapFile(file: File, suffix: String, dir: File, replace: String => String) {
- val tmpFile = File.createTempFile("tmp", suffix, dir) // prefix required by API
-
- val appender = StreamAppender(file, tmpFile)
- appender.runAndMap(replace)
- appender.closeAll()
-
- val appender2 = StreamAppender(tmpFile, file)
- appender2.run()
- appender2.closeAll()
+ val f = SFile(file)
- tmpFile.delete()
+ f.printlnAll(f.lines.toList map replace: _*)
}
}
diff --git a/src/partest/scala/tools/partest/nest/NestUI.scala b/src/partest/scala/tools/partest/nest/NestUI.scala
index 38110645ba..2bf7cd0667 100644
--- a/src/partest/scala/tools/partest/nest/NestUI.scala
+++ b/src/partest/scala/tools/partest/nest/NestUI.scala
@@ -116,4 +116,8 @@ object NestUI {
println(msg)
}
}
+ def shout(msg: String) {
+ warning("something is wrong:")
+ println(msg)
+ }
}
diff --git a/src/partest/scala/tools/partest/nest/StreamAppender.scala b/src/partest/scala/tools/partest/nest/StreamAppender.scala
deleted file mode 100644
index 8cebcf1685..0000000000
--- a/src/partest/scala/tools/partest/nest/StreamAppender.scala
+++ /dev/null
@@ -1,94 +0,0 @@
-/* NEST (New Scala Test)
- * Copyright 2007-2010 LAMP/EPFL
- * @author Philipp Haller
- */
-
-// $Id$
-
-package scala.tools.partest
-package nest
-
-import java.io._
-
-object StreamAppender {
- def wrapIn(in: InputStream): BufferedReader = new BufferedReader(new InputStreamReader(in))
- def wrapIn(reader: Reader): BufferedReader = new BufferedReader(reader)
- def wrapIn(str: String): BufferedReader = new BufferedReader(new StringReader(str))
-
- def wrapOut(out: OutputStream): PrintWriter = new PrintWriter(new OutputStreamWriter(out), true)
- def wrapOut(writer: Writer): PrintWriter = new PrintWriter(writer, true)
- def wrapOut(): PrintWriter = wrapOut(new StringWriter)
-
- def apply(reader: BufferedReader, writer: Writer): StreamAppender =
- new StreamAppender(reader, wrapOut(writer))
-
- def apply(reader: Reader, writer: Writer): StreamAppender =
- apply(wrapIn(reader), writer)
-
- def apply(in: InputStream, writer: Writer): StreamAppender =
- apply(wrapIn(in), writer)
-
- def apply(str: String, writer: Writer): StreamAppender =
- apply(wrapIn(str), writer)
-
- def apply(in: File, out: File): StreamAppender =
- apply(new FileReader(in), new FileWriter(out))
-
- def appendToString(in1: InputStream, in2: InputStream): String = {
- val swriter1 = new StringWriter
- val swriter2 = new StringWriter
- val app1 = StreamAppender(wrapIn(in1), swriter1)
- val app2 = StreamAppender(wrapIn(in2), swriter2)
-
- val async = new Thread(app2)
- async.start()
- app1.run()
- async.join()
- swriter1.toString + swriter2.toString
- }
-/*
- private def inParallel(t1: Runnable, t2: Runnable, t3: Runnable) {
- val thr1 = new Thread(t1)
- val thr2 = new Thread(t2)
- thr1.start()
- thr2.start()
- t3.run()
- thr1.join()
- thr2.join()
- }
-*/
- private def inParallel(t1: Runnable, t2: Runnable) {
- val thr = new Thread(t2)
- thr.start()
- t1.run()
- thr.join()
- }
-
- def concat(in: InputStream, err: InputStream, out: OutputStream) = new Runnable {
- override def run() {
- val outWriter = wrapOut(out)
- val inApp = StreamAppender(in, outWriter)
-
- val errStringWriter = new StringWriter
- val errApp = StreamAppender(wrapIn(err), errStringWriter)
-
- inParallel(inApp, errApp)
-
- // append error string to out
- StreamAppender(errStringWriter.toString, outWriter).run()
- }
- }
-}
-
-class StreamAppender(reader: BufferedReader, writer: PrintWriter) extends Runnable {
- override def run() = runAndMap(identity)
- private def lines() = Iterator continually reader.readLine() takeWhile (_ != null)
- def closeAll() = {
- reader.close()
- writer.close()
- }
-
- def runAndMap(f: String => String) =
- try lines() map f foreach (writer println _)
- catch { case e: IOException => e.printStackTrace() }
-}
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index 7aa4ccc546..73a09b4733 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -16,21 +16,18 @@ import scala.util.Properties.{ isWin }
import scala.tools.nsc.{ ObjectRunner, Settings, CompilerCommand, Global }
import scala.tools.nsc.io.{ AbstractFile, PlainFile, Path, Directory, File => SFile }
import scala.tools.nsc.reporters.ConsoleReporter
-import scala.tools.nsc.util.{ ClassPath, FakePos, ScalaClassLoader }
+import scala.tools.nsc.util.{ ClassPath, FakePos, ScalaClassLoader, stackTraceString }
import ClassPath.{ join, split }
import scala.actors.{ Actor, Exit, TIMEOUT }
import scala.actors.Actor._
-import scala.tools.scalap.scalax.rules.scalasig.{ByteCode, ClassFileParser, ScalaSigAttributeParsers}
-
+import scala.tools.scalap.scalax.rules.scalasig.ByteCode
import scala.collection.{ mutable, immutable }
-import scala.collection.immutable.{ HashMap, Map => ImmMap }
-import scala.collection.Map
-
-import scala.tools.nsc.interactive.{BuildManager, RefinedBuildManager}
+import scala.tools.nsc.interactive.{ BuildManager, RefinedBuildManager }
+import scala.sys.process._
case class RunTests(kind: String, files: List[File])
-case class Results(results: ImmMap[String, Int], logs: List[LogFile], outdirs: List[File])
+case class Results(results: Map[String, Int], logs: List[LogFile], outdirs: List[File])
case class LogContext(file: LogFile, writers: Option[(StringWriter, PrintWriter)])
@@ -67,12 +64,11 @@ object Output {
private val redirVar = new DynamicVariable[Option[PrintStream]](None)
class Redirecter(stream: PrintStream) extends PrintStream(new OutputStream {
- private def withStream(f: PrintStream => Unit) = {
- if (redirVar.value != None) f(redirVar.value.get)
- else f(stream)
- }
- def write(b: Int) = withStream(_.write(b))
- override def write(b: Array[Byte]) = withStream(_.write(b))
+ def write(b: Int) = withStream(_ write b)
+
+ private def withStream(f: PrintStream => Unit) = f(redirVar.value getOrElse stream)
+
+ override def write(b: Array[Byte]) = withStream(_ write b)
override def write(b: Array[Byte], off: Int, len: Int) = withStream(_.write(b, off, len))
override def flush = withStream(_.flush)
override def close = withStream(_.close)
@@ -83,22 +79,16 @@ object Output {
object errRedirect extends Redirecter(err)
// this supports thread-safe nested output redirects
- def withRedirected(newstream: PrintStream)(func: => Unit) {
+ def withRedirected[T](newstream: PrintStream)(func: => T): T = {
// note down old redirect destination
// this may be None in which case outRedirect and errRedirect print to stdout and stderr
- val oldred = redirVar.value
-
+ val saved = redirVar.value
// set new redirecter
// this one will redirect both out and err to newstream
redirVar.value = Some(newstream)
- try {
- func
- } finally {
- // revert to old redirect
- // this may be None, which makes outRedirect and errRedirect choose standard outputs again
- redirVar.value = oldred
- }
+ try func
+ finally redirVar.value = saved
}
}
@@ -137,7 +127,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
* I can see what they're doing when the world comes to a premature stop.
*/
private val filesRemaining = new mutable.HashSet[File]
- private def addFilesRemaining(xs: Traversable[File]) = filesRemaining ++= xs
+ private def addFilesRemaining(xs: Traversable[File]) = synchronized { filesRemaining ++= xs }
private var currentTestFile: File = _
private var currentFileStart: Long = System.currentTimeMillis
@@ -152,6 +142,18 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
currentTimerTask.kick()
}
+ /** This does something about absolute paths and file separator
+ * chars before diffing.
+ */
+ private def replaceSlashes(dir: File, s: String): String = {
+ val path = dir.getAbsolutePath+File.separator
+ val line = s indexOf path match {
+ case -1 => s
+ case idx => (s take idx) + (s drop idx + path.length)
+ }
+ line.replace('\\', '/')
+ }
+
private def currentFileString = {
"Current test file is: %s\n Started: %s (%s seconds ago)\n Current time: %s".format(
currentTestFile,
@@ -160,11 +162,14 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
new java.util.Date()
)
}
- private def getNextFile() = synchronized {
- currentTestFile = filesRemaining.head
- filesRemaining -= currentTestFile
- currentFileStart = System.currentTimeMillis
- currentTestFile
+ private def getNextFile(): File = synchronized {
+ if (filesRemaining.isEmpty) null
+ else {
+ currentTestFile = filesRemaining.head
+ filesRemaining -= currentTestFile
+ currentFileStart = System.currentTimeMillis
+ currentTestFile
+ }
}
// maps canonical file names to the test result (0: OK, 1: FAILED, 2: TIMOUT)
private val status = new mutable.HashMap[String, Int]
@@ -173,7 +178,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
}
override def toString = (
">> Partest Worker in state " + getState + ":\n" +
- currentFileString +
+ currentFileString + "\n" +
"There are " + filesRemaining.size + " files remaining:\n" +
filesRemaining.toList.sortBy(_.toString).map(" " + _ + "\n").mkString("") +
"\nstatus hashmap contains " + status.size + " entries:\n" +
@@ -203,15 +208,10 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val totalWidth = 56
val name = {
// 1. try with [...]/files/run/test.scala
- val testPathLen = testdir.getAbsolutePath.length
- val name = file.getAbsolutePath.substring(testPathLen)
- if (name.length <= totalWidth)
- name
+ val name = file.getAbsolutePath drop testdir.getAbsolutePath.length
+ if (name.length <= totalWidth) name
// 2. try with [...]/run/test.scala
- else {
- val filesPathLen = filesdir.getAbsolutePath.length
- file.getAbsolutePath.substring(filesPathLen)
- }
+ else file.getAbsolutePath drop filesdir.getAbsolutePath.length
}
NestUI.normal("[...]%s%s".format(name, " " * (totalWidth - name.length)), printer)
}
@@ -248,67 +248,37 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
def javac(outDir: File, files: List[File], output: File): Boolean = {
// compile using command-line javac compiler
- val cmd = javacCmd+
- " -d "+outDir.getAbsolutePath+
- " -classpath "+ join(outDir.toString, CLASSPATH) +
- " "+files.mkString(" ")
-
- val (success, msg) = try {
- val exitCode = runCommand(cmd, output)
- NestUI.verbose("javac returned exit code: "+exitCode)
- if (exitCode != 0)
- (false, "Running \"javac\" failed with exit code: "+exitCode+"\n"+cmd+"\n")
- else
- (true, "")
- } catch {
- case e: Exception =>
- val swriter = new StringWriter
- e.printStackTrace(new PrintWriter(swriter))
- (false, "Running \"javac\" failed:\n"+cmd+"\n"+swriter.toString+"\n")
+ val cmd = "%s -d %s -classpath %s %s".format(
+ javacCmd,
+ outDir.getAbsolutePath,
+ join(outDir.toString, CLASSPATH),
+ files mkString " "
+ )
+ def fail(msg: String) = {
+ SFile(output) appendAll msg
+ false
}
- if (!success) {
- val writer = new PrintWriter(new FileWriter(output, true), true)
- writer.print(msg)
- writer.close()
+ try runCommand(cmd, output) match {
+ case 0 => true
+ case code => fail("javac failed with exit code " + code + "\n" + cmd + "\n")
}
- success
+ catch exHandler(output, "javac command '" + cmd + "' failed:\n")
}
- /** Runs <code>command</code> redirecting standard out and
- * error out to <code>output</code> file.
+ /** Runs command redirecting standard out and
+ * error out to output file.
*/
def runCommand(command: String, output: File): Int = {
NestUI.verbose("running command:\n"+command)
- val proc = Runtime.getRuntime.exec(command)
- val in = proc.getInputStream
- val err = proc.getErrorStream
- val writer = new PrintWriter(new FileWriter(output), true)
- val inApp = StreamAppender(in, writer)
- val errApp = StreamAppender(err, writer)
- val async = new Thread(errApp)
- async.start()
- inApp.run()
- async.join()
- writer.close()
-
- try proc.exitValue()
- catch { case _: IllegalThreadStateException => 0 }
+ (command #> output !)
}
def execTest(outDir: File, logFile: File, fileBase: String) {
// check whether there is a ".javaopts" file
- val argsFile = new File(logFile.getParentFile, fileBase+".javaopts")
- val argString = if (argsFile.exists) {
- NestUI.verbose("Found javaopts file: "+argsFile)
- val fileReader = new FileReader(argsFile)
- val reader = new BufferedReader(fileReader)
- val options = reader.readLine()
- reader.close()
- NestUI.verbose("Found javaopts file '%s', using options: '%s'".format(argsFile, options))
- options
- } else ""
-
- def quote(path: String) = "\""+path+"\""
+ val argsFile = new File(logFile.getParentFile, fileBase + ".javaopts")
+ val argString = file2String(argsFile)
+ if (argString != "")
+ NestUI.verbose("Found javaopts file '%s', using options: '%s'".format(argsFile, argString))
// Note! As this currently functions, JAVA_OPTS must precede argString
// because when an option is repeated to java only the last one wins.
@@ -318,6 +288,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
//
// debug: Found javaopts file 'files/shootout/message.scala-2.javaopts', using options: '-Xss32k'
// debug: java -Xss32k -Xss2m -Xms256M -Xmx1024M -classpath [...]
+ val extras = if (isPartestDebug) List("-Dpartest.debug=true") else Nil
val propertyOptions = List(
"-Djava.library.path="+logFile.getParentFile.getAbsolutePath,
"-Dpartest.output="+outDir.getAbsolutePath,
@@ -326,9 +297,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
"-Djavacmd="+JAVACMD,
"-Djavaccmd="+javacCmd,
"-Duser.language=en -Duser.country=US"
- ) ::: (
- if (isPartestDebug) List("-Dpartest.debug=true") else Nil
- )
+ ) ++ extras
val cmd = (
List(
@@ -336,7 +305,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
JAVA_OPTS,
argString,
"-classpath " + join(outDir.toString, CLASSPATH)
- ) ::: propertyOptions ::: List(
+ ) ++ propertyOptions ++ List(
"scala.tools.nsc.MainGenericRunner",
"-usejavacp",
"Test",
@@ -355,7 +324,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
def chkFile(s: String) = Directory(dir) / "%s%s.check".format(fileBase, s)
val checkFile = if (chkFile("").isFile) chkFile("") else chkFile("-" + kind)
- if (checkFile.canRead) Some(checkFile) else None
+ Some(checkFile) filter (_.canRead)
}
def existsCheckFile(dir: File, fileBase: String, kind: String) =
@@ -375,58 +344,83 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
case _ => file2String(logFile)
}
- def file2String(logFile: File) = SFile(logFile).slurp()
+ def file2String(f: File) =
+ try SFile(f).slurp()
+ catch { case _: FileNotFoundException => "" }
+
def isJava(f: File) = SFile(f) hasExtension "java"
def isScala(f: File) = SFile(f) hasExtension "scala"
def isJavaOrScala(f: File) = isJava(f) || isScala(f)
def outputLogFile(logFile: File) {
- NestUI.normal("Log file '" + logFile + "': \n")
val lines = SFile(logFile).lines
- for (lin <- lines) NestUI.normal(lin + "\n")
+ if (lines.nonEmpty) {
+ NestUI.normal("Log file '" + logFile + "': \n")
+ lines foreach (x => NestUI.normal(x + "\n"))
+ }
+ }
+ def exHandler(logFile: File): PartialFunction[Throwable, Boolean] = exHandler(logFile, "")
+ def exHandler(logFile: File, msg: String): PartialFunction[Throwable, Boolean] = {
+ case e: Exception =>
+ SFile(logFile).writeAll(msg, stackTraceString(e))
+ outputLogFile(logFile) // if running the test threw an exception, output log file
+ false
}
-
/** Runs a list of tests.
*
* @param kind The test kind (pos, neg, run, etc.)
* @param files The list of test files
*/
- def runTests(kind: String, files: List[File])(topcont: ImmMap[String, Int] => Unit) {
+ def runTests(kind: String, files: List[File])(topcont: Map[String, Int] => Unit) {
val compileMgr = new CompileManager(fileManager)
if (kind == "scalacheck") fileManager.CLASSPATH += File.pathSeparator + PathSettings.scalaCheck
+ // You don't default "succeeded" to true.
+ var succeeded = false
var errors = 0
- var succeeded = true
var diff = ""
var log = ""
- def fail(what: Any) {
+ def initNextTest() = {
+ val swr = new StringWriter
+ val wr = new PrintWriter(swr)
+ diff = ""
+ log = ""
+
+ ((swr, wr))
+ }
+
+ def fail(what: Any) = {
NestUI.verbose("scalac: compilation of "+what+" failed\n")
- succeeded = false
+ false
}
def diffCheck(latestDiff: String) = {
diff = latestDiff
- if (latestDiff != "") {
- NestUI.verbose("output differs from log file\n")
- succeeded = false
- }
+ succeeded = diff == ""
+ succeeded
+ }
+
+ def timed[T](body: => T): (T, Long) = {
+ val t1 = System.currentTimeMillis
+ val result = body
+ val t2 = System.currentTimeMillis
+
+ (result, t2 - t1)
}
/** 1. Creates log file and output directory.
- * 2. Runs <code>script</code> function, providing log file and
- * output directory as arguments.
+ * 2. Runs script function, providing log file and output directory as arguments.
*/
- def runInContext(file: File, kind: String, script: (File, File) => Unit): LogContext = {
+ def runInContext(file: File, kind: String, script: (File, File) => Boolean): LogContext = {
// When option "--failed" is provided, execute test only if log file is present
// (which means it failed before)
val logFile = createLogFile(file, kind)
- if (!fileManager.failed || logFile.canRead) {
- val swr = new StringWriter
- val wr = new PrintWriter(swr)
- succeeded = true
- diff = ""
- log = ""
+
+ if (fileManager.failed && !logFile.canRead)
+ LogContext(logFile, None)
+ else {
+ val (swr, wr) = initNextTest()
printInfoStart(file, wr)
val fileBase: String = basename(file.getName)
@@ -436,132 +430,114 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
NestUI.verbose("output directory: "+outDir)
// run test-specific code
- try {
+ succeeded = try {
if (isPartestDebug) {
- val t1 = System.currentTimeMillis
- script(logFile, outDir)
- val t2 = System.currentTimeMillis
- fileManager.recordTestTiming(file.getPath, t2 - t1)
+ val (result, millis) = timed(script(logFile, outDir))
+ fileManager.recordTestTiming(file.getPath, millis)
+ result
}
- else {
- script(logFile, outDir)
- }
- } catch {
- case e: Exception =>
- val writer = new PrintWriter(new FileWriter(logFile), true)
- e.printStackTrace(writer)
- writer.close()
- outputLogFile(logFile) // if running the test threw an exception, output log file
- succeeded = false
+ else script(logFile, outDir)
}
+ catch exHandler(logFile)
LogContext(logFile, Some((swr, wr)))
- } else
- LogContext(logFile, None)
+ }
}
- def compileFilesIn(dir: File, kind: String, logFile: File, outDir: File) {
+ def compileFilesIn(dir: File, kind: String, logFile: File, outDir: File): Boolean = {
val testFiles = dir.listFiles.toList filter isJavaOrScala
def isInGroup(f: File, num: Int) = SFile(f).stripExtension endsWith ("_" + num)
val groups = (0 to 9).toList map (num => testFiles filter (f => isInGroup(f, num)))
val noGroupSuffix = testFiles filterNot (groups.flatten contains)
- def compileGroup(g: List[File]) {
+ def compileGroup(g: List[File]): Boolean = {
val (scalaFiles, javaFiles) = g partition isScala
+ val allFiles = javaFiles ++ scalaFiles
- if (scalaFiles.nonEmpty) {
- if (!compileMgr.shouldCompile(outDir, javaFiles ::: scalaFiles, kind, logFile))
- fail(g)
- }
-
- if (succeeded && javaFiles.nonEmpty) {
- succeeded = javac(outDir, javaFiles, logFile)
- if (succeeded && scalaFiles.nonEmpty && !compileMgr.shouldCompile(outDir, scalaFiles, kind, logFile))
- fail(scalaFiles)
+ // scala+java, then java, then scala
+ (scalaFiles.isEmpty || compileMgr.shouldCompile(outDir, allFiles, kind, logFile) || fail(g)) && {
+ (javaFiles.isEmpty || javac(outDir, javaFiles, logFile)) && {
+ (scalaFiles.isEmpty || compileMgr.shouldCompile(outDir, scalaFiles, kind, logFile) || fail(scalaFiles))
+ }
}
}
- if (noGroupSuffix.nonEmpty)
- compileGroup(noGroupSuffix)
-
- groups foreach (grp => if (succeeded) compileGroup(grp))
+ (noGroupSuffix.isEmpty || compileGroup(noGroupSuffix)) && (groups forall compileGroup)
}
- def failCompileFilesIn(dir: File, kind: String, logFile: File, outDir: File) {
+ def failCompileFilesIn(dir: File, kind: String, logFile: File, outDir: File): Boolean = {
val testFiles = dir.listFiles.toList
val sourceFiles = testFiles filter isJavaOrScala
- if (sourceFiles.nonEmpty) {
- if (!compileMgr.shouldFailCompile(outDir, sourceFiles, kind, logFile))
- fail(testFiles filter isScala)
- }
+ sourceFiles.isEmpty || compileMgr.shouldFailCompile(outDir, sourceFiles, kind, logFile) || fail(testFiles filter isScala)
}
- def runTestCommon(file: File, kind: String, expectFailure: Boolean)(onSuccess: (File, File) => Unit, onFail: (File, File) => Unit = (logf, outd) => ()): LogContext =
+ def runTestCommon(file: File, kind: String, expectFailure: Boolean)(
+ onSuccess: (File, File) => Boolean,
+ onFail: (File, File) => Unit = (_, _) => ()): LogContext =
+ {
runInContext(file, kind, (logFile: File, outDir: File) => {
+ val result =
+ if (file.isDirectory) {
+ if (expectFailure) failCompileFilesIn(file, kind, logFile, outDir)
+ else compileFilesIn(file, kind, logFile, outDir)
+ }
+ else {
+ if (expectFailure) compileMgr.shouldFailCompile(List(file), kind, logFile)
+ else compileMgr.shouldCompile(List(file), kind, logFile)
+ }
- if (file.isDirectory) {
- val f = if (expectFailure) failCompileFilesIn _ else compileFilesIn _
- f(file, kind, logFile, outDir)
- }
- else {
- val f: (List[File], String, File) => Boolean =
- if (expectFailure) compileMgr.shouldFailCompile _
- else compileMgr.shouldCompile _
-
- if (!f(List(file), kind, logFile))
- fail(file)
- }
-
- if (succeeded) // run test
- onSuccess(logFile, outDir)
- else
- onFail(logFile, outDir)
+ if (result) onSuccess(logFile, outDir)
+ else { onFail(logFile, outDir) ; false }
})
+ }
def runJvmTest(file: File, kind: String): LogContext =
runTestCommon(file, kind, expectFailure = false)((logFile, outDir) => {
val fileBase = basename(file.getName)
val dir = file.getParentFile
- execTest(outDir, logFile, fileBase)
+ execTest(outDir, logFile, fileBase)
diffCheck(compareOutput(dir, fileBase, kind, logFile))
})
def processSingleFile(file: File): LogContext = kind match {
case "scalacheck" =>
- runTestCommon(file, kind, expectFailure = false)((logFile, outDir) => {
+ val succFn: (File, File) => Boolean = { (logFile, outDir) =>
NestUI.verbose("compilation of "+file+" succeeded\n")
- val outURL = outDir.getCanonicalFile.toURI.toURL
-
+ val outURL = outDir.getCanonicalFile.toURI.toURL
val logWriter = new PrintStream(new FileOutputStream(logFile))
Output.withRedirected(logWriter) {
- // this classloader is test specific
- // its parent contains library classes and others
- val classloader = ScalaClassLoader.fromURLs(List(outURL), params.scalaCheckParentClassLoader)
- classloader.run("Test", Nil)
+ // this classloader is test specific: its parent contains library classes and others
+ ScalaClassLoader.fromURLs(List(outURL), params.scalaCheckParentClassLoader).run("Test", Nil)
}
- NestUI.verbose(SFile(logFile).slurp())
+ NestUI.verbose(file2String(logFile))
// obviously this must be improved upon
- val lines = SFile(logFile).lines.filter(_.trim != "").toBuffer
- succeeded = {
- val failures = lines filter (_ startsWith "!")
- //val passedok = lines filter (_ startsWith "+") forall (_ contains "OK") - OK may wrap!!
- failures.isEmpty
+ val lines = SFile(logFile).lines map (_.trim) filterNot (_ == "") toBuffer;
+ if (lines forall (x => !x.startsWith("!"))) {
+ NestUI.verbose("test for '" + file + "' success: " + succeeded)
+ true
}
- if (!succeeded) {
+ else {
NestUI.normal("ScalaCheck test failed. Output:\n")
- for (lin <- lines) NestUI.normal(lin + "\n")
+ lines foreach (x => NestUI.normal(x + "\n"))
+ false
}
- NestUI.verbose("test for '" + file + "' success: " + succeeded)
- }, (logFile, outDir) => outputLogFile(logFile))
+ }
+ runTestCommon(file, kind, expectFailure = false)(
+ succFn,
+ (logFile, outDir) => outputLogFile(logFile)
+ )
case "pos" =>
- runTestCommon(file, kind, expectFailure = false)((_, _) => ())
+ runTestCommon(file, kind, expectFailure = false)(
+ (logFile, outDir) => true,
+ (_, _) => ()
+ )
case "neg" =>
runTestCommon(file, kind, expectFailure = true)((logFile, outDir) => {
@@ -582,39 +558,36 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
case "buildmanager" =>
val logFile = createLogFile(file, kind)
if (!fileManager.failed || logFile.canRead) {
- val swr = new StringWriter
- val wr = new PrintWriter(swr)
- succeeded = true; diff = ""
+ val (swr, wr) = initNextTest()
printInfoStart(file, wr)
- val (outDir, testFile, changesDir, fileBase) =
-
- if (!file.isDirectory) {
- succeeded = false
- (null, null, null, null)
- } else {
- val fileBase: String = basename(file.getName)
- NestUI.verbose(this+" running test "+fileBase)
- val outDir = createOutputDir(file, fileBase, kind)
- if (!outDir.exists) outDir.mkdir()
- val testFile = new File(file, fileBase + ".test")
- val changesDir = new File(file, fileBase + ".changes")
- if (changesDir.isFile || !testFile.isFile) {
- // if changes exists then it has to be a dir
- if (!testFile.isFile) NestUI.verbose("invalid build manager test file")
- if (changesDir.isFile) NestUI.verbose("invalid build manager changes directory")
- succeeded = false
+ val (outDir, testFile, changesDir, fileBase) = (
+ if (!file.isDirectory)
(null, null, null, null)
- } else {
- copyTestFiles(file, outDir)
- NestUI.verbose("outDir: "+outDir)
- NestUI.verbose("logFile: "+logFile)
- (outDir, testFile, changesDir, fileBase)
+ else {
+ val fileBase: String = basename(file.getName)
+ NestUI.verbose(this+" running test "+fileBase)
+ val outDir = createOutputDir(file, fileBase, kind)
+ if (!outDir.exists) outDir.mkdir()
+ val testFile = new File(file, fileBase + ".test")
+ val changesDir = new File(file, fileBase + ".changes")
+
+ if (changesDir.isFile || !testFile.isFile) {
+ // if changes exists then it has to be a dir
+ if (!testFile.isFile) NestUI.verbose("invalid build manager test file")
+ if (changesDir.isFile) NestUI.verbose("invalid build manager changes directory")
+ (null, null, null, null)
+ }
+ else {
+ copyTestFiles(file, outDir)
+ NestUI.verbose("outDir: "+outDir)
+ NestUI.verbose("logFile: "+logFile)
+ (outDir, testFile, changesDir, fileBase)
+ }
}
- }
+ )
- if (succeeded) {
+ if (outDir != null) {
// Pre-conditions satisfied
-
try {
val sourcepath = outDir.getAbsolutePath+File.separator
@@ -639,12 +612,14 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
new BuilderGlobal(settings, reporter)
}
- val testCompile = (line: String) => {
+ val testCompile: String => Boolean = { line =>
NestUI.verbose("compiling " + line)
val args = (line split ' ').toList
val command = new CompilerCommand(args, settings)
- bM.update(filesToSet(settings.sourcepath.value, command.files), Set.empty)
- !reporter.hasErrors
+ command.ok && {
+ bM.update(filesToSet(settings.sourcepath.value, command.files), Set.empty)
+ !reporter.hasErrors
+ }
}
val updateFiles = (line: String) => {
@@ -668,39 +643,35 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
false
}
})
- if (!res)
- NestUI.verbose("updating failed")
- else
- NestUI.verbose("updating succeeded")
+ NestUI.verbose("updating " + (if (res) "succeeded" else "failed"))
res
}
- def loop() {
- val command = testReader.readLine()
- if ((command ne null) && command.length() > 0) {
- val commandResult = command match {
- case s if (s.startsWith(">>update ")) =>
- updateFiles(s.stripPrefix(">>update "))
- case s if (s.startsWith(">>compile ")) =>
- val files = s.stripPrefix(">>compile ")
- logWriter.println(prompt + files)
- testCompile(files) // In the end, it can finish with an error
- case _ =>
- NestUI.verbose("wrong command in test file: " + command)
- false
+ def loop(): Boolean = {
+ testReader.readLine() match {
+ case null | "" =>
+ NestUI.verbose("finished")
+ true
+ case s if s startsWith ">>update " =>
+ updateFiles(s stripPrefix ">>update ") && loop()
+ case s if s startsWith ">>compile " =>
+ val files = s stripPrefix ">>compile "
+ logWriter.println(prompt + files)
+ // In the end, it can finish with an error
+ if (testCompile(files)) loop()
+ else {
+ val t = testReader.readLine()
+ (t == null) || (t == "")
}
-
- if (commandResult) loop()
-
- } else {
- NestUI.verbose("finished")
- succeeded = true
+ case s =>
+ NestUI.verbose("wrong command in test file: " + s)
+ false
}
}
Output.withRedirected(logWriter) {
- loop()
- testReader.close()
+ try loop()
+ finally testReader.close()
}
fileManager.mapFile(logFile, "tmp", file, _.replace(sourcepath, "").
replaceAll(java.util.regex.Matcher.quoteReplacement("\\"), "/"))
@@ -714,6 +685,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
LogContext(logFile, None)
case "res" => {
+ // simulate resident compiler loop
+ val prompt = "\nnsc> "
+
// when option "--failed" is provided
// execute test only if log file is present
// (which means it failed before)
@@ -721,9 +695,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
//val (logFileOut, logFileErr) = createLogFiles(file, kind)
val logFile = createLogFile(file, kind)
if (!fileManager.failed || logFile.canRead) {
- val swr = new StringWriter
- val wr = new PrintWriter(swr)
- succeeded = true; diff = ""; log = ""
+ val (swr, wr) = initNextTest()
printInfoStart(file, wr)
val fileBase: String = basename(file.getName)
@@ -739,9 +711,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// run compiler in resident mode
// $SCALAC -d "$os_dstbase".obj -Xresident -sourcepath . "$@"
-
- try {
-
val sourcedir = logFile.getParentFile.getCanonicalFile
val sourcepath = sourcedir.getAbsolutePath+File.separator
NestUI.verbose("sourcepath: "+sourcepath)
@@ -766,9 +735,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val command = new CompilerCommand(argList, settings)
object compiler extends Global(command.settings, reporter)
- // simulate resident compiler loop
- val prompt = "\nnsc> "
-
val resCompile = (line: String) => {
NestUI.verbose("compiling "+line)
val cmdArgs = (line split ' ').toList map (fs => new File(dir, fs).getAbsolutePath)
@@ -776,66 +742,26 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val sett = new Settings(workerError)
sett.sourcepath.value = sourcepath
val command = new CompilerCommand(cmdArgs, sett)
- (new compiler.Run) compile command.files
+ command.ok && {
+ (new compiler.Run) compile command.files
+ !reporter.hasErrors
+ }
}
- def loop(action: (String) => Unit) {
+ def loop(action: String => Boolean): Boolean = {
logWriter.print(prompt)
- val line = resReader.readLine()
- if ((line ne null) && line.length() > 0) {
-/*
- val parent = self
- self.trapExit = true
- val child = link {
- action(line)
- }
-
- receiveWithin(fileManager.timeout.toLong) {
- case TIMEOUT =>
- NestUI.verbose("action timed out")
- false
- case Exit(from, reason) if from == child => reason match {
- case 'normal => // do nothing
- case t: Throwable =>
- NestUI.verbose("while invoking compiler:")
- NestUI.verbose("caught "+t)
- t.printStackTrace
- if (t.getCause != null)
- t.getCause.printStackTrace
- false
- }
- }
-*/
- action(line)
- loop(action)
+ resReader.readLine() match {
+ case null | "" => logWriter.flush() ; true
+ case line => action(line) && loop(action)
}
}
Output.withRedirected(logWriter) {
- loop(resCompile)
- resReader.close()
- }
-
- def replaceSlashes(s: String): String = {
- val path = dir.getAbsolutePath+File.separator
- // find `path` in `line`
- val index = s.indexOf(path)
- val line =
- if (index != -1)
- s.substring(0, index) + s.substring(index + path.length, s.length)
- else s
- line.replace('\\', '/')
+ try loop(resCompile)
+ finally resReader.close()
}
-
- fileManager.mapFile(logFile, "tmp", dir, replaceSlashes)
+ fileManager.mapFile(logFile, "tmp", dir, replaceSlashes(dir, _))
diffCheck(compareOutput(dir, fileBase, kind, logFile))
-
- } catch {
- case e =>
- e.printStackTrace()
- succeeded = false
- }
-
LogContext(logFile, Some((swr, wr)))
} else
LogContext(logFile, None)
@@ -847,9 +773,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// (which means it failed before)
val logFile = createLogFile(file, kind)
if (!fileManager.failed || logFile.canRead) {
- val swr = new StringWriter
- val wr = new PrintWriter(swr)
- succeeded = true; diff = ""; log = ""
+ val (swr, wr) = initNextTest()
printInfoStart(file, wr)
val fileBase: String = basename(file.getName)
@@ -867,44 +791,27 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// 3. cat {test}.scala.runner {test}.scala > testFile
val runnerFile = new File(dir, fileBase+".scala.runner")
val bodyFile = new File(dir, fileBase+".scala")
- SFile(testFile).writeAll(List(runnerFile, bodyFile) map (f => SFile(f).slurp()): _*)
-
- try { // *catch-all*
- // 4. compile testFile
- if (!compileMgr.shouldCompile(List(testFile), kind, logFile)) {
- NestUI.verbose("compilation of "+file+" failed\n")
- succeeded = false
- } else {
- NestUI.verbose("compilation of "+testFile+"succeeded")
- // -------- run test --------
-
- //TODO: detect whether we have to use Runtime.exec
- // val useRuntime = true
- //
- // if (useRuntime)
- // execTest(outDir, logFile, fileBase)
- // else
- // execTestObjectRunner(file, outDir, logFile)
-
- execTest(outDir, logFile, fileBase)
-
- NestUI.verbose(this+" finished running "+fileBase)
- } // successful compile
- } catch { // *catch-all*
- case e: Exception =>
- NestUI.verbose("caught "+e)
- succeeded = false
+ SFile(testFile).writeAll(
+ file2String(runnerFile),
+ file2String(bodyFile)
+ )
+
+ // 4. compile testFile
+ val ok = compileMgr.shouldCompile(List(testFile), kind, logFile)
+ NestUI.verbose("compilation of " + testFile + (if (ok) "succeeded" else "failed"))
+ if (ok) {
+ execTest(outDir, logFile, fileBase)
+ NestUI.verbose(this+" finished running "+fileBase)
+ diffCheck(compareOutput(dir, fileBase, kind, logFile))
}
- diffCheck(compareOutput(dir, fileBase, kind, logFile))
-
LogContext(logFile, Some((swr, wr)))
- } else
+ }
+ else
LogContext(logFile, None)
}
- case "scalap" => {
-
+ case "scalap" =>
runInContext(file, kind, (logFile: File, outDir: File) => {
val sourceDir = file.getParentFile
val sourceDirName = sourceDir.getName
@@ -916,14 +823,16 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
if (results.length != 1) {
NestUI.verbose("Result file not found in directory " + sourceDirName + " \n")
- } else {
+ false
+ }
+ else {
val resFile = results(0)
// 2. Compile source file
if (!compileMgr.shouldCompile(outDir, List(file), kind, logFile)) {
NestUI.verbose("compilerMgr failed to compile %s to %s".format(file, outDir))
- succeeded = false
- } else {
-
+ false
+ }
+ else {
// 3. Decompile file and compare results
val isPackageObject = sourceDir.getName.startsWith("package")
val className = sourceDirName.capitalize + (if (!isPackageObject) "" else ".package")
@@ -934,20 +843,11 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val byteCode = ByteCode.forClass(clazz)
val result = scala.tools.scalap.Main.decompileScala(byteCode.bytes, isPackageObject)
- try {
- val fstream = new FileWriter(logFile);
- val out = new BufferedWriter(fstream);
- out.write(result)
- out.close();
- } catch {
- case e: IOException => NestUI.verbose(e.getMessage()); succeeded = false
- }
-
+ SFile(logFile) writeAll result
diffCheck(fileManager.compareFiles(logFile, resFile))
}
}
})
- }
case "script" => {
// when option "--failed" is provided
@@ -955,9 +855,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// (which means it failed before)
val logFile = createLogFile(file, kind)
if (!fileManager.failed || logFile.canRead) {
- val swr = new StringWriter
- val wr = new PrintWriter(swr)
- succeeded = true; diff = ""; log = ""
+ val (swr, wr) = initNextTest()
printInfoStart(file, wr)
val fileBase: String = basename(file.getName)
@@ -966,9 +864,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// check whether there is an args file
val argsFile = new File(file.getParentFile, fileBase+".args")
NestUI.verbose("argsFile: "+argsFile)
- val argString =
- if (!argsFile.exists) ""
- else " " + SFile(argsFile).slurp()
+ val argString = file2String(argsFile)
try {
val cmdString =
@@ -978,23 +874,11 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
batchFile.getAbsolutePath
}
else file.getAbsolutePath
- val proc = Runtime.getRuntime.exec(cmdString+argString)
- val in = proc.getInputStream
- val err = proc.getErrorStream
- val writer = new PrintWriter(new FileWriter(logFile), true)
- val inApp = new StreamAppender(new BufferedReader(new InputStreamReader(in)),
- writer)
- val errApp = new StreamAppender(new BufferedReader(new InputStreamReader(err)),
- writer)
- val async = new Thread(errApp)
- async.start()
- inApp.run()
- async.join()
-
- writer.close()
+ succeeded = ((cmdString+argString) #> logFile !) == 0
diffCheck(compareOutput(file.getParentFile, fileBase, kind, logFile))
- } catch { // *catch-all*
+ }
+ catch { // *catch-all*
case e: Exception =>
NestUI.verbose("caught "+e)
succeeded = false
@@ -1006,86 +890,99 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
}
}
- def reportAll(results: ImmMap[String, Int], cont: ImmMap[String, Int] => Unit) {
- // NestUI.verbose("finished testing "+kind+" with "+errors+" errors")
- // NestUI.verbose("created "+compileMgr.numSeparateCompilers+" separate compilers")
+ def reportAll(results: Map[String, Int], cont: Map[String, Int] => Unit) {
timer.cancel()
cont(results)
}
+ object TestState {
+ val Ok = 0
+ val Fail = 1
+ val Timeout = 2
+ }
+
def reportResult(state: Int, logFile: Option[LogFile], writers: Option[(StringWriter, PrintWriter)]) {
- val good = (state == 0)
- if (!good) {
+ val isGood = state == TestState.Ok
+ val isFail = state == TestState.Fail
+ val isTimeout = state == TestState.Timeout
+
+ if (!isGood) {
errors += 1
NestUI.verbose("incremented errors: "+errors)
}
- try {
- // delete log file only if test was successful
- logFile filter (_ => good && !isPartestDebug) foreach (_.toDelete = true)
-
- writers match {
- case Some((swr, wr)) =>
- if (state == 2)
- printInfoTimeout(wr)
- else
- printInfoEnd(good, wr)
- wr.flush()
- swr.flush()
- NestUI.normal(swr.toString)
- if (state == 1 && fileManager.showDiff && diff != "")
- NestUI.normal(diff)
- if (state == 1 && fileManager.showLog)
- showLog(logFile.get)
- case None =>
+ // delete log file only if test was successful
+ if (isGood && !isPartestDebug)
+ logFile foreach (_.toDelete = true)
+
+ writers foreach { case (swr, wr) =>
+ if (swr == null || wr == null || fileManager == null || logFile.exists(_ == null)) {
+ NestUI.normal("Something is wrong, why are you sending nulls here?")
+ NestUI.normal(List(swr, wr, fileManager, logFile) mkString " ")
+ }
+ else {
+ if (isTimeout) printInfoTimeout(wr)
+ else printInfoEnd(isGood, wr)
+ wr.flush()
+ swr.flush()
+ NestUI.normal(swr.toString)
+ if (isFail && fileManager.showDiff && diff != "")
+ NestUI.normal(diff)
+ if (isFail && fileManager.showLog)
+ logFile foreach showLog
}
- } catch {
- case npe: NullPointerException =>
}
}
- if (files.isEmpty) reportAll(ImmMap(), topcont)
+ if (files.isEmpty) reportAll(Map(), topcont)
else addFilesRemaining(files)
- Actor.loopWhile(filesRemaining.nonEmpty) {
+ var done = false
+
+ Actor.loopWhile(!done) {
val parent = self
actor {
val testFile = getNextFile()
- updateTimerTask(parent ! Timeout(testFile))
-
- val context =
- try processSingleFile(testFile)
- catch {
- case t: Throwable =>
- NestUI.verbose("while invoking compiler ("+files+"):")
- NestUI.verbose("caught "+t)
- t.printStackTrace
- if (t.getCause != null)
- t.getCause.printStackTrace
- LogContext(null, None)
- }
- parent ! Result(testFile, context)
+ if (testFile == null) done = true
+ else {
+ updateTimerTask(parent ! Timeout(testFile))
+
+ val context =
+ try processSingleFile(testFile)
+ catch {
+ case t: Throwable =>
+ NestUI.shout("Caught something while invoking processSingleFile(%s)".format(testFile))
+ t.printStackTrace
+ NestUI.normal("There were " + filesRemaining.size + " files remaining: " + filesRemaining.mkString(", "))
+ LogContext(null, None)
+ }
+ parent ! Result(testFile, context)
+ }
}
react {
case res: TestResult =>
val path = res.file.getCanonicalPath
- if (status contains path) () // ignore message
+ if (status contains path) {
+ // ignore message
+ NestUI.debug("Why are we receiving duplicate messages? Received: " + res + "\nPath is " + path)
+ }
else res match {
case Timeout(_) =>
- updateStatus(path, 2)
+ updateStatus(path, TestState.Timeout)
val swr = new StringWriter
val wr = new PrintWriter(swr)
printInfoStart(res.file, wr)
- succeeded = false
- reportResult(2, None, Some((swr, wr)))
+ reportResult(TestState.Timeout, None, Some((swr, wr)))
case Result(_, logs) =>
- updateStatus(path, (if (succeeded) 0 else 1))
+ val state = if (succeeded) TestState.Ok else TestState.Fail
+ updateStatus(path, state)
reportResult(
- if (succeeded) 0 else 1,
- if (logs != null) Some(logs.file) else None,
- if (logs != null) logs.writers else None)
+ state,
+ Option(logs) map (_.file),
+ Option(logs) flatMap (_.writers)
+ )
}
if (filesRemaining.isEmpty) {
cancelTimerTask()
@@ -1107,10 +1004,10 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
}
def showLog(logFile: File) {
- try NestUI.normal(SFile(logFile).slurp())
- catch {
- case _: java.io.FileNotFoundException =>
- NestUI.failure("Couldn't open log file \""+logFile+"\".")
+ file2String(logFile) match {
+ case "" if logFile.canRead => ()
+ case "" => NestUI.failure("Couldn't open log file: " + logFile + "\n")
+ case s => NestUI.normal(s)
}
}
}
diff --git a/test/files/jvm/actor-link-getstate.scala b/test/files/jvm/actor-link-getstate.scala
index c4c33ef752..c24daf2eff 100644
--- a/test/files/jvm/actor-link-getstate.scala
+++ b/test/files/jvm/actor-link-getstate.scala
@@ -11,7 +11,7 @@ object Slave extends Actor {
loop {
react {
case 'doWork =>
- Console.err.println("Done")
+ Console.out.println("Done")
reply('done)
}
}
@@ -50,7 +50,7 @@ object Test {
Master.start()
react {
case Exit(from, reason) if (from == Slave) =>
- Console.err.println(Slave.getState)
+ Console.out.println(Slave.getState)
}
} catch {
case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] =>
diff --git a/test/files/res/bug687.check b/test/files/res/bug687.check
index ee9520d1ea..a905c3fbf0 100644
--- a/test/files/res/bug687.check
+++ b/test/files/res/bug687.check
@@ -6,6 +6,3 @@ method equals:(x$1: Any)Boolean in class Any
have same type after erasure: (o: java.lang.Object)Boolean
override def equals(o : Object) = false;
^
-
-nsc>
-nsc>
diff --git a/test/files/run/programmatic-main.scala b/test/files/run/programmatic-main.scala
index 9c7d0b7095..3a88252fd3 100644
--- a/test/files/run/programmatic-main.scala
+++ b/test/files/run/programmatic-main.scala
@@ -7,6 +7,8 @@ object Test {
val baseargs = Array("-usejavacp", "-bootclasspath", basedir + "/scala-library.jar", "-cp", basedir + "/scala-compiler.jar")
def main(args: Array[String]): Unit = {
- Main process (baseargs ++ Array("-Xshow-phases"))
+ Console.withErr(Console.out) {
+ Main process (baseargs ++ Array("-Xshow-phases"))
+ }
}
}