summaryrefslogtreecommitdiff
path: root/src/partest
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-11 00:32:00 +0000
committerPaul Phillips <paulp@improving.org>2010-04-11 00:32:00 +0000
commite93c1a93a2c8a40265b34bb9f1dd61b9470c908d (patch)
treeb9f13ffbe1d1ef59380e32f74380f9797b7fd2cb /src/partest
parent71b6aca681ab697304590a96b13847b9bba141dc (diff)
downloadscala-e93c1a93a2c8a40265b34bb9f1dd61b9470c908d.tar.gz
scala-e93c1a93a2c8a40265b34bb9f1dd61b9470c908d.tar.bz2
scala-e93c1a93a2c8a40265b34bb9f1dd61b9470c908d.zip
Introduces scala.tools.cmd providing command li...
Introduces scala.tools.cmd providing command line tool infrastructure. For a quick look at what can be done, see scala.tools.cmd.Demo For a more involved, potentially eye-straining look, see scala.tools.partest.PartestSpec To experience it through the eyes of Joe Partest User, run test/partest Review by community.
Diffstat (limited to 'src/partest')
-rw-r--r--src/partest/scala/tools/partest/Compilable.scala4
-rw-r--r--src/partest/scala/tools/partest/Config.scala3
-rw-r--r--src/partest/scala/tools/partest/Partest.scala14
-rw-r--r--src/partest/scala/tools/partest/PartestSpec.scala134
-rw-r--r--src/partest/scala/tools/partest/Runner.scala5
-rw-r--r--src/partest/scala/tools/partest/ant/JavaTask.scala12
-rw-r--r--src/partest/scala/tools/partest/ant/PartestTask.scala90
-rw-r--r--src/partest/scala/tools/partest/package.scala6
8 files changed, 88 insertions, 180 deletions
diff --git a/src/partest/scala/tools/partest/Compilable.scala b/src/partest/scala/tools/partest/Compilable.scala
index a1d987ad6d..c11532f278 100644
--- a/src/partest/scala/tools/partest/Compilable.scala
+++ b/src/partest/scala/tools/partest/Compilable.scala
@@ -27,8 +27,10 @@ trait PartestCompilation {
// }
def javac(args: List[String]): Boolean = {
+ val allArgString = fromArgs(javacpArg :: javacOpts :: args)
+
// javac -d outdir -classpath <basepath> <files>
- val cmd = "%s -d %s %s %s".format(javacCmd, outDir, javacpArg, fromArgs(args))
+ val cmd = "%s -d %s %s".format(javacCmd, outDir, allArgString)
def traceMsg =
if (isVerbose) cmd
else "%s -d %s %s".format(tracePath(Path(javacCmd)), tracePath(outDir), fromArgs(args))
diff --git a/src/partest/scala/tools/partest/Config.scala b/src/partest/scala/tools/partest/Config.scala
index 7d8bb80835..288a3034e9 100644
--- a/src/partest/scala/tools/partest/Config.scala
+++ b/src/partest/scala/tools/partest/Config.scala
@@ -23,8 +23,6 @@ trait Config {
* run we only allocate one worker so the output isn't interspersed.
*/
def workerTimeout = 3600 // 1 hour, probably overly generous
- def testTimeout = testTimeout_ flatMap safeToInt getOrElse 900 // test timeout
- def testWarning = testWarning_ flatMap safeToInt getOrElse (testTimeout / 10) // test warning
def numWorkers = if (isDryRun) 1 else propOrElse("partest.actors", "8").toInt
def expectedErrors = propOrElse("partest.errors", "0").toInt
def poolSize = (wrapAccessControl(propOrNone("actors.corePoolSize")) getOrElse "16").toInt
@@ -121,6 +119,7 @@ trait Config {
"Java binaries in: " + javaBin,
"Java runtime is: " + javaInfoString,
"Java runtime options: " + (Process.javaVmArguments mkString " "),
+ "Javac options are: " + universe.javacOpts,
"Java options are: " + universe.javaOpts,
"Source directory is: " + src,
"Selected categories: " + (selectedCategories mkString " "),
diff --git a/src/partest/scala/tools/partest/Partest.scala b/src/partest/scala/tools/partest/Partest.scala
index 019ed270e5..d6adcc6053 100644
--- a/src/partest/scala/tools/partest/Partest.scala
+++ b/src/partest/scala/tools/partest/Partest.scala
@@ -6,7 +6,7 @@ package scala.tools
package partest
import nsc.io._
-import nsc.util.CommandLine
+import nsc.util._
import category.AllCategories
/** Global object for a Partest run. It is completely configured by the list
@@ -15,10 +15,15 @@ import category.AllCategories
* for the complete list.
*/
class Partest(args: List[String]) extends {
- val parsed = PartestSpecReference(args: _*)
-} with Universe with PartestSpec with AllCategories {
+ val parsed = PartestSpec(args: _*)
+} with Universe with PartestSpec with cmd.Instance with AllCategories {
- debug("Partest object created with args: " + (args mkString " "))
+ if (parsed.propertyArgs.nonEmpty)
+ debug("Partest property args: " + fromArgs(parsed.propertyArgs))
+
+ debug("Partest created with args: " + fromArgs(args))
+
+ def helpMsg = PartestSpec.helpMsg
// The abstract values from Universe.
lazy val testBuildDir = searchForDir(buildDir)
@@ -30,7 +35,6 @@ class Partest(args: List[String]) extends {
// Coarse validation of partest directory: holds a file called partest.
(partestDir / "partest").isFile || error("'%s' is not a valid partest directory." format partestDir)
- def runSets = toArgs(parsed.getOrElse("--runsets", ""))
def specifiedTests = parsed.residualArgs map (x => Path(x).normalize)
def specifiedKinds = testKinds filter (x => isSet(x) || (runSets contains x))
def specifiedCats = specifiedKinds flatMap (x => allCategories find (_.kind == x))
diff --git a/src/partest/scala/tools/partest/PartestSpec.scala b/src/partest/scala/tools/partest/PartestSpec.scala
index a8a1d9b0cb..e4259d70be 100644
--- a/src/partest/scala/tools/partest/PartestSpec.scala
+++ b/src/partest/scala/tools/partest/PartestSpec.scala
@@ -6,9 +6,8 @@
package scala.tools
package partest
-import Properties._
import nsc.io._
-import nsc.util.{ CommandLine, CommandLineSpec, CommandLineReferenceSpec }
+import cmd._
/** This takes advantage of bits of scala goodness to fully define a command
* line program with a minimum of duplicated code. When the specification object
@@ -16,93 +15,90 @@ import nsc.util.{ CommandLine, CommandLineSpec, CommandLineReferenceSpec }
* a private accumulator. What emerges is a full list of the valid unary
* and binary arguments, as well as autogenerated help.
*/
-trait PartestSpec extends CommandLineSpec {
- override def isPassthroughProperty(key: String) = key == "partest.options"
- override def isSysPropOption(key: String) = {
- val segments = (key split '.').toList
- if (segments.size == 2 && segments.head == "partest") Some(segments.last)
- else None
- }
-
- private var _testKinds: List[String] = Nil
- private def kind(s: String) = returning(s)(_testKinds +:= _)
+trait PartestSpec extends Spec with Meta.StdOpts with Interpolation {
+ def referenceSpec = PartestSpec
+ def programInfo = Spec.Names("partest", "scala.tools.partest.Runner")
+ private val kind = new Spec.Accumulator[String]()
+ protected def testKinds = kind.get
- def testKinds = _testKinds
- def versionMsg = Properties.versionMsg
+ private implicit val tokenizeString = FromString.ArgumentsFromString // String => List[String]
help("""
+ |# Pro Tip! Instant bash completion: `partest --bash` (note backticks)
|Usage: partest [<options>] [<test> <test> ...]
| <test>: a path to a test designator, typically a .scala file or a directory.
- | Examples: files/pos/test1.scala, files/res/bug785""")
-
- heading ("Test categories:")
- val isAll = ("all" / "run all tests (default, unless no options given)" ?)
- (kind("pos") / "Compile files that are expected to build" ?)
- (kind("neg") / "Compile files that are expected to fail" ?)
- (kind("run") / "Test JVM backend" ?)
- (kind("jvm") / "Test JVM backend" ?)
- (kind("res") / "Run resident compiler scenarii" ?)
- (kind("buildmanager") / "Run Build Manager scenarii" ?)
- (kind("scalacheck") / "Run Scalacheck tests" ?)
- (kind("script") / "Run script files" ?)
- (kind("shootout") / "Run shootout tests" ?)
- (kind("scalap") / "Run scalap tests" ?)
+ | Examples: files/pos/test1.scala, files/res/bug785
+ |
+ | Test categories:""".stripMargin)
+
+ val isAll = ("all" / "run all tests (default, unless no options given)" --?)
+ (kind("pos") / "Compile files that are expected to build" --?)
+ (kind("neg") / "Compile files that are expected to fail" --?)
+ (kind("run") / "Test JVM backend" --?)
+ (kind("jvm") / "Test JVM backend" --?)
+ (kind("res") / "Run resident compiler scenarii" --?)
+ (kind("buildmanager") / "Run Build Manager scenarii" --?)
+ (kind("scalacheck") / "Run Scalacheck tests" --?)
+ (kind("script") / "Run script files" --?)
+ (kind("shootout") / "Run shootout tests" --?)
+ (kind("scalap") / "Run scalap tests" --?)
heading ("""Test "smart" categories:""")
- val grepExpr = "grep" / "run all tests with a source file containing <expr>" >>
- val isFailed = "failed" / "run all tests which failed on the last run" ?
+ val grepExpr = "grep" / "run all tests with a source file containing <expr>" --|
+ val isFailed = "failed" / "run all tests which failed on the last run" --?
heading ("Specifying paths and additional flags, ~ means repository root:")
- val rootDir = "rootdir" / "path from ~ to partest (default: test)" |> "test"
- val buildDir = "builddir" / "path from ~ to test build (default: build/pack)" |> "build/pack"
- val srcDir = "srcdir" / "path from --rootdir to sources (default: files)" |> "files"
- val javaOpts = "javaopts" / "flags to java on all runs (overrides JAVA_OPTS)" |> envOrElse("JAVA_OPTS", "")
- val scalacOpts = "scalacopts" / "flags to scalac on all tests (overrides SCALAC_OPTS)" |> envOrElse("SCALAC_OPTS", "")
- ("pack" / "alias for --builddir build/pack") ?+> List("--builddir", "build/pack")
- ("quick" / "alias for --builddir build/quick") ?+> List("--builddir", "build/quick")
+ val rootDir = "rootdir" / "path from ~ to partest" defaultTo "test"
+ val buildDir = "builddir" / "path from ~ to test build" defaultTo "build/pack"
+ val srcDir = "srcdir" / "path from --rootdir to sources" defaultTo "files"
+ val javaOpts = "javaopts" / "flags to java on all runs" defaultToEnv "JAVA_OPTS"
+ val javacOpts = "javacopts" / "flags to javac on all runs" defaultToEnv "JAVAC_OPTS"
+ val scalacOpts = "scalacopts" / "flags to scalac on all tests" defaultToEnv "SCALAC_OPTS"
+
+ "pack" / "" expandTo ("--builddir", "build/pack")
+ "quick" / "" expandTo ("--builddir", "build/quick")
heading ("Options influencing output:")
- val isTrace = "trace" / "show the individual steps taken by each test" ?
- val isShowDiff = "show-diff" / "show diff between log and check file" ?
- val isShowLog = "show-log" / "show log on failures" ?
- val isDryRun = "dry-run" / "do not run tests, only show their traces." ?
- val isTerse = "terse" / "be less verbose (almost silent except for failures)" ?
- val isVerbose = "verbose" / "be more verbose (additive with --trace)" ?
- val isDebug = "debug" / "maximum debugging output" ?
- val isAnsi = "ansi" / "print output in color" ?
+ val isTrace = "trace" / "show the individual steps taken by each test" --?
+ val isShowDiff = "show-diff" / "show diff between log and check file" --?
+ val isShowLog = "show-log" / "show log on failures" --?
+ val isDryRun = "dry-run" / "do not run tests, only show their traces." --?
+ val isTerse = "terse" / "be less verbose (almost silent except for failures)" --?
+ val isVerbose = "verbose" / "be more verbose (additive with --trace)" --?
+ val isDebug = "debug" / "maximum debugging output" --?
+ val isAnsi = "ansi" / "print output in color" --?
heading ("Other options:")
- val timeout_ = "timeout" / "Overall timeout in seconds" |> "14400"
- val testWarning_ = "test-warning" / "Test warning in seconds" >> ; // defaults to testTimeout / 10
- val testTimeout_ = "test-timeout" / "Test timeout in seconds" >> ; // defaults to 900
- val isCleanup = "cleanup" / "delete all stale files and dirs before run" ?
- val isNoCleanup = "nocleanup" / "do not delete any logfiles or object dirs" ?
- val isStats = "stats" / "collect and print statistics about the tests" ?
- val isValidate = "validate" / "examine test filesystem for inconsistencies" ?
- val isVersion = "version" / "print version" ?
+ val timeout = "timeout" / "Overall timeout in seconds" defaultTo 14400
+ val testWarning = "test-warning" / "Test warning in seconds" defaultTo 90
+ val testTimeout = "test-timeout" / "Test timeout in seconds" defaultTo 900
+ val isCleanup = "cleanup" / "delete all stale files and dirs before run" --?
+ val isNoCleanup = "nocleanup" / "do not delete any logfiles or object dirs" --?
+ val isStats = "stats" / "collect and print statistics about the tests" --?
+ val isValidate = "validate" / "examine test filesystem for inconsistencies" --?
+
+ "version" / "print version" --> runAndExit(println(Properties.versionMsg))
// no help for anything below this line - secret options
// mostly intended for property configuration.
- val runsets = "runsets" |> ""
- val isNoAlarms = ("noalarms" ?)
- val isInsideAnt = ("is-in-ant" ?)
+ val runSets = ("runsets" --^) getOrElse Nil
+ val isNoAlarms = "noalarms" --?
+ val isInsideAnt = "is-in-ant" --?
}
-object PartestSpecReference extends PartestSpec with CommandLineReferenceSpec {
- import CommandLineSpec._
+object PartestSpec extends PartestSpec with Property {
+ lazy val propMapper = new PropertyMapper(PartestSpec) {
+ override def isPassThrough(key: String) = key == "partest.options"
+ }
- def parsed: CommandLine = null
- override def creator(args: List[String]) =
- new ThisCommandLine(args) {
- override def onlyKnownOptions = true
- override def errorFn(msg: String) = printAndExit("Error: " + msg)
- }
+ type ThisCommandLine = PartestCommandLine
+ class PartestCommandLine(args: List[String]) extends SpecCommandLine(args) {
+ override def onlyKnownOptions = true
+ override def errorFn(msg: String) = printAndExit("Error: " + msg)
- def main(args: Array[String]): Unit = println(bashCompletion("partest"))
+ def propertyArgs = PartestSpec.propertyArgs
+ }
- /** Append bash completion for partest to the given file.
- */
- def appendCompletionTo(f: File) = f appendAll bashCompletion("partest")
+ override def creator(args: List[String]): PartestCommandLine = new PartestCommandLine(args)
}
-
diff --git a/src/partest/scala/tools/partest/Runner.scala b/src/partest/scala/tools/partest/Runner.scala
index 7f67c93478..1a28e60896 100644
--- a/src/partest/scala/tools/partest/Runner.scala
+++ b/src/partest/scala/tools/partest/Runner.scala
@@ -9,13 +9,10 @@ package partest
import nsc.io._
object Runner {
- def main(mainArgs: Array[String]) {
- val propArgs = PartestSpecReference.sysPropsAsOptions()
- val args = (propArgs ++ mainArgs).toList
+ def main(args: Array[String]) {
val runner = Partest(args: _*)
import runner._
- if (isVersion) return println(versionMsg)
if (args.isEmpty) return println(helpMsg)
if (isValidate) return validateAll()
diff --git a/src/partest/scala/tools/partest/ant/JavaTask.scala b/src/partest/scala/tools/partest/ant/JavaTask.scala
index 0bebf91368..6740554dd8 100644
--- a/src/partest/scala/tools/partest/ant/JavaTask.scala
+++ b/src/partest/scala/tools/partest/ant/JavaTask.scala
@@ -12,19 +12,21 @@ package ant
import org.apache.tools.ant.Task
import org.apache.tools.ant.taskdefs.Java
-import org.apache.tools.ant.types.{ EnumeratedAttribute, Commandline, Environment, PropertySet }
+import org.apache.tools.ant.types.Environment
import scala.tools.nsc.io._
-import scala.tools.nsc.util.{ ClassPath, CommandLineSpec }
-import CommandLineSpec._
+import scala.tools.nsc.util.ClassPath
+import cmd.Spec._
class JavaTask extends Java {
override def getTaskName() = "partest"
private val scalaRunnerClass = "scala.tools.nsc.MainGenericRunner"
+ private val partestRunnerClass = "scala.tools.partest.Runner"
+ def defaultJvmArgs = "-Xms64M -Xmx768M -Xss768K -XX:MaxPermSize=96M"
protected def rootDir = prop("partest.rootdir") getOrElse (baseDir / "test").path
- protected def partestJVMArgs = prop("partest.jvm.args") getOrElse "-Xms64M -Xmx768M -Xss768K -XX:MaxPermSize=96M"
- protected def runnerArgs = List("-usejavacp", "scala.tools.partest.Runner", "--javaopts", partestJVMArgs)
+ protected def partestJVMArgs = prop("partest.jvm.args") getOrElse defaultJvmArgs
+ protected def runnerArgs = List("-usejavacp", partestRunnerClass, "--javaopts", partestJVMArgs)
private def baseDir = Directory(getProject.getBaseDir)
private def prop(s: String) = Option(getProject getProperty s)
diff --git a/src/partest/scala/tools/partest/ant/PartestTask.scala b/src/partest/scala/tools/partest/ant/PartestTask.scala
deleted file mode 100644
index 65848fabb0..0000000000
--- a/src/partest/scala/tools/partest/ant/PartestTask.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala Parallel Testing **
-** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-/**** Note -- this isn't used anymore, but I left it in for the moment. ****/
-
-package scala.tools
-package partest
-package ant
-
-import java.io.{ File => JFile }
-
-import org.apache.tools.ant.Task
-import org.apache.tools.ant.types.{ Reference, FileSet}
-
-import scala.reflect.BeanProperty
-import scala.tools.ant.sabbus.CompilationPathProperty
-import scala.tools.nsc.io
-import scala.tools.nsc.util.CommandLineSpec._
-
-class PartestTask extends Task with CompilationPathProperty {
- /** Used only in ant task */
- @BeanProperty protected var errorOnFailed: Boolean = _
- @BeanProperty protected var jUnitReportDir: JFile = _
-
- /** Propagated to partest run via system properties */
- @BeanProperty protected var debug: Boolean = _
- @BeanProperty protected var javaOpts: String = _
- @BeanProperty protected var partestOpts: String = _
- @BeanProperty protected var runSets: String = _
- @BeanProperty protected var scalacOpts: String = _
- @BeanProperty protected var showDiff: Boolean = _
- @BeanProperty protected var showLog: Boolean = _
- @BeanProperty protected var srcDir: String = _
- @BeanProperty protected var timeout: Int = _
-
- /** Translating ant information into command line arguments. */
- private def notEmpty(s: String) = s != null && s.length > 0
- private def quoted(s: String) = if (s exists (_.isWhitespace)) "\"" + s.trim + "\"" else s
- private def optionCollection = List[(Boolean, () => List[String])](
- debug -> (() => List("--debug")),
- showLog -> (() => List("--show-log")),
- showDiff -> (() => List("--show-diff")),
- (timeout > 0) -> (() => List("--timeout", timeout.toString)),
- notEmpty(javaOpts) -> (() => List("--javaopts", javaOpts)),
- notEmpty(scalacOpts) -> (() => List("--scalacopts", scalacOpts)),
- notEmpty(srcDir) -> (() => List("--srcdir", srcDir)),
- notEmpty(partestOpts) -> (() => toArgs(partestOpts))
- )
-
- private def antPropOrNone(name: String) = Option(getProject getProperty name)
- private def antPropsToCommandLine() = {
- setProp("partest.isInAnt", "true")
- val partestDir = antPropOrNone("partest.dir") getOrElse error("Mandatory attribute 'partest.dir' is not set.")
-
- val root = List("--rootdir", io.Path(partestDir).path)
- val opts = optionCollection collect { case (true, f) => f() } flatten
- val sets = Option(runSets).toList flatMap toArgs map toOpt
-
- root ++ opts ++ sets
- }
- private def antRunTests() = {
- val args = antPropsToCommandLine()
- val runner = Partest(args: _*)
- import runner._
-
- normal("Ant options translate to command line: partest " + fromArgs(args))
- printConfigBanner()
-
- val result = launchTestSuite()
- val msg = result.toString
-
- if (result.hasFailures && errorOnFailed) error(msg)
- else log(msg)
- }
-
- override def execute() {
- try antRunTests()
- catch {
- case x =>
- System.err.println("Uncaught exception %s in partest ant ask: aborting." format x)
- x.printStackTrace()
- throw x
- }
- }
-}
diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala
index 3ef4db7cd8..f6d216e379 100644
--- a/src/partest/scala/tools/partest/package.scala
+++ b/src/partest/scala/tools/partest/package.scala
@@ -5,7 +5,6 @@
package scala.tools
import nsc.io.{ File, Path, Process, Directory }
-import nsc.util.CommandLineSpec
import java.nio.charset.CharacterCodingException
package object partest {
@@ -18,13 +17,12 @@ package object partest {
private[partest] def safeLines(f: File) = safeSlurp(f) split """\r\n|\r|\n""" toList
private[partest] def safeArgs(f: File) = toArgs(safeSlurp(f))
- private[partest] def safeToInt(s: String) = try Some(s.toInt) catch { case _: NumberFormatException => None }
private[partest] def isJava(f: Path) = f.isFile && (f hasExtension "java")
private[partest] def isScala(f: Path) = f.isFile && (f hasExtension "scala")
private[partest] def isJavaOrScala(f: Path) = isJava(f) || isScala(f)
- private[partest] def toArgs(line: String) = CommandLineSpec toArgs line
- private[partest] def fromArgs(args: List[String]) = CommandLineSpec fromArgs args
+ private[partest] def toArgs(line: String) = cmd toArgs line
+ private[partest] def fromArgs(args: List[String]) = cmd fromArgs args
/** Strings, argument lists, etc. */