pekko/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala

129 lines
4.2 KiB
Scala
Raw Normal View History

package akka.actor
2011-06-20 15:11:32 -06:00
import org.scalatest.BeforeAndAfterEach
import akka.testkit.TestEvent._
import akka.testkit.EventFilter
import org.multiverse.api.latches.StandardLatch
import java.util.concurrent.{ ConcurrentLinkedQueue, CountDownLatch, TimeUnit }
2011-10-11 16:05:48 +02:00
import akka.testkit.AkkaSpec
import org.jboss.netty.akka.util.{ Timeout TimeOut }
@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner])
2011-10-11 16:05:48 +02:00
class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach {
private val timeouts = new ConcurrentLinkedQueue[TimeOut]()
def collectTimeout(t: TimeOut): TimeOut = {
timeouts.add(t)
t
}
2011-10-11 16:05:48 +02:00
override def afterEach {
while (timeouts.peek() ne null) { Option(timeouts.poll()).foreach(_.cancel()) }
}
2011-10-11 16:05:48 +02:00
"A Scheduler" must {
2011-10-11 16:05:48 +02:00
"schedule more than once" in {
case object Tick
val countDownLatch = new CountDownLatch(3)
2011-10-18 17:56:23 +02:00
val tickActor = actorOf(new Actor {
2011-10-11 16:05:48 +02:00
def receive = { case Tick countDownLatch.countDown() }
})
// run every 50 millisec
collectTimeout(app.scheduler.schedule(tickActor, Tick, 0, 50, TimeUnit.MILLISECONDS))
2011-10-11 16:05:48 +02:00
// after max 1 second it should be executed at least the 3 times already
assert(countDownLatch.await(1, TimeUnit.SECONDS))
2011-10-11 16:05:48 +02:00
val countDownLatch2 = new CountDownLatch(3)
collectTimeout(app.scheduler.schedule(() countDownLatch2.countDown(), 0, 50, TimeUnit.MILLISECONDS))
2011-10-11 16:05:48 +02:00
// after max 1 second it should be executed at least the 3 times already
assert(countDownLatch2.await(2, TimeUnit.SECONDS))
}
2011-10-11 16:05:48 +02:00
"schedule once" in {
case object Tick
val countDownLatch = new CountDownLatch(3)
2011-10-18 17:56:23 +02:00
val tickActor = actorOf(new Actor {
2011-10-11 16:05:48 +02:00
def receive = { case Tick countDownLatch.countDown() }
})
2011-10-11 16:05:48 +02:00
// run every 50 millisec
collectTimeout(app.scheduler.scheduleOnce(tickActor, Tick, 50, TimeUnit.MILLISECONDS))
collectTimeout(app.scheduler.scheduleOnce(() countDownLatch.countDown(), 50, TimeUnit.MILLISECONDS))
2011-10-11 16:05:48 +02:00
// after 1 second the wait should fail
assert(countDownLatch.await(2, TimeUnit.SECONDS) == false)
// should still be 1 left
assert(countDownLatch.getCount == 1)
}
2011-10-11 16:05:48 +02:00
/**
* ticket #372
2011-10-13 13:41:44 +02:00
* FIXME rewrite the test so that registry is not used
2011-10-11 16:05:48 +02:00
*/
2011-10-13 13:41:44 +02:00
// "not create actors" in {
// object Ping
// val ticks = new CountDownLatch(1000)
2011-10-18 17:56:23 +02:00
// val actor = actorOf(new Actor {
2011-10-13 13:41:44 +02:00
// def receive = { case Ping ⇒ ticks.countDown }
// })
// val numActors = app.registry.local.actors.length
// (1 to 1000).foreach(_ ⇒ collectFuture(Scheduler.scheduleOnce(actor, Ping, 1, TimeUnit.MILLISECONDS)))
// assert(ticks.await(10, TimeUnit.SECONDS))
// assert(app.registry.local.actors.length === numActors)
// }
2011-10-11 16:05:48 +02:00
/**
* ticket #372
*/
"be cancellable" in {
object Ping
val ticks = new CountDownLatch(1)
2011-10-18 17:56:23 +02:00
val actor = actorOf(new Actor {
2011-10-11 16:05:48 +02:00
def receive = { case Ping ticks.countDown() }
})
2011-10-11 16:05:48 +02:00
(1 to 10).foreach { i
val timeout = collectTimeout(app.scheduler.scheduleOnce(actor, Ping, 1, TimeUnit.SECONDS))
timeout.cancel()
}
2011-10-11 16:05:48 +02:00
assert(ticks.await(3, TimeUnit.SECONDS) == false) //No counting down should've been made
}
2011-10-11 16:05:48 +02:00
/**
* ticket #307
*/
"pick up schedule after actor restart" in {
object Ping
object Crash
val restartLatch = new StandardLatch
val pingLatch = new CountDownLatch(6)
val supervisor = actorOf(Props[Supervisor].withFaultHandler(AllForOneStrategy(List(classOf[Exception]), 3, 1000)))
val props = Props(new Actor {
2011-10-11 16:05:48 +02:00
def receive = {
case Ping pingLatch.countDown()
case Crash throw new Exception("CRASH")
}
override def postRestart(reason: Throwable) = restartLatch.open
})
val actor = (supervisor ? props).as[ActorRef].get
2011-10-11 16:05:48 +02:00
collectTimeout(app.scheduler.schedule(actor, Ping, 500, 500, TimeUnit.MILLISECONDS))
2011-10-11 16:05:48 +02:00
// appx 2 pings before crash
collectTimeout(app.scheduler.scheduleOnce(actor, Crash, 1000, TimeUnit.MILLISECONDS))
2011-10-11 16:05:48 +02:00
assert(restartLatch.tryAwait(2, TimeUnit.SECONDS))
// should be enough time for the ping countdown to recover and reach 6 pings
assert(pingLatch.await(4, TimeUnit.SECONDS))
}
}
}