backup of supervisor tests that are not yet ported to specs
This commit is contained in:
parent
d6b43b9181
commit
bcc7d5f8a7
5 changed files with 765 additions and 0 deletions
202
supervisor/test-code/test/scala/GenericServerContainerSuite.scala
Executable file
202
supervisor/test-code/test/scala/GenericServerContainerSuite.scala
Executable file
|
|
@ -0,0 +1,202 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009 Scalable Solutions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.scalablesolutions.akka.supervisor
|
||||||
|
|
||||||
|
import org.specs.runner.JUnit4
|
||||||
|
import org.specs.Specification
|
||||||
|
|
||||||
|
import scala.actors._
|
||||||
|
import scala.actors.Actor._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||||
|
*/
|
||||||
|
class GenericServerContainerTest extends JUnit4(genericServerContainerSpec) // for JUnit4 and Maven
|
||||||
|
object genericServerContainerSpec extends Specification {
|
||||||
|
|
||||||
|
var inner: GenericServerContainerActor = null
|
||||||
|
var server: GenericServerContainer = null
|
||||||
|
def createProxy(f: () => GenericServer) = {
|
||||||
|
val server = new GenericServerContainer("server", f)
|
||||||
|
server.setTimeout(100)
|
||||||
|
server
|
||||||
|
}
|
||||||
|
|
||||||
|
inner = new GenericServerContainerActor
|
||||||
|
server = createProxy(() => inner)
|
||||||
|
server.newServer
|
||||||
|
server.start
|
||||||
|
|
||||||
|
"server should be initialized" in {
|
||||||
|
server.init("testInit")
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("initializing: testInit") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server should terminate with a reason " in {
|
||||||
|
server.terminate("testTerminateWithReason", 100)
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("terminating: testTerminateWithReason") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to async oneway message" in {
|
||||||
|
server ! OneWay
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("got a oneway") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to async ping message" in {
|
||||||
|
server ! Ping
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("got a ping") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to !!!" in {
|
||||||
|
expect("pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
expect("got a ping") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to !?" in {
|
||||||
|
expect("pong") {
|
||||||
|
val res: String = server !? Ping
|
||||||
|
res
|
||||||
|
}
|
||||||
|
expect("got a ping") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to !!! with timeout" in {
|
||||||
|
expect("pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
expect("got a ping") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to !!! with timeout" in {
|
||||||
|
expect("error handler") {
|
||||||
|
server !!! (OneWay, "error handler")
|
||||||
|
}
|
||||||
|
expect("got a oneway") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to !!! and return future with timeout" in {
|
||||||
|
val future = server !! Ping
|
||||||
|
future.receiveWithin(100) match {
|
||||||
|
case None => fail("timed out") // timed out
|
||||||
|
case Some(reply) =>
|
||||||
|
expect("got a ping") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
assert("pong" === reply)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond to !!! and return future with timeout" in {
|
||||||
|
val future = server !! OneWay
|
||||||
|
future.receiveWithin(100) match {
|
||||||
|
case None =>
|
||||||
|
expect("got a oneway") {
|
||||||
|
inner.log
|
||||||
|
}
|
||||||
|
case Some(reply) =>
|
||||||
|
fail("expected a timeout, got Some(reply)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond do hotswap" in {
|
||||||
|
// using base
|
||||||
|
expect("pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// hotswapping
|
||||||
|
server.hotswap(Some({
|
||||||
|
case Ping => reply("hotswapped pong")
|
||||||
|
}))
|
||||||
|
expect("hotswapped pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond do double hotswap" in {
|
||||||
|
// using base
|
||||||
|
expect("pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// hotswapping
|
||||||
|
server.hotswap(Some({
|
||||||
|
case Ping => reply("hotswapped pong")
|
||||||
|
}))
|
||||||
|
expect("hotswapped pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// hotswapping again
|
||||||
|
server.hotswap(Some({
|
||||||
|
case Ping => reply("hotswapped pong again")
|
||||||
|
}))
|
||||||
|
expect("hotswapped pong again") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"server respond do hotswap and then revert" in {
|
||||||
|
// using base
|
||||||
|
expect("pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// hotswapping
|
||||||
|
server.hotswap(Some({
|
||||||
|
case Ping => reply("hotswapped pong")
|
||||||
|
}))
|
||||||
|
expect("hotswapped pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// restoring original base
|
||||||
|
server.hotswap(None)
|
||||||
|
expect("pong") {
|
||||||
|
(server !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class GenericServerContainerActor extends GenericServer {
|
||||||
|
var log = ""
|
||||||
|
|
||||||
|
override def body: PartialFunction[Any, Unit] = {
|
||||||
|
case Ping =>
|
||||||
|
log = "got a ping"
|
||||||
|
reply("pong")
|
||||||
|
|
||||||
|
case OneWay =>
|
||||||
|
log = "got a oneway"
|
||||||
|
}
|
||||||
|
|
||||||
|
override def init(config: AnyRef) = log = "initializing: " + config
|
||||||
|
override def shutdown(reason: AnyRef) = log = "terminating: " + reason
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
40
supervisor/test-code/test/scala/GenericServerSuite.scala
Executable file
40
supervisor/test-code/test/scala/GenericServerSuite.scala
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009 Scalable Solutions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.scalablesolutions.akka.supervisor
|
||||||
|
|
||||||
|
import org.specs.runner.JUnit4
|
||||||
|
import org.specs.Specification
|
||||||
|
|
||||||
|
import scala.actors._
|
||||||
|
import scala.actors.Actor._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||||
|
*/
|
||||||
|
class GenericServerTest extends JUnit4(genericServerSpec) // for JUnit4 and Maven
|
||||||
|
object genericServerSpec extends Specification {
|
||||||
|
|
||||||
|
"server should respond to a regular message" in {
|
||||||
|
val server = new TestGenericServerActor
|
||||||
|
server.start
|
||||||
|
server !? Ping match {
|
||||||
|
case reply: String =>
|
||||||
|
assert("got a ping" === server.log)
|
||||||
|
assert("pong" === reply)
|
||||||
|
case _ => fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestGenericServerActor extends GenericServer {
|
||||||
|
var log: String = ""
|
||||||
|
|
||||||
|
override def body: PartialFunction[Any, Unit] = {
|
||||||
|
case Ping =>
|
||||||
|
log = "got a ping"
|
||||||
|
reply("pong")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
12
supervisor/test-code/test/scala/Messages.scala
Executable file
12
supervisor/test-code/test/scala/Messages.scala
Executable file
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009 Scalable Solutions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.scalablesolutions.akka.supervisor
|
||||||
|
|
||||||
|
sealed abstract class TestMessage
|
||||||
|
case object Ping extends TestMessage
|
||||||
|
case object Pong extends TestMessage
|
||||||
|
case object OneWay extends TestMessage
|
||||||
|
case object Die extends TestMessage
|
||||||
|
case object NotifySupervisorExit extends TestMessage
|
||||||
77
supervisor/test-code/test/scala/SupervisorStateSuite.scala
Executable file
77
supervisor/test-code/test/scala/SupervisorStateSuite.scala
Executable file
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009 Scalable Solutions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.scalablesolutions.akka.supervisor
|
||||||
|
|
||||||
|
import org.specs.runner.JUnit4
|
||||||
|
import org.specs.Specification
|
||||||
|
|
||||||
|
import scala.actors._
|
||||||
|
import scala.actors.Actor._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||||
|
*/
|
||||||
|
class SupervisorStateTest extends JUnit4(supervisorStateSpec) // for JUnit4 and Maven
|
||||||
|
object supervisorStateSpec extends Specification {
|
||||||
|
val dummyActor = new GenericServer { override def body: PartialFunction[Any, Unit] = { case _ => }}
|
||||||
|
val newDummyActor = () => dummyActor
|
||||||
|
var state: SupervisorState = _
|
||||||
|
var proxy: GenericServerContainer = _
|
||||||
|
var supervisor: Supervisor = _
|
||||||
|
|
||||||
|
proxy = new GenericServerContainer("server1", newDummyActor)
|
||||||
|
object factory extends SupervisorFactory {
|
||||||
|
override def getSupervisorConfig: SupervisorConfig = {
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(AllForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
proxy,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
:: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
supervisor = factory.newSupervisor
|
||||||
|
state = new SupervisorState(supervisor, new AllForOneStrategy(3, 100))
|
||||||
|
|
||||||
|
"supervisor state should return added server" in {
|
||||||
|
state.addServerContainer(proxy)
|
||||||
|
state.getServerContainer("server1") match {
|
||||||
|
case None => fail("should have returned server")
|
||||||
|
case Some(server) =>
|
||||||
|
assert(server != null)
|
||||||
|
assert(server.isInstanceOf[GenericServerContainer])
|
||||||
|
assert(proxy === server)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"supervisor state should remove added server" in {
|
||||||
|
state.addServerContainer(proxy)
|
||||||
|
|
||||||
|
state.removeServerContainer("server1")
|
||||||
|
state.getServerContainer("server1") match {
|
||||||
|
case Some(_) => fail("should have returned None")
|
||||||
|
case None =>
|
||||||
|
}
|
||||||
|
state.getServerContainer("dummyActor") match {
|
||||||
|
case Some(_) => fail("should have returned None")
|
||||||
|
case None =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"supervisor state should fail getting non-existent server by symbol" in {
|
||||||
|
state.getServerContainer("server2") match {
|
||||||
|
case Some(_) => fail("should have returned None")
|
||||||
|
case None =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"supervisor state should fail getting non-existent server by actor" in {
|
||||||
|
state.getServerContainer("dummyActor") match {
|
||||||
|
case Some(_) => fail("should have returned None")
|
||||||
|
case None =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
434
supervisor/test-code/test/scala/SupervisorSuite.scala
Executable file
434
supervisor/test-code/test/scala/SupervisorSuite.scala
Executable file
|
|
@ -0,0 +1,434 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009 Scalable Solutions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.scalablesolutions.akka.supervisor
|
||||||
|
|
||||||
|
import org.specs.runner.JUnit4
|
||||||
|
import org.specs.Specification
|
||||||
|
|
||||||
|
import scala.actors._
|
||||||
|
import scala.actors.Actor._
|
||||||
|
import scala.collection.Map
|
||||||
|
import scala.collection.mutable.HashMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||||
|
*/
|
||||||
|
class SupervisorTest extends JUnit4(supervisorSpec) // for JUnit4 and Maven
|
||||||
|
object supervisorSpec extends Specification {
|
||||||
|
|
||||||
|
var messageLog: String = ""
|
||||||
|
val pingpong1 = new GenericServerContainer("pingpong1", () => new PingPong1Actor)
|
||||||
|
val pingpong2 = new GenericServerContainer("pingpong2", () => new PingPong2Actor)
|
||||||
|
val pingpong3 = new GenericServerContainer("pingpong3", () => new PingPong3Actor)
|
||||||
|
|
||||||
|
pingpong1.setTimeout(100)
|
||||||
|
pingpong2.setTimeout(100)
|
||||||
|
pingpong3.setTimeout(100)
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
def setup = messageLog = ""
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"starting supervisor should start the servers" in {
|
||||||
|
val sup = getSingleActorAllForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"started supervisor should be able to return started servers" in {
|
||||||
|
val sup = getSingleActorAllForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
val server = sup.getServerOrElse("pingpong1", throw new RuntimeException("server not found"))
|
||||||
|
assert(server.isInstanceOf[GenericServerContainer])
|
||||||
|
assert(server === pingpong1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"started supervisor should fail returning non-existing server" in {
|
||||||
|
val sup = getSingleActorAllForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
sup.getServerOrElse("wrong_name", throw new RuntimeException("server not found"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart killed server with restart strategy one_for_one" in {
|
||||||
|
val sup = getSingleActorOneForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong1 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("oneforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart used killed server with restart strategy one_for_one" in {
|
||||||
|
val sup = getSingleActorOneForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("ping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong1 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingoneforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingoneforoneping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart killed server with restart strategy all_for_one" in {
|
||||||
|
val sup = getSingleActorAllForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong1 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("allforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart used killed server with restart strategy all_for_one" in {
|
||||||
|
val sup = getSingleActorAllForOneSupervisor
|
||||||
|
sup ! Start
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("ping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong1 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingallforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingallforoneping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart killed multiple servers with restart strategy one_for_one" in {
|
||||||
|
val sup = getMultipleActorsOneForOneConf
|
||||||
|
sup ! Start
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong3 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("oneforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart killed multiple servers with restart strategy one_for_one" in {
|
||||||
|
val sup = getMultipleActorsOneForOneConf
|
||||||
|
sup ! Start
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong2 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong3 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingpingping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong2 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingpingpingoneforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong2 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong3 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingpingpingoneforonepingpingping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart killed muliple servers with restart strategy all_for_one" in {
|
||||||
|
val sup = getMultipleActorsAllForOneConf
|
||||||
|
sup ! Start
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong2 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("allforoneallforoneallforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
"supervisor should restart killed muliple servers with restart strategy all_for_one" in {
|
||||||
|
val sup = getMultipleActorsAllForOneConf
|
||||||
|
sup ! Start
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong2 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong3 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingpingping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong2 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingpingpingallforoneallforoneallforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong1 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong2 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pong") {
|
||||||
|
(pingpong3 !!! Ping).getOrElse("nil")
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("pingpingpingallforoneallforoneallforonepingpingping") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"supervisor should restart killed first-level server with restart strategy all_for_one" in {
|
||||||
|
val sup = getNestedSupervisorsAllForOneConf
|
||||||
|
sup ! Start
|
||||||
|
intercept(classOf[RuntimeException]) {
|
||||||
|
pingpong1 !!! (Die, throw new RuntimeException("TIME OUT"))
|
||||||
|
}
|
||||||
|
Thread.sleep(100)
|
||||||
|
expect("allforoneallforoneallforone") {
|
||||||
|
messageLog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// Creat some supervisors with different configurations
|
||||||
|
|
||||||
|
def getSingleActorAllForOneSupervisor: Supervisor = {
|
||||||
|
|
||||||
|
// Create an abstract SupervisorContainer that works for all implementations
|
||||||
|
// of the different Actors (Services).
|
||||||
|
//
|
||||||
|
// Then create a concrete container in which we mix in support for the specific
|
||||||
|
// implementation of the Actors we want to use.
|
||||||
|
|
||||||
|
object factory extends TestSupervisorFactory {
|
||||||
|
override def getSupervisorConfig: SupervisorConfig = {
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(AllForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
pingpong1,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
:: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factory.newSupervisor
|
||||||
|
}
|
||||||
|
|
||||||
|
def getSingleActorOneForOneSupervisor: Supervisor = {
|
||||||
|
object factory extends TestSupervisorFactory {
|
||||||
|
override def getSupervisorConfig: SupervisorConfig = {
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(OneForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
pingpong1,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
:: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factory.newSupervisor
|
||||||
|
}
|
||||||
|
|
||||||
|
def getMultipleActorsAllForOneConf: Supervisor = {
|
||||||
|
object factory extends TestSupervisorFactory {
|
||||||
|
override def getSupervisorConfig: SupervisorConfig = {
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(AllForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
pingpong1,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
::
|
||||||
|
Worker(
|
||||||
|
pingpong2,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
::
|
||||||
|
Worker(
|
||||||
|
pingpong3,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
:: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factory.newSupervisor
|
||||||
|
}
|
||||||
|
|
||||||
|
def getMultipleActorsOneForOneConf: Supervisor = {
|
||||||
|
object factory extends TestSupervisorFactory {
|
||||||
|
override def getSupervisorConfig: SupervisorConfig = {
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(OneForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
pingpong1,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
::
|
||||||
|
Worker(
|
||||||
|
pingpong2,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
::
|
||||||
|
Worker(
|
||||||
|
pingpong3,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
:: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factory.newSupervisor
|
||||||
|
}
|
||||||
|
|
||||||
|
def getNestedSupervisorsAllForOneConf: Supervisor = {
|
||||||
|
object factory extends TestSupervisorFactory {
|
||||||
|
override def getSupervisorConfig: SupervisorConfig = {
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(AllForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
pingpong1,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
::
|
||||||
|
SupervisorConfig(
|
||||||
|
RestartStrategy(AllForOne, 3, 100),
|
||||||
|
Worker(
|
||||||
|
pingpong2,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
::
|
||||||
|
Worker(
|
||||||
|
pingpong3,
|
||||||
|
LifeCycle(Permanent, 100))
|
||||||
|
:: Nil)
|
||||||
|
:: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factory.newSupervisor
|
||||||
|
}
|
||||||
|
|
||||||
|
class PingPong1Actor extends GenericServer {
|
||||||
|
override def body: PartialFunction[Any, Unit] = {
|
||||||
|
case Ping =>
|
||||||
|
messageLog += "ping"
|
||||||
|
reply("pong")
|
||||||
|
case Die =>
|
||||||
|
throw new RuntimeException("Recieved Die message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PingPong2Actor extends GenericServer {
|
||||||
|
override def body: PartialFunction[Any, Unit] = {
|
||||||
|
case Ping =>
|
||||||
|
messageLog += "ping"
|
||||||
|
reply("pong")
|
||||||
|
case Die =>
|
||||||
|
throw new RuntimeException("Recieved Die message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PingPong3Actor extends GenericServer {
|
||||||
|
override def body: PartialFunction[Any, Unit] = {
|
||||||
|
case Ping =>
|
||||||
|
messageLog += "ping"
|
||||||
|
reply("pong")
|
||||||
|
case Die =>
|
||||||
|
throw new RuntimeException("Recieved Die message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
class TestAllForOneStrategy(maxNrOfRetries: Int, withinTimeRange: Int) extends AllForOneStrategy(maxNrOfRetries, withinTimeRange) {
|
||||||
|
override def postRestart(serverContainer: GenericServerContainer) = {
|
||||||
|
messageLog += "allforone"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestOneForOneStrategy(maxNrOfRetries: Int, withinTimeRange: Int) extends OneForOneStrategy(maxNrOfRetries, withinTimeRange) {
|
||||||
|
override def postRestart(serverContainer: GenericServerContainer) = {
|
||||||
|
messageLog += "oneforone"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TestSupervisorFactory extends SupervisorFactory {
|
||||||
|
override def create(strategy: RestartStrategy): Supervisor = strategy match {
|
||||||
|
case RestartStrategy(scheme, maxNrOfRetries, timeRange) =>
|
||||||
|
scheme match {
|
||||||
|
case AllForOne => new Supervisor(new TestAllForOneStrategy(maxNrOfRetries, timeRange))
|
||||||
|
case OneForOne => new Supervisor(new TestOneForOneStrategy(maxNrOfRetries, timeRange))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue