2015-05-11 10:14:16 +02:00
|
|
|
/**
|
2016-02-23 12:58:39 +01:00
|
|
|
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
|
2015-05-11 10:14:16 +02:00
|
|
|
*/
|
2014-03-21 20:22:16 +01:00
|
|
|
package akka.remote
|
|
|
|
|
|
|
|
|
|
import akka.remote.testkit.MultiNodeConfig
|
|
|
|
|
import akka.remote.testkit.MultiNodeSpec
|
|
|
|
|
import akka.remote.testkit.STMultiNodeSpec
|
|
|
|
|
import akka.testkit.ImplicitSender
|
|
|
|
|
import akka.actor.Actor
|
|
|
|
|
import akka.actor.ActorRef
|
|
|
|
|
import akka.actor.Props
|
|
|
|
|
import akka.remote.transport.ThrottlerTransportAdapter.Direction._
|
|
|
|
|
import com.typesafe.config.ConfigFactory
|
|
|
|
|
import akka.actor.ActorSystem
|
2014-08-25 15:49:28 +02:00
|
|
|
import scala.concurrent.Await
|
2014-03-21 20:22:16 +01:00
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
import akka.actor.ActorLogging
|
|
|
|
|
import akka.remote.testconductor.TestConductor
|
|
|
|
|
import akka.testkit.TestProbe
|
|
|
|
|
|
2016-06-02 20:44:27 +02:00
|
|
|
class RemoteReDeploymentConfig(artery: Boolean) extends MultiNodeConfig {
|
2014-03-21 20:22:16 +01:00
|
|
|
val first = role("first")
|
|
|
|
|
val second = role("second")
|
|
|
|
|
|
|
|
|
|
commonConfig(debugConfig(on = false).withFallback(ConfigFactory.parseString(
|
2016-06-02 20:44:27 +02:00
|
|
|
s"""akka.remote.transport-failure-detector {
|
2014-03-21 20:22:16 +01:00
|
|
|
threshold=0.1
|
|
|
|
|
heartbeat-interval=0.1s
|
|
|
|
|
acceptable-heartbeat-pause=1s
|
|
|
|
|
}
|
|
|
|
|
akka.remote.watch-failure-detector {
|
|
|
|
|
threshold=0.1
|
|
|
|
|
heartbeat-interval=0.1s
|
|
|
|
|
acceptable-heartbeat-pause=2.5s
|
2016-06-02 20:44:27 +02:00
|
|
|
}
|
|
|
|
|
akka.remote.artery.enabled = $artery
|
|
|
|
|
""")))
|
|
|
|
|
|
2014-03-21 20:22:16 +01:00
|
|
|
testTransport(on = true)
|
|
|
|
|
|
|
|
|
|
deployOn(second, "/parent/hello.remote = \"@first@\"")
|
2016-06-02 20:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RemoteReDeploymentFastMultiJvmNode1 extends RemoteReDeploymentFastMultiJvmSpec(artery = false)
|
|
|
|
|
class RemoteReDeploymentFastMultiJvmNode2 extends RemoteReDeploymentFastMultiJvmSpec(artery = false)
|
|
|
|
|
|
|
|
|
|
class ArteryRemoteReDeploymentFastMultiJvmNode1 extends RemoteReDeploymentFastMultiJvmSpec(artery = true)
|
|
|
|
|
class ArteryRemoteReDeploymentFastMultiJvmNode2 extends RemoteReDeploymentFastMultiJvmSpec(artery = true)
|
|
|
|
|
|
|
|
|
|
abstract class RemoteReDeploymentFastMultiJvmSpec(artery: Boolean) extends RemoteReDeploymentMultiJvmSpec(
|
|
|
|
|
new RemoteReDeploymentConfig(artery)) {
|
|
|
|
|
override def sleepAfterKill = 0.seconds // new association will come in while old is still “healthy”
|
|
|
|
|
override def expectQuarantine = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RemoteReDeploymentMediumMultiJvmNode1 extends RemoteReDeploymentMediumMultiJvmSpec(artery = false)
|
|
|
|
|
class RemoteReDeploymentMediumMultiJvmNode2 extends RemoteReDeploymentMediumMultiJvmSpec(artery = false)
|
|
|
|
|
|
|
|
|
|
class ArteryRemoteReDeploymentMediumMultiJvmNode1 extends RemoteReDeploymentMediumMultiJvmSpec(artery = true)
|
|
|
|
|
class ArteryRemoteReDeploymentMediumMultiJvmNode2 extends RemoteReDeploymentMediumMultiJvmSpec(artery = true)
|
|
|
|
|
|
|
|
|
|
abstract class RemoteReDeploymentMediumMultiJvmSpec(artery: Boolean) extends RemoteReDeploymentMultiJvmSpec(
|
|
|
|
|
new RemoteReDeploymentConfig(artery)) {
|
|
|
|
|
override def sleepAfterKill = 1.seconds // new association will come in while old is gated in ReliableDeliverySupervisor
|
|
|
|
|
override def expectQuarantine = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RemoteReDeploymentSlowMultiJvmNode1 extends RemoteReDeploymentSlowMultiJvmSpec(artery = false)
|
|
|
|
|
class RemoteReDeploymentSlowMultiJvmNode2 extends RemoteReDeploymentSlowMultiJvmSpec(artery = false)
|
|
|
|
|
|
|
|
|
|
class ArteryRemoteReDeploymentSlowMultiJvmNode1 extends RemoteReDeploymentSlowMultiJvmSpec(artery = true)
|
|
|
|
|
class ArteryRemoteReDeploymentSlowMultiJvmNode2 extends RemoteReDeploymentSlowMultiJvmSpec(artery = true)
|
2014-03-21 20:22:16 +01:00
|
|
|
|
2016-06-02 20:44:27 +02:00
|
|
|
abstract class RemoteReDeploymentSlowMultiJvmSpec(artery: Boolean) extends RemoteReDeploymentMultiJvmSpec(
|
|
|
|
|
new RemoteReDeploymentConfig(artery)) {
|
|
|
|
|
override def sleepAfterKill = 10.seconds // new association will come in after old has been quarantined
|
|
|
|
|
override def expectQuarantine = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object RemoteReDeploymentMultiJvmSpec {
|
2014-03-21 20:22:16 +01:00
|
|
|
class Parent extends Actor {
|
|
|
|
|
val monitor = context.actorSelection("/user/echo")
|
|
|
|
|
def receive = {
|
|
|
|
|
case (p: Props, n: String) ⇒ context.actorOf(p, n)
|
|
|
|
|
case msg ⇒ monitor ! msg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Hello extends Actor {
|
|
|
|
|
val monitor = context.actorSelection("/user/echo")
|
|
|
|
|
context.parent ! "HelloParent"
|
|
|
|
|
override def preStart(): Unit = monitor ! "PreStart"
|
|
|
|
|
override def postStop(): Unit = monitor ! "PostStop"
|
|
|
|
|
def receive = Actor.emptyBehavior
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Echo(target: ActorRef) extends Actor with ActorLogging {
|
|
|
|
|
def receive = {
|
|
|
|
|
case msg ⇒
|
2014-06-20 23:05:51 +02:00
|
|
|
log.info(s"received $msg from ${sender()}")
|
2014-03-21 20:22:16 +01:00
|
|
|
target ! msg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
def echoProps(target: ActorRef) = Props(new Echo(target))
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-02 20:44:27 +02:00
|
|
|
abstract class RemoteReDeploymentMultiJvmSpec(multiNodeConfig: RemoteReDeploymentConfig) extends MultiNodeSpec(multiNodeConfig)
|
2014-03-21 20:22:16 +01:00
|
|
|
with STMultiNodeSpec with ImplicitSender {
|
|
|
|
|
|
|
|
|
|
def sleepAfterKill: FiniteDuration
|
|
|
|
|
def expectQuarantine: Boolean
|
|
|
|
|
|
|
|
|
|
def initialParticipants = roles.size
|
|
|
|
|
|
2016-06-02 20:44:27 +02:00
|
|
|
import multiNodeConfig._
|
2014-03-21 20:22:16 +01:00
|
|
|
import RemoteReDeploymentMultiJvmSpec._
|
|
|
|
|
|
|
|
|
|
"A remote deployment target system" must {
|
|
|
|
|
|
|
|
|
|
"terminate the child when its parent system is replaced by a new one" in {
|
|
|
|
|
|
|
|
|
|
val echo = system.actorOf(echoProps(testActor), "echo")
|
2015-05-11 10:14:16 +02:00
|
|
|
enterBarrier("echo-started")
|
2014-03-21 20:22:16 +01:00
|
|
|
|
|
|
|
|
runOn(second) {
|
|
|
|
|
system.actorOf(Props[Parent], "parent") ! ((Props[Hello], "hello"))
|
2015-05-11 10:14:16 +02:00
|
|
|
expectMsg(15.seconds, "HelloParent")
|
2014-03-21 20:22:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runOn(first) {
|
2015-05-11 10:14:16 +02:00
|
|
|
expectMsg(15.seconds, "PreStart")
|
2014-03-21 20:22:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enterBarrier("first-deployed")
|
|
|
|
|
|
|
|
|
|
runOn(first) {
|
|
|
|
|
testConductor.blackhole(second, first, Both).await
|
|
|
|
|
testConductor.shutdown(second, abort = true).await
|
|
|
|
|
if (expectQuarantine)
|
|
|
|
|
within(sleepAfterKill) {
|
|
|
|
|
expectMsg("PostStop")
|
|
|
|
|
expectNoMsg()
|
|
|
|
|
}
|
|
|
|
|
else expectNoMsg(sleepAfterKill)
|
|
|
|
|
awaitAssert(node(second), 10.seconds, 100.millis)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var sys: ActorSystem = null
|
|
|
|
|
|
|
|
|
|
runOn(second) {
|
2014-08-25 15:49:28 +02:00
|
|
|
Await.ready(system.whenTerminated, 30.seconds)
|
2014-03-21 20:22:16 +01:00
|
|
|
expectNoMsg(sleepAfterKill)
|
|
|
|
|
sys = startNewSystem()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enterBarrier("cable-cut")
|
|
|
|
|
|
|
|
|
|
runOn(second) {
|
|
|
|
|
val p = TestProbe()(sys)
|
|
|
|
|
sys.actorOf(echoProps(p.ref), "echo")
|
|
|
|
|
p.send(sys.actorOf(Props[Parent], "parent"), (Props[Hello], "hello"))
|
2015-05-11 10:14:16 +02:00
|
|
|
p.expectMsg(15.seconds, "HelloParent")
|
2014-03-21 20:22:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enterBarrier("re-deployed")
|
|
|
|
|
|
|
|
|
|
runOn(first) {
|
2015-05-11 10:14:16 +02:00
|
|
|
within(15.seconds) {
|
|
|
|
|
if (expectQuarantine) expectMsg("PreStart")
|
|
|
|
|
else expectMsgAllOf("PostStop", "PreStart")
|
|
|
|
|
}
|
2014-03-21 20:22:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enterBarrier("the-end")
|
|
|
|
|
|
|
|
|
|
expectNoMsg(1.second)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 10:14:16 +02:00
|
|
|
}
|