summaryrefslogtreecommitdiff
path: root/src/partest/scala/tools/partest/nest
diff options
context:
space:
mode:
Diffstat (limited to 'src/partest/scala/tools/partest/nest')
-rw-r--r--src/partest/scala/tools/partest/nest/AntRunner.scala30
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleFileManager.scala189
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunner.scala219
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunnerSpec.scala54
-rw-r--r--src/partest/scala/tools/partest/nest/DirectCompiler.scala105
-rw-r--r--src/partest/scala/tools/partest/nest/FileManager.scala165
-rw-r--r--src/partest/scala/tools/partest/nest/NestRunner.scala15
-rw-r--r--src/partest/scala/tools/partest/nest/NestUI.scala181
-rw-r--r--src/partest/scala/tools/partest/nest/PathSettings.scala88
-rw-r--r--src/partest/scala/tools/partest/nest/ReflectiveRunner.scala99
-rw-r--r--src/partest/scala/tools/partest/nest/Runner.scala883
-rw-r--r--src/partest/scala/tools/partest/nest/SBTRunner.scala85
-rw-r--r--src/partest/scala/tools/partest/nest/StreamCapture.scala53
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)
- }
-}