diff options
Diffstat (limited to 'src/partest/scala/tools/partest/nest')
13 files changed, 0 insertions, 2166 deletions
diff --git a/src/partest/scala/tools/partest/nest/AntRunner.scala b/src/partest/scala/tools/partest/nest/AntRunner.scala deleted file mode 100644 index 1d3b79171b..0000000000 --- a/src/partest/scala/tools/partest/nest/AntRunner.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala Parallel Testing ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.tools.partest -package nest - -class AntRunner extends DirectRunner { - - val fileManager = new FileManager { - var JAVACMD: String = "java" - var JAVAC_CMD: String = "javac" - var CLASSPATH: String = _ - var LATEST_LIB: String = _ - var LATEST_REFLECT: String = _ - var LATEST_COMP: String = _ - var LATEST_PARTEST: String = _ - var LATEST_ACTORS: String = _ - val testRootPath: String = "test" - val testRootDir: Directory = Directory(testRootPath) - } - - def reflectiveRunTestsForFiles(kindFiles: Array[File], kind: String): List[TestState] = - runTestsForFiles(kindFiles.toList, kind) -} diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala deleted file mode 100644 index b436675d3a..0000000000 --- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala +++ /dev/null @@ -1,189 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - - - -package scala.tools.partest -package nest - -import java.io.{ FilenameFilter, IOException } -import java.net.URI -import scala.util.Properties.{ propOrElse, scalaCmd, scalacCmd } -import scala.tools.nsc.{ io, util } -import PathResolver.{ Environment, Defaults } - -class ConsoleFileManager extends FileManager { - var testBuild: Option[String] = PartestDefaults.testBuild - def testBuildFile = testBuild map (testParent / _) - - var testClasses: Option[String] = None - - def this(buildPath: String, rawClasses: Boolean) = { - this() - if (rawClasses) - testClasses = Some(buildPath) - else - testBuild = Some(buildPath) - // re-run because initialization of default - // constructor must be updated - findLatest() - } - - def this(buildPath: String) = { - this(buildPath, false) - } - - def this(buildPath: String, rawClasses: Boolean, moreOpts: String) = { - this(buildPath, rawClasses) - SCALAC_OPTS = SCALAC_OPTS ++ moreOpts.split(' ').toSeq.filter(_.length > 0) - } - - lazy val srcDir = PathSettings.srcDir - lazy val testRootDir = PathSettings.testRoot - lazy val testRootPath = testRootDir.toAbsolute.path - def testParent = testRootDir.parent - - var CLASSPATH = PartestDefaults.classPath - var JAVACMD = PartestDefaults.javaCmd - var JAVAC_CMD = PartestDefaults.javacCmd - - - vlog("CLASSPATH: "+CLASSPATH) - - if (!srcDir.isDirectory) { - NestUI.failure("Source directory \"" + srcDir.path + "\" not found") - sys.exit(1) - } - - CLASSPATH = { - val libs = (srcDir / Directory("lib")).files filter (_ hasExtension "jar") map (_.toCanonical.path) - - // add all jars in libs - (CLASSPATH :: libs.toList) mkString pathSeparator - } - - def findLatest() { - vlog("test parent: "+testParent) - - def prefixFileWith(parent: File, relPath: String) = (SFile(parent) / relPath).toCanonical - def prefixFile(relPath: String) = (testParent / relPath).toCanonical - - if (!testClasses.isEmpty) { - testClassesDir = Path(testClasses.get).toCanonical.toDirectory - vlog("Running with classes in "+testClassesDir) - - latestLibFile = testClassesDir / "library" - latestActorsFile = testClassesDir / "library" / "actors" - latestReflectFile = testClassesDir / "reflect" - latestCompFile = testClassesDir / "compiler" - latestPartestFile = testClassesDir / "partest" - } - else if (testBuild.isDefined) { - val dir = Path(testBuild.get) - vlog("Running on "+dir) - latestLibFile = dir / "lib/scala-library.jar" - latestActorsFile = dir / "lib/scala-actors.jar" - latestReflectFile = dir / "lib/scala-reflect.jar" - latestCompFile = dir / "lib/scala-compiler.jar" - latestPartestFile = dir / "lib/scala-partest.jar" - } - else { - def setupQuick() { - vlog("Running build/quick") - latestLibFile = prefixFile("build/quick/classes/library") - latestActorsFile = prefixFile("build/quick/classes/library/actors") - latestReflectFile = prefixFile("build/quick/classes/reflect") - latestCompFile = prefixFile("build/quick/classes/compiler") - latestPartestFile = prefixFile("build/quick/classes/partest") - } - - def setupInst() { - vlog("Running dist (installed)") - val p = testParent.getParentFile - latestLibFile = prefixFileWith(p, "lib/scala-library.jar") - latestActorsFile = prefixFileWith(p, "lib/scala-actors.jar") - latestReflectFile = prefixFileWith(p, "lib/scala-reflect.jar") - latestCompFile = prefixFileWith(p, "lib/scala-compiler.jar") - latestPartestFile = prefixFileWith(p, "lib/scala-partest.jar") - } - - def setupDist() { - vlog("Running dists/latest") - latestLibFile = prefixFile("dists/latest/lib/scala-library.jar") - latestActorsFile = prefixFile("dists/latest/lib/scala-actors.jar") - latestReflectFile = prefixFile("dists/latest/lib/scala-reflect.jar") - latestCompFile = prefixFile("dists/latest/lib/scala-compiler.jar") - latestPartestFile = prefixFile("dists/latest/lib/scala-partest.jar") - } - - def setupPack() { - vlog("Running build/pack") - latestLibFile = prefixFile("build/pack/lib/scala-library.jar") - latestActorsFile = prefixFile("build/pack/lib/scala-actors.jar") - latestReflectFile = prefixFile("build/pack/lib/scala-reflect.jar") - latestCompFile = prefixFile("build/pack/lib/scala-compiler.jar") - latestPartestFile = prefixFile("build/pack/lib/scala-partest.jar") - } - - def mostRecentOf(base: String, names: String*) = - names map (x => prefixFile(base + "/" + x).lastModified) reduceLeft (_ max _) - - // detect most recent build - val quickTime = mostRecentOf("build/quick/classes", "compiler/compiler.properties", "reflect/reflect.properties", "library/library.properties") - val packTime = mostRecentOf("build/pack/lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar") - val distTime = mostRecentOf("dists/latest/lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar") - val instTime = mostRecentOf("lib", "scala-compiler.jar", "scala-reflect.jar", "scala-library.jar") - - val pairs = Map( - (quickTime, () => setupQuick()), - (packTime, () => setupPack()), - (distTime, () => setupDist()), - (instTime, () => setupInst()) - ) - - // run setup based on most recent time - pairs(pairs.keys max)() - } - - LATEST_LIB = latestLibFile.getAbsolutePath - LATEST_REFLECT = latestReflectFile.getAbsolutePath - LATEST_COMP = latestCompFile.getAbsolutePath - LATEST_PARTEST = latestPartestFile.getAbsolutePath - LATEST_ACTORS = latestActorsFile.getAbsolutePath - } - - var LATEST_LIB: String = "" - var LATEST_REFLECT: String = "" - var LATEST_COMP: String = "" - var LATEST_PARTEST: String = "" - var LATEST_ACTORS: String = "" - - var latestLibFile: File = _ - var latestActorsFile: File = _ - var latestReflectFile: File = _ - var latestCompFile: File = _ - var latestPartestFile: File = _ - //def latestScalapFile: File = (latestLibFile.parent / "scalap.jar").jfile - //def latestScalapFile: File = new File(latestLibFile.getParentFile, "scalap.jar") - var testClassesDir: Directory = _ - // initialize above fields - findLatest() - - /* - def getFiles(kind: String, cond: Path => Boolean): List[File] = { - def ignoreDir(p: Path) = List("svn", "obj") exists (p hasExtension _) - - val dir = Directory(srcDir / kind) - - if (dir.isDirectory) NestUI.verbose("look in %s for tests" format dir) - else NestUI.failure("Directory '%s' not found" format dir) - - val files = dir.list filterNot ignoreDir filter cond toList - - ( if (failed) files filter (x => logFileExists(x, kind)) else files ) map (_.jfile) - } - */ - var latestFjbgFile: File = _ -} diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala deleted file mode 100644 index 8189446162..0000000000 --- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala +++ /dev/null @@ -1,219 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - -package scala.tools -package partest -package nest - -import utils.Properties._ -import scala.tools.nsc.Properties.{ versionMsg, setProp } -import scala.collection.{ mutable, immutable } -import PathSettings.srcDir -import TestKinds._ -import scala.reflect.internal.util.Collections.distinctBy -import scala.tools.cmd.{ CommandLine, CommandLineParser, Instance } - -class ConsoleRunner(argstr: String) extends { - val parsed = ConsoleRunnerSpec.creator(CommandLineParser tokenize argstr) -} with DirectRunner with ConsoleRunnerSpec with Instance { - import NestUI._ - import NestUI.color._ - - // So we can ctrl-C a test run and still hear all - // the buffered failure info. - scala.sys addShutdownHook issueSummaryReport() - - var fileManager: ConsoleFileManager = _ - - private var totalTests = 0 - private val passedTests = mutable.ListBuffer[TestState]() - private val failedTests = mutable.ListBuffer[TestState]() - - def comment(s: String) = echo(magenta("# " + s)) - def levyJudgment() = { - if (totalTests == 0) echoMixed("No tests to run.") - else if (elapsedMillis == 0) echoMixed("Test Run ABORTED") - else if (isSuccess) echoPassed("Test Run PASSED") - else echoFailed("Test Run FAILED") - } - - def passFailString(passed: Int, failed: Int, skipped: Int): String = { - val total = passed + failed + skipped - val isSuccess = failed == 0 - def p0 = s"$passed/$total" - def p = ( if (isSuccess) bold(green(p0)) else p0 ) + " passed" - def f = if (failed == 0) "" else bold(red("" + failed)) + " failed" - def s = if (skipped == 0) "" else bold(yellow("" + skipped)) + " skipped" - - oempty(p, f, s) mkString ", " - } - - private var summarizing = false - private var elapsedMillis = 0L - private var expectedFailures = 0 - private def isSuccess = failedTests.size == expectedFailures - - def issueSummaryReport() { - // Don't run twice - if (!summarizing) { - summarizing = true - - val passed0 = passedTests.toList - val failed0 = failedTests.toList - val passed = passed0.size - val failed = failed0.size - val skipped = totalTests - (passed + failed) - val passFail = passFailString(passed, failed, skipped) - val elapsed = if (elapsedMillis > 0) " (elapsed time: " + elapsedString(elapsedMillis) + ")" else "" - val message = passFail + elapsed - - if (failed0.nonEmpty) { - if (isPartestVerbose) { - echo(bold(cyan("##### Transcripts from failed tests #####\n"))) - failed0 foreach { state => - comment("partest " + state.testFile) - echo(state.transcriptString + "\n") - } - } - - def files_s = failed0.map(_.testFile).mkString(""" \""" + "\n ") - echo("# Failed test paths (this command will update checkfiles)") - echo("test/partest --update-check \\\n " + files_s + "\n") - } - - echo(message) - levyJudgment() - } - } - - def run(): Unit = { - // Early return on no args, version, or invalid args - if (optVersion) return echo(versionMsg) - if ((argstr == "") || optHelp) return NestUI.usage() - - val (individualTests, invalid) = parsed.residualArgs map (p => Path(p)) partition denotesTestPath - if (invalid.nonEmpty) { - if (isPartestVerbose) - invalid foreach (p => echoWarning(s"Discarding invalid test path " + p)) - else if (!isPartestTerse) - echoWarning(s"Discarding ${invalid.size} invalid test paths") - } - - optSourcePath foreach (x => setProp("partest.srcdir", x)) - optTimeout foreach (x => setProp("partest.timeout", x)) - - fileManager = - if (optBuildPath.isDefined) new ConsoleFileManager(optBuildPath.get) - else if (optClassPath.isDefined) new ConsoleFileManager(optClassPath.get, true) - else if (optPack) new ConsoleFileManager("build/pack") - else new ConsoleFileManager // auto detection, see ConsoleFileManager.findLatest - - fileManager.updateCheck = optUpdateCheck - fileManager.failed = optFailed - - val partestTests = ( - if (optSelfTest) TestKinds.testsForPartest - else Nil - ) - - val grepExpr = optGrep getOrElse "" - - // If --grep is given we suck in every file it matches. - val greppedTests = if (grepExpr == "") Nil else { - val paths = grepFor(grepExpr) - if (paths.isEmpty) - echoWarning(s"grep string '$grepExpr' matched no tests.\n") - - paths.sortBy(_.toString) - } - - val isRerun = optFailed - val rerunTests = if (isRerun) TestKinds.failedTests else Nil - def miscTests = partestTests ++ individualTests ++ greppedTests ++ rerunTests - - val givenKinds = standardKinds filter parsed.isSet - val kinds = ( - if (optAll) standardKinds - else if (givenKinds.nonEmpty) givenKinds - else if (invalid.isEmpty && miscTests.isEmpty && !isRerun) standardKinds // If no kinds, --grep, or individual tests were given, assume --all - else Nil - ) - val kindsTests = kinds flatMap testsFor - val dir = - if (fileManager.testClasses.isDefined) fileManager.testClassesDir - else fileManager.testBuildFile getOrElse { - fileManager.latestCompFile.getParentFile.getParentFile.getAbsoluteFile - } - - def testContributors = { - List( - if (partestTests.isEmpty) "" else "partest self-tests", - if (rerunTests.isEmpty) "" else "previously failed tests", - if (kindsTests.isEmpty) "" else s"${kinds.size} named test categories", - if (greppedTests.isEmpty) "" else s"${greppedTests.size} tests matching '$grepExpr'", - if (individualTests.isEmpty) "" else "specified tests" - ) filterNot (_ == "") mkString ", " - } - - def banner = { - val vmBin = javaHome + fileSeparator + "bin" - val vmName = "%s (build %s, %s)".format(javaVmName, javaVmVersion, javaVmInfo) - val vmOpts = fileManager.JAVA_OPTS - - s"""|Scala compiler classes in: $dir - |Scala version is: $versionMsg - |Scalac options are: ${fileManager.SCALAC_OPTS mkString " "} - |Java binaries in: $vmBin - |Java runtime is: $vmName - |Java options are: $vmOpts - |Source directory is: $srcDir - |Available processors: ${Runtime.getRuntime().availableProcessors()} - |Java Classpath: ${sys.props("java.class.path")} - """.stripMargin - } - - chatty(banner) - - val allTests: List[Path] = distinctBy(miscTests ++ kindsTests)(_.toCanonical) sortBy (_.toString) - val grouped = (allTests groupBy kindOf).toList sortBy (x => standardKinds indexOf x._1) - - totalTests = allTests.size - expectedFailures = propOrNone("partest.errors") match { - case Some(num) => num.toInt - case _ => 0 - } - val expectedFailureMessage = if (expectedFailures == 0) "" else s" (expecting $expectedFailures to fail)" - echo(s"Selected $totalTests tests drawn from $testContributors$expectedFailureMessage\n") - - val (_, millis) = timed { - for ((kind, paths) <- grouped) { - val num = paths.size - val ss = if (num == 1) "" else "s" - comment(s"starting $num test$ss in $kind") - val results = runTestsForFiles(paths map (_.jfile.getAbsoluteFile), kind) - val (passed, failed) = results partition (_.isOk) - - passedTests ++= passed - failedTests ++= failed - if (failed.nonEmpty) { - comment(passFailString(passed.size, failed.size, 0) + " in " + kind) - } - echo("") - } - } - this.elapsedMillis = millis - issueSummaryReport() - System exit ( if (isSuccess) 0 else 1 ) - } - - run() -} - -object ConsoleRunner { - def main(args: Array[String]): Unit = { - new ConsoleRunner(args mkString " ") - } -} - diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunnerSpec.scala b/src/partest/scala/tools/partest/nest/ConsoleRunnerSpec.scala deleted file mode 100644 index bb831a4964..0000000000 --- a/src/partest/scala/tools/partest/nest/ConsoleRunnerSpec.scala +++ /dev/null @@ -1,54 +0,0 @@ -package scala.tools.partest.nest - -import language.postfixOps - -import scala.tools.cmd.{ CommandLine, Interpolation, Meta, Reference, Spec } - -trait ConsoleRunnerSpec extends Spec with Meta.StdOpts with Interpolation { - def referenceSpec = ConsoleRunnerSpec - def programInfo = Spec.Info( - "console-runner", - "Usage: NestRunner [options] [test test ...]", - "scala.tools.partest.nest.ConsoleRunner") - - heading("Test categories:") - val optAll = "all" / "run all tests" --? - val optPos = "pos" / "run compilation tests (success)" --? - val optNeg = "neg" / "run compilation tests (failure)" --? - val optRun = "run" / "run interpreter and backend tests" --? - val optJvm = "jvm" / "run JVM backend tests" --? - val optRes = "res" / "run resident compiler tests" --? - val optAnt = "ant" / "run Ant tests" --? - val optScalap = "scalap" / "run scalap tests" --? - val optSpecialized = "specialized" / "run specialization tests" --? - val optScalacheck = "scalacheck" / "run ScalaCheck tests" --? - val optInstrumented = "instrumented" / "run instrumented tests" --? - val optPresentation = "presentation" / "run presentation compiler tests" --? - - heading("Test runner options:") - val optFailed = "failed" / "run only those tests that failed during the last run" --? - val optTimeout = "timeout" / "aborts the test suite after the given amount of time" --| - val optPack = "pack" / "pick compiler/reflect/library in build/pack, and run all tests" --? - val optGrep = "grep" / "run all tests whose source file contains the expression given to grep" --| - val optUpdateCheck = "update-check" / "instead of failing tests with output change, update checkfile (use with care!)" --? - val optBuildPath = "buildpath" / "set (relative) path to build jars (ex.: --buildpath build/pack)" --| - val optClassPath = "classpath" / "set (absolute) path to build classes" --| - val optSourcePath = "srcpath" / "set (relative) path to test source files (ex.: --srcpath pending)" --| - - heading("Test output options:") - val optShowDiff = "show-diff" / "show diffs for failed tests" --> NestUI.setDiffOnFail() - val optVerbose = "verbose" / "show verbose progress information" --> NestUI.setVerbose() - val optTerse = "terse" / "show terse progress information" --> NestUI.setTerse() - val optDebug = "debug" / "enable debugging output" --> NestUI.setDebug() - - heading("Other options:") - val optVersion = "version" / "show Scala version and exit" --? - val optSelfTest = "self-test" / "run tests for partest itself" --? - val optHelp = "help" / "show this page and exit" --? - -} - -object ConsoleRunnerSpec extends ConsoleRunnerSpec with Reference { - type ThisCommandLine = CommandLine - def creator(args: List[String]): ThisCommandLine = new CommandLine(ConsoleRunnerSpec, args) -} diff --git a/src/partest/scala/tools/partest/nest/DirectCompiler.scala b/src/partest/scala/tools/partest/nest/DirectCompiler.scala deleted file mode 100644 index 8e5ff2abc4..0000000000 --- a/src/partest/scala/tools/partest/nest/DirectCompiler.scala +++ /dev/null @@ -1,105 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - -package scala.tools.partest -package nest - -import scala.tools.nsc.{ Global, Settings, CompilerCommand, FatalError } -import scala.tools.nsc.reporters.{ Reporter, ConsoleReporter } -import scala.tools.nsc.util.{ FakePos, stackTraceString } -import scala.tools.nsc.Properties.{ setProp, propOrEmpty } -import scala.reflect.io.AbstractFile -import scala.reflect.internal.util.Position -import java.io.{ BufferedReader, PrintWriter, FileReader, Writer, FileWriter } - -class ExtConsoleReporter(settings: Settings, val writer: PrintWriter) extends ConsoleReporter(settings, Console.in, writer) { - shortname = true - // override def error(pos: Position, msg: String): Unit -} - -class TestSettings(cp: String, error: String => Unit) extends Settings(error) { - def this(cp: String) = this(cp, _ => ()) - - nowarnings.value = false - encoding.value = "UTF-8" - classpath.value = cp -} - -class PartestGlobal(settings: Settings, reporter: Reporter) extends Global(settings, reporter) { - // override def abort(msg: String): Nothing - // override def globalError(msg: String): Unit - // override def supplementErrorMessage(msg: String): String -} -class DirectCompiler(val fileManager: FileManager) { - def newGlobal(settings: Settings, reporter: Reporter): PartestGlobal = - new PartestGlobal(settings, reporter) - - def newGlobal(settings: Settings, logWriter: FileWriter): Global = - newGlobal(settings, new ExtConsoleReporter(settings, new PrintWriter(logWriter))) - - 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 - s - } - - def compile(runner: Runner, opts0: List[String], sources: List[File]): TestState = { - import runner.{ sources => _, _ } - - val testSettings = new TestSettings(ClassPath.join(fileManager.LATEST_LIB, outDir.getPath)) - val logWriter = new FileWriter(logFile) - val srcDir = if (testFile.isDirectory) testFile else Path(testFile).parent.jfile - val opts = fileManager.updatePluginPath(opts0, AbstractFile getDirectory outDir, AbstractFile getDirectory srcDir) - val command = new CompilerCommand(opts, testSettings) - val global = newGlobal(testSettings, logWriter) - val reporter = global.reporter.asInstanceOf[ExtConsoleReporter] - def errorCount = reporter.ERROR.count - - def defineSettings(s: Settings) = { - s.outputDirs setSingleOutput outDir.getPath - // adding codelib.jar to the classpath - // codelib provides the possibility to override standard reify - // this shields the massive amount of reification tests from changes in the API - prependToClasspaths(s, codelib) - s.classpath append fileManager.CLASSPATH // adding this why? - - // add the instrumented library version to classpath - if (kind == "specialized") - prependToClasspaths(s, speclib) - - // check that option processing succeeded - opts0.isEmpty || command.ok - } - - if (!defineSettings(testSettings)) - if (opts0.isEmpty) - reporter.error(null, s"bad settings: $testSettings") - else - reporter.error(null, opts0.mkString("bad options: ", space, "")) - - def ids = sources.map(_.testIdent) mkString space - vlog(s"% scalac $ids") - - def execCompile() = - if (command.shouldStopWithInfo) { - logWriter append (command getInfoMessage global) - runner genFail "compilation stopped with info" - } else { - new global.Run compile sources.map(_.getPath) - if (!reporter.hasErrors) runner.genPass() - else { - reporter.printSummary() - reporter.writer.close() - runner.genFail(s"compilation failed with $errorCount errors") - } - } - - try { execCompile() } - catch { case t: Throwable => reporter.error(null, t.getMessage) ; runner.genCrash(t) } - finally { logWriter.close() } - } -} diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala deleted file mode 100644 index 208418047c..0000000000 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ /dev/null @@ -1,165 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - -// $Id$ - -package scala.tools.partest -package nest - -import java.io.{File, FilenameFilter, IOException, StringWriter, - FileInputStream, FileOutputStream, BufferedReader, - FileReader, PrintWriter, FileWriter} -import java.net.URI -import scala.reflect.io.AbstractFile -import scala.collection.mutable - -trait FileUtil { - /** - * Compares two files using difflib to produce a unified diff. - * - * @param f1 the first file to be compared - * @param f2 the second file to be compared - * @return the unified diff of the compared files or the empty string if they're equal - */ - def compareFiles(f1: File, f2: File): String = { - compareContents(io.Source.fromFile(f1).getLines.toSeq, io.Source.fromFile(f2).getLines.toSeq, f1.getName, f2.getName) - } - - /** - * Compares two lists of lines using difflib to produce a unified diff. - * - * @param origLines the first seq of lines to be compared - * @param newLines the second seq of lines to be compared - * @param origName file name to be used in unified diff for `origLines` - * @param newName file name to be used in unified diff for `newLines` - * @return the unified diff of the `origLines` and `newLines` or the empty string if they're equal - */ - def compareContents(origLines: Seq[String], newLines: Seq[String], origName: String = "a", newName: String = "b"): String = { - import collection.JavaConverters._ - - val diff = difflib.DiffUtils.diff(origLines.asJava, newLines.asJava) - if (diff.getDeltas.isEmpty) "" - else difflib.DiffUtils.generateUnifiedDiff(origName, newName, origLines.asJava, diff, 1).asScala.mkString("\n") - } -} -object FileUtil extends FileUtil { } - -trait FileManager extends FileUtil { - - def testRootDir: Directory - def testRootPath: String - - var JAVACMD: String - var JAVAC_CMD: String - - var CLASSPATH: String - var LATEST_LIB: String - var LATEST_REFLECT: String - var LATEST_COMP: String - var LATEST_PARTEST: String - var LATEST_ACTORS: String - - protected def relativeToLibrary(what: String): String = { - def jarname = if (what startsWith "scala") s"$what.jar" else s"scala-$what.jar" - if (LATEST_LIB endsWith ".jar") - (SFile(LATEST_LIB).parent / jarname).toAbsolute.path - else - (SFile(LATEST_LIB).parent.parent / "classes" / what).toAbsolute.path - } - def latestParserCBLib = relativeToLibrary("parser-combinators") - def latestXmlLib = relativeToLibrary("xml") - def latestScaladoc = relativeToLibrary("scaladoc") - def latestInteractive = relativeToLibrary("interactive") - def latestScalapFile = relativeToLibrary("scalap") - def latestPaths = List( - LATEST_LIB, LATEST_REFLECT, LATEST_COMP, LATEST_PARTEST, LATEST_ACTORS, - latestParserCBLib, latestXmlLib, latestScalapFile, latestScaladoc, latestInteractive - ) - def latestFiles = latestPaths map (p => new java.io.File(p)) - def latestUrls = latestFiles map (_.toURI.toURL) - - var showDiff = false - var updateCheck = false - var showLog = false - var failed = false - - var SCALAC_OPTS = PartestDefaults.scalacOpts.split(' ').toSeq - var JAVA_OPTS = PartestDefaults.javaOpts - - /** Only when --debug is given. */ - lazy val testTimings = new mutable.HashMap[String, Long] - def recordTestTiming(name: String, milliseconds: Long) = - synchronized { testTimings(name) = milliseconds } - - def getLogFile(dir: File, fileBase: String, kind: String): File = - new File(dir, fileBase + "-" + kind + ".log") - - def getLogFile(file: File, kind: String): File = { - val dir = file.getParentFile - val fileBase = basename(file.getName) - - getLogFile(dir, fileBase, kind) - } - - def logFileExists(file: File, kind: String) = - getLogFile(file, kind).canRead - - def overwriteFileWith(dest: File, file: File) = - dest.isFile && copyFile(file, dest) - - def copyFile(from: File, dest: File): Boolean = { - 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 { - 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, replace: String => String) { - val f = SFile(file) - - f.printlnAll(f.lines.toList map replace: _*) - } - - /** Massage args to merge plugins and fix paths. - * Plugin path can be relative to test root, or cwd is out. - * While we're at it, mix in the baseline options, too. - * That's how ant passes in the plugins dir. - */ - def updatePluginPath(args: List[String], out: AbstractFile, srcdir: AbstractFile): List[String] = { - val dir = testRootDir - // The given path, or the output dir if ".", or a temp dir if output is virtual (since plugin loading doesn't like virtual) - def pathOrCwd(p: String) = - if (p == ".") { - val plugxml = "scalac-plugin.xml" - val pout = if (out.isVirtual) Directory.makeTemp() else Path(out.path) - val srcpath = Path(srcdir.path) - val pd = (srcpath / plugxml).toFile - if (pd.exists) pd copyTo (pout / plugxml) - pout.toAbsolute - } else Path(p) - def absolutize(path: String) = pathOrCwd(path) match { - case x if x.isAbsolute => x.path - case x => (dir / x).toAbsolute.path - } - - val xprefix = "-Xplugin:" - val (xplugs, others) = args partition (_ startsWith xprefix) - val Xplugin = if (xplugs.isEmpty) Nil else List(xprefix + - (xplugs map (_ stripPrefix xprefix) flatMap (_ split pathSeparator) map absolutize mkString pathSeparator) - ) - SCALAC_OPTS.toList ::: others ::: Xplugin - } -} diff --git a/src/partest/scala/tools/partest/nest/NestRunner.scala b/src/partest/scala/tools/partest/nest/NestRunner.scala deleted file mode 100644 index e398d2ead9..0000000000 --- a/src/partest/scala/tools/partest/nest/NestRunner.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - -// $Id$ - -package scala.tools.partest -package nest - -object NestRunner { - def main(args: Array[String]) { - new ReflectiveRunner main (args mkString " ") - } -} diff --git a/src/partest/scala/tools/partest/nest/NestUI.scala b/src/partest/scala/tools/partest/nest/NestUI.scala deleted file mode 100644 index d063c17ac0..0000000000 --- a/src/partest/scala/tools/partest/nest/NestUI.scala +++ /dev/null @@ -1,181 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - -package scala.tools.partest -package nest - -import java.io.PrintWriter - -class Colors(enabled: => Boolean) { - import Console._ - - val bold = colored(BOLD) - val yellow = colored(YELLOW) - val green = colored(GREEN) - val blue = colored(BLUE) - val red = colored(RED) - val red_b = colored(RED_B) - val green_b = colored(GREEN_B) - val cyan = colored(CYAN) - val magenta = colored(MAGENTA) - - private def colored(code: String): String => String = - s => if (enabled) code + s + RESET else s -} - -object NestUI { - private val testNum = new java.util.concurrent.atomic.AtomicInteger(1) - @volatile private var testNumberFmt = "%3d" - private def testNumber = testNumberFmt format testNum.getAndIncrement() - def resetTestNumber(max: Int = -1) { - testNum set 1 - val width = if (max > 0) max.toString.length else 3 - testNumberFmt = s"%${width}d" - } - - var colorEnabled = sys.props contains "partest.colors" - val color = new Colors(colorEnabled) - import color._ - - val NONE = 0 - val SOME = 1 - val MANY = 2 - - private var _outline = "" - private var _success = "" - private var _failure = "" - private var _warning = "" - private var _default = "" - - private var dotCount = 0 - private val DotWidth = 72 - - def leftFlush() { - if (dotCount != 0) { - normal("\n") - dotCount = 0 - } - } - - def statusLine(state: TestState) = { - import state._ - import TestState._ - val colorizer = state match { - case _: Skip => yellow - case _: Updated => cyan - case s if s.isOk => green - case _ => red - } - val word = bold(colorizer(state.shortStatus)) - f"$word $testNumber - $testIdent%-40s$reasonString" - } - - def reportTest(state: TestState) = { - if (isTerse && state.isOk) { - if (dotCount >= DotWidth) { - outline("\n.") - dotCount = 1 - } - else { - outline(".") - dotCount += 1 - } - } - else { - echo(statusLine(state)) - if (!state.isOk && isDiffy) { - val differ = bold(red("% ")) + "diff " - state.transcript find (_ startsWith differ) foreach (echo(_)) - } - } - } - - def echo(message: String): Unit = synchronized { - leftFlush() - print(message + "\n") - } - def chatty(msg: String) = if (isVerbose) echo(msg) - - def echoSkipped(msg: String) = echo(yellow(msg)) - def echoPassed(msg: String) = echo(bold(green(msg))) - def echoFailed(msg: String) = echo(bold(red(msg))) - def echoMixed(msg: String) = echo(bold(yellow(msg))) - def echoWarning(msg: String) = echo(bold(red(msg))) - - def initialize(number: Int) = number match { - case MANY => - _outline = Console.BOLD + Console.BLACK - _success = Console.BOLD + Console.GREEN - _failure = Console.BOLD + Console.RED - _warning = Console.BOLD + Console.YELLOW - _default = Console.RESET - case SOME => - _outline = Console.BOLD + Console.BLACK - _success = Console.RESET - _failure = Console.BOLD + Console.BLACK - _warning = Console.BOLD + Console.BLACK - _default = Console.RESET - case _ => - } - - def outline(msg: String) = print(_outline + msg + _default) - def outline(msg: String, wr: PrintWriter) = synchronized { - wr.print(_outline + msg + _default) - } - - def success(msg: String) = print(_success + msg + _default) - def success(msg: String, wr: PrintWriter) = synchronized { - wr.print(_success + msg + _default) - } - - def failure(msg: String) = print(_failure + msg + _default) - def failure(msg: String, wr: PrintWriter) = synchronized { - wr.print(_failure + msg + _default) - } - - def warning(msg: String) = print(_warning + msg + _default) - - def normal(msg: String) = print(_default + msg) - def normal(msg: String, wr: PrintWriter) = synchronized { - wr.print(_default + msg) - } - - def usage() { - println(ConsoleRunnerSpec.programInfo.usage) - println(ConsoleRunnerSpec.helpMsg) - sys.exit(1) - } - - var _verbose = false - var _debug = false - var _terse = false - var _diff = false - - def isVerbose = _verbose - def isDebug = _debug - def isTerse = _terse - def isDiffy = _diff - - def setVerbose() { - _verbose = true - } - def setDebug() { - _debug = true - } - def setTerse() { - _terse = true - } - def setDiffOnFail() { - _diff = true - } - def verbose(msg: String) { - if (isVerbose) - System.err.println(msg) - } - def debug(msg: String) { - if (isDebug) - System.err.println(msg) - } -} diff --git a/src/partest/scala/tools/partest/nest/PathSettings.scala b/src/partest/scala/tools/partest/nest/PathSettings.scala deleted file mode 100644 index 030c515947..0000000000 --- a/src/partest/scala/tools/partest/nest/PathSettings.scala +++ /dev/null @@ -1,88 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - */ - -package scala.tools.partest -package nest - -import scala.tools.nsc.util.ClassPath -import scala.tools.nsc.io.{ Path, File, Directory } -import Path._ - -object PathSettings { - import PartestDefaults.{ testRootDir, srcDirName } - - private def cwd = Directory.Current getOrElse sys.error("user.dir property not set") - private def isPartestDir(d: Directory) = (d.name == "test") && (d / srcDirName isDirectory) - private def findJar(d: Directory, name: String): Option[File] = findJar(d.files, name) - private def findJar(files: Iterator[File], name: String): Option[File] = - files filter (_ hasExtension "jar") find { _.name startsWith name } - private def findJarOrFail(name: String, ds: Directory*): File = findJar(ds flatMap (_.files) iterator, name) getOrElse - sys.error(s"'${name}.jar' not found in '${ds map (_.path) mkString ", "}'.") - - // Directory <root>/test - lazy val testRoot: Directory = testRootDir getOrElse { - val candidates: List[Directory] = (cwd :: cwd.parents) flatMap (d => List(d, Directory(d / "test"))) - - candidates find isPartestDir getOrElse sys.error("Directory 'test' not found.") - } - - // Directory <root>/test/files or .../scaladoc - def srcDir = Directory(testRoot / srcDirName toCanonical) - - // Directory <root>/test/files/lib - lazy val srcLibDir = Directory(srcDir / "lib") - - // Directory <root>/test/files/speclib - lazy val srcSpecLibDir = Directory(srcDir / "speclib") - - lazy val srcSpecLib: File = findJar(srcSpecLibDir, "instrumented") getOrElse { - sys.error("No instrumented.jar found in %s".format(srcSpecLibDir)) - } - - // Directory <root>/test/files/codelib - lazy val srcCodeLibDir = Directory(srcDir / "codelib") - - lazy val srcCodeLib: File = ( - findJar(srcCodeLibDir, "code") - orElse findJar(Directory(testRoot / "files" / "codelib"), "code") // work with --srcpath pending - getOrElse sys.error("No code.jar found in %s".format(srcCodeLibDir)) - ) - - lazy val instrumentationAgentLib: File = { - findJar(buildPackLibDir.files, "scala-partest-javaagent") getOrElse { - sys.error("No partest-javaagent jar found in '%s' or '%s'".format(buildPackLibDir, srcLibDir)) - } - } - - // Directory <root>/build - lazy val buildDir: Directory = { - val bases = testRoot :: testRoot.parents - // In the classic "ant" build, the relevant subdirectory is called build, - // but in the postmodern "sbt" build, it is called target. Look for both. - val dirs = Path.onlyDirs(bases flatMap (x => List(x / "build", x / "target"))) - - dirs.headOption getOrElse sys.error("Neither 'build' nor 'target' dir found under test root " + testRoot + ".") - } - - // Directory <root>/build/pack/lib - lazy val buildPackLibDir = Directory(buildDir / "pack" / "lib") - - lazy val scalaCheck: File = - findJar(buildPackLibDir.files ++ srcLibDir.files, "scalacheck") getOrElse { - sys.error("No scalacheck jar found in '%s' or '%s'".format(buildPackLibDir, srcLibDir)) - } - - lazy val testInterface: File = findJarOrFail("test-interface", buildPackLibDir, srcLibDir) - - lazy val diffUtils: File = - findJar(buildPackLibDir.files, "diffutils") getOrElse sys.error(s"No diffutils.jar found in '$buildPackLibDir'.") - - /** The platform-specific support jar, `tools.jar`. - */ - lazy val platformTools: Option[File] = PathResolver.SupplementalLocations.platformTools -} - -class PathSettings() { - // def classpathAsURLs: List[URL] -} diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala deleted file mode 100644 index 3c77a03f1e..0000000000 --- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala +++ /dev/null @@ -1,99 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Philipp Haller - */ - -package scala.tools.partest -package nest - -import scala.tools.nsc.Properties.{ setProp, propOrEmpty } -import scala.tools.nsc.util.ClassPath -import scala.tools.nsc.io -import io.Path -import java.net.URLClassLoader - -/* This class is used to load an instance of DirectRunner using - * a custom class loader. - * The purpose is to "auto-detect" a good classpath for the - * rest of the classes (Worker, CompileManager etc.), so that - * the main NestRunner can be started merely by putting its - * class on the classpath (ideally). - */ -class ReflectiveRunner { - // TODO: we might also use fileManager.CLASSPATH - // to use the same classes as used by `scala` that - // was used to start the runner. - val sepRunnerClassName = "scala.tools.partest.nest.ConsoleRunner" - - private def searchPath(option: String, as: List[String]): Option[String] = as match { - case `option` :: r :: _ => Some(r) - case _ :: rest => searchPath(option, rest) - case Nil => None - } - - def main(args: String) { - val argList = (args.split("\\s")).toList - - if (isPartestDebug) - showAllJVMInfo - - // find out which build to test - val buildPath = searchPath("--buildpath", argList) - val classPath = searchPath("--classpath", argList) - val fileManager = - if (!buildPath.isEmpty) - new ConsoleFileManager(buildPath.get) - else if (!classPath.isEmpty) - new ConsoleFileManager(classPath.get, true) - else if (argList contains "--pack") - new ConsoleFileManager("build/pack") - else // auto detection - new ConsoleFileManager - - // this is a workaround for https://issues.scala-lang.org/browse/SI-5433 - // when that bug is fixed, the addition of PathSettings.srcCodeLib can be removed - // we hack into the classloader that will become parent classloader for scalac - // this way we ensure that reflective macro lookup will pick correct Code.lift - // it's also used to inject diffutils into the classpath when running partest from the test/partest script - val srcCodeLibAndDiff = List(PathSettings.srcCodeLib, PathSettings.diffUtils, PathSettings.testInterface) - val sepUrls = srcCodeLibAndDiff.map(_.toURI.toURL) ::: fileManager.latestUrls - // this seems to be the core classloader that determines which classes can be found when running partest from the test/partest script - val sepLoader = new URLClassLoader(sepUrls.toArray, null) - - if (isPartestDebug) - println("Loading classes from:\n " + fileManager.latestUrls.mkString("\n ")) - - // @partest maintainer: it seems to me that commented lines are incorrect - // if classPath is not empty, then it has been provided by the --classpath option - // which points to the root of Scala home (see ConsoleFileManager's testClasses and the true flag in the ctor for more information) - // this doesn't mean that we had custom Java classpath set, so we don't have to override latestXXXFiles from the file manager - // - //val paths = classPath match { - // case Some(cp) => Nil - // case _ => files.toList map (_.path) - //} - - setProp("java.class.path", ClassPath.join(fileManager.latestPaths: _*)) - - // don't let partest find pluginsdir; in ant build, standard plugin has dedicated test suite - //setProp("scala.home", latestLibFile.parent.parent.path) - setProp("scala.home", "") - - if (isPartestDebug) - for (prop <- List("java.class.path", "sun.boot.class.path", "java.ext.dirs")) - println(prop + ": " + propOrEmpty(prop)) - - try { - val sepRunnerClass = sepLoader loadClass sepRunnerClassName - val sepMainMethod = sepRunnerClass.getMethod("main", classOf[Array[String]]) - val cargs: Array[AnyRef] = Array(Array(args)) - sepMainMethod.invoke(null, cargs: _*) - } - catch { - case cnfe: ClassNotFoundException => - cnfe.printStackTrace() - NestUI.failure(sepRunnerClassName +" could not be loaded from:\n") - sepUrls foreach (x => NestUI.failure(x + "\n")) - } - } -} diff --git a/src/partest/scala/tools/partest/nest/Runner.scala b/src/partest/scala/tools/partest/nest/Runner.scala deleted file mode 100644 index 470a2188de..0000000000 --- a/src/partest/scala/tools/partest/nest/Runner.scala +++ /dev/null @@ -1,883 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Paul Phillips - */ -package scala.tools.partest -package nest - -import java.io.{ Console => _, _ } -import java.net.URL -import java.nio.charset.{ Charset, CharsetDecoder, CharsetEncoder, CharacterCodingException, CodingErrorAction => Action } -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit.NANOSECONDS -import scala.collection.mutable.ListBuffer -import scala.concurrent.duration.Duration -import scala.io.Codec -import scala.reflect.internal.FatalError -import scala.sys.process.{ Process, ProcessLogger } -import scala.tools.nsc.Properties.{ envOrElse, isWin, jdkHome, javaHome, propOrElse, propOrEmpty, setProp } -import scala.tools.nsc.{ Settings, CompilerCommand, Global } -import scala.tools.nsc.reporters.ConsoleReporter -import scala.tools.nsc.util.{ Exceptional, ScalaClassLoader, stackTraceString } -import scala.tools.scalap.Main.decompileScala -import scala.tools.scalap.scalasig.ByteCode -import scala.util.{ Try, Success, Failure } -import ClassPath.{ join, split } -import PartestDefaults.{ javaCmd, javacCmd } -import TestState.{ Pass, Fail, Crash, Uninitialized, Updated } - -trait PartestRunSettings { - def gitPath: Path - def reportPath: Path - def logPath: Path - - def testPaths: List[Path] - - def gitDiffOptions: List[String] - def extraScalacOptions: List[String] - def extraJavaOptions: List[String] -} - -class TestTranscript { - import NestUI.color._ - private val buf = ListBuffer[String]() - private def pass(s: String) = bold(green("% ")) + s - private def fail(s: String) = bold(red("% ")) + s - - def add(action: String): this.type = { buf += action ; this } - def append(text: String) { val s = buf.last ; buf.trimEnd(1) ; buf += (s + text) } - - // Colorize prompts according to pass/fail - def fail: List[String] = buf.toList match { - case Nil => Nil - case xs => (xs.init map pass) :+ fail(xs.last) - } -} - -/** Run a single test. Rubber meets road. */ -class Runner(val testFile: File, fileManager: FileManager, val testRunParams: TestRunParams) { - import fileManager._ - - // Override to true to have the outcome of this test displayed - // whether it passes or not; in general only failures are reported, - // except for a . per passing test to show progress. - def isEnumeratedTest = false - - private var _lastState: TestState = null - private var _transcript = new TestTranscript - - def lastState = if (_lastState == null) Uninitialized(testFile) else _lastState - def setLastState(s: TestState) = _lastState = s - def transcript: List[String] = _transcript.fail ++ logFile.fileLines - def pushTranscript(msg: String) = _transcript add msg - - val parentFile = testFile.getParentFile - val kind = parentFile.getName - val fileBase = basename(testFile.getName) - val logFile = new File(parentFile, s"$fileBase-$kind.log") - val outFile = logFile changeExtension "obj" - val checkFile = testFile changeExtension "check" - val flagsFile = testFile changeExtension "flags" - val testIdent = testFile.testIdent // e.g. pos/t1234 - - lazy val outDir = { outFile.mkdirs() ; outFile } - - type RanOneTest = (Boolean, LogContext) - - def showCrashInfo(t: Throwable) { - System.err.println(s"Crashed running test $testIdent: $t") - if (!isPartestTerse) - System.err.println(stackTraceString(t)) - } - protected def crashHandler: PartialFunction[Throwable, TestState] = { - case t: InterruptedException => - genTimeout() - case t: Throwable => - showCrashInfo(t) - logFile.appendAll(stackTraceString(t)) - genCrash(t) - } - - def genPass() = Pass(testFile) - def genFail(reason: String) = Fail(testFile, reason, _transcript.fail) - def genTimeout() = Fail(testFile, "timed out", _transcript.fail) - def genCrash(caught: Throwable) = Crash(testFile, caught, _transcript.fail) - def genUpdated() = Updated(testFile) - - def speclib = PathSettings.srcSpecLib.toString // specialization lib - def codelib = PathSettings.srcCodeLib.toString // reify lib - - // Prepend to a classpath, but without incurring duplicate entries - def prependTo(classpath: String, path: String): String = { - val segments = ClassPath split classpath - - if (segments startsWith path) classpath - else ClassPath.join(path :: segments distinct: _*) - } - - def prependToJavaClasspath(path: String) { - val jcp = sys.props.getOrElse("java.class.path", "") - prependTo(jcp, path) match { - case `jcp` => - case cp => sys.props("java.class.path") = cp - } - } - def prependToClasspaths(s: Settings, path: String) { - prependToJavaClasspath(path) - val scp = s.classpath.value - prependTo(scp, path) match { - case `scp` => - case cp => s.classpath.value = cp - } - } - - private def workerError(msg: String): Unit = System.err.println("Error: " + msg) - - def javac(files: List[File]): TestState = { - // compile using command-line javac compiler - val args = Seq( - javacCmd, - "-d", - outDir.getAbsolutePath, - "-classpath", - join(outDir.toString, CLASSPATH) - ) ++ files.map(_.getAbsolutePath) - - pushTranscript(args mkString " ") - val captured = StreamCapture(runCommand(args, logFile)) - if (captured.result) genPass() else { - logFile appendAll captured.stderr - genFail("java compilation failed") - } - } - - def testPrompt = kind match { - case "res" => "nsc> " - case _ => "% " - } - - /** Evaluate an action body and update the test state. - * @param failFn optionally map a result to a test state. - */ - def nextTestAction[T](body: => T)(failFn: PartialFunction[T, TestState]): T = { - val result = body - setLastState( if (failFn isDefinedAt result) failFn(result) else genPass() ) - result - } - def nextTestActionExpectTrue(reason: String, body: => Boolean): Boolean = ( - nextTestAction(body) { case false => genFail(reason) } - ) - def nextTestActionFailing(reason: String): Boolean = nextTestActionExpectTrue(reason, false) - - private def assembleTestCommand(outDir: File, logFile: File): List[String] = { - // check whether there is a ".javaopts" file - val argsFile = testFile changeExtension "javaopts" - val argString = file2String(argsFile) - if (argString != "") - NestUI.verbose("Found javaopts file '%s', using options: '%s'".format(argsFile, argString)) - - val testFullPath = testFile.getAbsolutePath - - // Note! As this currently functions, JAVA_OPTS must precede argString - // because when an option is repeated to java only the last one wins. - // That means until now all the .javaopts files were being ignored because - // they all attempt to change options which are also defined in - // partest.java_opts, leading to debug output like: - // - // 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( - "-Dfile.encoding=UTF-8", - "-Djava.library.path="+logFile.getParentFile.getAbsolutePath, - "-Dpartest.output="+outDir.getAbsolutePath, - "-Dpartest.lib="+LATEST_LIB, - "-Dpartest.reflect="+LATEST_REFLECT, - "-Dpartest.cwd="+outDir.getParent, - "-Dpartest.test-path="+testFullPath, - "-Dpartest.testname="+fileBase, - "-Djavacmd="+javaCmd, - "-Djavaccmd="+javacCmd, - "-Duser.language=en", - "-Duser.country=US" - ) ++ extras - - val classpath = if (extraClasspath != "") join(extraClasspath, CLASSPATH) else CLASSPATH - - javaCmd +: ( - (JAVA_OPTS.split(' ') ++ extraJavaOptions.split(' ') ++ argString.split(' ')).map(_.trim).filter(_ != "").toList ++ Seq( - "-classpath", - join(outDir.toString, classpath) - ) ++ propertyOptions ++ Seq( - "scala.tools.nsc.MainGenericRunner", - "-usejavacp", - "Test", - "jvm" - ) - ) - } - - /** Runs command redirecting standard out and - * error out to output file. - */ - private def runCommand(args: Seq[String], outFile: File): Boolean = { - //(Process(args) #> outFile !) == 0 or (Process(args) ! pl) == 0 - val pl = ProcessLogger(outFile) - val nonzero = 17 // rounding down from 17.3 - def run: Int = { - val p = Process(args) run pl - try p.exitValue - catch { - case e: InterruptedException => - NestUI verbose s"Interrupted waiting for command to finish (${args mkString " "})" - p.destroy - nonzero - case t: Throwable => - NestUI verbose s"Exception waiting for command to finish: $t (${args mkString " "})" - p.destroy - throw t - } - finally pl.close() - } - (pl buffer run) == 0 - } - - private def execTest(outDir: File, logFile: File): Boolean = { - val cmd = assembleTestCommand(outDir, logFile) - - pushTranscript((cmd mkString s" \\$EOL ") + " > " + logFile.getName) - nextTestAction(runCommand(cmd, logFile)) { - case false => - _transcript append EOL + logFile.fileContents - genFail("non-zero exit code") - } - } - - override def toString = s"""Test($testIdent, lastState = $lastState)""" - - // result is unused - def newTestWriters() = { - val swr = new StringWriter - val wr = new PrintWriter(swr, true) - // diff = "" - - ((swr, wr)) - } - - def fail(what: Any) = { - NestUI.verbose("scalac: compilation of "+what+" failed\n") - false - } - - /** Filter the check file for conditional blocks. - * The check file can contain lines of the form: - * `#partest java7` - * where the line contains a conventional flag name. - * If the flag tests true, succeeding lines are retained - * (removed on false) until the next #partest flag. - * A missing flag evaluates the same as true. - */ - def filteredCheck: Seq[String] = { - import scala.util.Properties.{javaVersion, isAvian} - // use lines in block so labeled? Default to sorry, Charlie. - def retainOn(expr: String) = { - val f = expr.trim - def flagWasSet(f: String) = fileManager.SCALAC_OPTS contains f - val (invert, token) = - if (f startsWith "!") (true, f drop 1) else (false, f) - val cond = token.trim match { - case "java7" => javaVersion startsWith "1.7" - case "java6" => javaVersion startsWith "1.6" - case "avian" => isAvian - case "true" => true - case "-optimise" | "-optimize" - => flagWasSet("-optimise") || flagWasSet("-optimize") - case flag if flag startsWith "-" - => flagWasSet(flag) - case rest => rest.isEmpty - } - if (invert) !cond else cond - } - val prefix = "#partest" - val b = new ListBuffer[String]() - var on = true - for (line <- file2String(checkFile).lines) { - if (line startsWith prefix) { - on = retainOn(line stripPrefix prefix) - } else if (on) { - b += line - } - } - b.toList - } - - def currentDiff = { - val logged = augmentString(file2String(logFile)).lines.toList - val (other, othername) = - if (checkFile.canRead) (filteredCheck, checkFile.getName) else (Nil, "empty") - compareContents(logged, other, logFile.getName, othername) - } - - val gitRunner = List("/usr/local/bin/git", "/usr/bin/git") map (f => new java.io.File(f)) find (_.canRead) - val gitDiffOptions = "--ignore-space-at-eol --no-index " + propOrEmpty("partest.git_diff_options") - // --color=always --word-diff - - def gitDiff(f1: File, f2: File): Option[String] = { - try gitRunner map { git => - val cmd = s"$git diff $gitDiffOptions $f1 $f2" - val diff = Process(cmd).lines_!.drop(4).map(_ + "\n").mkString - - "\n" + diff - } - catch { case t: Exception => None } - } - - /** Normalize the log output by applying test-specific filters - * and fixing filesystem-specific paths. - * - * Line filters are picked up from `filter: pattern` at the top of sources. - * The filtered line is detected with a simple "contains" test, - * and yes, "filter" means "filter out" in this context. - * - * File paths are detected using the absolute path of the test root. - * A string that looks like a file path is normalized by replacing - * the leading segments (the root) with "$ROOT" and by replacing - * any Windows backslashes with the one true file separator char. - */ - def normalizeLog() { - // Apply judiciously; there are line comments in the "stub implementations" error output. - val slashes = """[/\\]+""".r - def squashSlashes(s: String) = slashes replaceAllIn (s, "/") - - // this string identifies a path and is also snipped from log output. - // to preserve more of the path, could use fileManager.testRootPath - val elided = parentFile.getAbsolutePath - - // something to mark the elision in the log file (disabled) - val ellipsis = "" //".../" // using * looks like a comment - - // no spaces in test file paths below root, because otherwise how to detect end of path string? - val pathFinder = raw"""(?i)\Q${elided}${File.separator}\E([\${File.separator}\S]*)""".r - def canonicalize(s: String): String = ( - pathFinder replaceAllIn (s, m => ellipsis + squashSlashes(m group 1)) - ) - - def masters = { - val files = List(new File(parentFile, "filters"), new File(PathSettings.srcDir.path, "filters")) - files filter (_.exists) flatMap (_.fileLines) map (_.trim) filter (s => !(s startsWith "#")) - } - val filters = toolArgs("filter", split = false) ++ masters - val elisions = ListBuffer[String]() - //def lineFilter(s: String): Boolean = !(filters exists (s contains _)) - def lineFilter(s: String): Boolean = ( - filters map (_.r) forall { r => - val res = (r findFirstIn s).isEmpty - if (!res) elisions += s - res - } - ) - - logFile.mapInPlace(canonicalize)(lineFilter) - if (isPartestVerbose && elisions.nonEmpty) { - import NestUI.color._ - val emdash = bold(yellow("--")) - pushTranscript(s"filtering ${logFile.getName}$EOL${elisions mkString (emdash, EOL + emdash, EOL)}") - } - } - - def diffIsOk: Boolean = { - // always normalize the log first - normalizeLog() - val diff = currentDiff - // if diff is not empty, is update needed? - val updating: Option[Boolean] = ( - if (diff == "") None - else Some(fileManager.updateCheck) - ) - pushTranscript(s"diff $logFile $checkFile") - nextTestAction(updating) { - case Some(true) => - NestUI.verbose("Updating checkfile " + checkFile) - checkFile writeAll file2String(logFile) - genUpdated() - case Some(false) => - // Get a word-highlighted diff from git if we can find it - val bestDiff = if (updating.isEmpty) "" else { - if (checkFile.canRead) - gitDiff(logFile, checkFile) getOrElse { - s"diff $logFile $checkFile\n$diff" - } - else diff - } - _transcript append bestDiff - genFail("output differs") - // TestState.fail("output differs", "output differs", - // genFail("output differs") - // TestState.Fail("output differs", bestDiff) - case None => genPass() // redundant default case - } getOrElse true - } - - /** 1. Creates log file and output directory. - * 2. Runs script function, providing log file and output directory as arguments. - * 2b. or, just run the script without context and return a new context - */ - def runInContext(body: => Boolean): (Boolean, LogContext) = { - val (swr, wr) = newTestWriters() - val succeeded = body - (succeeded, LogContext(logFile, swr, wr)) - } - - /** Grouped files in group order, and lex order within each group. */ - def groupedFiles(sources: List[File]): List[List[File]] = ( - if (sources.tail.nonEmpty) { - val grouped = sources groupBy (_.group) - grouped.keys.toList.sorted map (k => grouped(k) sortBy (_.getName)) - } - else List(sources) - ) - - /** Source files for the given test file. */ - def sources(file: File): List[File] = ( - if (file.isDirectory) - file.listFiles.toList filter (_.isJavaOrScala) - else - List(file) - ) - - def newCompiler = new DirectCompiler(fileManager) - - def attemptCompile(sources: List[File]): TestState = { - val state = newCompiler.compile(this, flagsForCompilation(sources), sources) - if (!state.isOk) - _transcript append ("\n" + file2String(logFile)) - - state - } - - // snort or scarf all the contributing flags files - def flagsForCompilation(sources: List[File]): List[String] = { - def argsplitter(s: String) = words(s) filter (_.nonEmpty) - val perTest = argsplitter(flagsFile.fileContents) - val perGroup = if (testFile.isDirectory) { - sources flatMap { f => SFile(Path(f) changeExtension "flags").safeSlurp map argsplitter getOrElse Nil } - } else Nil - perTest ++ perGroup - } - - def toolArgs(tool: String, split: Boolean = true): List[String] = { - def argsplitter(s: String) = if (split) words(s) filter (_.nonEmpty) else List(s) - def argsFor(f: File): List[String] = { - import scala.util.matching.Regex - val p = new Regex(s"(?:.*\\s)?${tool}:(?:\\s*)(.*)?", "args") - val max = 10 - val src = Path(f).toFile.chars(codec) - val args = try { - src.getLines take max collectFirst { - case s if (p findFirstIn s).nonEmpty => for (m <- p findFirstMatchIn s) yield m group "args" - } - } finally src.close() - args.flatten map argsplitter getOrElse Nil - } - sources(testFile) flatMap argsFor - } - - abstract class CompileRound { - def fs: List[File] - def result: TestState - def description: String - - def fsString = fs map (_.toString stripPrefix parentFile.toString + "/") mkString " " - def isOk = result.isOk - def mkScalacString(): String = s"""scalac $fsString""" - override def toString = description + ( if (result.isOk) "" else "\n" + result.status ) - } - case class OnlyJava(fs: List[File]) extends CompileRound { - def description = s"""javac $fsString""" - lazy val result = { pushTranscript(description) ; javac(fs) } - } - case class OnlyScala(fs: List[File]) extends CompileRound { - def description = mkScalacString() - lazy val result = { pushTranscript(description) ; attemptCompile(fs) } - } - case class ScalaAndJava(fs: List[File]) extends CompileRound { - def description = mkScalacString() - lazy val result = { pushTranscript(description) ; attemptCompile(fs) } - } - - def compilationRounds(file: File): List[CompileRound] = ( - (groupedFiles(sources(file)) map mixedCompileGroup).flatten - ) - def mixedCompileGroup(allFiles: List[File]): List[CompileRound] = { - val (scalaFiles, javaFiles) = allFiles partition (_.isScala) - val isMixed = javaFiles.nonEmpty && scalaFiles.nonEmpty - val round1 = if (scalaFiles.isEmpty) None else Some(ScalaAndJava(allFiles)) - val round2 = if (javaFiles.isEmpty) None else Some(OnlyJava(javaFiles)) - val round3 = if (!isMixed) None else Some(OnlyScala(scalaFiles)) - - List(round1, round2, round3).flatten - } - - def runNegTest() = runInContext { - val rounds = compilationRounds(testFile) - - // failing means Does Not Compile - val failing = rounds find (x => nextTestActionExpectTrue("compilation failed", x.isOk) == false) - - // which means passing if it checks and didn't crash the compiler - // or, OK, we'll let you crash the compiler with a FatalError if you supply a check file - def checked(r: CompileRound) = r.result match { - case Crash(_, t, _) if !checkFile.canRead || !t.isInstanceOf[FatalError] => false - case _ => diffIsOk - } - - failing map (checked) getOrElse nextTestActionFailing("expected compilation failure") - } - - def runTestCommon(andAlso: => Boolean): (Boolean, LogContext) = runInContext { - compilationRounds(testFile).forall(x => nextTestActionExpectTrue("compilation failed", x.isOk)) && andAlso - } - - // Apache Ant 1.6 or newer - def ant(args: Seq[String], output: File): Boolean = { - val antDir = Directory(envOrElse("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 - ) - - runCommand(cmd, output) - } - - def runAntTest(): (Boolean, LogContext) = { - val (swr, wr) = newTestWriters() - - val succeeded = 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.getPath, "-file", testFile.getPath) - NestUI.verbose("ant "+args.mkString(" ")) - - pushTranscript(s"ant ${args.mkString(" ")}") - nextTestActionExpectTrue("ant failed", ant(args, logFile)) && diffIsOk - } - catch { // *catch-all* - case e: Exception => - NestUI.warning("caught "+e) - false - } - - (succeeded, LogContext(logFile, swr, wr)) - } - - def extraClasspath = kind match { - case "specialized" => PathSettings.srcSpecLib.toString - case _ => "" - } - def extraJavaOptions = kind match { - case "instrumented" => "-javaagent:"+PathSettings.instrumentationAgentLib - case _ => "" - } - - def runScalacheckTest() = runTestCommon { - NestUI verbose f"compilation of $testFile succeeded%n" - - // this classloader is test specific: its parent contains library classes and others - val loader = { - import PathSettings.scalaCheck - val locations = List(outDir, scalaCheck.jfile) map (_.getAbsoluteFile.toURI.toURL) - ScalaClassLoader.fromURLs(locations, getClass.getClassLoader) - } - val logWriter = new PrintStream(new FileOutputStream(logFile), true) - - def runInFramework(): Boolean = { - import org.scalatools.testing._ - val f: Framework = loader.instantiate[Framework]("org.scalacheck.ScalaCheckFramework") - val logger = new Logger { - def ansiCodesSupported = false //params.env.isSet("colors") - def error(msg: String) = logWriter println msg - def warn(msg: String) = logWriter println msg - def info(msg: String) = logWriter println msg - def debug(msg: String) = logWriter println msg - def trace(t: Throwable) = t printStackTrace logWriter - } - var bad = 0 - val handler = new EventHandler { - // testName, description, result, error - // Result = Success, Failure, Error, Skipped - def handle(event: Event): Unit = event.result match { - case Result.Success => - //case Result.Skipped => // an exhausted test is skipped, therefore bad - case _ => bad += 1 - } - } - val loggers = Array(logger) - val r = f.testRunner(loader, loggers).asInstanceOf[Runner2] // why? - val claas = "Test" - val fingerprint = f.tests collectFirst { case x: SubclassFingerprint if x.isModule => x } - val args = toolArgs("scalacheck") - vlog(s"Run $testFile with args $args") - // set the context class loader for scaladoc/scalacheck tests (FIX ME) - ScalaClassLoader(testRunParams.scalaCheckParentClassLoader).asContext { - r.run(claas, fingerprint.get, handler, args.toArray) // synchronous? - } - val ok = (bad == 0) - if (!ok) _transcript append logFile.fileContents - ok - } - try nextTestActionExpectTrue("ScalaCheck test failed", runInFramework()) finally logWriter.close() - } - - def runResidentTest() = { - // simulate resident compiler loop - val prompt = "\nnsc> " - val (swr, wr) = newTestWriters() - - NestUI.verbose(this+" running test "+fileBase) - val dir = parentFile - val resFile = new File(dir, fileBase + ".res") - - // run compiler in resident mode - // $SCALAC -d "$os_dstbase".obj -Xresident -sourcepath . "$@" - val sourcedir = logFile.getParentFile.getAbsoluteFile - val sourcepath = sourcedir.getAbsolutePath+File.separator - NestUI.verbose("sourcepath: "+sourcepath) - - val argList = List( - "-d", outDir.getAbsoluteFile.getPath, - "-Xresident", - "-sourcepath", sourcepath) - - // configure input/output files - val logOut = new FileOutputStream(logFile) - val logWriter = new PrintStream(logOut, true) - val resReader = new BufferedReader(new FileReader(resFile)) - val logConsoleWriter = new PrintWriter(new OutputStreamWriter(logOut), true) - - // create compiler - val settings = new Settings(workerError) - settings.sourcepath.value = sourcepath - settings.classpath.value = fileManager.CLASSPATH - val reporter = new ConsoleReporter(settings, scala.Console.in, logConsoleWriter) - val command = new CompilerCommand(argList, settings) - object compiler extends Global(command.settings, reporter) - - def resCompile(line: String): Boolean = { - // NestUI.verbose("compiling "+line) - val cmdArgs = (line split ' ').toList map (fs => new File(dir, fs).getAbsolutePath) - // NestUI.verbose("cmdArgs: "+cmdArgs) - val sett = new Settings(workerError) - sett.sourcepath.value = sourcepath - val command = new CompilerCommand(cmdArgs, sett) - // "scalac " + command.files.mkString(" ") - pushTranscript("scalac " + command.files.mkString(" ")) - nextTestActionExpectTrue( - "compilation failed", - command.ok && { - (new compiler.Run) compile command.files - !reporter.hasErrors - } - ) - } - def loop(): Boolean = { - logWriter.print(prompt) - resReader.readLine() match { - case null | "" => logWriter.close() ; true - case line => resCompile(line) && loop() - } - } - // res/t687.res depends on ignoring its compilation failure - // and just looking at the diff, so I made them all do that - // because this is long enough. - if (!Output.withRedirected(logWriter)(try loop() finally resReader.close())) - setLastState(genPass()) - - (diffIsOk, LogContext(logFile, swr, wr)) - } - - def run(): TestState = { - // javac runner, for one, would merely append to an existing log file, so just delete it before we start - logFile.delete() - - if (kind == "neg" || (kind endsWith "-neg")) runNegTest() - else kind match { - case "pos" => runTestCommon(true) - case "ant" => runAntTest() - case "scalacheck" => runScalacheckTest() - case "res" => runResidentTest() - case "scalap" => runScalapTest() - case "script" => runScriptTest() - case _ => runTestCommon(execTest(outDir, logFile) && diffIsOk) - } - - lastState - } - - def runScalapTest() = runTestCommon { - val isPackageObject = testFile.getName startsWith "package" - val className = testFile.getName.stripSuffix(".scala").capitalize + (if (!isPackageObject) "" else ".package") - val loader = ScalaClassLoader.fromURLs(List(outDir.toURI.toURL), this.getClass.getClassLoader) - val byteCode = ByteCode forClass (loader loadClass className) - val result = decompileScala(byteCode.bytes, isPackageObject) - - logFile writeAll result - diffIsOk - } - def runScriptTest() = { - import scala.sys.process._ - val (swr, wr) = newTestWriters() - - val args = file2String(testFile changeExtension "args") - val cmdFile = if (isWin) testFile changeExtension "bat" else testFile - val succeeded = (((cmdFile + " " + args) #> logFile !) == 0) && diffIsOk - - (succeeded, LogContext(logFile, swr, wr)) - } - - def cleanup() { - if (lastState.isOk) - logFile.delete() - if (!isPartestDebug) - Directory(outDir).deleteRecursively() - } -} - -case class TestRunParams(val scalaCheckParentClassLoader: ScalaClassLoader) - -/** Extended by Ant- and ConsoleRunner for running a set of tests. */ -trait DirectRunner { - def fileManager: FileManager - - import PartestDefaults.{ numThreads, waitTime } - - setUncaughtHandler - - def runTestsForFiles(kindFiles: List[File], kind: String): List[TestState] = { - - NestUI.resetTestNumber(kindFiles.size) - - // this special class loader is for the benefit of scaladoc tests, which need a class path - import PathSettings.{ testInterface, scalaCheck } - val allUrls = scalaCheck.toURL :: testInterface.toURL :: fileManager.latestUrls - val parentClassLoader = ScalaClassLoader fromURLs allUrls - // add scalacheck.jar to a special classloader, but use our loader as parent with test-interface - //val parentClassLoader = ScalaClassLoader fromURLs (List(scalaCheck.toURL), getClass().getClassLoader) - val pool = Executors newFixedThreadPool numThreads - val manager = new RunnerManager(kind, fileManager, TestRunParams(parentClassLoader)) - val futures = kindFiles map (f => pool submit callable(manager runTest f.getAbsoluteFile)) - - pool.shutdown() - Try (pool.awaitTermination(waitTime) { - throw TimeoutException(waitTime) - }) match { - case Success(_) => futures map (_.get) - case Failure(e) => - e match { - case TimeoutException(d) => - NestUI warning "Thread pool timeout elapsed before all tests were complete!" - case ie: InterruptedException => - NestUI warning "Thread pool was interrupted" - ie.printStackTrace() - } - pool.shutdownNow() // little point in continuing - // try to get as many completions as possible, in case someone cares - val results = for (f <- futures) yield { - try { - Some(f.get(0, NANOSECONDS)) - } catch { - case _: Throwable => None - } - } - results.flatten - } - } -} - -case class TimeoutException(duration: Duration) extends RuntimeException - -class LogContext(val file: File, val writers: Option[(StringWriter, PrintWriter)]) - -object LogContext { - def apply(file: File, swr: StringWriter, wr: PrintWriter): LogContext = { - require (file != null) - new LogContext(file, Some((swr, wr))) - } - def apply(file: File): LogContext = new LogContext(file, None) -} - -object Output { - object outRedirect extends Redirecter(out) - object errRedirect extends Redirecter(err) - - System.setOut(outRedirect) - System.setErr(errRedirect) - - import scala.util.DynamicVariable - private def out = java.lang.System.out - private def err = java.lang.System.err - private val redirVar = new DynamicVariable[Option[PrintStream]](None) - - class Redirecter(stream: PrintStream) extends PrintStream(new OutputStream { - 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) - }) - - // this supports thread-safe nested output redirects - 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 saved = redirVar.value - // set new redirecter - // this one will redirect both out and err to newstream - redirVar.value = Some(newstream) - - try func - finally { - newstream.flush() - redirVar.value = saved - } - } -} - -/** Use a Runner to run a test. */ -class RunnerManager(kind: String, fileManager: FileManager, params: TestRunParams) { - fileManager.CLASSPATH += File.pathSeparator + PathSettings.scalaCheck - fileManager.CLASSPATH += File.pathSeparator + PathSettings.diffUtils // needed to put diffutils on test/partest's classpath - - def runTest(testFile: File): TestState = { - val runner = new Runner(testFile, fileManager, params) - - // when option "--failed" is provided execute test only if log - // is present (which means it failed before) - if (fileManager.failed && !runner.logFile.canRead) - runner.genPass() - else { - val (state, _) = - try timed(runner.run()) - catch { - case t: Throwable => throw new RuntimeException(s"Error running $testFile", t) - } - NestUI.reportTest(state) - runner.cleanup() - state - } - } -} diff --git a/src/partest/scala/tools/partest/nest/SBTRunner.scala b/src/partest/scala/tools/partest/nest/SBTRunner.scala deleted file mode 100644 index 1cf3aa858f..0000000000 --- a/src/partest/scala/tools/partest/nest/SBTRunner.scala +++ /dev/null @@ -1,85 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - */ -package scala.tools.partest -package nest - -import java.io.File -import scala.tools.nsc.io.{ Directory } -import scala.util.Properties.setProp -import scala.collection.JavaConverters._ - -object SBTRunner extends DirectRunner { - - val fileManager = new FileManager { - var JAVACMD: String = "java" - var JAVAC_CMD: String = "javac" - var CLASSPATH: String = _ - var LATEST_LIB: String = _ - var LATEST_REFLECT: String = _ - var LATEST_COMP: String = _ - var LATEST_PARTEST: String = _ - var LATEST_ACTORS: String = _ - val testRootPath: String = "test" - val testRootDir: Directory = Directory(testRootPath) - } - - def reflectiveRunTestsForFiles(kindFiles: Array[File], kind: String): java.util.List[TestState] = { - def failedOnlyIfRequired(files:List[File]):List[File]={ - if (fileManager.failed) files filter (x => fileManager.logFileExists(x, kind)) else files - } - runTestsForFiles(failedOnlyIfRequired(kindFiles.toList), kind).asJava - } - - case class CommandLineOptions(classpath: Option[String] = None, - tests: Map[String, Array[File]] = Map(), - scalacOptions: Seq[String] = Seq(), - justFailedTests: Boolean = false) - - def mainReflect(args: Array[String]): java.util.List[TestState] = { - setProp("partest.debug", "true") - - val Argument = new scala.util.matching.Regex("-(.*)") - def parseArgs(args: Seq[String], data: CommandLineOptions): CommandLineOptions = args match { - case Seq("--failed", rest @ _*) => parseArgs(rest, data.copy(justFailedTests = true)) - case Seq("-cp", cp, rest @ _*) => parseArgs(rest, data.copy(classpath=Some(cp))) - case Seq("-scalacoption", opt, rest @ _*) => parseArgs(rest, data.copy(scalacOptions= data.scalacOptions :+ opt)) - case Seq(Argument(name), runFiles, rest @ _*) => parseArgs(rest, data.copy(tests=data.tests + (name -> runFiles.split(",").map(new File(_))))) - case Seq() => data - case x => sys.error("Unknown command line options: " + x) - } - val config = parseArgs(args, CommandLineOptions()) - fileManager.SCALAC_OPTS = config.scalacOptions - fileManager.CLASSPATH = config.classpath getOrElse sys.error("No classpath set") - - def findClasspath(jar: String, name: String): Option[String] = { - val optJar = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches (".*"+jar+".*\\.jar"))).headOption - val optClassDir = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches (".*"+name+File.separator+"classes"))).headOption - optJar orElse optClassDir - } - // Find scala library jar file... - fileManager.LATEST_LIB = findClasspath("scala-library", "scala-library") getOrElse sys.error("No scala-library found! Classpath = " + fileManager.CLASSPATH) - fileManager.LATEST_REFLECT = findClasspath("scala-reflect", "scala-reflect") getOrElse sys.error("No scala-reflect found! Classpath = " + fileManager.CLASSPATH) - fileManager.LATEST_COMP = findClasspath("scala-compiler", "scala-compiler") getOrElse sys.error("No scala-compiler found! Classpath = " + fileManager.CLASSPATH) - fileManager.LATEST_PARTEST = findClasspath("scala-partest", "partest") getOrElse sys.error("No scala-partest found! Classpath = " + fileManager.CLASSPATH) - fileManager.LATEST_ACTORS = findClasspath("scala-actors", "actors") getOrElse sys.error("No scala-actors found! Classpath = " + fileManager.CLASSPATH) - - // TODO - Do something useful here!!! - fileManager.JAVAC_CMD = "javac" - fileManager.failed = config.justFailedTests - // TODO - Make this a flag? - //fileManager.updateCheck = true - // Now run and report... - val runs = config.tests.filterNot(_._2.isEmpty) - val result = runs.toList flatMap { case (kind, files) => reflectiveRunTestsForFiles(files, kind).asScala } - - result.asJava - } - - def main(args: Array[String]): Unit = { - val failures = mainReflect(args).asScala collect { case s if !s.isOk => s.longStatus } - // Re-list all failures so we can go figure out what went wrong. - failures foreach System.err.println - if(!failures.isEmpty) sys.exit(1) - } -} diff --git a/src/partest/scala/tools/partest/nest/StreamCapture.scala b/src/partest/scala/tools/partest/nest/StreamCapture.scala deleted file mode 100644 index dc155b1787..0000000000 --- a/src/partest/scala/tools/partest/nest/StreamCapture.scala +++ /dev/null @@ -1,53 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Paul Phillips - */ -package scala.tools.partest -package nest - -import java.io.{ Console => _, _ } - -object StreamCapture { - case class Captured[T](stdout: String, stderr: String, result: T) { - override def toString = s""" - |result: $result - |[stdout] - |$stdout - |[stderr] - |$stderr""".stripMargin.trim - } - - private def mkStream = { - val swr = new StringWriter - val wr = new PrintWriter(swr, true) - val ostream = new PrintStream(new OutputStream { def write(b: Int): Unit = wr write b }, true) // autoFlush = true - - (ostream, () => { ostream.close() ; swr.toString }) - } - - def savingSystem[T](body: => T): T = { - val savedOut = System.out - val savedErr = System.err - try body - finally { - System setErr savedErr - System setOut savedOut - } - } - - def apply[T](body: => T): Captured[T] = { - val (outstream, stdoutFn) = mkStream - val (errstream, stderrFn) = mkStream - - val result = savingSystem { - System setOut outstream - System setErr errstream - Console.withOut(outstream) { - Console.withErr(errstream) { - body - } - } - } - Captured(stdoutFn(), stderrFn(), result) - } -} |