diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-07-19 17:33:17 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-08-20 16:16:02 -0700 |
commit | 473a1692abf4d64e5df81cd19be214fe5bfa06ec (patch) | |
tree | c5f26f42296e3e585fe211b5a4e93f7c45d3b543 /src/partest | |
parent | 738441cf58136bd4af9985886dd0cd38ccda0777 (diff) | |
download | scala-473a1692abf4d64e5df81cd19be214fe5bfa06ec.tar.gz scala-473a1692abf4d64e5df81cd19be214fe5bfa06ec.tar.bz2 scala-473a1692abf4d64e5df81cd19be214fe5bfa06ec.zip |
Move partest to https://github.com/scala/scala-partest
As partest is now resolved from maven, `test/partest` uses `ant test.suite.init`
to determine the classpath (serialized to build/pack/partest.properties)
that's necessary to run `scala.tools.partest.nest.ConsoleRunner`.
Thus, partest gets exactly the same classpath, whether run from
the command line through `test/partest` or via `ant test`.
The version of partest we're using is specified by
properties defined in versions.properties (formerly `starr.number`).
Currently, we're using:
```
scala.binary.version=2.11.0-M4
partest.version.number=1.0-RC3
```
NOTES:
- The version of Scala being tested must be backwards binary compatible with
the version of Scala that was used to compile partest.
- Once 2.11 goes final, `scala.binary.version=2.11`, and `starr.version=2.11.0`.
- Need scalacheck on classpath for test/partest scalacheck tests.
- Removed atrophied ant tests (haven't been run/changed for at least two years
I checked 81d659141a as a "random" sample).
- Removed scalacheck. It's resolved as a partest dependency.
- For now, use a locally built scalap
- Kept the trace macro in the main repo (partest-extras)
- New targets for faster pr validation: test-core-opt, test-stab-opt
- Reused partest eclipse/intellij project to partest-extras
(note: the partest dependency is hard-coded)
Diffstat (limited to 'src/partest')
40 files changed, 0 insertions, 3896 deletions
diff --git a/src/partest/README b/src/partest/README deleted file mode 100644 index 17594dbb1e..0000000000 --- a/src/partest/README +++ /dev/null @@ -1,31 +0,0 @@ -How partest chooses the compiler / library: - - * ''-Dpartest.build=build/four-pack'' -> will search for libraries in - ''lib'' directory of given path - * ''--pack'' -> will set ''partest.build=build/pack'', and run all tests. - add ''--[kind]'' to run a selected set of tests. - * auto detection: - - partest.build property -> ''bin'' / ''lib'' directories - - distribution (''dists/latest'') - - supersabbus pack (''build/pack'') - - sabbus quick (''build/quick'') - - installed dist (test files in ''misc/scala-test/files'') - -How partest choses test files: the test files must be accessible from -the directory on which partest is run. So the test files must be either -at: - * ./test/files - * ./files (cwd is "test") - * ./misc/scala-test/files (installed scala distribution) - -Other arguments: - * --pos next files test a compilation success - * --neg next files test a compilation failure - * --run next files test the interpreter and all backends - * --jvm next files test the JVM backend - * --res next files test the resident compiler - * --shootout next files are shootout tests - * --script next files test the script runner - * ''-Dpartest.scalac_opts=...'' -> add compiler options - * ''--verbose'' -> print verbose messages - * ''-Dpartest.debug=true'' -> print debug messages diff --git a/src/partest/scala/tools/partest/ASMConverters.scala b/src/partest/scala/tools/partest/ASMConverters.scala deleted file mode 100644 index d618e086f4..0000000000 --- a/src/partest/scala/tools/partest/ASMConverters.scala +++ /dev/null @@ -1,71 +0,0 @@ -package scala.tools.partest - -import scala.collection.JavaConverters._ -import scala.tools.asm -import asm.tree.{ClassNode, MethodNode, InsnList} - -/** Makes using ASM from ByteCodeTests more convenient. - * - * Wraps ASM instructions in case classes so that equals and toString work - * for the purpose of bytecode diffing and pretty printing. - */ -trait ASMConverters { - // wrap ASM's instructions so we get case class-style `equals` and `toString` - object instructions { - def fromMethod(meth: MethodNode): List[Instruction] = { - val insns = meth.instructions - val asmToScala = new AsmToScala{ def labelIndex(l: asm.tree.AbstractInsnNode) = insns.indexOf(l) } - - asmToScala.mapOver(insns.iterator.asScala.toList).asInstanceOf[List[Instruction]] - } - - sealed abstract class Instruction { def opcode: String } - case class Field (opcode: String, desc: String, name: String, owner: String) extends Instruction - case class Incr (opcode: String, incr: Int, `var`: Int) extends Instruction - case class Op (opcode: String) extends Instruction - case class IntOp (opcode: String, operand: Int) extends Instruction - case class Jump (opcode: String, label: Label) extends Instruction - case class Ldc (opcode: String, cst: Any) extends Instruction - case class LookupSwitch (opcode: String, dflt: Label, keys: List[Integer], labels: List[Label]) extends Instruction - case class TableSwitch (opcode: String, dflt: Label, max: Int, min: Int, labels: List[Label]) extends Instruction - case class Method (opcode: String, desc: String, name: String, owner: String) extends Instruction - case class NewArray (opcode: String, desc: String, dims: Int) extends Instruction - case class TypeOp (opcode: String, desc: String) extends Instruction - case class VarOp (opcode: String, `var`: Int) extends Instruction - case class Label (offset: Int) extends Instruction { def opcode: String = "" } - case class FrameEntry (local: List[Any], stack: List[Any]) extends Instruction { def opcode: String = "" } - case class LineNumber (line: Int, start: Label) extends Instruction { def opcode: String = "" } - } - - abstract class AsmToScala { - import instructions._ - - def labelIndex(l: asm.tree.AbstractInsnNode): Int - - def mapOver(is: List[Any]): List[Any] = is map { - case i: asm.tree.AbstractInsnNode => apply(i) - case x => x - } - - def op(i: asm.tree.AbstractInsnNode) = if (asm.util.Printer.OPCODES.isDefinedAt(i.getOpcode)) asm.util.Printer.OPCODES(i.getOpcode) else "?" - def lst[T](xs: java.util.List[T]): List[T] = if (xs == null) Nil else xs.asScala.toList - def apply(l: asm.tree.LabelNode): Label = this(l: asm.tree.AbstractInsnNode).asInstanceOf[Label] - def apply(x: asm.tree.AbstractInsnNode): Instruction = x match { - case i: asm.tree.FieldInsnNode => Field (op(i), i.desc: String, i.name: String, i.owner: String) - case i: asm.tree.IincInsnNode => Incr (op(i), i.incr: Int, i.`var`: Int) - case i: asm.tree.InsnNode => Op (op(i)) - case i: asm.tree.IntInsnNode => IntOp (op(i), i.operand: Int) - case i: asm.tree.JumpInsnNode => Jump (op(i), this(i.label)) - case i: asm.tree.LdcInsnNode => Ldc (op(i), i.cst: Any) - case i: asm.tree.LookupSwitchInsnNode => LookupSwitch (op(i), this(i.dflt), lst(i.keys), mapOver(lst(i.labels)).asInstanceOf[List[Label]]) - case i: asm.tree.TableSwitchInsnNode => TableSwitch (op(i), this(i.dflt), i.max: Int, i.min: Int, mapOver(lst(i.labels)).asInstanceOf[List[Label]]) - case i: asm.tree.MethodInsnNode => Method (op(i), i.desc: String, i.name: String, i.owner: String) - case i: asm.tree.MultiANewArrayInsnNode => NewArray (op(i), i.desc: String, i.dims: Int) - case i: asm.tree.TypeInsnNode => TypeOp (op(i), i.desc: String) - case i: asm.tree.VarInsnNode => VarOp (op(i), i.`var`: Int) - case i: asm.tree.LabelNode => Label (labelIndex(x)) - case i: asm.tree.FrameNode => FrameEntry (mapOver(lst(i.local)), mapOver(lst(i.stack))) - case i: asm.tree.LineNumberNode => LineNumber (i.line: Int, this(i.start): Label) - } - } -}
\ No newline at end of file diff --git a/src/partest/scala/tools/partest/AsmNode.scala b/src/partest/scala/tools/partest/AsmNode.scala deleted file mode 100644 index e6a91498d1..0000000000 --- a/src/partest/scala/tools/partest/AsmNode.scala +++ /dev/null @@ -1,61 +0,0 @@ -package scala.tools.partest - -import scala.collection.JavaConverters._ -import scala.tools.asm -import asm._ -import asm.tree._ -import java.lang.reflect.Modifier - -sealed trait AsmNode[+T] { - def node: T - def access: Int - def desc: String - def name: String - def signature: String - def attrs: List[Attribute] - def visibleAnnotations: List[AnnotationNode] - def invisibleAnnotations: List[AnnotationNode] - def characteristics = f"$name%15s $desc%-30s$accessString$sigString" - def erasedCharacteristics = f"$name%15s $desc%-30s$accessString" - - private def accessString = if (access == 0) "" else " " + Modifier.toString(access) - private def sigString = if (signature == null) "" else " " + signature - override def toString = characteristics -} - -object AsmNode { - type AsmMethod = AsmNode[MethodNode] - type AsmField = AsmNode[FieldNode] - type AsmMember = AsmNode[_] - - implicit class ClassNodeOps(val node: ClassNode) { - def fieldsAndMethods: List[AsmMember] = { - val xs: List[AsmMember] = ( - node.methods.asScala.toList.map(x => (x: AsmMethod)) - ++ node.fields.asScala.toList.map(x => (x: AsmField)) - ) - xs sortBy (_.characteristics) - } - } - implicit class AsmMethodNode(val node: MethodNode) extends AsmNode[MethodNode] { - def access: Int = node.access - def desc: String = node.desc - def name: String = node.name - def signature: String = node.signature - def attrs: List[Attribute] = node.attrs.asScala.toList - def visibleAnnotations: List[AnnotationNode] = node.visibleAnnotations.asScala.toList - def invisibleAnnotations: List[AnnotationNode] = node.invisibleAnnotations.asScala.toList - } - implicit class AsmFieldNode(val node: FieldNode) extends AsmNode[FieldNode] { - def access: Int = node.access - def desc: String = node.desc - def name: String = node.name - def signature: String = node.signature - def attrs: List[Attribute] = node.attrs.asScala.toList - def visibleAnnotations: List[AnnotationNode] = node.visibleAnnotations.asScala.toList - def invisibleAnnotations: List[AnnotationNode] = node.invisibleAnnotations.asScala.toList - } - - def apply(node: MethodNode): AsmMethodNode = new AsmMethodNode(node) - def apply(node: FieldNode): AsmFieldNode = new AsmFieldNode(node) -} diff --git a/src/partest/scala/tools/partest/BytecodeTest.scala b/src/partest/scala/tools/partest/BytecodeTest.scala deleted file mode 100644 index 7650a892fd..0000000000 --- a/src/partest/scala/tools/partest/BytecodeTest.scala +++ /dev/null @@ -1,167 +0,0 @@ -package scala.tools.partest - -import scala.tools.nsc.util.JavaClassPath -import scala.collection.JavaConverters._ -import scala.tools.asm.{ClassWriter, ClassReader} -import scala.tools.asm.tree.{ClassNode, MethodNode, InsnList} -import java.io.{FileOutputStream, FileInputStream, File => JFile, InputStream} -import AsmNode._ - -/** - * Provides utilities for inspecting bytecode using ASM library. - * - * HOW TO USE - * 1. Create subdirectory in test/files/jvm for your test. Let's name it $TESTDIR. - * 2. Create $TESTDIR/BytecodeSrc_1.scala that contains Scala source file that you - * want to inspect the bytecode for. The '_1' suffix signals to partest that it - * should compile this file first. - * 3. Create $TESTDIR/Test.scala: - * import scala.tools.partest.BytecodeTest - * object Test extends BytecodeTest { - * def show { - * // your code that inspect ASM trees and prints values - * } - * } - * 4. Create corresponding check file. - * - * EXAMPLE - * See test/files/jvm/bytecode-test-example for an example of bytecode test. - * - */ -abstract class BytecodeTest extends ASMConverters { - import instructions._ - - /** produce the output to be compared against a checkfile */ - protected def show(): Unit - - def main(args: Array[String]): Unit = show - - // asserts - def sameBytecode(methA: MethodNode, methB: MethodNode) = { - val isa = instructions.fromMethod(methA) - val isb = instructions.fromMethod(methB) - if (isa == isb) println("bytecode identical") - else diffInstructions(isa, isb) - } - - // Do these classes have all the same methods, with the same names, access, - // descriptors and generic signatures? Method bodies are not considered, and - // the names of the classes containing the methods are substituted so they do - // not appear as differences. - def sameMethodAndFieldSignatures(clazzA: ClassNode, clazzB: ClassNode) = - sameCharacteristics(clazzA, clazzB)(_.characteristics) - - // Same as sameMethodAndFieldSignatures, but ignoring generic signatures. - // This allows for methods which receive the same descriptor but differing - // generic signatures. In particular, this happens with value classes, - // which get a generic signature where a method written in terms of the - // underlying values does not. - def sameMethodAndFieldDescriptors(clazzA: ClassNode, clazzB: ClassNode) = - sameCharacteristics(clazzA, clazzB)(_.erasedCharacteristics) - - private def sameCharacteristics(clazzA: ClassNode, clazzB: ClassNode)(f: AsmNode[_] => String): Boolean = { - val ms1 = clazzA.fieldsAndMethods.toIndexedSeq - val ms2 = clazzB.fieldsAndMethods.toIndexedSeq - val name1 = clazzA.name - val name2 = clazzB.name - - if (ms1.length != ms2.length) { - println(s"Different member counts in $name1 and $name2") - false - } - else (ms1, ms2).zipped forall { (m1, m2) => - val c1 = f(m1) - val c2 = f(m2).replaceAllLiterally(name2, name1) - if (c1 == c2) - println(s"[ok] $m1") - else - println(s"[fail]\n in $name1: $c1\n in $name2: $c2") - - c1 == c2 - } - } - - // bytecode is equal modulo local variable numbering - def equalsModuloVar(a: Instruction, b: Instruction) = (a, b) match { - case _ if a == b => true - case (VarOp(op1, _), VarOp(op2, _)) if op1 == op2 => true - case _ => false - } - - def similarBytecode(methA: MethodNode, methB: MethodNode, similar: (Instruction, Instruction) => Boolean) = { - val isa = fromMethod(methA) - val isb = fromMethod(methB) - if (isa == isb) println("bytecode identical") - else if ((isa, isb).zipped.forall { case (a, b) => similar(a, b) }) println("bytecode similar") - else diffInstructions(isa, isb) - } - - def diffInstructions(isa: List[Instruction], isb: List[Instruction]) = { - val len = Math.max(isa.length, isb.length) - if (len > 0 ) { - val width = isa.map(_.toString.length).max - val lineWidth = len.toString.length - (1 to len) foreach { line => - val isaPadded = isa.map(_.toString) orElse Stream.continually("") - val isbPadded = isb.map(_.toString) orElse Stream.continually("") - val a = isaPadded(line-1) - val b = isbPadded(line-1) - - println(s"""$line${" " * (lineWidth-line.toString.length)} ${if (a==b) "==" else "<>"} $a${" " * (width-a.length)} | $b""") - } - } - } - -// loading - protected def getMethod(classNode: ClassNode, name: String): MethodNode = - classNode.methods.asScala.find(_.name == name) getOrElse - sys.error(s"Didn't find method '$name' in class '${classNode.name}'") - - protected def loadClassNode(name: String, skipDebugInfo: Boolean = true): ClassNode = { - val classBytes: InputStream = (for { - classRep <- classpath.findClass(name) - binary <- classRep.binary - } yield binary.input) getOrElse sys.error(s"failed to load class '$name'; classpath = $classpath") - - val cr = new ClassReader(classBytes) - val cn = new ClassNode() - cr.accept(cn, if (skipDebugInfo) ClassReader.SKIP_DEBUG else 0) - cn - } - - protected lazy val classpath: JavaClassPath = { - import scala.tools.nsc.util.ClassPath.DefaultJavaContext - import scala.tools.util.PathResolver.Defaults - // logic inspired by scala.tools.util.PathResolver implementation - val containers = DefaultJavaContext.classesInExpandedPath(Defaults.javaUserClassPath) - new JavaClassPath(containers, DefaultJavaContext) - } -} - -object BytecodeTest { - /** Parse `file` as a class file, transforms the ASM representation with `f`, - * and overwrites the orginal file. - */ - def modifyClassFile(file: JFile)(f: ClassNode => ClassNode) { - val rfile = new reflect.io.File(file) - def readClass: ClassNode = { - val cr = new ClassReader(rfile.toByteArray()) - val cn = new ClassNode() - cr.accept(cn, 0) - cn - } - - def writeClass(cn: ClassNode) { - val writer = new ClassWriter(0) - cn.accept(writer) - val os = rfile.bufferedOutput() - try { - os.write(writer.toByteArray) - } finally { - os.close() - } - } - - writeClass(f(readClass)) - } -} diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala deleted file mode 100644 index df4a81dee2..0000000000 --- a/src/partest/scala/tools/partest/CompilerTest.scala +++ /dev/null @@ -1,60 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.partest - -import scala.reflect.runtime.{universe => ru} -import scala.tools.nsc._ - -/** For testing compiler internals directly. - * Each source code string in "sources" will be compiled, and - * the check function will be called with the source code and the - * resulting CompilationUnit. The check implementation should - * test for what it wants to test and fail (via assert or other - * exception) if it is not happy. - */ -abstract class CompilerTest extends DirectTest { - def check(source: String, unit: global.CompilationUnit): Unit - - lazy val global: Global = newCompiler() - lazy val units: List[global.CompilationUnit] = compilationUnits(global)(sources: _ *) - import global._ - import definitions.{ compilerTypeFromTag } - - override def extraSettings = "-usejavacp -d " + testOutput.path - - def show() = (sources, units).zipped foreach check - - // Override at least one of these... - def code = "" - def sources: List[String] = List(code) - - // Utility functions - class MkType(sym: Symbol) { - def apply[M](implicit t: ru.TypeTag[M]): Type = - if (sym eq NoSymbol) NoType - else appliedType(sym, compilerTypeFromTag(t)) - } - implicit def mkMkType(sym: Symbol) = new MkType(sym) - - def allMembers(root: Symbol): List[Symbol] = { - def loop(seen: Set[Symbol], roots: List[Symbol]): List[Symbol] = { - val latest = roots flatMap (_.info.members) filterNot (seen contains _) - if (latest.isEmpty) seen.toList.sortWith(_ isLess _) - else loop(seen ++ latest, latest) - } - loop(Set(), List(root)) - } - - class SymsInPackage(pkgName: String) { - def pkg = rootMirror.getPackage(pkgName) - def classes = allMembers(pkg) filter (_.isClass) - def modules = allMembers(pkg) filter (_.isModule) - def symbols = classes ++ terms filterNot (_ eq NoSymbol) - def terms = allMembers(pkg) filter (s => s.isTerm && !s.isConstructor) - def tparams = classes flatMap (_.info.typeParams) - def tpes = symbols map (_.tpe) distinct - } -} diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala deleted file mode 100644 index 2e6c3baa02..0000000000 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ /dev/null @@ -1,128 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.partest - -import scala.tools.nsc._ -import settings.ScalaVersion -import util.{ SourceFile, BatchSourceFile } -import reporters.{Reporter, ConsoleReporter} -import scala.tools.cmd.CommandLineParser - -/** A class for testing code which is embedded as a string. - * It allows for more complete control over settings, compiler - * configuration, sequence of events, etc. than does partest. - */ -abstract class DirectTest extends App { - // The program being tested in some fashion - def code: String - // produce the output to be compared against a checkfile - def show(): Unit - - // the test file or dir, and output directory - def testPath = SFile(sys.props("partest.test-path")) - def testOutput = Directory(sys.props("partest.output")) - - // override to add additional settings with strings - def extraSettings: String = "" - // a default Settings object - def settings: Settings = newSettings(CommandLineParser tokenize extraSettings) - // a custom Settings object - def newSettings(args: List[String]) = { - val s = new Settings - val allArgs = args ++ (CommandLineParser tokenize debugSettings) - log("newSettings: allArgs = " + allArgs) - s processArguments (allArgs, true) - s - } - // new compiler - def newCompiler(args: String*): Global = { - val settings = newSettings((CommandLineParser tokenize ("-d \"" + testOutput.path + "\" " + extraSettings)) ++ args.toList) - newCompiler(settings) - } - - def newCompiler(settings: Settings): Global = Global(settings, reporter(settings)) - - def reporter(settings: Settings): Reporter = new ConsoleReporter(settings) - - private def newSourcesWithExtension(ext: String)(codes: String*): List[BatchSourceFile] = - codes.toList.zipWithIndex map { - case (src, idx) => new BatchSourceFile(s"newSource${idx + 1}.$ext", src) - } - - def newJavaSources(codes: String*) = newSourcesWithExtension("java")(codes: _*) - def newSources(codes: String*) = newSourcesWithExtension("scala")(codes: _*) - - def compileString(global: Global)(sourceCode: String): Boolean = { - withRun(global)(_ compileSources newSources(sourceCode)) - !global.reporter.hasErrors - } - - def javaCompilationUnits(global: Global)(sourceCodes: String*) = { - sourceFilesToCompiledUnits(global)(newJavaSources(sourceCodes: _*)) - } - - def sourceFilesToCompiledUnits(global: Global)(files: List[SourceFile]) = { - withRun(global) { run => - run compileSources files - run.units.toList - } - } - - def compilationUnits(global: Global)(sourceCodes: String*): List[global.CompilationUnit] = { - val units = sourceFilesToCompiledUnits(global)(newSources(sourceCodes: _*)) - if (global.reporter.hasErrors) { - global.reporter.flush() - sys.error("Compilation failure.") - } - units - } - - def withRun[T](global: Global)(f: global.Run => T): T = { - global.reporter.reset() - f(new global.Run) - } - - // compile the code, optionally first adding to the settings - def compile(args: String*) = compileString(newCompiler(args: _*))(code) - - /** Constructor/main body **/ - try show() - catch { case t: Exception => println(t.getMessage) ; t.printStackTrace ; sys.exit(1) } - - /** Debugger interest only below this line **/ - protected def isDebug = (sys.props contains "partest.debug") || (sys.env contains "PARTEST_DEBUG") - protected def debugSettings = sys.props.getOrElse("partest.debug.settings", "") - - final def log(msg: => Any) { - if (isDebug) Console.err println msg - } - - /** - * Run a test only if the current java version is at least the version specified. - */ - def testUnderJavaAtLeast[A](version: String)(yesRun: =>A) = new TestUnderJavaAtLeast(version, { yesRun }) - - class TestUnderJavaAtLeast[A](version: String, yesRun: => A) { - val javaVersion = System.getProperty("java.specification.version") - - // the "ScalaVersion" class parses Java specification versions just fine - val requiredJavaVersion = ScalaVersion(version) - val executingJavaVersion = ScalaVersion(javaVersion) - val shouldRun = executingJavaVersion >= requiredJavaVersion - val preamble = if (shouldRun) "Attempting" else "Doing fallback for" - - def logInfo() = log(s"$preamble java $version specific test under java version $javaVersion") - - /* - * If the current java version is at least 'version' then 'yesRun' is evaluated - * otherwise 'fallback' is - */ - def otherwise(fallback: =>A): A = { - logInfo() - if (shouldRun) yesRun else fallback - } - } -} diff --git a/src/partest/scala/tools/partest/IcodeTest.scala b/src/partest/scala/tools/partest/IcodeTest.scala deleted file mode 100644 index b12ec0de61..0000000000 --- a/src/partest/scala/tools/partest/IcodeTest.scala +++ /dev/null @@ -1,43 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.partest - -import scala.tools.partest.nest.FileUtil.compareContents - -/** A trait for testing icode. All you need is this in a - * partest source file: - * {{{ - * object Test extends IcodeTest - * }}} - * And then the generated output will be the icode for everything - * in that file. See source for possible customizations. - */ -abstract class IcodeTest extends DirectTest { - // override to check icode at a different point. - def printIcodeAfterPhase = "icode" - // override to use source code other than the file being tested. - def code = testPath.slurp() - - override def extraSettings: String = "-usejavacp -Xprint-icode:" + printIcodeAfterPhase - - // Compile, read in all the *.icode files, delete them, and return their contents - def collectIcode(args: String*): List[String] = { - compile("-d" :: testOutput.path :: args.toList : _*) - val icodeFiles = testOutput.files.toList filter (_ hasExtension "icode") - - try icodeFiles sortBy (_.name) flatMap (f => f.lines.toList) - finally icodeFiles foreach (f => f.delete()) - } - - // Default show() compiles the code with and without optimization and - // outputs the diff. - def show() { - val lines1 = collectIcode("") - val lines2 = collectIcode("-optimise") - - println(compareContents(lines1, lines2)) - } -} diff --git a/src/partest/scala/tools/partest/JavapTest.scala b/src/partest/scala/tools/partest/JavapTest.scala deleted file mode 100644 index 3cb3dc6ca8..0000000000 --- a/src/partest/scala/tools/partest/JavapTest.scala +++ /dev/null @@ -1,26 +0,0 @@ - -package scala.tools.partest - -import scala.util.{Try,Success,Failure} -import java.lang.System.{out => sysout} - -/** A trait for testing repl's javap command - * or possibly examining its output. - */ -abstract class JavapTest extends ReplTest { - - /** Your Assertion Here, whatever you want to bejahen. - * Assertions must be satisfied by all flavors of javap - * and should not be fragile with respect to compiler output. - */ - def yah(res: Seq[String]): Boolean - - def baddies = List(":javap unavailable", ":javap not yet working") - - // give it a pass if javap is broken - override def show() = try { - val res = eval().toSeq - val unsupported = res exists (s => baddies exists (s contains _)) - assert ((unsupported || yah(res)), res.mkString("","\n","\n")) - } catch { case ae: AssertionError => ae.printStackTrace(sysout) } -} diff --git a/src/partest/scala/tools/partest/MemoryTest.scala b/src/partest/scala/tools/partest/MemoryTest.scala deleted file mode 100644 index 58d25d2f01..0000000000 --- a/src/partest/scala/tools/partest/MemoryTest.scala +++ /dev/null @@ -1,38 +0,0 @@ -package scala.tools.partest - -abstract class MemoryTest { - def maxDelta: Double - def calcsPerIter: Int - def calc(): Unit - - def main(args: Array[String]) { - val rt = Runtime.getRuntime() - def memUsage() = { - import java.lang.management._ - import scala.collection.JavaConverters._ - val pools = ManagementFactory.getMemoryPoolMXBeans.asScala - pools.map(_.getUsage.getUsed).sum / 1000000d - } - - val history = scala.collection.mutable.ListBuffer[Double]() - def stressTestIter() = { - var i = 0 - while (i < calcsPerIter) { calc(); i += 1 } - 1 to 5 foreach (_ => rt.gc()) - history += memUsage - } - - 1 to 5 foreach (_ => stressTestIter()) - val reference = memUsage() - 1 to 5 foreach (_ => stressTestIter()) - 1 to 5 foreach (_ => rt.gc()) - val result = memUsage() - history += result - - val delta = result - reference - if (delta > maxDelta) { - println("FAILED") - history foreach (mb => println(mb + " Mb")) - } - } -} diff --git a/src/partest/scala/tools/partest/PartestDefaults.scala b/src/partest/scala/tools/partest/PartestDefaults.scala deleted file mode 100644 index 8478edeb4d..0000000000 --- a/src/partest/scala/tools/partest/PartestDefaults.scala +++ /dev/null @@ -1,28 +0,0 @@ -package scala.tools -package partest - -import scala.concurrent.duration.Duration -import scala.tools.nsc.Properties.{ propOrElse, propOrNone, propOrEmpty } -import java.lang.Runtime.{ getRuntime => runtime } - -object PartestDefaults { - - def testRootName = propOrNone("partest.root") - def srcDirName = propOrElse("partest.srcdir", "files") - def testRootDir = testRootName map (x => Directory(x)) - - // def classPath = propOrElse("partest.classpath", "") - def classPath = PathResolver.Environment.javaUserClassPath // XXX - - def javaCmd = propOrElse("partest.javacmd", "java") - def javacCmd = propOrElse("partest.javac_cmd", "javac") - def javaOpts = propOrElse("partest.java_opts", "") - def scalacOpts = propOrElse("partest.scalac_opts", "") - - def testBuild = propOrNone("partest.build") - def errorCount = propOrElse("partest.errors", "0").toInt - def numThreads = propOrNone("partest.threads") map (_.toInt) getOrElse runtime.availableProcessors - def waitTime = propOrNone("partest.timeout") map (Duration.apply) getOrElse Duration("4 hours") - - //def timeout = "1200000" // per-test timeout -} diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala deleted file mode 100644 index 8b88021dbf..0000000000 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ /dev/null @@ -1,207 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala Parallel Testing ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.tools -package partest - -import scala.util.Properties.setProp -import scala.tools.ant.sabbus.CompilationPathProperty -import java.lang.reflect.Method -import org.apache.tools.ant.Task -import org.apache.tools.ant.types.{ Reference, FileSet} -import org.apache.tools.ant.types.Commandline.Argument -import scala.tools.ant.ScalaTask - -/** An Ant task to execute the Scala test suite (NSC). - * - * This task can take the following parameters as attributes: - * - `srcdir`, - * - `classpath`, - * - `classpathref`, - * - `erroronfailed`, - * - `javacmd`, - * - `javaccmd`, - * - `scalacopts`, - * - `debug`, - * - `junitreportdir`. - * - * It also takes the following parameters as nested elements: - * - `compilationpath`. - * - * @author Philippe Haller - */ -class PartestTask extends Task with CompilationPathProperty with ScalaTask { - type Path = org.apache.tools.ant.types.Path - - private var kinds: List[String] = Nil - private var classpath: Option[Path] = None - private var debug = false - private var errorOnFailed: Boolean = true - private var jUnitReportDir: Option[File] = None - private var javaccmd: Option[File] = None - private var javacmd: Option[File] = Option(sys.props("java.home")) map (x => new File(x, "bin/java")) - private var scalacArgs: Option[Seq[Argument]] = None - private var srcDir: Option[String] = None - private var colors: Int = 0 - - def setSrcDir(input: String) { - srcDir = Some(input) - } - - def setColors(input: String) { - try colors = input.toInt catch { case _: NumberFormatException => () } - if (colors > 0) - sys.props("partest.colors") = colors.toString - } - - def setClasspath(input: Path) { - if (classpath.isEmpty) - classpath = Some(input) - else - classpath.get.append(input) - } - - def createClasspath(): Path = { - if (classpath.isEmpty) classpath = Some(new Path(getProject())) - classpath.get.createPath() - } - - def setClasspathref(input: Reference) { - createClasspath().setRefid(input) - } - def setErrorOnFailed(input: Boolean) { - errorOnFailed = input - } - - def setJavaCmd(input: File) { - javacmd = Some(input) - } - - def setKinds(input: String) { - kinds = words(input) - } - - def setJavacCmd(input: File) { - javaccmd = Some(input) - } - - def setScalacOpts(input: String) { - val s = input.split(' ').map { s => val a = new Argument; a.setValue(s); a } - scalacArgs = Some(scalacArgs.getOrElse(Seq()) ++ s) - } - - def createCompilerArg(): Argument = { - val a = new Argument - scalacArgs = Some(scalacArgs.getOrElse(Seq()) :+ a) - a - } - - def setDebug(input: Boolean) { - debug = input - } - - def setJUnitReportDir(input: File) { - jUnitReportDir = Some(input) - } - - override def execute() { - if (debug || sys.props.contains("partest.debug")) { - nest.NestUI.setDebug() - } - - srcDir foreach (x => setProp("partest.srcdir", x)) - - val classpath = this.compilationPath getOrElse sys.error("Mandatory attribute 'compilationPath' is not set.") - val cpfiles = classpath.list map { fs => new File(fs) } toList - def findCp(name: String) = cpfiles find (f => - (f.getName == s"scala-$name.jar") - || (f.absolutePathSegments endsWith Seq("classes", name)) - ) getOrElse sys.error(s"Provided classpath does not contain a Scala $name element.") - - val scalaLibrary = findCp("library") - val scalaReflect = findCp("reflect") - val scalaCompiler = findCp("compiler") - val scalaPartest = findCp("partest") - val scalaActors = findCp("actors") - - def scalacArgsFlat: Option[Seq[String]] = scalacArgs map (_ flatMap { a => - val parts = a.getParts - if (parts eq null) Nil else parts.toSeq - }) - - val antRunner = new scala.tools.partest.nest.AntRunner - val antFileManager = antRunner.fileManager - - // antFileManager.failed = runFailed - antFileManager.CLASSPATH = ClassPath.join(classpath.list: _*) - antFileManager.LATEST_LIB = scalaLibrary.getAbsolutePath - antFileManager.LATEST_REFLECT = scalaReflect.getAbsolutePath - antFileManager.LATEST_COMP = scalaCompiler.getAbsolutePath - antFileManager.LATEST_PARTEST = scalaPartest.getAbsolutePath - antFileManager.LATEST_ACTORS = scalaActors.getAbsolutePath - - javacmd foreach (x => antFileManager.JAVACMD = x.getAbsolutePath) - javaccmd foreach (x => antFileManager.JAVAC_CMD = x.getAbsolutePath) - scalacArgsFlat foreach (antFileManager.SCALAC_OPTS ++= _) - - def runSet(kind: String, files: Array[File]): (Int, Int, List[String]) = { - if (files.isEmpty) (0, 0, List()) - else { - log(s"Running ${files.length} tests in '$kind' at $now") - // log(s"Tests: ${files.toList}") - val results = antRunner.reflectiveRunTestsForFiles(files, kind) - val (passed, failed) = results partition (_.isOk) - val numPassed = passed.size - val numFailed = failed.size - def failedMessages = failed map (_.longStatus) - - log(s"Completed '$kind' at $now") - - // create JUnit Report xml files if directory was specified - jUnitReportDir foreach { d => - d.mkdir - - val report = testReport(kind, results, numPassed, numFailed) - scala.xml.XML.save(d.getAbsolutePath+"/"+kind+".xml", report) - } - - (numPassed, numFailed, failedMessages) - } - } - - val _results = kinds map (k => runSet(k, TestKinds testsFor k map (_.jfile) toArray)) - val allSuccesses = _results map (_._1) sum - val allFailures = _results map (_._2) sum - val allFailedPaths = _results flatMap (_._3) - - def f = if (errorOnFailed && allFailures > 0) buildError(_: String) else log(_: String) - def s = if (allFailures > 1) "s" else "" - val msg = - if (allFailures > 0) - "Test suite finished with %d case%s failing:\n".format(allFailures, s)+ - allFailedPaths.mkString("\n") - else if (allSuccesses == 0) "There were no tests to run." - else "Test suite finished with no failures." - - f(msg) - } - - private def oneResult(res: TestState) = - <testcase name={res.testIdent}>{ - if (res.isOk) scala.xml.NodeSeq.Empty - else <failure message="Test failed"/> - }</testcase> - - private def testReport(kind: String, results: Iterable[TestState], succs: Int, fails: Int) = - <testsuite name={kind} tests={(succs + fails).toString} failures={fails.toString}> - <properties/> - { - results map oneResult - } - </testsuite> -} diff --git a/src/partest/scala/tools/partest/ReplTest.scala b/src/partest/scala/tools/partest/ReplTest.scala deleted file mode 100644 index 7381b8af54..0000000000 --- a/src/partest/scala/tools/partest/ReplTest.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.partest - -import scala.tools.nsc.Settings -import scala.tools.nsc.interpreter.ILoop -import scala.tools.partest.nest.FileUtil -import java.lang.reflect.{ Method => JMethod, Field => JField } - -/** A trait for testing repl code. It drops the first line - * of output because the real repl prints a version number. - */ -abstract class ReplTest extends DirectTest { - // override to transform Settings object immediately before the finish - def transformSettings(s: Settings): Settings = s - // final because we need to enforce the existence of a couple settings. - final override def settings: Settings = { - val s = super.settings - // s.Yreplsync.value = true - s.Xnojline.value = true - transformSettings(s) - } - def eval() = { - val s = settings - log("eval(): settings = " + s) - ILoop.runForTranscript(code, s).lines drop 1 - } - def show() = eval() foreach println -} - -abstract class SessionTest extends ReplTest with FileUtil { - def session: String - override final def code = expected filter (_.startsWith(prompt)) map (_.drop(prompt.length)) mkString "\n" - def expected = session.stripMargin.lines.toList - final def prompt = "scala> " - override def show() = { - val out = eval().toList - if (out.size != expected.size) Console println s"Expected ${expected.size} lines, got ${out.size}" - if (out != expected) Console print compareContents(expected, out, "expected", "actual") - } -} diff --git a/src/partest/scala/tools/partest/SecurityTest.scala b/src/partest/scala/tools/partest/SecurityTest.scala deleted file mode 100644 index 1f1c8a95ea..0000000000 --- a/src/partest/scala/tools/partest/SecurityTest.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.partest - -import java.security._ -import java.util._ - -abstract class SecurityTest extends App { - def throwIt(x: Any) = throw new AccessControlException("" + x) - def propertyCheck(p: PropertyPermission): Unit = throwIt(p) - - def check(perm: Permission): Unit = perm match { - case p: PropertyPermission => propertyCheck(p) - case _ => () - } -} diff --git a/src/partest/scala/tools/partest/SigTest.scala b/src/partest/scala/tools/partest/SigTest.scala deleted file mode 100644 index fe233a4fb5..0000000000 --- a/src/partest/scala/tools/partest/SigTest.scala +++ /dev/null @@ -1,52 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.partest - -import scala.tools.nsc.Settings -import scala.tools.nsc.interpreter.ILoop -import java.lang.reflect.{ Method => JMethod, Field => JField } -import scala.reflect.{ClassTag, classTag} - -/** Support code for testing signatures. - */ -trait SigTest { - def mstr(m: JMethod) = " (m) %s%s".format( - m.toGenericString, - if (m.isBridge) " (bridge)" else "" - ) - def fstr(f: JField) = " (f) %s".format(f.toGenericString) - - def isObjectMethodName(name: String) = classOf[Object].getMethods exists (_.getName == name) - - def fields[T: ClassTag](p: JField => Boolean) = { - val cl = classTag[T].runtimeClass - val fs = (cl.getFields ++ cl.getDeclaredFields).distinct sortBy (_.getName) - - fs filter p - } - def methods[T: ClassTag](p: JMethod => Boolean) = { - val cl = classTag[T].runtimeClass - val ms = (cl.getMethods ++ cl.getDeclaredMethods).distinct sortBy (x => (x.getName, x.isBridge)) - - ms filter p - } - def allFields[T: ClassTag]() = fields[T](_ => true) - def allMethods[T: ClassTag]() = methods[T](m => !isObjectMethodName(m.getName)) - def fieldsNamed[T: ClassTag](name: String) = fields[T](_.getName == name) - def methodsNamed[T: ClassTag](name: String) = methods[T](_.getName == name) - - def allGenericStrings[T: ClassTag]() = - (allMethods[T]() map mstr) ++ (allFields[T]() map fstr) - - def genericStrings[T: ClassTag](name: String) = - (methodsNamed[T](name) map mstr) ++ (fieldsNamed[T](name) map fstr) - - def show[T: ClassTag](name: String = "") = { - println(classTag[T].runtimeClass.getName) - if (name == "") allGenericStrings[T]() foreach println - else genericStrings[T](name) foreach println - } -} diff --git a/src/partest/scala/tools/partest/StoreReporterDirectTest.scala b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala deleted file mode 100644 index 7f3604c86c..0000000000 --- a/src/partest/scala/tools/partest/StoreReporterDirectTest.scala +++ /dev/null @@ -1,15 +0,0 @@ -package scala.tools.partest - -import scala.tools.nsc.Settings -import scala.tools.nsc.reporters.StoreReporter -import scala.collection.mutable - -trait StoreReporterDirectTest extends DirectTest { - lazy val storeReporter: StoreReporter = new scala.tools.nsc.reporters.StoreReporter() - - /** Discards all but the first message issued at a given position. */ - def filteredInfos: Seq[storeReporter.Info] = storeReporter.infos.groupBy(_.pos).map(_._2.head).toList - - /** Hook into [[scala.tools.partest.DirectTest]] to install the custom reporter */ - override def reporter(settings: Settings) = storeReporter -} diff --git a/src/partest/scala/tools/partest/TestKinds.scala b/src/partest/scala/tools/partest/TestKinds.scala deleted file mode 100644 index b4e8afd0d2..0000000000 --- a/src/partest/scala/tools/partest/TestKinds.scala +++ /dev/null @@ -1,66 +0,0 @@ -package scala.tools -package partest - -import nest.PathSettings.srcDir - -object TestKinds { - val standardKinds = ("pos neg run jvm res scalacheck scalap specialized instrumented presentation ant" split "\\s+").toList - - def denotesTestFile(p: Path) = p.isFile && p.hasExtension("scala", "res", "xml") - def denotesTestDir(p: Path) = kindOf(p) match { - case "res" => false - case _ => p.isDirectory && p.extension == "" - } - def denotesTestPath(p: Path) = denotesTestDir(p) || denotesTestFile(p) - - // TODO - def isTestForPartest(p: Path) = ( - (p.name == "intentional-failure.scala") - || (p.path contains "test-for-partest") - ) - - def kindOf(p: Path) = { - p.toAbsolute.segments takeRight 2 head - - // (srcDir relativize p.toCanonical).segments match { - // case (".." :: "scaladoc" :: xs) => xs.head - // case xs => xs.head - // } - } - def logOf(p: Path) = { - p.parent / s"${p.stripExtension}-${kindOf(p)}.log" - // p.parent / s"${p.stripExtension}.log" - } - - // true if a test path matches the --grep expression. - private def pathMatchesExpr(path: Path, expr: String) = { - // Matches the expression if any source file contains the expr, - // or if the checkfile contains it, or if the filename contains - // it (the last is case-insensitive.) - def matches(p: Path) = ( - (p.path.toLowerCase contains expr.toLowerCase) - || (p.fileContents contains expr) - ) - def candidates = { - (path changeExtension "check") +: { - if (path.isFile) List(path) - else path.toDirectory.deepList() filter (_.isJavaOrScala) toList - } - } - - (candidates exists matches) - } - - def groupedTests(paths: List[Path]): List[(String, List[Path])] = - (paths.distinct groupBy kindOf).toList sortBy (standardKinds indexOf _._1) - - /** Includes tests for testing partest. */ - private def allTestsForKind(kind: String): List[Path] = - (srcDir / kind toDirectory).list.toList filter denotesTestPath - - def testsForPartest: List[Path] = standardKinds flatMap allTestsForKind filter isTestForPartest - def testsFor(kind: String): List[Path] = allTestsForKind(kind) filterNot isTestForPartest - def grepFor(expr: String): List[Path] = standardTests filter (t => pathMatchesExpr(t, expr)) - def standardTests: List[Path] = standardKinds flatMap testsFor - def failedTests: List[Path] = standardTests filter (p => logOf(p).isFile) -} diff --git a/src/partest/scala/tools/partest/TestState.scala b/src/partest/scala/tools/partest/TestState.scala deleted file mode 100644 index e58b479e54..0000000000 --- a/src/partest/scala/tools/partest/TestState.scala +++ /dev/null @@ -1,64 +0,0 @@ -package scala.tools.partest - -import scala.tools.nsc.FatalError -import scala.tools.nsc.util.stackTraceString - -sealed abstract class TestState { - def testFile: File - def what: String - def reason: String - def transcript: List[String] - - def isOk = false - def isSkipped = false - def testIdent = testFile.testIdent - def transcriptString = transcript mkString EOL - - def identAndReason = testIdent + reasonString - def status = s"$what - $identAndReason" - def longStatus = status + transcriptString - def reasonString = if (reason == "") "" else s" [$reason]" - - def shortStatus = if (isOk) "ok" else "!!" - - override def toString = status -} - -object TestState { - case class Uninitialized(testFile: File) extends TestState { - def what = "uninitialized" - def reason = what - def transcript = Nil - override def shortStatus = "??" - } - case class Pass(testFile: File) extends TestState { - def what = "pass" - override def isOk = true - def transcript: List[String] = Nil - def reason = "" - } - case class Updated(testFile: File) extends TestState { - def what = "updated" - override def isOk = true - def transcript: List[String] = Nil - def reason = "updated check file" - override def shortStatus = "++" - } - case class Skip(testFile: File, reason: String) extends TestState { - def what = "skip" - override def isOk = true - override def isSkipped = true - def transcript: List[String] = Nil - override def shortStatus = "--" - } - case class Fail(testFile: File, reason: String, transcript: List[String]) extends TestState { - def what = "fail" - } - case class Crash(testFile: File, caught: Throwable, transcript: List[String]) extends TestState { - def what = "crash" - def reason = s"caught $caught_s - ${caught.getMessage}" - - private def caught_s = (caught.getClass.getName split '.').last - override def transcriptString = nljoin(super.transcriptString, caught_s) - } -} diff --git a/src/partest/scala/tools/partest/TestUtil.scala b/src/partest/scala/tools/partest/TestUtil.scala deleted file mode 100644 index 5c177ac962..0000000000 --- a/src/partest/scala/tools/partest/TestUtil.scala +++ /dev/null @@ -1,38 +0,0 @@ -package scala.tools.partest - -import scala.reflect.{ classTag, ClassTag } - -trait TestUtil { - /** Given function and block of code, evaluates code block, - * calls function with nanoseconds elapsed, and returns block result. - */ - def timed[T](f: Long => Unit)(body: => T): T = { - val start = System.nanoTime - val result = body - val end = System.nanoTime - - f(end - start) - result - } - /** Times body and returns (nanos, result). - */ - def alsoNanos[T](body: => T): (Long, T) = { - var nanos = 0L - val result = timed(nanos = _)(body) - - (nanos, result) - } - def nanos(body: => Unit): Long = alsoNanos(body)._1 - - def intercept[T <: Exception : ClassTag](code: => Unit): Unit = - try { - code - assert(false, "did not throw " + classTag[T]) - } catch { - case ex: Exception if classTag[T].runtimeClass isInstance ex => - } -} - -// Used in tests. -object TestUtil extends TestUtil { -} diff --git a/src/partest/scala/tools/partest/antlib.xml b/src/partest/scala/tools/partest/antlib.xml deleted file mode 100644 index b3b98e853f..0000000000 --- a/src/partest/scala/tools/partest/antlib.xml +++ /dev/null @@ -1,4 +0,0 @@ -<antlib> - <taskdef name="partest" - classname="scala.tools.partest.PartestTask"/> -</antlib> diff --git a/src/partest/scala/tools/partest/instrumented/Instrumentation.scala b/src/partest/scala/tools/partest/instrumented/Instrumentation.scala deleted file mode 100644 index 18dd740208..0000000000 --- a/src/partest/scala/tools/partest/instrumented/Instrumentation.scala +++ /dev/null @@ -1,93 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Grzegorz Kossakowski - */ - -package scala.tools.partest.instrumented - -import scala.collection.JavaConverters._ - -case class MethodCallTrace(className: String, methodName: String, methodDescriptor: String) { - override def toString(): String = className + "." + methodName + methodDescriptor -} -object MethodCallTrace { - implicit val ordering: Ordering[MethodCallTrace] = Ordering.by(x => (x.className, x.methodName, x.methodDescriptor)) -} - -/** - * An object that controls profiling of instrumented byte-code. The instrumentation is achieved - * by using `java.lang.instrument` package. The instrumentation agent can be found in - * `scala.tools.partest.javaagent` package. - * - * At the moment the following classes are being instrumented: - * * all classes with empty package - * * all classes from scala package (except for classes responsible for instrumentation) - * - * The canonical way of using instrumentation is have a test-case in `files/instrumented` directory. - * The following code in main: - * - * {{{ - * import scala.tools.partest.instrumented.Instrumentation._ - * def main(args: Array[String]): Unit = { - * startProfiling() - * // should box the boolean - println(true) - stopProfiling() - printStatistics() - * } - * }}} - * - * - * should print: - * - * {{{ - * true - * Method call statistics: - * scala/Predef$.println(Ljava/lang/Object;)V: 1 - * scala/runtime/BoxesRunTime.boxToBoolean(Z)Ljava/lang/Boolean;: 1 - * }}} - */ -object Instrumentation { - - type Statistics = Map[MethodCallTrace, Int] - - def startProfiling(): Unit = Profiler.startProfiling() - def stopProfiling(): Unit = Profiler.stopProfiling() - def resetProfiling(): Unit = Profiler.resetProfiling() - def isProfiling(): Boolean = Profiler.isProfiling() - - def getStatistics: Statistics = { - val isProfiling = Profiler.isProfiling() - if (isProfiling) { - Profiler.stopProfiling() - } - val stats = Profiler.getStatistics().asScala.toSeq.map { - case (trace, count) => MethodCallTrace(trace.className, trace.methodName, trace.methodDescriptor) -> count.intValue - } - val res = Map(stats: _*) - if (isProfiling) { - Profiler.startProfiling() - } - res - } - - val standardFilter: MethodCallTrace => Boolean = t => { - // ignore all calls to Console trigger by printing - t.className != "scala/Console$" && - // console accesses DynamicVariable, let's discard it too - !t.className.startsWith("scala/util/DynamicVariable") - } - - // Used in tests. - def printStatistics(stats: Statistics = getStatistics, filter: MethodCallTrace => Boolean = standardFilter): Unit = { - val stats = getStatistics - println("Method call statistics:") - val toBePrinted = stats.toSeq.filter(p => filter(p._1)).sortBy(_._1) - // <count> <trace> - val format = "%5d %s\n" - toBePrinted foreach { - case (trace, count) => printf(format, count, trace) - } - } - -} diff --git a/src/partest/scala/tools/partest/instrumented/Profiler.java b/src/partest/scala/tools/partest/instrumented/Profiler.java deleted file mode 100644 index e267e197e7..0000000000 --- a/src/partest/scala/tools/partest/instrumented/Profiler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Grzegorz Kossakowski - */ - -package scala.tools.partest.instrumented; - -import java.util.HashMap; -import java.util.Map; - -/** - * A simple profiler class that counts method invocations. It is being used in byte-code instrumentation by inserting - * call to {@link Profiler#methodCalled(String, String, String)} at the beginning of every instrumented class. - * - * WARANING: This class is INTERNAL implementation detail and should never be used directly. It's made public only - * because it must be universally accessible for instrumentation needs. If you want to profile your test use - * {@link Instrumentation} instead. - */ -public class Profiler { - - private static boolean isProfiling = false; - private static Map<MethodCallTrace, Integer> counts = new HashMap<MethodCallTrace, Integer>(); - - static public class MethodCallTrace { - final String className; - final String methodName; - final String methodDescriptor; - - public MethodCallTrace(final String className, final String methodName, final String methodDescriptor) { - this.className = className; - this.methodName = methodName; - this.methodDescriptor = methodDescriptor; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof MethodCallTrace)) { - return false; - } else { - MethodCallTrace that = (MethodCallTrace) obj; - return that.className.equals(className) && that.methodName.equals(methodName) && that.methodDescriptor.equals(methodDescriptor); - } - } - @Override - public int hashCode() { - return className.hashCode() ^ methodName.hashCode() ^ methodDescriptor.hashCode(); - } - } - - public static void startProfiling() { - isProfiling = true; - } - - public static void stopProfiling() { - isProfiling = false; - } - - public static boolean isProfiling() { - return isProfiling; - } - - public static void resetProfiling() { - counts = new HashMap<MethodCallTrace, Integer>(); - } - - public static void methodCalled(final String className, final String methodName, final String methodDescriptor) { - if (isProfiling) { - MethodCallTrace trace = new MethodCallTrace(className, methodName, methodDescriptor); - Integer counter = counts.get(trace); - if (counter == null) { - counts.put(trace, 1); - } else { - counts.put(trace, counter+1); - } - } - } - - public static Map<MethodCallTrace, Integer> getStatistics() { - return new HashMap<MethodCallTrace, Integer>(counts); - } - -} diff --git a/src/partest/scala/tools/partest/javaagent/ASMTransformer.java b/src/partest/scala/tools/partest/javaagent/ASMTransformer.java deleted file mode 100644 index 878c8613d5..0000000000 --- a/src/partest/scala/tools/partest/javaagent/ASMTransformer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Grzegorz Kossakowski - */ - -package scala.tools.partest.javaagent; - -import java.lang.instrument.ClassFileTransformer; -import java.security.ProtectionDomain; - -import scala.tools.asm.ClassReader; -import scala.tools.asm.ClassWriter; - -public class ASMTransformer implements ClassFileTransformer { - - private boolean shouldTransform(String className) { - return - // do not instrument instrumentation logic (in order to avoid infinite recursion) - !className.startsWith("scala/tools/partest/instrumented/") && - !className.startsWith("scala/tools/partest/javaagent/") && - // we instrument all classes from empty package - (!className.contains("/") || - // we instrument all classes from scala package - className.startsWith("scala/") || - // we instrument all classes from `instrumented` package - className.startsWith("instrumented/")); - } - - public byte[] transform(final ClassLoader classLoader, final String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { - if (shouldTransform(className)) { - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS) { - @Override protected String getCommonSuperClass(final String type1, final String type2) { - // Since we are not recomputing stack frame map, this should never be called we override this method because - // default implementation uses reflection for implementation and might try to load the class that we are - // currently processing. That leads to weird results like swallowed exceptions and classes being not - // transformed. - throw new RuntimeException("Unexpected call to getCommonSuperClass(" + type1 + ", " + type2 + - ") while transforming " + className); - } - }; - ProfilerVisitor visitor = new ProfilerVisitor(writer); - ClassReader reader = new ClassReader(classfileBuffer); - reader.accept(visitor, 0); - return writer.toByteArray(); - } else { - return classfileBuffer; - } - } -} diff --git a/src/partest/scala/tools/partest/javaagent/MANIFEST.MF b/src/partest/scala/tools/partest/javaagent/MANIFEST.MF deleted file mode 100644 index be0fee46a2..0000000000 --- a/src/partest/scala/tools/partest/javaagent/MANIFEST.MF +++ /dev/null @@ -1 +0,0 @@ -Premain-Class: scala.tools.partest.javaagent.ProfilingAgent diff --git a/src/partest/scala/tools/partest/javaagent/ProfilerVisitor.java b/src/partest/scala/tools/partest/javaagent/ProfilerVisitor.java deleted file mode 100644 index 8306327b14..0000000000 --- a/src/partest/scala/tools/partest/javaagent/ProfilerVisitor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Grzegorz Kossakowski - */ - -package scala.tools.partest.javaagent; - -import scala.tools.asm.ClassVisitor; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -public class ProfilerVisitor extends ClassVisitor implements Opcodes { - - private static String profilerClass = "scala/tools/partest/instrumented/Profiler"; - - public ProfilerVisitor(final ClassVisitor cv) { - super(ASM4, cv); - } - - private String className = null; - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - className = name; - super.visit(version, access, name, signature, superName, interfaces); - } - - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - // delegate the method call to the next - // chained visitor - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); - if (!profilerClass.equals(className)) { - // only instrument non-abstract methods - if((access & ACC_ABSTRACT) == 0) { - assert(className != null); - /* The following instructions do not modify compressed stack frame map so - * we don't need to worry about recalculating stack frame map. Specifically, - * let's quote "ASM 4.0, A Java bytecode engineering library" guide (p. 40): - * - * In order to save space, a compiled method does not contain one frame per - * instruction: in fact it contains only the frames for the instructions - * that correspond to jump targets or exception handlers, or that follow - * unconditional jump instructions. Indeed the other frames can be easily - * and quickly inferred from these ones. - * - * Instructions below are just loading constants and calling a method so according - * to definition above they do not contribute to compressed stack frame map. - */ - mv.visitLdcInsn(className); - mv.visitLdcInsn(name); - mv.visitLdcInsn(desc); - mv.visitMethodInsn(INVOKESTATIC, profilerClass, "methodCalled", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - } - } - return mv; - } - -} diff --git a/src/partest/scala/tools/partest/javaagent/ProfilingAgent.java b/src/partest/scala/tools/partest/javaagent/ProfilingAgent.java deleted file mode 100644 index 3b18987040..0000000000 --- a/src/partest/scala/tools/partest/javaagent/ProfilingAgent.java +++ /dev/null @@ -1,25 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - * @author Grzegorz Kossakowski - */ - -package scala.tools.partest.javaagent; - -import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; - -/** - * Profiling agent that instruments byte-code to insert calls to - * {@link scala.tools.partest.instrumented.Profiler#methodCalled(String, String, String)} - * by using ASM library for byte-code manipulation. - */ -public class ProfilingAgent { - public static void premain(String args, Instrumentation inst) throws UnmodifiableClassException { - // NOTE: we are adding transformer that won't be applied to classes that are already loaded - // This should be ok because premain should be executed before main is executed so Scala library - // and the test-case itself won't be loaded yet. We rely here on the fact that ASMTransformer does - // not depend on Scala library. In case our assumptions are wrong we can always insert call to - // inst.retransformClasses. - inst.addTransformer(new ASMTransformer(), false); - } -} 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) - } -} diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala deleted file mode 100644 index 77400b1b9c..0000000000 --- a/src/partest/scala/tools/partest/package.scala +++ /dev/null @@ -1,241 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2013 LAMP/EPFL - */ - -package scala.tools - -import java.util.concurrent.{ Callable, ExecutorService } -import scala.concurrent.duration.Duration -import scala.sys.process.javaVmArguments -import scala.tools.partest.nest.NestUI -import scala.tools.nsc.util.{ ScalaClassLoader, Exceptional } - -package object partest { - type File = java.io.File - type SFile = scala.reflect.io.File - type Directory = scala.reflect.io.Directory - type Path = scala.reflect.io.Path - type PathResolver = scala.tools.util.PathResolver - type ClassPath[T] = scala.tools.nsc.util.ClassPath[T] - type StringWriter = java.io.StringWriter - - val SFile = scala.reflect.io.File - val Directory = scala.reflect.io.Directory - val Path = scala.reflect.io.Path - val PathResolver = scala.tools.util.PathResolver - val ClassPath = scala.tools.nsc.util.ClassPath - - val space = "\u0020" - val EOL = scala.compat.Platform.EOL - def onull(s: String) = if (s == null) "" else s - def oempty(xs: String*) = xs filterNot (x => x == null || x == "") - def ojoin(xs: String*): String = oempty(xs: _*) mkString space - def nljoin(xs: String*): String = oempty(xs: _*) mkString EOL - - implicit val codec = scala.io.Codec.UTF8 - - def setUncaughtHandler() = { - Thread.setDefaultUncaughtExceptionHandler( - new Thread.UncaughtExceptionHandler { - def uncaughtException(thread: Thread, t: Throwable) { - val t1 = Exceptional unwrap t - System.err.println(s"Uncaught exception on thread $thread: $t1") - t1.printStackTrace() - } - } - ) - } - - /** Sources have a numerical group, specified by name_7 and so on. */ - private val GroupPattern = """.*_(\d+)""".r - - implicit class FileOps(val f: File) { - private def sf = SFile(f) - - def testIdent = { - f.toString split """[/\\]+""" takeRight 2 mkString "/" // e.g. pos/t1234 - } - - def mapInPlace(mapFn: String => String)(filterFn: String => Boolean = _ => true): Unit = - writeAll(fileLines filter filterFn map (x => mapFn(x) + EOL): _*) - - def appendAll(strings: String*): Unit = sf.appendAll(strings: _*) - def writeAll(strings: String*): Unit = sf.writeAll(strings: _*) - def absolutePathSegments: List[String] = f.getAbsolutePath split """[/\\]+""" toList - - def isJava = f.isFile && (sf hasExtension "java") - def isScala = f.isFile && (sf hasExtension "scala") - def isJavaOrScala = isJava || isScala - - def extension = sf.extension - def hasExtension(ext: String) = sf hasExtension ext - def changeExtension(ext: String): File = (sf changeExtension ext).jfile - - /** The group number for this source file, or -1 for no group. */ - def group: Int = - sf.stripExtension match { - case GroupPattern(g) if g.toInt >= 0 => g.toInt - case _ => -1 - } - - def fileContents: String = try sf.slurp() catch { case _: java.io.FileNotFoundException => "" } - def fileLines: List[String] = augmentString(fileContents).lines.toList - } - - implicit class PathOps(p: Path) extends FileOps(p.jfile) { } - - implicit class Copier(val f: SFile) extends AnyVal { - def copyTo(dest: Path): Unit = dest.toFile writeAll f.slurp(scala.io.Codec.UTF8) - } - - implicit class LoaderOps(val loader: ClassLoader) extends AnyVal { - import scala.util.control.Exception.catching - /** Like ScalaClassLoader.create for the case where the result type is - * available to the current class loader, implying that the current - * loader is a parent of `loader`. - */ - def instantiate[A >: Null](name: String): A = ( - catching(classOf[ClassNotFoundException], classOf[SecurityException]) opt - (loader loadClass name).newInstance.asInstanceOf[A] orNull - ) - } - - implicit class ExecutorOps(val executor: ExecutorService) { - def awaitTermination[A](wait: Duration)(failing: => A = ()): Option[A] = ( - if (executor awaitTermination (wait.length, wait.unit)) None - else Some(failing) - ) - } - - implicit def temporaryPath2File(x: Path): File = x.jfile - implicit def stringPathToJavaFile(path: String): File = new File(path) - - implicit lazy val postfixOps = scala.language.postfixOps - implicit lazy val implicitConversions = scala.language.implicitConversions - - def fileSeparator = java.io.File.separator - def pathSeparator = java.io.File.pathSeparator - - def pathToTestIdent(path: Path) = path.jfile.testIdent - - def canonicalizeSlashes(line: String) = line.replaceAll("""[/\\]+""", "/") - - def words(s: String): List[String] = (s.trim split "\\s+").toList - - def timed[T](body: => T): (T, Long) = { - val t1 = System.currentTimeMillis - val result = body - val t2 = System.currentTimeMillis - - (result, t2 - t1) - } - - def callable[T](body: => T): Callable[T] = new Callable[T] { override def call() = body } - - def file2String(f: File): String = f.fileContents - - def basename(name: String): String = Path(name).stripExtension - - /** In order to allow for spaces in flags/options, this - * parses .flags, .javaopts, javacopts etc files as follows: - * If it is exactly one line, it is split (naively) on spaces. - * If it contains more than one line, each line is its own - * token, spaces and all. - */ - def readOptionsFile(file: File): List[String] = { - file.fileLines match { - case x :: Nil => words(x) - case xs => xs map (_.trim) - } - } - - def findProgram(name: String): Option[File] = { - val pathDirs = sys.env("PATH") match { - case null => List("/usr/local/bin", "/usr/bin", "/bin") - case path => path split "[:;]" filterNot (_ == "") toList - } - pathDirs.iterator map (d => new File(d, name)) find (_.canExecute) - } - - def now = (new java.util.Date).toString - def elapsedString(millis: Long): String = { - val elapsedSecs = millis/1000 - val elapsedMins = elapsedSecs/60 - val elapsedHrs = elapsedMins/60 - val dispMins = elapsedMins - elapsedHrs * 60 - val dispSecs = elapsedSecs - elapsedMins * 60 - - "%02d:%02d:%02d".format(elapsedHrs, dispMins, dispSecs) - } - - def vmArgString = javaVmArguments.mkString( - "Java VM started with arguments: '", - " ", - "'" - ) - - def allPropertiesString = { - import scala.collection.JavaConversions._ - System.getProperties.toList.sorted map { case (k, v) => "%s -> %s\n".format(k, v) } mkString "" - } - - def showAllJVMInfo() { - vlog(vmArgString) - vlog(allPropertiesString) - } - - import scala.language.experimental.macros - - /** - * `trace("".isEmpty)` will return `true` and as a side effect print the following to standard out. - * {{{ - * trace> "".isEmpty - * res: Boolean = true - * - * }}} - * - * An alternative to [[scala.tools.partest.ReplTest]] that avoids the inconvenience of embedding - * test code in a string. - */ - def trace[A](a: A) = macro traceImpl[A] - - import scala.reflect.macros.Context - def traceImpl[A: c.WeakTypeTag](c: Context)(a: c.Expr[A]): c.Expr[A] = { - import c.universe._ - import definitions._ - - // xeno.by: reify shouldn't be used explicitly before the final release of 2.10.0, - // because this impairs reflection refactorings - // - // val exprCode = c.literal(show(a.tree)) - // val exprType = c.literal(show(a.actualType)) - // reify { - // println(s"trace> ${exprCode.splice}\nres: ${exprType.splice} = ${a.splice}\n") - // a.splice - // } - - c.Expr(Block( - List(Apply( - Select(Ident(PredefModule), TermName("println")), - List(Apply( - Select(Apply( - Select(Ident(ScalaPackage), TermName("StringContext")), - List( - Literal(Constant("trace> ")), - Literal(Constant("\\nres: ")), - Literal(Constant(" = ")), - Literal(Constant("\\n")))), - TermName("s")), - List( - Literal(Constant(show(a.tree))), - Literal(Constant(show(a.actualType))), - a.tree))))), - a.tree)) - } - - def isPartestTerse = NestUI.isTerse - def isPartestDebug = NestUI.isDebug - def isPartestVerbose = NestUI.isVerbose - - def vlog(msg: => String) = if (isPartestVerbose) System.err.println(msg) -} diff --git a/src/partest/scala/tools/partest/utils/Properties.scala b/src/partest/scala/tools/partest/utils/Properties.scala deleted file mode 100644 index b9394b50c9..0000000000 --- a/src/partest/scala/tools/partest/utils/Properties.scala +++ /dev/null @@ -1,18 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala Parallel Testing ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.tools.partest -package utils - -/** Loads partest.properties from the jar. */ -object Properties extends scala.util.PropertiesTrait { - protected def propCategory = "partest" - protected def pickJarBasedOn = classOf[nest.RunnerManager] - override def isAvian = super.isAvian -} |