summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-12 06:17:22 +0000
committerPaul Phillips <paulp@improving.org>2011-01-12 06:17:22 +0000
commit2263afdf115a9a499762ff60fa876c77eccfabc8 (patch)
treedf70c413e5a444713cd67718d69f0f4ead570f07
parent2e7d7d45557474df61d54e672bedf07a8ff149d4 (diff)
downloadscala-2263afdf115a9a499762ff60fa876c77eccfabc8.tar.gz
scala-2263afdf115a9a499762ff60fa876c77eccfabc8.tar.bz2
scala-2263afdf115a9a499762ff60fa876c77eccfabc8.zip
Some fixes for partest issues.
prejudice and puts the new process code to work instead. There are still a couple bugs on my short term partest list. If this commit causes some weird issue which only arises on virtualized windows you can expect to hear from me next by postcard from st. lucia. No review.
-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"))
+ }
}
}