diff options
Diffstat (limited to 'src')
5 files changed, 67 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/io/ZipArchive.scala b/src/compiler/scala/tools/nsc/io/ZipArchive.scala index 6843c7ec49..5f708b3c82 100644 --- a/src/compiler/scala/tools/nsc/io/ZipArchive.scala +++ b/src/compiler/scala/tools/nsc/io/ZipArchive.scala @@ -209,7 +209,7 @@ final class ZipArchive(file: File, val archive: ZipFile) extends PlainFile(file) protected lazy val root = new ZipRootCreator(_.parent)() protected def DirEntryConstructor = new DirEntry(_, _, _) protected def FileEntryConstructor = new FileEntry(_, _, _, _) - protected def ZipTravConstructor = zipTraversableFromZipFile _ + protected def ZipTravConstructor = new ZipFileIterable(_) abstract class Entry( override val container: AbstractFile, @@ -247,15 +247,14 @@ final class ZipArchive(file: File, val archive: ZipFile) extends PlainFile(file) override def input = archive getInputStream entry } - private def zipTraversableFromZipFile(z: ZipFile): ZipTrav = - new Iterable[ZipEntry] with ZipTrav { - def zis: () => ZipInputStream = null // not valid for this type - def iterator = new Iterator[ZipEntry] { - val enum = z.entries() - def hasNext = enum.hasMoreElements - def next = enum.nextElement - } + class ZipFileIterable(z: ZipFile) extends Iterable[ZipEntry] with ZipTrav { + def zis: () => ZipInputStream = null // not valid for this type + def iterator = new Iterator[ZipEntry] { + val enum = z.entries() + def hasNext = enum.hasMoreElements + def next = enum.nextElement } + } } /** diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 9a4a9c31b4..7f5f4cc1b1 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -159,15 +159,15 @@ abstract class SymbolLoaders { root.setInfo(new PackageClassInfoType(new Scope(), root)) val sourcepaths = classpath.sourcepaths - for (classRep <- classpath.classes if doLoad(classRep)) { - ((classRep.binary, classRep.source) : @unchecked) match { - case (Some(bin), Some(src)) if needCompile(bin, src) => + for (classRep <- classpath.classes ; if doLoad(classRep)) { + ((classRep.binary, classRep.source) : @unchecked) match { + case (Some(bin), Some(src)) if needCompile(bin, src) => enterToplevelsFromSource(root, classRep.name, src) - case (None, Some(src)) => + case (None, Some(src)) => enterToplevelsFromSource(root, classRep.name, src) - case (Some(bin), _) => + case (Some(bin), _) => enterClassAndModule(root, classRep.name, newClassLoader(bin)) - } + } } for (pkg <- classpath.packages) { diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala index d15f851ffc..ce35a830cb 100644 --- a/src/partest/scala/tools/partest/nest/DirectRunner.scala +++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala @@ -51,6 +51,13 @@ trait DirectRunner { println("Dumping partest internals.") println("results.size = " + results.size + ", " + workers.size + " workers.") workers foreach println + workers filter (_.currentFileElapsed > 60) foreach { w => + val elapsed = w.currentFileElapsed + println("A worker requires euthanasia! At least so it seems, since I received") + println("a signal and this one has been in la-la land for " + elapsed + " seconds.") + println("Attempting to force test timeout.") + w.forceTimeout() + } } def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, Int] = { diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index 35f4494f65..13afc5b34b 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -50,6 +50,7 @@ trait FileManager { var SCALAC_OPTS = PartestDefaults.scalacOpts var JAVA_OPTS = PartestDefaults.javaOpts var timeout = PartestDefaults.timeout + var oneTestTimeout = 5 * 60 * 1000 // if one test takes over 5 minutes it must go /** Only when --debug is given. */ lazy val testTimings = new HashMap[String, Long] diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index 734404bf1c..ef0a1e910c 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -116,15 +116,54 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor else fileManager.JAVAC_CMD + private var currentTimerTask: KickableTimerTask = _ + + def cancelTimerTask() = if (currentTimerTask != null) currentTimerTask.cancel() + def updateTimerTask(body: => Unit) = { + cancelTimerTask() + currentTimerTask = new KickableTimerTask(body) + timer.schedule(currentTimerTask, fileManager.oneTestTimeout) + } + + class KickableTimerTask(body: => Unit) extends TimerTask { + def run() = body + def kick() = { + cancel() + body + } + } + /** Formerly deeper inside, these next few things are now promoted outside so * I can see what they're doing when the world comes to a premature stop. */ private val filesRemaining = new mutable.HashSet[File] private def addFilesRemaining(xs: Traversable[File]) = filesRemaining ++= xs private var currentTestFile: File = _ + private var currentFileStart: Long = System.currentTimeMillis + + def currentFileElapsed = (System.currentTimeMillis - currentFileStart) / 1000 + def forceTimeout() = { + println("Let's see what them threads are doing before I kill that test.") + system.allThreads foreach { t => + println(t) + t.getStackTrace foreach println + println("") + } + currentTimerTask.kick() + } + + private def currentFileString = { + "Current test file is: %s\n Started: %s (%s seconds ago)\n Current time: %s".format( + currentTestFile, + new java.util.Date(currentFileStart), + currentFileElapsed, + new java.util.Date() + ) + } private def getNextFile() = synchronized { currentTestFile = filesRemaining.head filesRemaining -= currentTestFile + currentFileStart = System.currentTimeMillis currentTestFile } // maps canonical file names to the test result (0: OK, 1: FAILED, 2: TIMOUT) @@ -133,8 +172,8 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor status(key) = num } override def toString = ( - ">> Partest Worker:\n" + - "Current test file is: " + currentTestFile + "\n" + + ">> Partest Worker in state " + getState + ":\n" + + currentFileString + "There are " + filesRemaining.size + " files remaining:\n" + filesRemaining.toList.sortBy(_.toString).map(" " + _ + "\n").mkString("") + "\nstatus hashmap contains " + status.size + " entries:\n" + @@ -485,15 +524,6 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor runTestCommon(file, kind, expectFailure = false)((logFile, outDir) => { val fileBase = basename(file.getName) val dir = file.getParentFile - - //TODO: detect whether we have to use Runtime.exec - // val useRuntime = true - // - // if (useRuntime) - // execTest(outDir, logFile, fileBase) - // else - // execTestObjectRunner(file, outDir, logFile) - // // NestUI.verbose(this+" finished running "+fileBase) execTest(outDir, logFile, fileBase) diffCheck(compareOutput(dir, fileBase, kind, logFile)) @@ -1022,10 +1052,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor actor { val testFile = getNextFile() - val ontimeout = new TimerTask { - def run() = parent ! Timeout(testFile) - } - timer.schedule(ontimeout, fileManager.timeout.toLong) + updateTimerTask(parent ! Timeout(testFile)) val context = try processSingleFile(testFile) @@ -1060,8 +1087,10 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor if (logs != null) Some(logs.file) else None, if (logs != null) logs.writers else None) } - if (filesRemaining.isEmpty) + if (filesRemaining.isEmpty) { + cancelTimerTask() reportAll(status.toMap, topcont) + } } } } |