1
/* NEST (New Scala Test)
2
* Copyright 2007-2011 LAMP/EPFL
3
* @author Paul Phillips
9
import java.util.{ Timer, TimerTask }
14
def interruptMeIn[T](debugMsg: String, seconds: Int)(body: => T): Option[T] = {
15
val thisThread = currentThread
16
val alarm = new SimpleAlarm(seconds * 1000) set thisThread.interrupt()
17
debug("interruptMeIn(%d) '%s'".format(seconds, debugMsg))
20
catch { case _: InterruptedException => debug("Received interrupted exception.") ; None }
21
finally { debug("Cancelling interruptMeIn '%s'" format debugMsg) ; alarm.cancel() ; Thread.interrupted() }
24
case class AlarmerAction(secs: Int, action: () => Unit) extends Runnable {
25
override def run() = action()
28
/** Set any number of alarms up with tuples of the form:
29
* seconds to alarm -> Function0[Unit] to execute
31
class Alarmer(alarms: AlarmerAction*) {
32
import java.util.concurrent._
34
val exec = Executors.newSingleThreadScheduledExecutor()
35
alarms foreach (x => exec.schedule(x, x.secs, TimeUnit.SECONDS))
38
def cancelAll() = exec.shutdownNow()
41
class SimpleAlarm(timeout: Long) {
42
private val alarm = new Timer
44
/** Start a timer, running the given body if it goes off.
46
def set(body: => Unit) = returning(new TimerTask { def run() = body })(alarm.schedule(_, timeout))
50
def cancel() = alarm.cancel()
56
private def warning1 = AlarmerAction(testWarning, () => warning(
57
"""|I've been waiting %s seconds for this to complete:
59
|It may be stuck, or if not, it should be broken into smaller tests.
60
|""".stripMargin.format(testWarning, test))
62
private def warning2 = AlarmerAction(testWarning * 2, () => warning(
63
"""|Now I've been waiting %s seconds for this to complete:
65
|If partest seems hung it would be a good place to look.
66
|""".stripMargin.format(testWarning * 2, test))
69
def startAlarms(onTimeout: => Unit) =
70
if (isNoAlarms) new Alarmer() // for alarm debugging
71
else new Alarmer(Seq(warning1, warning2, AlarmerAction(testTimeout, () => onTimeout)): _*)
74
// Thread.setDefaultUncaughtExceptionHandler(new UncaughtException)
75
// class UncaughtException extends Thread.UncaughtExceptionHandler {
76
// def uncaughtException(t: Thread, e: Throwable) {
77
// Console.println("Uncaught in %s: %s".format(t, e))
81
// lazy val logger = File("/tmp/partest.log").bufferedWriter()
82
// def flog(msg: String) = logger synchronized {
83
// logger write (msg + "\n")