summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-19 22:38:16 +0000
committerPaul Phillips <paulp@improving.org>2011-01-19 22:38:16 +0000
commitc28a86006bcb7816f212da84005bd0bde4ce334b (patch)
treecaebd0744d9b819575cfcb723d0bf7f7b3f444b0 /src
parentf3711ed324ddea02873cd3aa4c9eb8d306257662 (diff)
downloadscala-c28a86006bcb7816f212da84005bd0bde4ce334b.tar.gz
scala-c28a86006bcb7816f212da84005bd0bde4ce334b.tar.bz2
scala-c28a86006bcb7816f212da84005bd0bde4ce334b.zip
More on partest.
multiple-reporting-of-failures bug. No review.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/io/Directory.scala12
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala13
-rw-r--r--src/partest-alternative/scala/tools/partest/Actions.scala46
-rw-r--r--src/partest-alternative/scala/tools/partest/Config.scala14
-rw-r--r--src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala94
-rw-r--r--src/partest/scala/tools/partest/nest/CompileManager.scala49
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleFileManager.scala1
-rw-r--r--src/partest/scala/tools/partest/nest/DirectRunner.scala51
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala3
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala154
10 files changed, 128 insertions, 309 deletions
diff --git a/src/compiler/scala/tools/nsc/io/Directory.scala b/src/compiler/scala/tools/nsc/io/Directory.scala
index 7c279a79e2..3b54f6d362 100644
--- a/src/compiler/scala/tools/nsc/io/Directory.scala
+++ b/src/compiler/scala/tools/nsc/io/Directory.scala
@@ -72,16 +72,4 @@ class Directory(jfile: JFile) extends Path(jfile) {
*/
def subdirs(depth: Int = 1): Iterator[Directory] =
deepList(depth) collect { case x: Directory => x }
-
- /** Deletes the directory recursively. Returns false on failure.
- * Use with caution!
- */
- def deleteRecursively(): Boolean = deleteRecursively(jfile)
- private def deleteRecursively(f: JFile): Boolean = {
- if (f.isDirectory) f.listFiles match {
- case null =>
- case xs => xs foreach deleteRecursively
- }
- f.delete()
- }
}
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
index b6699ce901..5b1bf5e9fa 100644
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ b/src/compiler/scala/tools/nsc/io/Path.scala
@@ -248,6 +248,19 @@ class Path private[io] (val jfile: JFile) {
// deletions
def delete() = jfile.delete()
def deleteIfExists() = if (jfile.exists()) delete() else false
+
+ /** Deletes the path recursively. Returns false on failure.
+ * Use with caution!
+ */
+ def deleteRecursively(): Boolean = deleteRecursively(jfile)
+ private def deleteRecursively(f: JFile): Boolean = {
+ if (f.isDirectory) f.listFiles match {
+ case null =>
+ case xs => xs foreach deleteRecursively
+ }
+ f.delete()
+ }
+
def truncate() =
isFile && {
val raf = new RandomAccessFile(jfile, "rw")
diff --git a/src/partest-alternative/scala/tools/partest/Actions.scala b/src/partest-alternative/scala/tools/partest/Actions.scala
index cb60152b71..30a338c68b 100644
--- a/src/partest-alternative/scala/tools/partest/Actions.scala
+++ b/src/partest-alternative/scala/tools/partest/Actions.scala
@@ -11,6 +11,7 @@ package partest
import util._
import nsc.io._
+import scala.sys.process._
trait Actions {
partest: Universe =>
@@ -43,53 +44,10 @@ trait Actions {
isDryRun || execAndLog(cmd)
}
- /** Runs <code>command</code> redirecting standard out and
- * error out to <code>output</code> file.
- */
- private def runCommandOld(command: String, output: java.io.File): Int = {
- import java.io._
- import nest.StreamAppender
-
- // 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 }
- }
-
/** Exec a process to run a command. Assumes 0 exit value is success.
* Of necessity, also treats no available exit value as success.
*/
- protected def execAndLog(cmd: String): Boolean = {
- runCommandOld(cmd, logFile.jfile) == 0
-
- // var proc: Process = null
- //
- // val result = interruptMeIn(cmd, testTimeout) {
- // loggingResult {
- // proc = Process.exec(toArgs(cmd), execEnv, execCwd.orNull, true)
- // proc.slurp()
- // }
- // proc != null && (proc.waitFor() == 0)
- // }
- // result getOrElse {
- // warning("Process never terminated: '%s'" format cmd)
- // if (proc != null)
- // proc.destroy()
- //
- // false
- // }
- }
+ protected def execAndLog(cmd: String) = (cmd #> logFile.jfile !) == 0
}
trait ScriptableTest {
diff --git a/src/partest-alternative/scala/tools/partest/Config.scala b/src/partest-alternative/scala/tools/partest/Config.scala
index 288a3034e9..d0b94dffae 100644
--- a/src/partest-alternative/scala/tools/partest/Config.scala
+++ b/src/partest-alternative/scala/tools/partest/Config.scala
@@ -71,20 +71,6 @@ trait Config {
/** Internal **/
private def repo = partestDir.parent.normalize
- // XXX - is this needed? Where?
- //
- // private val pluginOptionString = "-Xplugin:"
- // private def updatedPluginPath(options: String): String = {
- // val (pluginArgs, rest) = toArgs(options) partition (_ startsWith pluginOptionString)
- // // join all plugin paths as one classpath
- // val pluginPaths = ClassPath.join(pluginArgs map (_ stripPrefix pluginOptionString): _*)
- // // map all paths to absolute
- // val newPath = ClassPath.map(pluginPaths, x => absolutize(x).path)
- // // recreate option
- // val pluginOption = if (newPath == "") None else Some(pluginOptionString + newPath)
- //
- // fromArgs(rest ::: pluginOption.toList)
- // }
private def pathForComponent(what: String, jarFormat: String = "scala-%s.jar"): Path = {
def asDir = testBuildDir / "classes" / what
diff --git a/src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala b/src/partest-alternative/scala/tools/partest/nest/StreamAppender.scala
deleted file mode 100644
index 3d1cee95c6..0000000000
--- a/src/partest-alternative/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 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 4010f1eadd..1c91390165 100644
--- a/src/partest/scala/tools/partest/nest/CompileManager.scala
+++ b/src/partest/scala/tools/partest/nest/CompileManager.scala
@@ -17,9 +17,17 @@ import io.Path
import java.io.{ File, BufferedReader, PrintWriter, FileReader, Writer, FileWriter, StringWriter }
import File.pathSeparator
-class ExtConsoleReporter(override val settings: Settings, reader: BufferedReader, var writer: PrintWriter)
-extends ConsoleReporter(settings, reader, writer) {
- def this(settings: Settings) = this(settings, Console.in, new PrintWriter(new FileWriter("/dev/null")))
+class ExtConsoleReporter(settings: Settings, val writer: PrintWriter) extends ConsoleReporter(settings, Console.in, writer) {
+ shortname = true
+}
+
+class TestSettings(cp: String, error: String => Unit) extends Settings(error) {
+ def this(cp: String) = this(cp, _ => ())
+
+ deprecation.value = true
+ nowarnings.value = false
+ encoding.value = "ISO-8859-1"
+ classpath.value = cp
}
abstract class SimpleCompiler {
@@ -30,29 +38,18 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
def newGlobal(settings: Settings, reporter: Reporter): Global =
new Global(settings, reporter)
- def newGlobal(settings: Settings, logWriter: FileWriter): Global = {
- val rep = newReporter(settings, logWriter)
- rep.shortname = true
- newGlobal(settings, rep)
- }
+ def newGlobal(settings: Settings, logWriter: FileWriter): Global =
+ newGlobal(settings, new ExtConsoleReporter(settings, new PrintWriter(logWriter)))
- 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"
+ def newSettings(): TestSettings = new TestSettings(fileManager.LATEST_LIB)
+ def newSettings(outdir: String): TestSettings = {
+ val cp = ClassPath.join(fileManager.LATEST_LIB, outdir)
+ val s = new TestSettings(cp)
+ s.outdir.value = outdir
- val classpathElements = fileManager.LATEST_LIB :: out.toList
- settings.classpath.value = ClassPath.join(classpathElements: _*)
- out foreach (settings.outdir.value = _)
-
- settings
+ s
}
- def newReporter(sett: Settings, writer: Writer = new StringWriter) =
- new ExtConsoleReporter(sett, Console.in, new PrintWriter(writer))
-
private def updatePluginPath(options: String): String = {
val dir = fileManager.testRootDir
def absolutize(path: String) = Path(path) match {
@@ -68,7 +65,10 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
}
def compile(out: Option[File], files: List[File], kind: String, log: File): Boolean = {
- val testSettings = newSettings(out map (_.getAbsolutePath))
+ val testSettings = out match {
+ case Some(f) => newSettings(f.getAbsolutePath)
+ case _ => newSettings()
+ }
val logWriter = new FileWriter(log)
// check whether there is a ".flags" file
@@ -106,7 +106,6 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
}
testRep.printSummary
- testRep.writer.flush
testRep.writer.close
}
finally logWriter.close()
@@ -147,7 +146,7 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
// }
class CompileManager(val fileManager: FileManager) {
- var compiler: SimpleCompiler = new /*ReflectiveCompiler*/ DirectCompiler(fileManager)
+ var compiler: SimpleCompiler = new DirectCompiler(fileManager)
var numSeparateCompilers = 1
def createSeparateCompiler() = {
diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
index e108db0c97..19896af402 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
@@ -12,7 +12,6 @@ import java.io.{ File, FilenameFilter, IOException, StringWriter }
import java.net.URI
import scala.util.Properties.{ propOrElse, scalaCmd, scalacCmd }
import scala.tools.util.PathResolver
-import scala.tools.nsc.{ Settings }
import scala.tools.nsc.{ io, util }
import util.{ ClassPath }
import io.{ Path, Directory }
diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala
index 52bdb10b54..72fdb7c9e3 100644
--- a/src/partest/scala/tools/partest/nest/DirectRunner.scala
+++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala
@@ -13,7 +13,7 @@ import java.util.StringTokenizer
import scala.util.Properties.{ setProp }
import scala.tools.util.Signallable
import scala.tools.nsc.util.ScalaClassLoader
-import scala.tools.nsc.io.Directory
+import scala.tools.nsc.io.Path
import scala.collection.{ mutable, immutable }
import scala.actors.Actor._
import scala.actors.TIMEOUT
@@ -36,30 +36,6 @@ trait DirectRunner {
}
}
- /** These things, formerly inside runTestsForFiles, have been promoted
- * into private fields so I can inspect them via signal when partest shows
- * signs of dementia.
- */
- private var workers: List[Worker] = Nil
- private var logsToDelete: List[File] = Nil
- private var outdirsToDelete: List[File] = Nil
- private val results = new mutable.HashMap[String, Int]()
- private def addResults(kvs: Traversable[(String, Int)]) = synchronized { results ++= kvs }
- private val signallable = Signallable("HUP", "Make partest dump its state.")(dumpState())
-
- def dumpState() {
- println("Dumping partest internals.")
- println("results.size = " + results.size + ", " + workers.size + " workers.")
- workers foreach println
- workers filter (_.currentFileElapsed > 60) foreach { w =>
- val elapsed = w.currentFileElapsed
- println("A worker requires euthanasia! At least so it seems, since I received")
- println("a signal and this one has been in la-la land for " + elapsed + " seconds.")
- println("Attempting to force test timeout.")
- w.forceTimeout()
- }
- }
-
def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, Int] = {
/** NO DUPLICATES, or partest will blow the count and hang forever. */
val kindFiles = _kindFiles.distinct
@@ -73,36 +49,21 @@ trait DirectRunner {
)
Output.init
- this.workers = kindFiles.grouped(groupSize).toList map { toTest =>
+ val workers = kindFiles.grouped(groupSize).toList map { toTest =>
val worker = new Worker(fileManager, TestRunParams(scalaCheckParentClassLoader))
worker.start()
worker ! RunTests(kind, toTest)
worker
}
- workers foreach { w =>
+ workers map { w =>
receiveWithin(3600 * 1000) {
- case Results(res, logs, outdirs) =>
- logsToDelete ++= logs
- outdirsToDelete ++= outdirs
- addResults(res)
+ case Results(testResults) => testResults
case TIMEOUT =>
// add at least one failure
NestUI.verbose("worker timed out; adding failed test")
- addResults(Seq(("worker timed out; adding failed test" -> 2)))
+ Map("worker timed out; adding failed test" -> 2)
}
- }
-
- if (isPartestDebug)
- fileManager.showTestTimings()
- else {
- for (x <- logsToDelete ++ outdirsToDelete) {
- NestUI.verbose("deleting "+x)
- Directory(x).deleteRecursively()
- }
- }
-
- results.toMap
+ } reduceLeft (_ ++ _)
}
-
}
diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala
index 5689c71134..1f19fc460c 100644
--- a/src/partest/scala/tools/partest/nest/FileManager.scala
+++ b/src/partest/scala/tools/partest/nest/FileManager.scala
@@ -14,6 +14,7 @@ import java.io.{File, FilenameFilter, IOException, StringWriter,
import java.net.URI
import scala.tools.nsc.io.{ Path, Directory, File => SFile }
import scala.collection.mutable.HashMap
+import sys.process._
trait FileManager {
/**
@@ -96,7 +97,7 @@ trait FileManager {
}
}
- def mapFile(file: File, suffix: String, dir: File, replace: String => String) {
+ def mapFile(file: File, replace: String => String) {
val f = SFile(file)
f.printlnAll(f.lines.toList map replace: _*)
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index ad09baae23..52059d7f56 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -27,7 +27,7 @@ import scala.tools.nsc.interactive.{ BuildManager, RefinedBuildManager }
import scala.sys.process._
case class RunTests(kind: String, files: List[File])
-case class Results(results: Map[String, Int], logs: List[File], outdirs: List[File])
+case class Results(results: Map[String, Int])
class LogContext(val file: File, val writers: Option[(StringWriter, PrintWriter)])
@@ -92,7 +92,10 @@ object Output {
redirVar.value = Some(newstream)
try func
- finally redirVar.value = saved
+ finally {
+ newstream.flush()
+ redirVar.value = saved
+ }
}
}
@@ -110,7 +113,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
else
fileManager.JAVAC_CMD
- private var currentTimerTask: KickableTimerTask = _
def cancelTimerTask() = if (currentTimerTask != null) currentTimerTask.cancel()
def updateTimerTask(body: => Unit) = {
@@ -130,13 +132,35 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
/** Formerly deeper inside, these next few things are now promoted outside so
* I can see what they're doing when the world comes to a premature stop.
*/
- private val filesRemaining = new mutable.HashSet[File]
- private var currentTestFile: File = _
+ private var filesRemaining: List[File] = Nil
+ private val toDelete = new mutable.HashSet[File]
+ private val status = new mutable.HashMap[String, Int]
+
+ private var currentTimerTask: KickableTimerTask = _
private var currentFileStart: Long = System.currentTimeMillis
- private val logsToDelete = new mutable.HashSet[File]
+ private var currentTestFile: File = _
+
+ private def compareFiles(f1: File, f2: File): String =
+ try fileManager.compareFiles(f1, f2)
+ catch { case t => t.toString }
+
+ // maps canonical file names to the test result (0: OK, 1: FAILED, 2: TIMOUT)
+ private def updateStatus(key: String, num: Int) = status(key) = num
+
+ private def cleanup() {
+ toDelete foreach (_.deleteRecursively())
+ toDelete.clear()
+ }
+ sys addShutdownHook cleanup()
- private def addFilesRemaining(xs: Traversable[File]) = synchronized { filesRemaining ++= xs }
- private def addLogToDelete(f: File) = synchronized { logsToDelete += f }
+ private def resetAll() {
+ cancelTimerTask()
+ filesRemaining = Nil
+ cleanup()
+ status.clear()
+ currentTestFile = null
+ currentTimerTask = null
+ }
def currentFileElapsed = (System.currentTimeMillis - currentFileStart) / 1000
def forceTimeout() = {
@@ -152,13 +176,10 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
/** 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('\\', '/')
+ val base = (dir.getAbsolutePath + File.separator).replace('\\', '/')
+ s.replace('\\', '/').replaceAll("""\Q%s\E""" format base, "")
}
private def currentFileString = {
@@ -175,15 +196,12 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
}
else {
currentTestFile = filesRemaining.head
- filesRemaining -= currentTestFile
+ filesRemaining = filesRemaining.tail
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]
- private def updateStatus(key: String, num: Int) = status(key) = num
override def toString = (
">> Partest Worker in state " + getState + ":\n" +
@@ -201,10 +219,10 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
def act() {
react {
case RunTests(kind, files) =>
- //NestUI.normal("received "+files.length+" to test")
val master = sender
runTests(kind, files) { results =>
- master ! Results(results, createdLogFiles, createdOutputDirs)
+ master ! Results(results.toMap)
+ resetAll()
}
}
}
@@ -237,20 +255,16 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
NestUI.normal("]\n", printer)
}
- var log = ""
- var createdLogFiles: List[File] = Nil
- var createdOutputDirs: List[File] = Nil
-
- def createLogFile(file: File, kind: String): File = {
- val logFile = fileManager.getLogFile(file, kind)
- createdLogFiles ::= logFile
- logFile
+ def createLogFile(file: File, kind: String) = {
+ val f = fileManager.getLogFile(file, kind)
+ toDelete += f // add it now to avoid leaving a mess on ctrl-C ; remove if test fails
+ f
}
def createOutputDir(dir: File, fileBase: String, kind: String): File = {
val outDir = Path(dir) / Directory("%s-%s.obj".format(fileBase, kind))
outDir.createDirectory()
- createdOutputDirs ::= outDir.jfile
+ toDelete += outDir.jfile
outDir.jfile
}
@@ -323,10 +337,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
) mkString " "
runCommand(cmd, logFile)
-
- if (fileManager.showLog)
- // produce log as string in `log`
- log = SFile(logFile).slurp()
}
def getCheckFile(dir: File, fileBase: String, kind: String) = {
@@ -343,7 +353,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// if check file exists, compare with log file
getCheckFile(dir, fileBase, kind) match {
case Some(f) =>
- val diff = fileManager.compareFiles(logFile, f.jfile)
+ val diff = compareFiles(logFile, f.jfile)
if (diff != "" && fileManager.updateCheck) {
NestUI.verbose("output differs from log file: updating checkfile\n")
f.toFile writeAll file2String(logFile)
@@ -388,17 +398,18 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val compileMgr = new CompileManager(fileManager)
if (kind == "scalacheck") fileManager.CLASSPATH += File.pathSeparator + PathSettings.scalaCheck
+ filesRemaining = files
+
// You don't default "succeeded" to true.
var succeeded = false
+ var done = filesRemaining.isEmpty
var errors = 0
var diff = ""
- var log = ""
def initNextTest() = {
val swr = new StringWriter
- val wr = new PrintWriter(swr)
+ val wr = new PrintWriter(swr, true)
diff = ""
- log = ""
((swr, wr))
}
@@ -530,7 +541,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
NestUI.verbose("compilation of "+file+" succeeded\n")
val outURL = outDir.getCanonicalFile.toURI.toURL
- val logWriter = new PrintStream(new FileOutputStream(logFile))
+ val logWriter = new PrintStream(new FileOutputStream(logFile), true)
Output.withRedirected(logWriter) {
// this classloader is test specific: its parent contains library classes and others
@@ -592,7 +603,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
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")
@@ -617,9 +627,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val sourcepath = outDir.getAbsolutePath+File.separator
// configure input/output files
- val logWriter = new PrintStream(new FileOutputStream(logFile))
+ val logWriter = new PrintStream(new FileOutputStream(logFile), true)
val testReader = new BufferedReader(new FileReader(testFile))
- val logConsoleWriter = new PrintWriter(logWriter)
+ val logConsoleWriter = new PrintWriter(logWriter, true)
// create proper settings for the compiler
val settings = new Settings(workerError)
@@ -637,7 +647,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
new BuilderGlobal(settings, reporter)
}
- val testCompile: String => Boolean = { line =>
+ def testCompile(line: String): Boolean = {
NestUI.verbose("compiling " + line)
val args = (line split ' ').toList
val command = new CompilerCommand(args, settings)
@@ -698,9 +708,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
try loop()
finally testReader.close()
}
- fileManager.mapFile(logFile, "tmp", file, _.replace(sourcepath, "").
- replaceAll(java.util.regex.Matcher.quoteReplacement("\\"), "/"))
-
+ fileManager.mapFile(logFile, replaceSlashes(new File(sourcepath), _))
diffCheck(compareOutput(file, fileBase, kind, logFile))
}
LogContext(logFile, swr, wr)
@@ -716,8 +724,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// when option "--failed" is provided
// execute test only if log file is present
// (which means it failed before)
-
- //val (logFileOut, logFileErr) = createLogFiles(file, kind)
val logFile = createLogFile(file, kind)
if (!fileManager.failed || logFile.canRead) {
val (swr, wr) = initNextTest()
@@ -727,7 +733,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
NestUI.verbose(this+" running test "+fileBase)
val dir = file.getParentFile
val outDir = createOutputDir(dir, fileBase, kind)
- if (!outDir.exists) outDir.mkdir()
val resFile = new File(dir, fileBase + ".res")
NestUI.verbose("outDir: "+outDir)
NestUI.verbose("logFile: "+logFile)
@@ -748,9 +753,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
// configure input/output files
val logOut = new FileOutputStream(logFile)
- val logWriter = new PrintStream(logOut)
+ val logWriter = new PrintStream(logOut, true)
val resReader = new BufferedReader(new FileReader(resFile))
- val logConsoleWriter = new PrintWriter(new OutputStreamWriter(logOut))
+ val logConsoleWriter = new PrintWriter(new OutputStreamWriter(logOut), true)
// create compiler
val settings = new Settings(workerError)
@@ -785,7 +790,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
try loop(resCompile)
finally resReader.close()
}
- fileManager.mapFile(logFile, "tmp", dir, replaceSlashes(dir, _))
+ fileManager.mapFile(logFile, replaceSlashes(dir, _))
diffCheck(compareOutput(dir, fileBase, kind, logFile))
LogContext(logFile, swr, wr)
} else
@@ -805,7 +810,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
NestUI.verbose(this+" running test "+fileBase)
val dir = file.getParentFile
val outDir = createOutputDir(dir, fileBase, kind)
- if (!outDir.exists) outDir.mkdir()
// 2. define file {outDir}/test.scala that contains code to compile/run
val testFile = new File(outDir, "test.scala")
@@ -869,7 +873,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val result = scala.tools.scalap.Main.decompileScala(byteCode.bytes, isPackageObject)
SFile(logFile) writeAll result
- diffCheck(fileManager.compareFiles(logFile, resFile))
+ diffCheck(compareFiles(logFile, resFile))
}
}
})
@@ -932,12 +936,11 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
val isTimeout = state == TestState.Timeout
val hasLog = logFile != null
- // delete log file only if test was successful
- if (isGood && hasLog) {
- if (!isPartestDebug)
- addLogToDelete(logFile)
- }
- else {
+ if (!isGood) {
+ // remove logfile from deletion list if failed
+ if (hasLog)
+ toDelete -= logFile
+
errors += 1
NestUI.verbose("incremented errors: "+errors)
}
@@ -953,33 +956,38 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
if (isFail && fileManager.showLog && hasLog)
showLog(logFile)
}
+ cleanup()
}
- if (files.isEmpty) reportAll(Map(), topcont)
- else addFilesRemaining(files)
-
- var done = false
+ def finish() = {
+ done = true
+ cancelTimerTask()
+ reportAll(status.toMap, topcont)
+ }
Actor.loopWhile(!done) {
val parent = self
actor {
val testFile = getNextFile()
- if (testFile == null) {
- done = true
- cancelTimerTask()
- reportAll(status.toMap, topcont)
- }
+
+ if (testFile == null)
+ finish()
else {
updateTimerTask(parent ! Timeout(testFile))
val context =
try processSingleFile(testFile)
catch {
- case t: Throwable =>
- val logFile = createLogFile(testFile, kind)
- logStackTrace(logFile, t, "Possible compiler crash during test of: " + testFile)
- LogContext(logFile)
+ case t =>
+ try {
+ val logFile = createLogFile(testFile, kind)
+ logStackTrace(logFile, t, "Possible compiler crash during test of: " + testFile + "\n")
+ LogContext(logFile)
+ }
+ catch {
+ case t => LogContext(null)
+ }
}
parent ! Result(testFile, context)
}
@@ -989,7 +997,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
case Timeout(file) =>
updateStatus(file.getCanonicalPath, TestState.Timeout)
val swr = new StringWriter
- val wr = new PrintWriter(swr)
+ val wr = new PrintWriter(swr, true)
printInfoStart(file, wr)
reportResult(
TestState.Timeout,