diff options
author | michelou <michelou@epfl.ch> | 2007-09-11 15:41:12 +0000 |
---|---|---|
committer | michelou <michelou@epfl.ch> | 2007-09-11 15:41:12 +0000 |
commit | 385b899a0cb04337525b32c201e1dbabb5b1bef9 (patch) | |
tree | e056f154572164dc6b55ce4b0c40caf5c0490d98 | |
parent | cf471e6091fa5c2d74ddbafde7da08f3ca64f416 (diff) | |
download | scala-385b899a0cb04337525b32c201e1dbabb5b1bef9.tar.gz scala-385b899a0cb04337525b32c201e1dbabb5b1bef9.tar.bz2 scala-385b899a0cb04337525b32c201e1dbabb5b1bef9.zip |
partest integration (alpha)
-rw-r--r-- | build.xml | 61 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/MasterActor.scala | 163 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/TestRunner.scala | 197 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/WorkerActor.scala | 307 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/utils/PrintMgr.scala | 51 | ||||
-rwxr-xr-x | test/partest | 906 |
6 files changed, 1684 insertions, 1 deletions
@@ -61,8 +61,10 @@ PROPERTIES <property name="lib.jar.name" value="scala-library.jar"/> <property name="dbc.jar.name" value="scala-dbc.jar"/> <property name="comp.jar.name" value="scala-compiler.jar"/> + <property name="partest.jar.name" value="scala-partest.jar"/> <property name="libsrc.jar.name" value="scala-library-src.jar"/> <property name="dbcsrc.jar.name" value="scala-dbc-src.jar"/> + <property name="parsrc.jar.name" value="scala-partest-src.jar"/> <property name="compsrc.jar.name" value="scala-compiler-src.jar"/> <property name="scala.exec.name" value="scala"/> <property name="scalac.exec.name" value="scalac"/> @@ -568,6 +570,19 @@ BUILD QUICK-TEST LAYER message="copyright.string=${copyright.string}${line.separator}" append="true" /> + <!-- Build partest --> + <mkdir dir="${quick.dir}/lib/partest"/> + <starr + srcdir="${src.dir}/partest" + destdir="${quick.dir}/lib/partest" + addparams="${nsc.params}" + deprecation="yes" unchecked="yes"> + <classpath> + <pathelement location="${quick.dir}/lib/library"/> + <pathelement location="${quick.dir}/lib/compiler"/> + <pathelement location="${quick.dir}/lib/actors"/> + </classpath> + </starr> <!-- Timing the build --> <stopwatch name="timer.quick" action="total"/> <!-- Copy support files to build folder and links external libraries--> @@ -955,7 +970,19 @@ TEST message="copyright.string=${copyright.string}${line.separator}" append="true" /> - + <!-- Build partest --> + <mkdir dir="${strap.dir}/lib/partest"/> + <starr + srcdir="${src.dir}/partest" + destdir="${strap.dir}/lib/partest" + addparams="${nsc.params}" + deprecation="yes" unchecked="yes"> + <classpath> + <pathelement location="${strap.dir}/lib/library"/> + <pathelement location="${strap.dir}/lib/compiler"/> + <pathelement location="${strap.dir}/lib/actors"/> + </classpath> + </starr> <!-- Timing the build --> <stopwatch name="timer.strap" action="total"/> <!-- Copy support files to build folder and links external libraries--> @@ -1290,6 +1317,33 @@ GENERATES A DISTRIBUTION <attribute name="Bundle-RequiredExecutionEnvironment" value="J2SE-1.4"/> </manifest> </jar> + <jar destfile="${dist.current.dir}/lib/${partest.jar.name}"> + <fileset dir="${strap.dir}/lib/partest"/> + <manifest> + <attribute name="Signature-Version" value="${version.number}"/> + <attribute name="Built-By" value="${user.name}"/> + <attribute name="Main-Class" value="scala.tools.partest.TestRunner"/> + <attribute name="Class-Path" value="${lib.jar.name}"/> + <section name="scala/tools/partest"> + <attribute name="Extension-Name" value="scala.tools.partest"/> + <attribute name="Specification-Title" value="Scala Test Utility"/> + <attribute name="Specification-Version" value="${version.number}"/> + <attribute name="Specification-Vendor" value="${vendor.name}"/> + <attribute name="Implementation-Title" value="scala.tools.partest"/> + <attribute name="Implementation-Version" value="${version.number}"/> + <attribute name="Implementation-Vendor" value="${vendor.name}"/> + </section> + <attribute name="Bundle-DocURL" value="http://www.scala-lang.org/"/> + <attribute name="Bundle-ManifestVersion" value="2"/> + <attribute name="Bundle-Name" value="Scala Test Bundle"/> + <attribute name="Bundle-SymbolicName" value="scala_compiler"/> + <attribute name="Bundle-Version" value="${osgi.version.number}"/> + <attribute name="Bundle-Vendor" value="${vendor.name}"/> + <attribute name="Export-Package" value="scala.tools.partest;version="${osgi.version.number}",scala.tools.partest.utils;version="${osgi.version.number}""/> + <attribute name="Import-Package" value="javax.swing"/> + <attribute name="Bundle-RequiredExecutionEnvironment" value="J2SE-1.4"/> + </manifest> + </jar> <!-- build source jars --> <jar @@ -1303,6 +1357,11 @@ GENERATES A DISTRIBUTION includes="**/*.scala" /> <jar + destfile="${dist.current.dir}/lib/${parsrc.jar.name}" + basedir="${src.dir}/partest" + includes="**/*.scala" + /> + <jar destfile="${dist.current.dir}/lib/${compsrc.jar.name}" basedir="${src.dir}/compiler" includes="**/*.scala" diff --git a/src/partest/scala/tools/partest/MasterActor.scala b/src/partest/scala/tools/partest/MasterActor.scala new file mode 100644 index 0000000000..77924a73b5 --- /dev/null +++ b/src/partest/scala/tools/partest/MasterActor.scala @@ -0,0 +1,163 @@ +/* __ *\ +** ________ ___ / / ___ Scala Parallel Testing ** +** / __/ __// _ | / / / _ | (c) 2007-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + +package scala.tools.partest + +import java.awt.event.{ActionEvent, ActionListener} +import java.io.{File, FileOutputStream, PrintStream} +import javax.swing.Timer + +import scala.actors.Actor +import scala.tools.nsc.Settings + +import utils.PrintMgr._ + +/** + * @author Adriaan Moors, Thomas Hofer + * @version 1.0 + */ +class MasterActor(testDir: File, out: PrintStream) extends Actor { + import scala.actors.Actor._ + + private final val testPathLen = testDir.getPath.length + + private final val WIDTH = 56 + private final val TIMEOUT = 1360000 + + private var counter = 0 + private var failed = 0 + + private var conservative = false + + private val globalSettings = new Settings(x => ()) + + //private var numOfActors = Math.min(4, Math.max(Integer.parseInt(System.getProperty("actors.maxPoolSize")), + private val numOfActors = 4 + //println("Starting with " + numOfActors + " actors...") + + private var workers = (for (i <- 0 until numOfActors) yield (new WorkerActor(this, new Settings(x => ()), new ExtConsoleReporter(globalSettings)), i)).toList + + private var workingOn: List[(Int, Test)] = List() + + private var timers = (for (i <- 0 until numOfActors) yield createTimer(workers(i)._1)).toList + + private var testsToRun: List[Test] = List() + + private var failedTests: List[Test] = List() + + private def createTimer(worker: WorkerActor): Timer = { + val action: ActionListener = new ActionListener { + def actionPerformed(event: ActionEvent) { + val workerID = workers.find((_)._1 == worker) match { + case Some(x) => x + case None => (null, -1) + } + val test = workingOn.find((_)._1 == workerID._2) match { + case Some(x) => x._2 + case None => null + } + println("Actor " + workerID._1 + " failed, while testing " + test.file.getPath) + failedTests.find(_ == test) match { + case Some(x) => //... + case None => testFailed(workerID, test) + } + + } + } + + new Timer(TIMEOUT, action) + } + + private def testFailed(actor: (WorkerActor, Int), test: Test) = { + failedTests = test :: failedTests + var newWorker = new WorkerActor(this, new Settings(x => ()), new ExtConsoleReporter(globalSettings)) + timers(actor._2).stop + timers = timers.take(actor._2 - 1) ::: List(createTimer(newWorker)) ::: timers.drop(actor._2) + newWorker.start + //println("Started actor " + newWorker) + workers = (newWorker, actor._2) :: workers.remove(_ == actor) + + timers(actor._2).start + newWorker ! (test, true, conservative) + } + + private def hasNextTest = !testsToRun.isEmpty + + private def nextTest(): Test = { + val test = testsToRun.head + testsToRun = testsToRun.tail + test + } + + def act() { + loop { + react { + case (test: Test) => + testsToRun = test :: testsToRun + + case ("start", conservative: Boolean) => + this.conservative = conservative + workers foreach ((x) => { + if (hasNextTest) { + x._1.start + val test = nextTest() + // TODO Change here should be x._1 ! (test, false, conservative) + x._1 ! (test, false, conservative) + timers(x._2).start + workingOn = (x._2, test) :: workingOn + } + }) + + case (kind: String, succeeded: Boolean, file: File) => + val workerID = workers.find((_)._1 == sender) match { + case Some(x) => x + case None => (null, -1) + } + if (workerID._2 != -1) { + workingOn = workingOn.remove((_)._1 == workerID._2) + if (hasNextTest) { + val test = nextTest() + // TODO Change here should be x._1 ! (test, false, conservative) + sender ! (test, false, conservative) + timers(workerID._2).restart + workingOn = (workerID._2, test) :: workingOn + } else { + sender ! false + timers(workerID._2).stop + } + } else { + //Houston, we got a problem... + } + counter += 1 + printOutline("testing: ") + val name = file.getPath.substring(testPathLen) + print("[...]" + name + List.toString(List.make(WIDTH - name.length, ' ')) + "[") + if (succeeded) { + printSuccess(" OK ") + } else { + failed += 1 + printFailure("FAILED") + } + println("]") + if (workingOn.isEmpty) { + out.println(failed) + out.println(counter - failed) + out.close + println + exit + } + + case msg => + println(msg) + } + } + } + +} diff --git a/src/partest/scala/tools/partest/TestRunner.scala b/src/partest/scala/tools/partest/TestRunner.scala new file mode 100644 index 0000000000..1fa0680a9a --- /dev/null +++ b/src/partest/scala/tools/partest/TestRunner.scala @@ -0,0 +1,197 @@ +/* __ *\ +** ________ ___ / / ___ Scala Parallel Testing ** +** / __/ __// _ | / / / _ | (c) 2007-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + +package scala.tools.partest + +import java.awt.event.{ActionEvent, ActionListener} +import java.io.{File, FilenameFilter, FileOutputStream, PrintStream} + +import scala.tools.nsc.Settings + +import utils.PrintMgr +import utils.PrintMgr._ + +/** + * @author Adriaan Moors, Thomas Hofer + * @version 1.0 + */ +class Test(val kind: String, val file: File) { + val dir = file.getParent + protected def baseSettings(settings: Settings) { + settings.classpath.value = dir + settings.outdir.value = { + var outDir = new File(dir, fileBase + "-" + kind + ".obj") + outDir.mkdir + outDir.toString + } + settings.deprecation.value = true + settings.nowarnings.value = false + settings.encoding.value = "iso-8859-1" + } + def defineSettings(settings: Settings) { + baseSettings(settings) + } + private def basename(name: String): String = { + val inx = name.lastIndexOf(".") + if (inx < 0) name else name.substring(0, inx) + } + val fileBase: String = basename(file.getName) + val logFile: File = new File(dir, fileBase + "-" + kind + ".log") + val checkFile: File = { + var chkFile = new File(dir, fileBase + ".check") + if (chkFile.isFile) { + chkFile + } else { + new File(dir, fileBase + "-" + kind + ".check") + } + } +} + +case class PosTest(override val file: File) extends Test("pos", file) +case class NegTest(override val file: File) extends Test("neg", file) +case class JVMTest(override val file: File) extends Test("jvm", file) { + override def defineSettings(settings: Settings) { + baseSettings(settings) + settings.target.value = + if (dir endsWith "jvm5") "jvm-1.5" else "jvm-1.4" + settings.classpath.value = System.getProperty("JVMEXTCP") + TestRunner.printVerbose("CLASSPATH="+settings.classpath.value +"\n") + } +} +case class ShootoutTest(override val file: File) extends Test("shootout", file) { + override def defineSettings(settings: Settings) { + baseSettings(settings) + settings.classpath.value = System.getProperty("JVMEXTCP") + } +} + +/** + * @author Stephane Micheloud + * @version 1.0 + */ +object TestRunner { + private var posCheck = false + private var negCheck = false + private var jvmCheck = false + private var runCheck = false + private var shootoutCheck = false + + private var conservative = false + private var verbose = false + + private var testDir: File = _ + private val con = new PrintStream(Console.out) + private var out = con + + private def go { + val master = new MasterActor(testDir, out) + val filter = new FilenameFilter { + def accept(dir: File, name: String): Boolean = name endsWith ".scala" + } + def getFiles(kind: String): List[File] = { + val kindDir = "files" + File.separator + kind + val dir = new File(testDir, kindDir) + if (dir.isDirectory) dir.listFiles(filter).toList + else { + println("Directory \"" + testDir.getPath + File.separator + kindDir + "\" not found") + Nil + } + } + + master.start + + if (posCheck) { + printOutline("Testing compiler (on files whose compilation should succeed)\n") + for (file <- getFiles("pos")) master ! PosTest(file) + } + if (negCheck) { + printOutline("Testing compiler (on files whose compilation should fail)\n") + for (file <- getFiles("neg")) master ! NegTest(file) + } + if (jvmCheck) { + printOutline("Testing JVM backend\n") + for (file <- getFiles("jvm")) master ! JVMTest(file) + for (file <- getFiles("run")) master ! JVMTest(file) + for (file <- getFiles("jvm5")) master ! JVMTest(file) + } else if (runCheck) { + printOutline("Testing JVM backend\n") + for (file <- getFiles("run")) master ! JVMTest(file) + } + if (shootoutCheck) { + printOutline("Testing shootout benchmarks\n") + for (file <- getFiles("shootout")) master! ShootoutTest(file) + } + + master ! ("start", conservative) + } + + private def printUsage { + println("Usage: TestRunner [<options>] <testdir> [<resfile>]") + println(" --pos ...") + println(" --neg ...") + println(" --jvm ...") + println(" --run ...") + println(" --shootout ...") + println(" --conservative ...") + println(" --verbose display progress information") + println + println("Send bugs to <scala@listes.epfl.ch>") + exit(1) + } + + final def printVerbose(msg: String) { + if (verbose) { + printOutline("debug : ") + println(msg) + } + } + + def main(args: Array[String]) { + if (args.length == 0) + printUsage + else { + for (arg <- args) { + arg match { + case "--pos" => posCheck = true + case "--neg" => negCheck = true + case "--jvm" => jvmCheck = true + case "--run" => runCheck = true + case "--shootout" => shootoutCheck = true + case "--conservative" => conservative = true + case "--verbose" => verbose = true + case _ => + if (testDir eq null) { + val dir = new File(arg) + if (dir.isDirectory) testDir = dir + else { + println("Directory \"" + arg + "\" not found") + exit(1) + } + } else if (out eq con) { + val file = new File(arg) + if (file.isFile || file.createNewFile) + out = new PrintStream(file) + else { + println("Result file \"" + arg + "\" not found") + exit(1) + } + } else + printUsage + } + } + if (!(posCheck | negCheck | jvmCheck | runCheck | shootoutCheck)) { + posCheck = true + negCheck = true + } + initialization(PrintMgr.MANY) + go + } + } +} diff --git a/src/partest/scala/tools/partest/WorkerActor.scala b/src/partest/scala/tools/partest/WorkerActor.scala new file mode 100644 index 0000000000..4b8bd3b4d0 --- /dev/null +++ b/src/partest/scala/tools/partest/WorkerActor.scala @@ -0,0 +1,307 @@ +/* __ *\ +** ________ ___ / / ___ Scala Parallel Testing ** +** / __/ __// _ | / / / _ | (c) 2007-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + +package scala.tools.partest + +import java.io.{BufferedInputStream, BufferedReader, File, FileReader, + FileInputStream, FileOutputStream, InputStreamReader, + PrintStream, PrintWriter} +import java.net.URL + +import scala.actors.Actor +import scala.tools.nsc.{Global, ObjectRunner, Settings} +import scala.tools.nsc.reporters.{Reporter, AbstractReporter, ConsoleReporter} + + +class ExtConsoleReporter(override val settings: Settings, reader: BufferedReader, var writer: PrintWriter) extends ConsoleReporter(settings, reader, writer) { + def this(settings: Settings) = { + this(settings, Console.in, new PrintWriter("/dev/null")) + } + def hasWarnings: Boolean = WARNING.count != 0 +} + +class ExtGlobal(settings: Settings, reporter: Reporter) extends Global(settings, reporter) { + override def inform(msg: String) {} +} + +/** + * @author Adriaan Moors, Thomas Hofer + * @version 1.0 + */ +class WorkerActor(val master: MasterActor, val settings: Settings, var reporter: ExtConsoleReporter) extends Actor { + import scala.actors.Actor._ + + def newGlobal: ExtGlobal = new ExtGlobal(settings, reporter) + + def newGlobal(log: File): ExtGlobal = { + reporter = new ExtConsoleReporter(new Settings(x => ()), Console.in, new PrintWriter(log)) + reporter.shortname = true + newGlobal + } + + private def dirDelete(dir: File) { + if (dir.isDirectory) { + for (file <- dir.list) dirDelete(new File(dir, file)) + } + dir.delete + } + + def act() { + var compiler = newGlobal + val bufferSize = 1024 + val originBuffer = new Array[Byte](bufferSize) + val destBuffer = new Array[Byte](bufferSize) + loop { + react { + case (test: Test, bypass: Boolean, conservative: Boolean) => { + var bypassObjectRunner = bypass + if (!bypassObjectRunner) { + // TODO check the shootout source files for "dangerous" patterns, such as: Console.read, Scheduler.impl, + val dangerousCode = List("Console.read", "Scheduler.impl", "System.exit", "System.out").foldLeft("")((x, y) => x + " -e " + y) + val grepCmd = "grep " + test.file.getPath + " " + dangerousCode + TestRunner.printVerbose("grep cmd: " + grepCmd + "\n") + + val grep = Runtime.getRuntime.exec(grepCmd) + + val in = new BufferedReader(new InputStreamReader(grep.getInputStream)) + + val line = in.readLine + bypassObjectRunner = (line != null) + + in.close + + //println(bypassObjectRunner) + } + + var start = System.currentTimeMillis + //println("Starting..." + test.kind + " " + test.test) + + var toCompile = List(test.file.getPath) + + var outDir: File = new File(test.dir, test.fileBase + "-" + test.kind + ".obj") + if (! outDir.exists) { + outDir.mkdir + //println(this.toString + " " + "Created " + outDir) + } else { + //println(this.toString + " " + "Didn't need to create " + outDir) + } + test match { + case NegTest(_) => + compiler = newGlobal(test.logFile) + + case JVMTest(_) => + //println(test.file.getPath + ": " + test.checkFile.exists + " / " + test.logFile.exists) + if (test.checkFile.exists) { + var checkReader = new BufferedReader(new FileReader(test.checkFile)) + var firstLine = checkReader.readLine + if (firstLine != null && firstLine.startsWith("warning")) { + //reporter = new ExtConsoleReporter(new Settings(x => ()), Console.in, new PrintWriter(logFile)) + //reporter.shortname = true + compiler = newGlobal(test.logFile) + } + } else if (conservative) compiler = newGlobal + + case ShootoutTest(_) => + var testFile = new File(outDir, "Test.scala") + if (testFile.exists) { + toCompile = List(testFile.toString) + //println(this.toString + " ready to compile :" + toCompile) + } else { + // BASH script couldn't create test file... + } + if (test.checkFile.exists) { + var checkReader = new BufferedReader(new FileReader(test.checkFile)) + var firstLine = checkReader.readLine + if (firstLine.startsWith("warning")) { + //reporter = new ExtConsoleReporter(new Settings(x => ()), Console.in, new PrintWriter(logFile)) + //reporter.shortname = true + compiler = newGlobal(test.logFile) + } + } else if (conservative) compiler = newGlobal + + case _ => + } + + val c = compiler + + //println("about to define compilation settings...") + + test.defineSettings(settings) + try { + //println(this.toString + " " + "Launching compiler on " + toCompile) + (new c.Run) compile toCompile + reporter.printSummary + reporter.writer.flush + reporter.writer.close + //println(this.toString + " " + "Finished compiling " + test.fileBase) + } catch { + case e => { + e.printStackTrace + reporter.error(null, "IO/Error") + } + } + (reporter.hasErrors, test) match { + case (_, NegTest(_)) => + case (true, _) => + compiler = newGlobal + val c = compiler + try { + (new c.Run) compile toCompile + } catch { + case e => reporter.error(null, "IO/Error") + } + case _ => + } + + var result = test match { + case NegTest(_) => reporter.hasErrors + case _ => !reporter.hasErrors + } + + (bypassObjectRunner, result, test) match { + case (_, _, PosTest(_)) => + case (_, _, NegTest(_)) => + case (false, true, _) => + System.setProperty("scalatest.output", outDir.toString) + test match { + case ShootoutTest(_) => System.setProperty("scalatest.cwd", test.dir) + case _ => {} + } + + var classpath: List[URL] = outDir.toURL :: List((new File(test.dir)).toURL) ::: List.fromString(System.getProperty("CLASSPATH"), ':').map(x => (new File(x)).toURL) ::: List.fromString(System.getProperty("JVMEXTCP"), ':').map(x => (new File(x)).toURL) + + try { + //println(this.toString + " " + "Launching test " + test.fileBase) + var out = new FileOutputStream(test.logFile, true) + Console.withOut(new PrintStream(out)) { + ObjectRunner.run(classpath, "Test", List("jvm")) + } + out.flush + out.close + //println(this.toString + " " + "Finished running " + test.fileBase) + } catch { case t => println(t) } + + case _ => + } + (!bypassObjectRunner && result, test.checkFile.exists, test) match { + case (_, _, PosTest(_)) => + case (true, true, _) => + /*var cmd: String = "diff " + test.logFile + " " + test.checkFile + //println(this.toString + " Comparing files " + test.fileBase) + var proc: Process = Runtime.getRuntime.exec(cmd) + proc.waitFor + result = (proc.exitValue == 0)*/ + var equalNow = true + if (test.checkFile.canRead) { + val originStream = new FileInputStream(test.logFile) + val destStream = new FileInputStream(test.checkFile) + var originSize = originStream.read(originBuffer) + while (originSize >= 0) { + if (originSize == destStream.read(destBuffer)) { + for (idx <- 0 until originSize) + equalNow = equalNow && (originBuffer(idx) == destBuffer(idx)) + if (!equalNow) { + result = false + //println("Diff1: diffs found") + } + } + else { + result = false + //println("Diff1: diffs found") + } + originSize = originStream.read(originBuffer) + } + if (destStream.read(destBuffer) >= 0) result = false + } + + case _ => + //println("Not testing diff... " + test.test) + } + + (bypassObjectRunner || !result, test) match { + case (_, PosTest(_)) => + case (_, NegTest(_)) => + case (true, _) => + result = true + var javaoptsFile = new File(test.dir, test.fileBase + ".javaopts") + //var javaNewOpts = (new BufferedFileReader(javaoptsFile)).readLine + //if (javaoptsFile.exists && javaNewOpts != null) {} + //Use Runtime.exec to execute the compiled file and pipe the standard system out and the console out to the logfile + var cmd = "env JAVACMD=java JAVA_OPTS=-Djava.library.path="+test.dir+" "+System.getProperty("SCALA")+" -Dscalatest.lib="+System.getProperty("scalatest.lib")+" -Dscalatest.cwd="+test.dir+" -Dscalatest.output="+outDir+" -classpath "+outDir+":"+System.getProperty("CLASSPATH")+":"+System.getProperty("JVMEXTCP")+" Test jvm" + + //println(cmd) + + var execution = Runtime.getRuntime.exec(cmd) + + var in = execution.getInputStream + var out = new FileOutputStream(test.logFile) + + var c = in.read + while (c != -1) { + out.write(c) + c = in.read + } + + in.close + out.close + + //println("Running diff") + + /*var diff = Runtime.getRuntime.exec("diff " + test.logFile + " " + test.checkFile) + diff.waitFor + + result = (diff.exitValue == 0)*/ + var equalNow = true + if (test.checkFile.canRead) { + val originStream = new FileInputStream(test.logFile) + val destStream = new FileInputStream(test.checkFile) + var originSize = originStream.read(originBuffer) + while (originSize >= 0) { + if (originSize == destStream.read(destBuffer)) { + for (idx <- 0 until originSize) + equalNow = equalNow && (originBuffer(idx) == destBuffer(idx)) + if (!equalNow) { + result = false + //println("Differences found between the log and check files..") + } + } + else { + result = false + //println("Differences found between the log and check files..") + } + + originSize = originStream.read(originBuffer) + } + if (destStream.read(destBuffer) >= 0) result = false + } + //else reportMissing(originFile) + + case _ => + //println("Not Using runtime... " + test.test) + } + test.logFile.delete + + var end = System.currentTimeMillis + + //println(test.test + ": " + (end - start)) + + //printSuccess(this.toString + " " + fileBase + ": "+ result + "\n") + master ! (test.kind, result, test.file) + dirDelete(outDir) + } + case false => + exit + + case msg => + println("Unknown message : " + msg) + } + } + } +} diff --git a/src/partest/scala/tools/partest/utils/PrintMgr.scala b/src/partest/scala/tools/partest/utils/PrintMgr.scala new file mode 100644 index 0000000000..a47657d611 --- /dev/null +++ b/src/partest/scala/tools/partest/utils/PrintMgr.scala @@ -0,0 +1,51 @@ +/* __ *\ +** ________ ___ / / ___ Scala Parallel Testing ** +** / __/ __// _ | / / / _ | (c) 2007-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + +package scala.tools.partest.utils + +/** + * @author Thomas Hofer + */ +object PrintMgr { + + val NONE = 0 + val SOME = 1 + val MANY = 2 + + var outline = "" + var success = "" + var failure = "" + var warning = "" + var default = "" + + def initialization(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 printOutline(msg: String) = print(outline + msg + default) + + def printSuccess(msg: String) = print(success + msg + default) + + def printFailure(msg: String) = print(failure + msg + default) + + def printWarning(msg: String) = print(warning + msg + default) +} diff --git a/test/partest b/test/partest new file mode 100755 index 0000000000..31e3680b32 --- /dev/null +++ b/test/partest @@ -0,0 +1,906 @@ +#!/bin/sh +############################################################################## +# __ # +# ________ ___ / / ___ Scala Tools Launch Script # +# / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL # +# __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ # +# /____/\___/_/ |_/____/_/ | | # +# |/ # +############################################################################## + +# $Id$ + +############################################################################## +# Error functions + +# Prints a warning message on stderr. +warning() { + echo "$0: warning:" "$@" 1>&2; +} + +# Prints an error message on stderr. +error() { + echo "$0:" "$@" 1>&2; +} + +# Prints an error message on stderr and exits with a non-zero status. +abort() { + error "$@"; + exit 1; +} + +############################################################################## +# Printing functions + +# Initializes the printf functions +printf_initialization() { + case "$1" in + many ) + printf_font_outline="printf \\033[1;39m"; + printf_font_success="printf \\033[1;32m"; + printf_font_failure="printf \\033[1;31m"; + printf_font_warning="printf \\033[1;33m"; + printf_font_default="printf \\033[0;39m"; + ;; + some ) + printf_font_outline="printf \\033[1m"; + printf_font_success="printf \\033[0m"; + printf_font_failure="printf \\033[1m"; + printf_font_warning="printf \\033[1m"; + printf_font_default="printf \\033[0m"; + ;; + none ) + printf_font_outline=""; + printf_font_success=""; + printf_font_failure=""; + printf_font_warning=""; + printf_font_default=""; + ;; + * ) + abort "unknown color mode \`$1'"; + ;; + esac; +} + +# Prints formated text in outline font. +printf_outline() { + $printf_font_outline; + printf "$@"; + $printf_font_default; +} + +# Prints formated text in success font. +printf_success() { + $printf_font_success; + printf "$@"; + $printf_font_default; +} + +# Prints formated text in failure font. +printf_failure() { + $printf_font_failure; + printf "$@"; + $printf_font_default; +} + +# Prints formated text in warning font. +printf_warning() { + $printf_font_warning; + printf "$@"; + $printf_font_default; +} + +############################################################################## +# File name and path list conversion functions + +# Prints the OS-specific form of the specified Unix form file name. +get_os_filename() { + [ $# = 1 ] || abort "internal error"; + case "$UNAME" in + CYGWIN* ) cygpath --windows "$1";; + * ) echo "$@";; + esac; +} + +# Prints the Unix form of the specified OS-specific form file name. +get_unix_filename() { + [ $# = 1 ] || abort "internal error"; + case "$UNAME" in + CYGWIN* ) cygpath --unix "$1";; + * ) echo "$@";; + esac; +} + +# Prints the OS-specific form of the specified Unix form path list. +get_os_pathlist() { + [ $# = 1 ] || abort "internal error"; + case "$UNAME" in + CYGWIN* ) cygpath --window --path "$1";; + * ) echo "$@";; + esac; +} + +# Prints the Unix form of the specified OS-specific form path list. +get_unix_pathlist() { + [ $# = 1 ] || abort "internal error"; + case "$UNAME" in + CYGWIN* ) cygpath --unix --path "$1";; + * ) echo "$@";; + esac; +} + +# Collects all jar files in the given path +get_ext_classpath() { + [ $# = 1 ] || abort "internal error"; + # Constructing the extension classpath + cp="" + for ext in `ls $1/*.jar` ; do + if [ -z "$cp" ] ; then + cp="$ext" + else + cp="$cp:$ext" + fi + done + + echo $cp +} + +############################################################################## +# Implementation of scalatest + +# Prints the scalatest usage. +test_print_usage() { + [ $# = 0 ] || abort "internal error"; + echo "Usage: `basename $0` [OPTION]... [FILE]..." +} + +# Prints the scalatest help. +test_print_help() { + [ $# = 0 ] || abort "internal error"; + test_print_usage; + echo ""; + echo "--auto use filenames to select the test to run"; + echo "--dis next files test the class file disassembler"; + echo "--run next files test the interpreter and all backends"; + echo "--jvm next files test the JVM backend"; + echo "--pos next files test a compilation success"; + echo "--neg next files test a compilation failure"; + echo "--res next files test the resident compiler"; + echo "--msil next files test the .NET backend"; + echo "--script next files test Scala embedded in scripts"; + echo "--ant next files test the Ant tasks"; + echo "--pending perform the tests in the 'pending' directory"; + echo "--shootout next files test Debian's language shootout benchmarks"; + echo "--quick use the 'quick' build instead of distribution"; + echo '--installed use the installed programs on $PATH' + echo "--no-run run no test, use results of last run"; + echo "--show-log show output of failed tests"; + echo "--show-diff show differences between actual and expected output"; + echo "--use-fsc use the Fast Scala compiler"; + echo "--failed test only files that failed last time"; + echo "--errors=<int> specify the number of expected errors"; + echo "--flags=<flags> specify flags to pass on to the executable"; + echo "--color=USAGE control the color usage (USAGE=none|some|many)"; + echo "--objdir=<dir> specify where to place generated files"; + echo "--help, -? display this help and exit"; + echo "--version output version information and exit"; + echo ""; + echo "Report bugs to <scala@listes.epfl.ch>"; +} + +# Prints the scalatest version. +test_print_version() { + [ $# = 0 ] || abort "internal error"; + echo "$SCRIPT "'$Revision$'; +} + +# Prints the name of the specified test file. +test_print_testing() { + [ $# = 1 ] || abort "internal error"; + printf_outline "testing: "; + case "$1" in + "$TESTROOT"* ) + printf "%-60s " "[...]`expr "$1" : "$TESTROOT\(.*\)"`"; + return 0; + ;; + esac; + printf "%-60s " "$1"; +} + +# Prints a test success notification. +test_print_success() { + [ $# = 0 ] || abort "internal error"; + printf "["; + printf_success " OK "; + printf "]\\n"; +} + +# Prints a test failure notification. +test_print_failure() { + [ $# = 0 ] || abort "internal error"; + printf "["; + printf_failure "FAILED"; + printf "]\\n"; +} + +# Tests resident compiler. +test_run_res() { + rm -rf "$dstbase".obj && + mkdir -p "$dstbase".obj && + (cd "$srcdir" && cat "$testname".res | $SCALAC -d "$os_dstbase".obj -Xresident -sourcepath . "$@"; ); + rm -rf "$dstbase".obj; +} + + +# Tests the JVM backend. +# NB. property '-Djavacmd=$JAVACMD' is e.g used by jvm/inner.scala +test_run_jvm() { + javaopts=$JAVA_OPTS; + if [ -f "$os_srcbase".javaopts ]; then + javaopts="$javaopts `cat "$os_srcbase".javaopts`" + if [ "$JAVA5" = "false" ]; then + # -Xss option available in Java versions 1.5 or newer + javaopts=`echo "$javaopts" | sed -e "s/-Xss[0-9]*[MmKk]//g"` + fi + fi + rm -rf "$dstbase".obj && + mkdir -p "$dstbase".obj && + (cd "$srcdir" && env JAVACMD="$JAVACMD" JAVA_OPTS="$javaopts" $SCALAC -d "$os_dstbase".obj \ + -cp "$JVM_EXT_CLASSPATH" "$@" "$testname".scala ) && + libpath=`get_os_pathlist "$dstdir"` && + scala_javaopts=`echo -Djava.library.path=$libpath` && + scala_lib=`get_os_filename "$SCALA_LIB"` && + classpath=`get_os_pathlist "$os_dstbase".obj:$CLASSPATH` && + env JAVA_OPTS="$scala_javaopts" $SCALA -Djavacmd="$JAVACMD" \ + -Dscalatest.output=$os_dstbase.obj -Dscalatest.lib=$scala_lib \ + -classpath $classpath:$JVM_EXT_CLASSPATH Test "jvm" && + rm -rf "$dstbase".obj; +} + +# Test the disassemblers. +test_run_dis() { + argsfile="$srcbase".args; + [ ! -f "$argsfile" ] && argsfile=/dev/null; + rm -rf "$dstbase".obj && + mkdir -p "$dstbase".obj && + $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala && + $SCALAP -classpath "$os_dstbase".obj `cat "$argsfile"` && + rm -rf "$dstbase".obj; +} + +MSIL="msil" +EXE="exe" +# Tests the .NET backend. +test_run_msil() { + assemblies=`get_os_pathlist $LATEST_ASSEM`; + rm -f "$dstbase".$MSIL && + rm -f "$dstbase".$EXE && + + $SCALAC -nowarn -target:msil -Xassem "$os_dstbase" -Xassem-path $assemblies "$@" \ + -sourcepath "$PREFIX/build/msil/src" "$os_srcbase".scala && + case "$UNAME" in + CYGWIN* ) + $ILASM /qui /nol /out="$os_dstbase".$EXE "$os_dstbase".$MSIL \ + > /dev/null && +# peverify /il "$os_dstbase".EXE > /dev/null && + "$dstbase".$EXE_SUFFIX "msil";; + * ) + $ILASM /output:"$os_dstbase".$EXE "$os_dstbase".$MSIL \ + > /dev/null && + monopath=`get_os_pathlist $PREFIX/build/msil:$PREFIX/lib` && + env MONO_PATH="$monopath" $MONO "$dstbase.$EXE" "msil";; + esac && + rm -f "$dstbase".$EXE && + rm -f "$dstbase".$MSIL; +} + +# Tests a script with Scala code embedded in it +test_run_script() { + argsfile="$srcbase.args" + if [ ! -r "$argsfile" ]; then + argsfile=/dev/null + fi + chmod +x "$srcbase.scala" 2> /dev/null + PATH="$BIN_DIR:$PATH" "$srcbase.scala" `cat $argsfile` +} + +# Tests the Scala Ant task +test_run_ant() { + if [ "$BIN_DIR" = "" ]; then BINARY=installed + elif [ "$BIN_DIR" = "$QUICK" ]; then BINARY=quick + else BINARY=latest + fi; + testname=`basename "$srcbase"`; + buildfile=`get_os_filename "$srcdir/$testname-build.xml"`; + rm -rf "$dstbase".obj && + $ANT -f "$buildfile" -Dbinary="$BINARY" -Dbuild.dir="$os_dstbase".obj && + rm -rf "$dstbase".obj; +} + +# Tests the shootout benchmarks +test_run_shootout() { + javaopts=$JAVA_OPTS; + if [ -f "$os_srcbase".javaopts ]; then + javaopts="$javaopts `cat "$os_srcbase".javaopts`" + if [ "$JAVA5" = "false" ]; then + # -Xss option available in Java versions 1.5 or newer + javaopts=`echo "$javaopts" | sed -e "s/-Xss[0-9]*[MmKk]//g"` + fi + fi + rm -rf "$dstbase".obj && + mkdir -p "$dstbase".obj && + testfile=`get_os_filename "$dstbase".obj/test.scala` && + cat "$os_srcbase".scala.runner "$os_srcbase".scala > "$testfile" && + $SCALAC -d "$os_dstbase".obj -cp "$JVM_EXT_CLASSPATH" "$@" "$testfile" && + scala_lib=`get_os_filename "$SCALA_LIB"` && + classpath=`get_os_pathlist "$os_dstbase".obj:$CLASSPATH` && + env JAVACMD="$JAVACMD" JAVA_OPTS="$javaopts" \ + $SCALA -Dscalatest.cwd="$srcdir" -Dscalatest.output=$os_dstbase.obj \ + -Dscalatest.lib=$scala_lib -classpath $classpath:$JVM_EXT_CLASSPATH Test && + rm -rf "$dstbase".obj; +} + +# Checks the specified test. +test_check_test() { + [ $# = 1 ] || abort "internal error"; + testfile="$1"; shift 1; + # compute test name + testname=`basename "$testfile" ."$TEST_EXT"`; + + # compute source and destination directories (absolute paths) + srcdir=`dirname "$testfile"`; + srcdir=`cd "$srcdir"; pwd`; + + dstdir="$OBJDIR""$srcdir"; + + # compute source and destination base names + srcbase="$srcdir"/"$testname"; + + dstbase="$dstdir"/"$testname"-$kind; + os_srcbase=`get_os_filename "$srcbase"`; + os_dstbase=`get_os_filename "$dstbase"`; + + # compute flags file + flagsfile="$srcbase".flags; + [ ! -f "$flagsfile" ] && flagsfile=/dev/null; + + # compute check file + checkfile="$srcbase"-$kind.check; + [ ! -f "$checkfile" ] && checkfile="$srcbase".check; + [ ! -f "$checkfile" ] && checkfile=/dev/null; + + # compute log file + logfile="$dstbase".log; + + # if we are testing only failed tests, skip successful tests + if [ "$FAILED" = "true" -a ! -f "$logfile" ]; then + return 0; + fi; + + # print tested file + test_print_testing "$testfile"; + + # run test + if [ "$NORUN" = "true" ]; then + [ ! -f "$logfile" ]; + else + rm -f "$logfile"; + { [ -d "$dstdir" ] || mkdir -p "$dstdir"; } && + ( test_run_$kind `cat "$flagsfile"` $FLAGS 1> "$logfile" 2>&1; ) && + $DIFF "$logfile" "$checkfile" 1> /dev/null 2>&1 && + rm -f "$logfile"; + fi; + + # print result + if [ "$?" = 0 ]; then + SUCCESS_COUNT=`echo "$SUCCESS_COUNT+1" | bc`; + test_print_success; + else + FAILURE_COUNT=`echo "$FAILURE_COUNT+1" | bc`; + test_print_failure; + [ ! -f "$logfile" ] && logfile=/dev/null; + [ "$SHOWLOG" = "true" ] && cat "$logfile"; + [ "$SHOWDIFF" = "true" ] && $DIFF "$logfile" "$checkfile"; + fi; +} + +# Checks the specified file +test_check_file() { + [ $# = 1 ] || abort "internal error"; + file="$1"; shift 1; + for testfile in "" `find "$file" -name "*.obj" -prune -o -name "*.$TEST_EXT" -a -type f -print`; do + [ -z "$testfile" ] && continue; + test_check_test "$testfile"; + done; +} + +load_results() { + if [ -f "$RESFILE" ]; then + FAIL=`head -1 $RESFILE`; + SUCCESS=`head -2 $RESFILE | tail -1`; + FAILURE_COUNT=`echo "$FAILURE_COUNT+$FAIL" | bc` + SUCCESS_COUNT=`echo "$SUCCESS_COUNT+$SUCCESS" | bc` + rm -f "$RESFILE"; + else + abort "Couldn't load TestRunner results' file"; + fi; +} + +# Checks all files of the specified kind. +test_check_kind() { + [ $# -ge 2 ] || abort "internal error"; + header="$1"; shift 1; + kind="$1"; shift 1; + testdir=`get_os_filename "$TESTROOT"`; + resfile=`get_os_filename "$RESFILE"`; + if [ "$kind" = "res" ]; then TEST_EXT="res"; else TEST_EXT="scala"; fi; + if [ "$kind" = "pos" -o "$kind" = "neg" ]; then + $SCALA -Dactors.corePoolsize=7 -Dactors.maxPoolSize=8 \ + scala.tools.partest.TestRunner --"$kind" $testdir $resfile 2> /dev/null; + load_results; + elif [ "$kind" = "jvm" ]; then + javaopts=$JAVA_OPTS; + if [ -f "$os_srcbase".javaopts ]; then + javaopts="$javaopts `cat "$os_srcbase".javaopts`" + if [ "$JAVA5" = "false" ]; then + # -Xss option available in Java versions 1.5 or newer + javaopts=`echo "$javaopts" | sed -e "s/-Xss[0-9]*[MmKk]//g"` + fi; + fi; + scala_lib=`get_os_filename "$SCALA_LIB"` && + classpath=`get_os_pathlist $CLASSPATH` && + # -Djava.library.path + $SCALA -DSCALA=$SCALA -DJAVA_OPTS="$java_opts -Xss16M" \ + -DJVMEXTCP=$JVM_EXT_CLASSPATH -Dscalatest.lib=$scala_lib -DCLASSPATH=$classpath \ + -Dactors.corePoolsize=7 -Dactors.maxPoolSize=8 \ + scala.tools.partest.TestRunner --"$kind" $testdir $resfile 2> /dev/null; + load_results; + elif [ "$kind" = "shootout" ]; then + javaopts=$JAVA_OPTS; + if [ -f "$os_srcbase".javaopts ]; then + javaopts="$javaopts `cat "$os_srcbase".javaopts`" + if [ "$JAVA5" = "false" ]; then + # -Xss option available in Java versions 1.5 or newer + javaopts=`echo "$javaopts" | sed -e "s/-Xss[0-9]*[MmKk]//g"` + fi; + fi; + for file in "" "$@"; do + [ -z "$file" ] && continue; + if [ -d "$file" ]; then + for file2 in "" `find "$file" -name "*.obj" -prune -o -name "*.scala" -a -type f -print`; do + [ -z "$file"/"$file2" ] && continue; + filename=`basename "$file"/"$file2" .scala`; + rm -rf "$file"/"$filename"-"$kind".obj; + mkdir "$file"/"$filename"-"$kind".obj; + cat "$file"/"$filename".scala.runner "$file"/"$filename".scala > "$file"/"$filename"-"$kind".obj/Test.scala 2>/dev/null; + done + fi; + done + scala_lib=`get_os_filename "$SCALA_LIB"` && + classpath=`get_os_pathlist $CLASSPATH` && + env JAVACMD="$JAVACMDE" $SCALA -DSCALA=$SCALA -DJVMEXTCP=$JVM_EXT_CLASSPATH \ + -Dscalatest.lib=$scala_lib -DCLASSPATH=$classpath \ + -Dactors.corePoolsize=5 -Dactors.maxPoolSize=6 \ + scala.tools.partest.TestRunner --"$kind" $testdir $resfile 2> /dev/null; + load_results; + else + for file in "" "$@"; do + [ -z "$file" ] && continue; + test_check_file "$file"; + done + fi; + #[ -z "$header" ] && echo ""; + +} + +# Checks everything. +test_check_all() { + [ $# = 0 ] || abort "internal error"; + test_check_kind "Testing disassembler" \ + "dis" $FILES_DIS; + [ "$FILES_JVM" = "" ] || test_check_kind "Testing JVM backend" \ + "jvm" $FILES_RUN $FILES_JVM; + [ "$FILES_POS" = "" ] || test_check_kind "Testing compiler (on files whose compilation should succeed)" \ + "pos" $FILES_POS; + [ "$FILES_NEG" = "" ] || test_check_kind "Testing compiler (on files whose compilation should fail)" \ + "neg" $FILES_NEG; + test_check_kind "Testing .NET backend" \ + "msil" $FILES_MSIL; + test_check_kind "Testing Scala embedded in script files" \ + "script" $FILES_SCRIPT; + test_check_kind "Testing Scala Ant tasks" \ + "ant" $FILES_ANT; + test_check_kind "Testing resident compiler" \ + "res" $FILES_RES; + [ "$FILES_SHOOTOUT" = "" ] || test_check_kind "Testing shootout benchmarks" \ + "shootout" $FILES_SHOOTOUT; +} + + +# Adds a new file to the appropriate file list(s). +test_add_file() { + [ $# = 1 ] || abort "internal error"; + case "$1" in + *.scala | *.res ) + if [ ! \( -d "$1" -o -f "$1" \) ]; then + abort "don't know what to do with '$1'"; + fi;; + * ) + if [ ! -d "$1" ]; then + abort "don't know what to do with '$1'"; + fi;; + esac; + TEST_ALL="false"; + case "$TEST_TYPE" in + auto ) ;; + dis ) FILES_DIS="$FILES_DIS $1"; return;; + run ) FILES_RUN="$FILES_RUN $1"; return;; + jvm ) FILES_JVM="$FILES_JVM $1"; return;; + pos ) FILES_POS="$FILES_POS $1"; return;; + neg ) FILES_NEG="$FILES_NEG $1"; return;; + res ) FILES_RES="$FILES_RES $1"; return;; + msil ) FILES_MSIL="$FILES_MSIL $1"; return;; + script ) FILES_SCRIPT="$FILES_SCRIPT $1"; return;; + ant ) FILES_ANT="$FILES_ANT $1"; return;; + shootout ) FILES_SHOOTOUT="$FILES_SHOOTOUT $1"; return;; + * ) abort "unknown test type \`$TEST_TYPE'";; + esac; + case "$1" in + dis | */dis | */dis/* | dis/* ) FILES_DIS="$FILES_DIS $1";; + run | */run | */run/* | run/* ) FILES_RUN="$FILES_RUN $1";; + jvm5 | */jvm5 | */jvm5* | jvm5/* ) + if [ "$JAVA5" = "true" ]; then + FILES_JVM="$FILES_JVM $1" + fi;; + jvm | */jvm | */jvm/* | jvm/* ) FILES_JVM="$FILES_JVM $1";; + pos | */pos | */pos/* | pos/* ) FILES_POS="$FILES_POS $1";; + neg | */neg | */neg/* | neg/* ) FILES_NEG="$FILES_NEG $1";; + res | */res | */res/* | res/* ) FILES_RES="$FILES_RES $1";; + msil | */msil | */msil/* | msil/* ) FILES_MSIL="$FILES_MSIL $1";; + script | */script | */script/* | script/* ) FILES_SCRIPT="$FILES_SCRIPT $1";; + shootout | */shootout | */shootout/* | shootout/* ) FILES_SHOOTOUT="$FILES_SHOOTOUT $1";; + * ) abort "don't known what to do with \`$1'";; + esac; +} + +test_get_location() { + [ $# = 1 ] || abort "internal error"; + source="$1"; shift 1; + script=`basename "$source"`; + while [ -h "$source" ]; do + script=`basename "$source"`; + lookup=`ls -ld "$source"`; + target=`expr "$lookup" : '.*-> \(.*\)$'`; + if expr "${target:-.}/" : '/.*/$' > /dev/null; then + source=${target:-.}; + else + source=`dirname "$source"`/${target:-.}; + fi; + done; + location=`dirname "$source"`; + location=`cd "$location"; pwd`; + echo $location; +} + +############################################################################## +# Definition of UNAME, SOURCE, SCRIPT and PREFIX + +unset SCRIPT; +UNAME=`uname`; +SOURCE=$0; +SCRIPT=`basename "$SOURCE"`; +while [ -h "$SOURCE" ]; do + SCRIPT=`basename "$SOURCE"`; + LOOKUP=`ls -ld "$SOURCE"`; + TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`; + if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then + SOURCE=${TARGET:-.}; + else + SOURCE=`dirname "$SOURCE"`/${TARGET:-.}; + fi; +done; +PREFIX=`dirname "$SOURCE"`/..; +PREFIX=`cd "$PREFIX"; pwd`; + +############################################################################## +# Invocation of $SCRIPT + +NORUN="false"; +SHOWLOG="false"; +SHOWDIFF="false"; +USEFSC="false"; +FAILED="false"; +ERRORS=0; +SUCCESS_COUNT=0; +FAILURE_COUNT=0; +if [ -d "$PREFIX/test" ]; then + TESTROOT="$PREFIX/test"; +elif [ -d "$PREFIX/misc/scala-test" ]; then + TESTROOT="$PREFIX/misc/scala-test"; +else + abort "Test directory not found"; +fi; +SRCDIR="$TESTROOT/files"; +OBJDIR=""""; + +TEST_ALL="true"; +TEST_TYPE="auto"; +FILES_RUN=""; +FILES_JVM=""; +FILES_POS=""; +FILES_RES=""; +FILES_NEG=""; +FILES_MSIL=""; +FILES_SCRIPT=""; +FILES_DIS=""; +FILES_ANT=""; +FILES_SHOOTOUT=""; + +QUICK="$PREFIX/build/quick/bin" +QUICK_LIB="$PREFIX/build/quick/lib/library" +QUICK_COMP="$PREFIX/build/quick/lib/compiler" +QUICK_ACT="$PREFIX/build/quick/lib/actors" +QUICK_PAR="$PREFIX/build/quick/lib/partest" + +JVM_EXT_CLASSPATH=`get_ext_classpath $TESTROOT/files/lib` + +if [ -d "$PREFIX/dists" ]; then + LATEST="$PREFIX/dists/latest/bin"; + LATEST_LIB="$PREFIX/dists/latest/lib/scala-library.jar"; + LATEST_COMP="$PREFIX/dists/latest/lib/scala-compiler.jar"; + LATEST_PAR="$PREFIX/dists/latest/lib/scala-partest.jar"; + LATEST_PREDEF="$PREFIX/dists/latest/lib/predef.dll"; + LATEST_ASSEM="$LATEST_PREDEF;$PREFIX/lib/scalaruntime.dll:$PREFIX/lib/mscorlib.dll"; +elif [ -d "$PREFIX/build" ]; then + LATEST="$QUICK"; + LATEST_LIB=$QUICK_LIB + LATEST_COMP=$QUICK_COMP + LATEST_ACT=$QUICK_ACT + LATEST_PAR=$QUICK_PAR + LATEST_PREDEF="$PREFIX/build/quick/lib/predef.dll"; + LATEST_ASSEM="$LATEST_PREDEF:$PREFIX/build/quick/lib/scalaruntime.dll:$PREFIX/build/quick/lib/mscorlib.dll"; +elif [ -d "$PREFIX/bin" ]; then + LATEST="$PREFIX/bin"; + LATEST_LIB="$PREFIX/lib/scala-library.jar"; + LATEST_COMP="$PREFIX/lib/scala-compiler.jar"; + LATEST_PAR="$PREFIX/lib/scala-partest.jar"; + LATEST_PREDEF="$PREFIX/lib/predef.dll"; + LATEST_ASSEM="$LATEST_PREDEF:$PREFIX/lib/scalaruntime.dll:$PREFIX/lib/mscorlib.dll"; +else + abort "Scala binaries could not be found"; +fi; +BIN_DIR="$LATEST/" # BIN_DIR should have a trailing / when needed, so that + # it can also be set to the empty string + +SCALA_LIB="$LATEST_LIB"; +SCALA_COMP="$LATEST_COMP"; +SCALA_ACT="$LATEST_ACT"; +SCALA_PAR="$LATEST_PAR"; + +[ -x "$JAVACMD" ] || JAVACMD=java; +[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms16M"; +case `$JAVACMD \-version 2>&1 | xargs` in + *1.5.*IBM* ) JAVA5="true"; IBM_J9="true"; JAVA_OPTS="$JAVA_OPTS -Xss2M";; + *1.6.*IBM* ) JAVA5="true"; IBM_J9="true";; + *1.[5-7].* ) JAVA5="true";; + *1.4.*GNU* ) JAVA5="false"; GIJ="true"; JAVA_OPTS="--mx256m --ms16m";; + * ) JAVA5="false";; +esac; + +DIFF="diff"; + +case `uname` in + CYGWIN* ) + DIFF="diff --text --strip-trailing-cr"; + ;; +esac; + +while [ $# -gt 0 ]; do + case "$1" in + --auto ) TEST_TYPE="auto"; shift 1;; + --dis ) TEST_TYPE="dis"; shift 1;; + --run ) TEST_TYPE="run"; shift 1;; + --jvm ) TEST_TYPE="jvm"; shift 1;; + --pos ) TEST_TYPE="pos"; shift 1;; + --neg ) TEST_TYPE="neg"; shift 1;; + --res ) TEST_TYPE="res"; shift 1;; + --msil ) TEST_TYPE="msil"; shift 1;; + --script ) TEST_TYPE="script"; shift 1;; + --ant ) TEST_TYPE="ant"; shift 1;; + --shootout ) TEST_TYPE="shootout"; shift 1;; + --quick ) BIN_DIR="$QUICK/"; SCALA_LIB=$QUICK_LIB; + SCALA_COMP=$QUICK_COMP; SCALA_ACT=$QUICK_ACT; + SCALA_PAR=$QUICK_PAR; shift 1;; + --installed ) BIN_DIR=""; shift 1;; + --no-run ) NORUN="true"; shift 1;; + --show-log ) SHOWLOG="true"; shift 1;; + --show-diff ) SHOWDIFF="true"; shift 1;; + --use-fsc ) USEFSC="true"; shift 1;; + --failed ) FAILED="true"; shift 1;; + --pending ) SRCDIR="$TESTROOT/pending"; shift 1;; + --errors= ) abort "illegal empty argument for option --errors";; + --errors=* ) ERRORS=`expr "$1" : "--errors=\([0-9]*\)$"`;shift 1;; + --flags= ) abort "illegal empty argument for option --flags";; + --flags=* ) FLAGS=`expr "$1" : "--flags=\(.*\)"`; shift 1;; + --color= ) abort "illegal empty argument for option --color";; + --color=* ) COLOR=`expr "$1" : "--color=\(.*\)"`; shift 1;; + --objdir=* ) OBJDIR=`expr "$1" : "--objdir=\(.*\)"`; shift 1;; + --help| -? ) test_print_help; exit 0;; + --version ) test_print_version; exit 0;; + --profile ) JAVACMDE="$JAVACMD -agentpath:/localhome/thhofer/netbeans-5.5.1/profiler1/lib/deployed/jdk15/linux/libprofilerinterface.so=/localhome/thhofer/netbeans-5.5.1/profiler1/lib,5140"; shift 1;; + -* ) abort "unknown option $1";; + * ) test_add_file "$1"; shift 1;; + esac; +done; + +[ -x "$JAVACMDE" ] || JAVACMDE=java; + +if [ "$JAVA5" = "true" -a "$TEST_TYPE" != "msil" ]; then + FLAGS="$FLAGS -target:jvm-1.5" +fi; + +if [ -z "$ERRORS" ]; then + abort "illegal non-numerical argument for option --errors"; +fi; + +if [ -z "$COLOR" -a -n "$EMACS" ]; then + COLOR="none"; +fi; +printf_initialization "${COLOR:-many}"; + +if [ "$TEST_ALL" = "true" ]; then + case "$TEST_TYPE" in + dis ) FILES_DIS="$FILES_DIS $SRCDIR/dis";; + esac; + case "$TEST_TYPE" in + run ) FILES_RUN="$FILES_RUN $SRCDIR/run";; + esac; + case "$TEST_TYPE" in + auto | shootout ) FILES_SHOOTOUT="$FILES_SHOOTOUT $SRCDIR/shootout";; + esac; + case "$TEST_TYPE" in + auto | jvm ) + FILES_JVM="$FILES_JVM $SRCDIR/run $SRCDIR/jvm" + if [ "$JAVA5" = "true" ]; then + FILES_JVM="$FILES_JVM $SRCDIR/jvm5"; + fi;; + esac; + case "$TEST_TYPE" in + auto | pos ) FILES_POS="$FILES_POS $SRCDIR/pos";; + esac; + case "$TEST_TYPE" in + auto | neg ) FILES_NEG="$FILES_NEG $SRCDIR/neg";; + esac; + case "$TEST_TYPE" in + auto | res ) FILES_RES="$FILES_RES $SRCDIR/res";; + esac; + case "$TEST_TYPE" in + msil ) FILES_MSIL="$FILES_MSIL $SRCDIR/run";; + esac; + case "$TEST_TYPE" in + auto | script ) FILES_SCRIPT="$FILES_SCRIPT $SRCDIR/script";; + esac; + case "$TEST_TYPE" in + ant ) FILES_ANT="$FILES_ANT $SRCDIR/ant";; + esac; +fi; + +SCALA="${BIN_DIR}scala"; +[ -z "$SCALAC_OPTS" ] && SCALAC_OPTS="-deprecation -encoding iso-8859-1"; +if [ "$USEFSC" = "true" ]; then + if [ "${BIN_DIR}" = "" ]; then + SCALAC_CMD=`which fsc`; + else + SCALAC_CMD="${BIN_DIR}fsc"; + fi; +else + if [ "${BIN_DIR}" = "" ]; then + SCALAC_CMD=`which scalac`; + else + SCALAC_CMD="${BIN_DIR}scalac"; + fi; +fi; +if [ ! -x "$SCALAC_CMD" ]; then + printf_failure "Missing command \"$SCALAC_CMD\"; run 'ant <target>'.\\n"; + exit 1; +fi; +SCALAC="$SCALAC_CMD $SCALAC_OPTS"; +SCALAP="scalap"; + +CLASSPATH=$SCALA_COMP:$SCALA_ACT:$SCALA_PAR + +RESFILE=`mktemp -t results.XXXXXX`; +[ -f "$RESFILE" ] || RESFILE=`get_os_filename "$TESTROOT"/.results.txt` + +if [ -z "$ANT" ]; then + if [ -d "$ANT_HOME" ]; then + ANT="$ANT_HOME/bin/ant"; + else + ANT="ant"; + fi +fi; +if [ -z "$ILASM" ]; then + if [ -d "$MONO_HOME" ]; then + ILASM="$MONO_HOME/bin/ilasm"; + else + ILASM="ilasm"; + fi +fi; +if [ -z "$MONO" ]; then + if [ -d "$MONO_HOME" ]; then + MONO="$MONO_HOME/bin/mono"; + else + MONO="mono"; + fi +fi; + +if [ -n "$OBJDIR" ]; then + if [ -d "$OBJDIR" ] || mkdir -p "$OBJDIR"; then + OBJDIR=`cd "$OBJDIR"; pwd`; + else + abort "could not create directory '$OBJDIR'"; + fi +fi; + +printf_outline "Source directory is : $SRCDIR\\n"; +bin_dir=$BIN_DIR +if [ -z "$bin_dir" ]; then + scalac=`which $SCALAC_CMD`; + bin_dir=`test_get_location $scalac`; +fi; +printf_outline "Scala binaries in : $bin_dir\\n"; +scala_version=`${SCALAC_CMD} -version 2>&1` +printf_outline "Scala version is : $scala_version\\n"; +[ -n "$SCALAC_OPTS" ] && printf_outline "Scalac options are : $SCALAC_OPTS\\n"; + +if [ $TEST_TYPE = "msil" ]; then + ilasm_version=`$ILASM --version 2>&1`; + printf_outline "ILasm version is : $ilasm_version\\n"; + mono_version=`$MONO --version | head -1`; + printf_outline "Mono version is : $mono_version\\n"; + if [ -f "$LATEST_PREDEF" ]; then + printf_outline "DLL library is : $LATEST_PREDEF\\n"; + else + printf_failure "Missing library \"predef.dll\"; run 'ant msil'.\\n"; + exit 1; + fi +else + javacmd=`which $JAVACMD 2>/dev/null`; + bin_dir=`test_get_location $javacmd`; + printf_outline "Java binaries in : $bin_dir\\n"; + if [ "$GIJ" = "true" ]; then + jvm_version=`$JAVACMD -version 2>&1 | head -2 | tail -1` + else + jvm_version=`$JAVACMD -version 2>&1 | head -3 | tail -1` + fi; + printf_outline "Java runtime is : $jvm_version\\n"; + [ -n "$JAVA_OPTS" ] && printf_outline "Java options are : $JAVA_OPTS\\n"; + if [ "$TEST_TYPE" = "ant" ]; then + ant_version=`$ANT -version`; + printf_outline "Ant version is : $ant_version\\n"; + fi +fi; +printf_outline "\\n"; + +START_SECONDS=`date +%s`; +test_check_all; +END_SECONDS=`date +%s`; + +TOTAL_COUNT=`echo "$FAILURE_COUNT+$SUCCESS_COUNT" | bc`; + +ELAPSED_SECONDS=`expr $END_SECONDS - $START_SECONDS`; +ELAPSED_TIME=`date --date="1970-01-01 $ELAPSED_SECONDS sec" +%T`; + +if [ $FAILURE_COUNT -eq 0 ]; then + printf_success "All of $TOTAL_COUNT tests were successful (elapsed time: $ELAPSED_TIME)\\n"; +else + printf_failure "$FAILURE_COUNT of $TOTAL_COUNT tests failed (elapsed time: $ELAPSED_TIME)\\n"; +fi; + +if [ $FAILURE_COUNT -eq "$ERRORS" ]; then + exit 0; +else + exit 1; +fi; + +############################################################################## |