summaryrefslogtreecommitdiff
path: root/src/partest
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-01-24 22:57:30 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-01-24 22:57:30 +0000
commite4e513079f2662758a0737a2a9a28abbcf1c9f7e (patch)
treebab62ecec0ba2bc9f0cbc76ca8d5af0deea28a8d /src/partest
parent7140e9c3ad9c60a0a55aee63ecd20940534375d4 (diff)
downloadscala-e4e513079f2662758a0737a2a9a28abbcf1c9f7e.tar.gz
scala-e4e513079f2662758a0737a2a9a28abbcf1c9f7e.tar.bz2
scala-e4e513079f2662758a0737a2a9a28abbcf1c9f7e.zip
Added new target for partest for testing Build ...
Added new target for partest for testing Build Manager behaviour. Updated Refined Build Manager for consistency. --buildmanager requires the test file that describes actions to be done on the refined build manager (compiling files, making changes to the classes), sources of changes, the check file and the initial scala source files. Cleaned up some code in partest, refactored some obvious code duplication. Tests to follow... Review by phaller.
Diffstat (limited to 'src/partest')
-rw-r--r--src/partest/README1
-rw-r--r--src/partest/scala/tools/partest/PartestTask.scala23
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunner.scala10
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala43
-rw-r--r--src/partest/scala/tools/partest/nest/NestUI.scala17
-rw-r--r--src/partest/scala/tools/partest/nest/TestFile.scala8
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala277
7 files changed, 280 insertions, 99 deletions
diff --git a/src/partest/README b/src/partest/README
index 430a2987f8..27159ca078 100644
--- a/src/partest/README
+++ b/src/partest/README
@@ -24,6 +24,7 @@ Other arguments:
* --run next files test the interpreter and all backends
* --jvm next files test the JVM backend
* --res next files test the resident compiler
+ * --buildmanager next files test the build manager
* --shootout next files are shootout tests
* --script next files test the script runner
* ''-Dscalatest.scalac_opts=...'' -> add compiler options
diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala
index 59781b0aa2..d97adfa166 100644
--- a/src/partest/scala/tools/partest/PartestTask.scala
+++ b/src/partest/scala/tools/partest/PartestTask.scala
@@ -40,6 +40,10 @@ class PartestTask extends Task {
residentFiles = Some(input)
}
+ def addConfiguredBuildManagerTests(input: FileSet) {
+ buildManagerFiles = Some(input)
+ }
+
def addConfiguredScriptTests(input: FileSet) {
scriptFiles = Some(input)
}
@@ -111,6 +115,7 @@ class PartestTask extends Task {
private var runFiles: Option[FileSet] = None
private var jvmFiles: Option[FileSet] = None
private var residentFiles: Option[FileSet] = None
+ private var buildManagerFiles: Option[FileSet] = None
private var scriptFiles: Option[FileSet] = None
private var shootoutFiles: Option[FileSet] = None
private var scalapFiles: Option[FileSet] = None
@@ -144,14 +149,15 @@ class PartestTask extends Task {
else
Array()
- private def getPosFiles = getFilesAndDirs(posFiles)
- private def getNegFiles = getFilesAndDirs(negFiles)
- private def getRunFiles = getFiles(runFiles)
- private def getJvmFiles = getFilesAndDirs(jvmFiles)
- private def getResidentFiles = getFiles(residentFiles)
- private def getScriptFiles = getFiles(scriptFiles)
- private def getShootoutFiles = getFiles(shootoutFiles)
- private def getScalapFiles = getFiles(scalapFiles)
+ private def getPosFiles = getFilesAndDirs(posFiles)
+ private def getNegFiles = getFilesAndDirs(negFiles)
+ private def getRunFiles = getFiles(runFiles)
+ private def getJvmFiles = getFilesAndDirs(jvmFiles)
+ private def getResidentFiles = getFiles(residentFiles)
+ private def getBuildManagerFiles = getFiles(buildManagerFiles)
+ private def getScriptFiles = getFiles(scriptFiles)
+ private def getShootoutFiles = getFiles(shootoutFiles)
+ private def getScalapFiles = getFiles(scalapFiles)
override def execute() {
if (debug)
@@ -220,6 +226,7 @@ class PartestTask extends Task {
(getRunFiles, "run", "Compiling and running files"),
(getJvmFiles, "jvm", "Compiling and running files"),
(getResidentFiles, "res", "Running resident compiler scenarii"),
+ (getBuildManagerFiles, "buildmanager", "Running Build Manager scenarii"),
(getScriptFiles, "script", "Running script files"),
(getShootoutFiles, "shootout", "Running shootout tests"),
(getScalapFiles, "scalap", "Running scalap tests")
diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
index 574cc70762..94b1d6c684 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
@@ -24,12 +24,13 @@ class ConsoleRunner extends DirectRunner with RunnerUtils {
List(
TestSet("pos", fileFilter, "pos",
"Testing compiler (on files whose compilation should succeed)"),
- TestSet("neg", fileFilter, "neg",
+ TestSet("neg", fileFilter, "neg",
"Testing compiler (on files whose compilation should fail)"),
- TestSet("run", fileFilter, "run", "Testing JVM backend"),
- TestSet("jvm", fileFilter, "jvm", "Testing JVM backend"),
- TestSet("res", Some((".res", false)), "res",
+ TestSet("run", fileFilter, "run", "Testing JVM backend"),
+ TestSet("jvm", fileFilter, "jvm", "Testing JVM backend"),
+ TestSet("res", Some((".res", false)), "res",
"Testing resident compiler"),
+ TestSet("buildmanager", Some((".nothing", true)), "buildmanager", "Testing Build Manager"),
TestSet("shootout", fileFilter, "shootout", "Testing shootout tests"),
TestSet("script", fileFilter, "script", "Testing script tests"),
TestSet("scalacheck", fileFilter, "scalacheck", "Testing ScalaCheck tests"),
@@ -210,6 +211,7 @@ class ConsoleRunner extends DirectRunner with RunnerUtils {
case "sho" => "shootout"
case "scr" => "script"
case "sca" => "scalacheck"
+ case "bui" => "buildmanager"
}
}
}
diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala
index 637999cc36..df7a8e129c 100644
--- a/src/partest/scala/tools/partest/nest/FileManager.scala
+++ b/src/partest/scala/tools/partest/nest/FileManager.scala
@@ -8,7 +8,9 @@
package scala.tools.partest
package nest
-import java.io.{File, FilenameFilter, IOException, StringWriter}
+import java.io.{File, FilenameFilter, IOException, StringWriter,
+ FileInputStream, FileOutputStream, BufferedReader,
+ FileReader, PrintWriter, FileWriter}
import java.net.URI
import scala.tools.nsc.io.Directory
@@ -76,4 +78,43 @@ trait FileManager {
val logFile = getLogFile(file, kind)
logFile.exists && logFile.canRead
}
+
+ def overwriteFileWith(dest: File, file: File): Boolean =
+ if (dest.exists && dest.isFile)
+ copyFile(file, dest)
+ else
+ false
+
+ def copyFile(from: File, to: File): Boolean =
+ try {
+ val fromReader = new BufferedReader(new FileReader(from))
+ val toWriter = new PrintWriter(new FileWriter(to))
+
+ new StreamAppender(fromReader, toWriter).run()
+
+ fromReader.close()
+ toWriter.close()
+ 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 fileReader = new BufferedReader(new FileReader(file))
+ val tmpFilePrinter = new PrintWriter(new FileWriter(tmpFile))
+ val appender = new StreamAppender(fileReader, tmpFilePrinter)
+
+ appender.runAndMap(replace)
+
+ fileReader.close()
+ tmpFilePrinter.close()
+
+ val tmpFileReader = new BufferedReader(new FileReader(tmpFile))
+ val filePrinter= new PrintWriter(new FileWriter(file), true)
+ (new StreamAppender(tmpFileReader, filePrinter)).run
+ tmpFileReader.close()
+ filePrinter.close()
+ tmpFile.delete()
+ }
}
diff --git a/src/partest/scala/tools/partest/nest/NestUI.scala b/src/partest/scala/tools/partest/nest/NestUI.scala
index b8d77bc704..5fe10ce271 100644
--- a/src/partest/scala/tools/partest/nest/NestUI.scala
+++ b/src/partest/scala/tools/partest/nest/NestUI.scala
@@ -70,14 +70,15 @@ object NestUI {
println(" <options>:")
println
println(" Test categories:")
- println(" --all run all tests")
- println(" --pos run compilation tests (success)")
- println(" --neg run compilation tests (failure)")
- println(" --run run interpreter and backend tests")
- println(" --jvm run JVM backend tests")
- println(" --res run resident compiler tests")
- println(" --script run script runner tests")
- println(" --shootout run shootout tests")
+ println(" --all run all tests")
+ println(" --pos run compilation tests (success)")
+ println(" --neg run compilation tests (failure)")
+ println(" --run run interpreter and backend tests")
+ println(" --jvm run JVM backend tests")
+ println(" --res run resident compiler tests")
+ println(" --buildmanager run Build Manager tests")
+ println(" --script run script runner tests")
+ println(" --shootout run shootout tests")
println
println(" Other options:")
println(" --pack pick compiler/library in build/pack, and run all tests")
diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala
index 7ffe11e5b6..5a62beb48d 100644
--- a/src/partest/scala/tools/partest/nest/TestFile.scala
+++ b/src/partest/scala/tools/partest/nest/TestFile.scala
@@ -74,6 +74,14 @@ case class RunTestFile(override val file: File, override val fileManager: FileMa
}
}
+case class BuildManagerTestFile(override val file: File, override val fileManager: FileManager, createOutDir: Boolean) extends TestFile("bm", file, fileManager, createOutDir) {
+ override def defineSettings(settings: Settings) {
+ baseSettings(settings)
+ settings.classpath.value = settings.classpath.value+
+ File.pathSeparator+fileManager.CLASSPATH
+ }
+}
+
case class ScalaCheckTestFile(override val file: File, override val fileManager: FileManager, createOutDir: Boolean) extends TestFile("scalacheck", file, fileManager, createOutDir) {
override def defineSettings(settings: Settings) {
baseSettings(settings)
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index 37a98860ad..be0a2c606d 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -19,8 +19,12 @@ import scala.actors.{Actor, Exit, TIMEOUT}
import scala.actors.Actor._
import scala.tools.scalap.scalax.rules.scalasig.{ByteCode, ClassFileParser, ScalaSigAttributeParsers}
+import io.{AbstractFile, PlainFile}
+
import scala.collection.mutable.HashMap
+import scala.tools.nsc.interactive.{BuildManager, RefinedBuildManager}
+
case class RunTests(kind: String, files: List[File])
case class Results(succ: Int, fail: Int, logs: List[LogFile], outdirs: List[File])
case class LogContext(file: LogFile, writers: Option[(StringWriter, PrintWriter)])
@@ -136,32 +140,13 @@ class Worker(val fileManager: FileManager) extends Actor {
// grab global lock
fileManager.synchronized {
-
- val oldStdOut = System.out
- val oldStdErr = System.err
- System.setOut(logWriter)
- System.setErr(logWriter)
-
- /*
- " -Djava.library.path="+logFile.getParentFile.getAbsolutePath+
- " -Dscalatest.output="+outDir.getAbsolutePath+
- " -Dscalatest.lib="+LATEST_LIB+
- " -Dscalatest.cwd="+outDir.getParent+
- " -Djavacmd="+JAVACMD+
- */
-
- System.setProperty("java.library.path", logFile.getParentFile.getCanonicalFile.getAbsolutePath)
- System.setProperty("scalatest.output", outDir.getCanonicalFile.getAbsolutePath)
- System.setProperty("scalatest.lib", LATEST_LIB)
- System.setProperty("scalatest.cwd", outDir.getParent)
-
- ObjectRunner.run(classpath, "Test", List("jvm"))
-
- logWriter.flush()
- logWriter.close()
-
- System.setOut(oldStdOut)
- System.setErr(oldStdErr)
+ withOutputRedirected(logWriter) {
+ System.setProperty("java.library.path", logFile.getParentFile.getCanonicalFile.getAbsolutePath)
+ System.setProperty("scalatest.output", outDir.getCanonicalFile.getAbsolutePath)
+ System.setProperty("scalatest.lib", LATEST_LIB)
+ System.setProperty("scalatest.cwd", outDir.getParent)
+ ObjectRunner.run(classpath, "Test", List("jvm"))
+ }
}
/*val out = new FileOutputStream(logFile, true)
@@ -475,20 +460,11 @@ class Worker(val fileManager: FileManager) extends Actor {
List(outURL, scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL,
latestActFile.toURI.toURL, latestPartestFile.toURI.toURL).removeDuplicates
- // XXX this is a big cut-and-paste mess, but the revamp is coming
- val logOut = new FileOutputStream(logFile)
- val logWriter = new PrintStream(logOut)
- val oldStdOut = System.out
- val oldStdErr = System.err
- System.setOut(logWriter)
- System.setErr(logWriter)
-
- ObjectRunner.run(classpath, "Test", Nil)
+ val logWriter = new PrintStream(new FileOutputStream(logFile))
- logWriter.flush()
- logWriter.close()
- System.setOut(oldStdOut)
- System.setErr(oldStdErr)
+ withOutputRedirected(logWriter) {
+ ObjectRunner.run(classpath, "Test", Nil)
+ }
NestUI.verbose(io.File(logFile).slurp())
// obviously this must be improved upon
@@ -535,6 +511,143 @@ class Worker(val fileManager: FileManager) extends Actor {
case "jvm" =>
runJvmTest(file, kind)
+ case "buildmanager" =>
+ val logFile = createLogFile(file, kind)
+ if (!fileManager.failed || (logFile.exists && logFile.canRead)) {
+ val swr = new StringWriter
+ val wr = new PrintWriter(swr)
+ succeeded = true; diff = ""
+ 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.exists && !changesDir.isDirectory) {
+ // if changes exists then it has to be a dir
+ succeeded = false
+ (null, null, null, null)
+ } else {
+ copyTestFiles(file, outDir)
+ NestUI.verbose("outDir: "+outDir)
+ NestUI.verbose("logFile: "+logFile)
+ (outDir, testFile, changesDir, fileBase)
+ }
+ }
+
+ if (succeeded) {
+ // Pre-conditions satisfied
+
+ try {
+ val sourcepath = outDir.getAbsolutePath+File.separator
+
+ // configure input/output files
+ val logWriter = new PrintStream(new FileOutputStream(logFile))
+ val testReader = new BufferedReader(new FileReader(testFile))
+ //val logConsoleWriter = new PrintWriter(new OutputStreamWriter(logOut))
+ val logConsoleWriter = new PrintWriter(logWriter)
+
+ // create proper settings for the compiler
+ val settings = new Settings(error)
+ settings.outdir.value = outDir.getCanonicalFile.getAbsolutePath
+ settings.sourcepath.value = sourcepath
+ settings.classpath.value = fileManager.CLASSPATH
+
+ // simulate Build Manager loop
+ val prompt = "builder > "
+ reporter = new ConsoleReporter(settings, scala.Console.in, logConsoleWriter)
+ val bM: BuildManager =
+ new RefinedBuildManager(settings) {
+ override protected def newCompiler(settings: Settings) =
+ new BuilderGlobal(settings, reporter)
+ }
+
+ val testCompile = (line: String) => {
+ NestUI.verbose("compiling " + line)
+ val args = (line split ' ').toList
+ val command = new CompilerCommand(args, settings, error, true)
+ bM.update(filesToSet(settings.sourcepath.value, command.files), Set.empty)
+ !reporter.hasErrors
+ }
+
+ val updateFiles = (line: String) => {
+ NestUI.verbose("updating " + line)
+ val res =
+ ((line split ' ').toList).forall(u => {
+ (u split "=>").toList match {
+ case origFileName::(newFileName::Nil) =>
+ val newFile = new File(changesDir, newFileName)
+ if (newFile.exists && newFile.isFile) {
+ val v = overwriteFileWith(new File(outDir, origFileName), newFile)
+ if (!v)
+ NestUI.verbose("'update' operation on " + u + " failed")
+ v
+ } else {
+ NestUI.verbose("File " + newFile + " is invalid")
+ false
+ }
+ case a =>
+ NestUI.verbose("Other =: " + a)
+ false
+ }
+ })
+ if (!res)
+ NestUI.verbose("updating failed")
+ else
+ NestUI.verbose("updating succeeded")
+ 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
+ }
+
+ if (commandResult) loop()
+
+ } else {
+ NestUI.verbose("finished")
+ succeeded = true
+ }
+ }
+
+ withOutputRedirected(logWriter) {
+ loop()
+ testReader.close()
+ }
+
+ fileManager.mapFile(logFile, "tmp", file, {s => s.replace(sourcepath, "")})
+
+ diff = compareOutput(file, fileBase, kind, logFile)
+ if (!diff.equals("")) {
+ NestUI.verbose("output differs from log file\n")
+ succeeded = false
+ }
+
+ }
+ LogContext(logFile, Some((swr, wr)))
+ } else
+ LogContext(logFile, None)
+ } else
+ LogContext(logFile, None)
+
case "res" => {
// when option "--failed" is provided
// execute test only if log file is present
@@ -632,48 +745,25 @@ class Worker(val fileManager: FileManager) extends Actor {
loop(action)
}
}
- val oldStdOut = System.out
- val oldStdErr = System.err
- System.setOut(logWriter)
- System.setErr(logWriter)
- loop(resCompile)
- resReader.close()
- logWriter.flush()
- logWriter.close()
-
- System.setOut(oldStdOut)
- System.setErr(oldStdErr)
-
- val tempLogFile = new File(dir, fileBase+".temp.log")
- val logFileReader = new BufferedReader(new FileReader(logFile))
- val tempLogFilePrinter = new PrintWriter(new FileWriter(tempLogFile))
- val appender =
- new StreamAppender(logFileReader, tempLogFilePrinter)
-
- // function that removes a given string from another string
- def removeFrom(line: String, path: String): String = {
- // find `path` in `line`
- val index = line.indexOf(path)
- if (index != -1) {
- line.substring(0, index) + line.substring(index + path.length, line.length)
- } else line
- }
- appender.runAndMap({ s =>
- val woPath = removeFrom(s, dir.getAbsolutePath/*.replace(File.separatorChar,'/')*/+File.separator)
- // now replace single '\' with '/'
- woPath.replace('\\', '/')
- })
- logFileReader.close()
- tempLogFilePrinter.close()
+ withOutputRedirected(logWriter) {
+ loop(resCompile)
+ resReader.close()
+ }
- val tempLogFileReader = new BufferedReader(new FileReader(tempLogFile))
- val logFilePrinter= new PrintWriter(new FileWriter(logFile), true)
- (new StreamAppender(tempLogFileReader, logFilePrinter)).run
- tempLogFileReader.close()
- logFilePrinter.close()
+ def replaceSlashes(s: String): String = {
+ val path = dir.getAbsolutePath/*.replace(File.separatorChar,'/')*/+
+ 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('\\', '/')
+ }
- tempLogFile.delete()
+ fileManager.mapFile(logFile, "tmp", dir, replaceSlashes)
diff = compareOutput(dir, fileBase, kind, logFile)
if (!diff.equals("")) {
@@ -982,6 +1072,37 @@ class Worker(val fileManager: FileManager) extends Actor {
}
}
+ private def withOutputRedirected(out: PrintStream)(func: => Unit) {
+ val oldStdOut = System.out
+ val oldStdErr = System.err
+
+ try {
+ System.setOut(out)
+ System.setErr(out)
+ func
+ out.flush()
+ out.close()
+ } finally {
+ System.setOut(oldStdOut)
+ System.setErr(oldStdErr)
+ }
+ }
+
+ private def filesToSet(pre: String, fs: List[String]): Set[AbstractFile] = {
+ Set.empty ++ fs.map( s => AbstractFile.getFile(pre + s)).filter(_ != null)
+ }
+
+ private def copyTestFiles(testDir: File, destDir: File) {
+ val filter =
+ new FilenameFilter {
+ def accept(dir: File, name: String) =
+ (name.endsWith(".scala") || name.endsWith(".java")) &&
+ ((new File(dir, name).isFile))
+ }
+ (testDir.listFiles(filter)).foreach( f =>
+ fileManager.copyFile(f, new File(destDir, f.getName)) )
+ }
+
def showLog(logFile: File) {
try {
val logReader = new BufferedReader(new FileReader(logFile))