From b194689adaed9bd5bf3f7e0491659da525b0be09 Mon Sep 17 00:00:00 2001 From: michelou Date: Sun, 27 Nov 2011 15:57:15 +0000 Subject: added support for ant tests to partest --- src/partest/scala/tools/partest/PartestTask.scala | 49 ++++- .../scala/tools/partest/nest/CompileManager.scala | 1 + .../scala/tools/partest/nest/ConsoleRunner.scala | 6 +- .../scala/tools/partest/nest/DirectRunner.scala | 2 +- .../scala/tools/partest/nest/TestFile.scala | 1 + src/partest/scala/tools/partest/nest/Worker.scala | 243 ++++++++++++--------- 6 files changed, 196 insertions(+), 106 deletions(-) (limited to 'src/partest') diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala index 588f87449d..a08100a33f 100644 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ b/src/partest/scala/tools/partest/PartestTask.scala @@ -6,8 +6,6 @@ ** |/ ** \* */ -// $Id$ - package scala.tools package partest @@ -25,6 +23,39 @@ import org.apache.tools.ant.Task import org.apache.tools.ant.types.{Path, Reference, FileSet} import org.apache.tools.ant.types.Commandline.Argument +/** An Ant task to execute the Scala test suite (NSC). + * + * This task can take the following parameters as attributes: + * - `srcdir`, + * - `classpath`, + * - `classpathref`, + * - `showlog`, + * - `showdiff`, + * - `erroronfailed`, + * - `javacmd`, + * - `javaccmd`, + * - `scalacopts`, + * - `timeout`, + * - `debug`, + * - `junitreportdir`. + * + * It also takes the following parameters as nested elements: + * - `compilationpath`. + * - `postests`, + * - `negtests`, + * - `runtests`, + * - `jvmtests`, + * - `residenttests`, + * - `buildmanagertests`, + * - `shootouttests`, + * - `scalaptests`, + * - `scalachecktests`, + * - `specializedtests`, + * - `presentationtests`, + * - `scripttests`. + * + * @author Philippe Haller + */ class PartestTask extends Task with CompilationPathProperty { def addConfiguredPosTests(input: FileSet) { @@ -75,6 +106,10 @@ class PartestTask extends Task with CompilationPathProperty { presentationFiles = Some(input) } + def addConfiguredAntTests(input: FileSet) { + antFiles = Some(input) + } + def setSrcDir(input: String) { srcDir = Some(input) @@ -158,6 +193,7 @@ class PartestTask extends Task with CompilationPathProperty { private var scalapFiles: Option[FileSet] = None private var specializedFiles: Option[FileSet] = None private var presentationFiles: Option[FileSet] = None + private var antFiles: Option[FileSet] = None private var errorOnFailed: Boolean = false private var scalacArgs: Option[Seq[Argument]] = None private var timeout: Option[String] = None @@ -213,6 +249,7 @@ class PartestTask extends Task with CompilationPathProperty { private def getScalapFiles = getFiles(scalapFiles) private def getSpecializedFiles = getFiles(specializedFiles) private def getPresentationFiles = getDirs(presentationFiles) + private def getAntFiles = getFiles(antFiles) override def execute() { val opts = getProject().getProperties() get "env.PARTEST_OPTS" @@ -276,7 +313,8 @@ class PartestTask extends Task with CompilationPathProperty { (getShootoutFiles, "shootout", "Running shootout tests"), (getScalapFiles, "scalap", "Running scalap tests"), (getSpecializedFiles, "specialized", "Running specialized files"), - (getPresentationFiles, "presentation", "Running presentation compiler test files") + (getPresentationFiles, "presentation", "Running presentation compiler test files"), + (getAntFiles, "ant", "Running ant task tests") ) def runSet(set: TFSet): (Int, Int, Iterable[String]) = { @@ -320,7 +358,8 @@ class PartestTask extends Task with CompilationPathProperty { f(msg) } - def oneResult(res: (String, Int)) = + + private def oneResult(res: (String, Int)) = { res._2 match { case 0 => scala.xml.NodeSeq.Empty @@ -329,7 +368,7 @@ class PartestTask extends Task with CompilationPathProperty { } } - def testReport(kind: String, results: Iterable[(String, Int)], succs: Int, fails: Int) = + private def testReport(kind: String, results: Iterable[(String, Int)], succs: Int, fails: Int) = { diff --git a/src/partest/scala/tools/partest/nest/CompileManager.scala b/src/partest/scala/tools/partest/nest/CompileManager.scala index 24eafaf456..f4ebfb7e7d 100644 --- a/src/partest/scala/tools/partest/nest/CompileManager.scala +++ b/src/partest/scala/tools/partest/nest/CompileManager.scala @@ -96,6 +96,7 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler { case "scalacheck" => ScalaCheckTestFile.apply case "specialized" => SpecializedTestFile.apply case "presentation" => PresentationTestFile.apply + case "ant" => AntTestFile.apply } val test: TestFile = testFileFn(files.head, fileManager) if (!test.defineSettings(command.settings, out.isEmpty)) { diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala index 9cc0f699de..85060ad633 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala @@ -21,7 +21,8 @@ class ConsoleRunner extends DirectRunner { import PathSettings.{ srcDir, testRoot } case class TestSet(kind: String, filter: Path => Boolean, msg: String) - def stdFilter(p: Path) = p.isDirectory || (p hasExtension "scala") + private def stdFilter(p: Path) = p.isDirectory || (p hasExtension "scala") + private def antFilter(p: Path) = p.isFile && (p endsWith "build.xml") val testSets = { val pathFilter: Path => Boolean = x => x.isDirectory || (x hasExtension "scala") @@ -38,7 +39,8 @@ class ConsoleRunner extends DirectRunner { TestSet("scalacheck", stdFilter, "Testing ScalaCheck tests"), TestSet("scalap", _.isDirectory, "Run scalap decompiler tests"), TestSet("specialized", stdFilter, "Testing specialized tests"), - TestSet("presentation", _.isDirectory, "Testing presentation compiler tests.") + TestSet("presentation", _.isDirectory, "Testing presentation compiler tests."), + TestSet("ant", antFilter, "Run Ant task tests.") ) } diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala index 811e0c46ba..78184664c2 100644 --- a/src/partest/scala/tools/partest/nest/DirectRunner.scala +++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala @@ -24,7 +24,7 @@ trait DirectRunner { import PartestDefaults.numActors - def denotesTestFile(arg: String) = Path(arg).hasExtension("scala", "res") + def denotesTestFile(arg: String) = Path(arg).hasExtension("scala", "res", "xml") def denotesTestDir(arg: String) = Path(arg).ifDirectory(_.files.nonEmpty) exists (x => x) def denotesTestPath(arg: String) = denotesTestDir(arg) || denotesTestFile(arg) diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala index f2e34ced30..9c61097cb0 100644 --- a/src/partest/scala/tools/partest/nest/TestFile.scala +++ b/src/partest/scala/tools/partest/nest/TestFile.scala @@ -66,3 +66,4 @@ case class SpecializedTestFile(file: JFile, fileManager: FileManager) extends Te } } case class PresentationTestFile(file: JFile, fileManager: FileManager) extends TestFile("presentation") +case class AntTestFile(file: JFile, fileManager: FileManager) extends TestFile("ant") diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index fb1546798a..8a6c3dd5c1 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -3,8 +3,6 @@ * @author Philipp Haller */ -// $Id$ - package scala.tools.partest package nest @@ -212,7 +210,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor status.toList.map(x => " " + x._1 + " -> " + x._2).sorted.mkString("\n") + "\n" ) - def workerError(msg: String): Unit = reporter.error( + private def workerError(msg: String): Unit = reporter.error( FakePos("scalac"), msg + "\n scalac -help gives more information" ) @@ -229,7 +227,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor } } - def printInfoStart(file: File, printer: PrintWriter) { + private def printInfoStart(file: File, printer: PrintWriter) { NestUI.outline("testing: ", printer) val filesdir = file.getAbsoluteFile.getParentFile.getParentFile val testdir = filesdir.getParentFile @@ -244,29 +242,29 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor NestUI.normal("[...]%s%s".format(name, " " * (totalWidth - name.length)), printer) } - def printInfoEnd(success: Boolean, printer: PrintWriter) { + private def printInfoEnd(success: Boolean, printer: PrintWriter) { NestUI.normal("[", printer) if (success) NestUI.success(" OK ", printer) else NestUI.failure("FAILED", printer) NestUI.normal("]\n", printer) } - def printInfoTimeout(printer: PrintWriter) { + private def printInfoTimeout(printer: PrintWriter) { NestUI.normal("[", printer) NestUI.failure("TIMOUT", printer) NestUI.normal("]\n", printer) } - def createLogFile(file: File) = fileManager.getLogFile(file, kind) + private def createLogFile(file: File) = fileManager.getLogFile(file, kind) - def createOutputDir(dir: File): File = { + private def createOutputDir(dir: File): File = { val outDir = Path(dir) / Directory("%s-%s.obj".format(fileBase, kind)) outDir.createDirectory() toDelete += outDir.jfile outDir.jfile } - def javac(outDir: File, files: List[File], output: File): Boolean = { + private def javac(outDir: File, files: List[File], output: File): Boolean = { // compile using command-line javac compiler val args = Seq( javacCmd, @@ -283,16 +281,12 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor /** Runs command redirecting standard out and * error out to output file. */ - def runCommand(args: Seq[String], outFile: File): Boolean = { + private def runCommand(args: Seq[String], outFile: File): Boolean = { NestUI.verbose("running command:\n"+args.map(" " + _ + "\n").mkString) (Process(args) #> outFile !) == 0 } - private def q(s: String) = { - val quot = "\"" - if ((s == "") || (s.head == '"')) s else quot + s + quot - } - def execTest(outDir: File, logFile: File, classpathPrefix: String = ""): Boolean = { + private def execTest(outDir: File, logFile: File, classpathPrefix: String = ""): Boolean = { // check whether there is a ".javaopts" file val argsFile = new File(logFile.getParentFile, fileBase + ".javaopts") val argString = file2String(argsFile) @@ -348,15 +342,15 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor runCommand(cmd, logFile) } - def getCheckFilePath(dir: File, suffix: String = "") = { + private def getCheckFilePath(dir: File, suffix: String = "") = { def chkFile(s: String) = (Directory(dir) / "%s%s.check".format(fileBase, s)).toFile if (chkFile("").isFile || suffix == "") chkFile("") else chkFile("-" + suffix) } - def getCheckFile(dir: File) = Some(getCheckFilePath(dir, kind)) filter (_.canRead) + private def getCheckFile(dir: File) = Some(getCheckFilePath(dir, kind)) filter (_.canRead) - def compareOutput(dir: File, logFile: File): String = { + private def compareOutput(dir: File, logFile: File): String = { val checkFile = getCheckFilePath(dir, kind) // if check file exists, compare with log file val diff = @@ -372,25 +366,26 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor else diff } - def isJava(f: File) = SFile(f) hasExtension "java" - def isScala(f: File) = SFile(f) hasExtension "scala" - def isJavaOrScala(f: File) = isJava(f) || isScala(f) + @inline private def isJava(f: File) = SFile(f) hasExtension "java" + @inline private def isScala(f: File) = SFile(f) hasExtension "scala" + @inline private def isJavaOrScala(f: File) = isJava(f) || isScala(f) - def outputLogFile(logFile: File) { + private def outputLogFile(logFile: File) { val lines = SFile(logFile).lines if (lines.nonEmpty) { NestUI.normal("Log file '" + logFile + "': \n") lines foreach (x => NestUI.normal(x + "\n")) } } - def logStackTrace(logFile: File, t: Throwable, msg: String): Boolean = { + private def logStackTrace(logFile: File, t: Throwable, msg: String): Boolean = { SFile(logFile).writeAll(msg, stackTraceString(t)) outputLogFile(logFile) // if running the test threw an exception, output log file false } - def exHandler(logFile: File): PartialFunction[Throwable, Boolean] = exHandler(logFile, "") - def exHandler(logFile: File, msg: String): PartialFunction[Throwable, Boolean] = { + private def exHandler(logFile: File): PartialFunction[Throwable, Boolean] = + exHandler(logFile, "") + private def exHandler(logFile: File, msg: String): PartialFunction[Throwable, Boolean] = { case e: Exception => logStackTrace(logFile, e, msg) } @@ -398,7 +393,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor * * @param files The list of test files */ - def runTests(files: List[File])(topcont: Map[String, Int] => Unit) { + private def runTests(files: List[File])(topcont: Map[String, Int] => Unit) { val compileMgr = new CompileManager(fileManager) // if (kind == "scalacheck") fileManager.CLASSPATH += File.pathSeparator + PathSettings.scalaCheck @@ -526,6 +521,57 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor execTest(outDir, logFile) && diffCheck(compareOutput(dir, logFile)) }) + // Apache Ant 1.6 or newer + def ant(args: Seq[String], output: File): Boolean = { + val antDir = Directory(System.getProperty("ANT_HOME", "/opt/ant/")) + val antLibDir = Directory(antDir / "lib") + val antLauncherPath = SFile(antLibDir / "ant-launcher.jar").path + val antOptions = + if (NestUI._verbose) List("-verbose", "-noinput") + else List("-noinput") + val cmd = javaCmd +: ( + JAVA_OPTS.split(' ').map(_.trim).filter(_ != "") ++ Seq( + "-classpath", + antLauncherPath, + "org.apache.tools.ant.launch.Launcher" + ) ++ antOptions ++ args + ) + + try runCommand(cmd, output) + catch exHandler(output, "ant command '" + cmd + "' failed:\n") + } + + def runAntTest(file: File): LogContext = { + val logFile = createLogFile(file) + if (!fileManager.failed || logFile.canRead) { + val (swr, wr) = initNextTest() + printInfoStart(file, wr) + + NestUI.verbose(this+" running test "+fileBase) + + try { + val binary = "-Dbinary="+( + if (fileManager.LATEST_LIB endsWith "build/quick/classes/library") "quick" + else if (fileManager.LATEST_LIB endsWith "build/pack/lib/scala-library.jar") "pack" + else if (fileManager.LATEST_LIB endsWith "dists/latest/lib/scala-library.jar/") "latest" + else "installed" + ) + val args = Array(binary, "-logfile", logFile.path, "-file", file.path) + NestUI.verbose("ant "+args.mkString(" ")) + succeeded = ant(args, logFile) + diffCheck(compareOutput(file.getParentFile, logFile)) + } + catch { // *catch-all* + case e: Exception => + NestUI.verbose("caught "+e) + succeeded = false + } + + LogContext(logFile, swr, wr) + } else + LogContext(logFile) + } + def runSpecializedTest(file: File): LogContext = runTestCommon(file, expectFailure = false)((logFile, outDir) => { val dir = file.getParentFile @@ -591,6 +637,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor case "presentation" => runJvmTest(file) // for the moment, it's exactly the same as for a run test + case "ant" => + runAntTest(file) + case "buildmanager" => val logFile = createLogFile(file) if (!fileManager.failed || logFile.canRead) { @@ -794,48 +843,47 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor LogContext(logFile) } - case "shootout" => { - // when option "--failed" is provided - // execute test only if log file is present - // (which means it failed before) - val logFile = createLogFile(file) - if (!fileManager.failed || logFile.canRead) { - val (swr, wr) = initNextTest() - printInfoStart(file, wr) + case "shootout" => + // when option "--failed" is provided + // execute test only if log file is present + // (which means it failed before) + val logFile = createLogFile(file) + if (!fileManager.failed || logFile.canRead) { + val (swr, wr) = initNextTest() + printInfoStart(file, wr) - NestUI.verbose(this+" running test "+fileBase) - val dir = file.getParentFile - val outDir = createOutputDir(dir) + NestUI.verbose(this+" running test "+fileBase) + val dir = file.getParentFile + val outDir = createOutputDir(dir) + + // 2. define file {outDir}/test.scala that contains code to compile/run + val testFile = new File(outDir, "test.scala") + NestUI.verbose("outDir: "+outDir) + NestUI.verbose("logFile: "+logFile) + NestUI.verbose("testFile: "+testFile) + + // 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( + file2String(runnerFile), + file2String(bodyFile) + ) - // 2. define file {outDir}/test.scala that contains code to compile/run - val testFile = new File(outDir, "test.scala") - NestUI.verbose("outDir: "+outDir) - NestUI.verbose("logFile: "+logFile) - NestUI.verbose("testFile: "+testFile) - - // 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( - 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) && { - NestUI.verbose(this+" finished running "+fileBase) - diffCheck(compareOutput(dir, logFile)) - } + // 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) && { + NestUI.verbose(this+" finished running "+fileBase) + diffCheck(compareOutput(dir, logFile)) } - - LogContext(logFile, swr, wr) } - else - LogContext(logFile) + + LogContext(logFile, swr, wr) } + else + LogContext(logFile) case "scalap" => runInContext(file, (logFile: File, outDir: File) => { @@ -871,44 +919,43 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor } }) - case "script" => { - // when option "--failed" is provided - // execute test only if log file is present - // (which means it failed before) - val logFile = createLogFile(file) - if (!fileManager.failed || logFile.canRead) { - val (swr, wr) = initNextTest() - printInfoStart(file, wr) + case "script" => + // when option "--failed" is provided + // execute test only if log file is present + // (which means it failed before) + val logFile = createLogFile(file) + if (!fileManager.failed || logFile.canRead) { + val (swr, wr) = initNextTest() + printInfoStart(file, wr) - NestUI.verbose(this+" running test "+fileBase) + NestUI.verbose(this+" running test "+fileBase) - // check whether there is an args file - val argsFile = new File(file.getParentFile, fileBase+".args") - NestUI.verbose("argsFile: "+argsFile) - val argString = file2String(argsFile) + // check whether there is an args file + val argsFile = new File(file.getParentFile, fileBase+".args") + NestUI.verbose("argsFile: "+argsFile) + val argString = file2String(argsFile) - try { - val cmdString = - if (isWin) { - val batchFile = new File(file.getParentFile, fileBase+".bat") - NestUI.verbose("batchFile: "+batchFile) - batchFile.getAbsolutePath - } - else file.getAbsolutePath + try { + val cmdString = + if (isWin) { + val batchFile = new File(file.getParentFile, fileBase+".bat") + NestUI.verbose("batchFile: "+batchFile) + batchFile.getAbsolutePath + } + else file.getAbsolutePath - succeeded = ((cmdString+argString) #> logFile !) == 0 - diffCheck(compareOutput(file.getParentFile, logFile)) - } - catch { // *catch-all* - case e: Exception => - NestUI.verbose("caught "+e) - succeeded = false - } + succeeded = ((cmdString+argString) #> logFile !) == 0 + diffCheck(compareOutput(file.getParentFile, logFile)) + } + catch { // *catch-all* + case e: Exception => + NestUI.verbose("caught "+e) + succeeded = false + } - LogContext(logFile, swr, wr) - } else - LogContext(logFile) - } + LogContext(logFile, swr, wr) + } else + LogContext(logFile) } def reportAll(results: Map[String, Int], cont: Map[String, Int] => Unit) { @@ -954,7 +1001,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor cleanup() } - def finish() = { + def finish() { done = true cancelTimerTask() reportAll(status.toMap, topcont) @@ -1024,7 +1071,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor { f => fileManager.copyFile(f, destDir) } } - def showLog(logFile: File) { + private def showLog(logFile: File) { file2String(logFile) match { case "" if logFile.canRead => () case "" => NestUI.failure("Couldn't open log file: " + logFile + "\n") -- cgit v1.2.3