2016-05-09 07:31:41 +02:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com>
|
|
|
|
|
*/
|
|
|
|
|
package akka.remote.artery
|
|
|
|
|
|
2016-05-13 08:06:13 +02:00
|
|
|
import scala.concurrent.Await
|
2016-05-09 07:31:41 +02:00
|
|
|
import scala.concurrent.duration._
|
2016-05-13 08:06:13 +02:00
|
|
|
|
2016-05-09 07:31:41 +02:00
|
|
|
import akka.actor._
|
2016-05-13 08:06:13 +02:00
|
|
|
import akka.remote.AddressUidExtension
|
|
|
|
|
import akka.remote.RARP
|
2016-05-09 07:31:41 +02:00
|
|
|
import akka.remote.testconductor.RoleName
|
|
|
|
|
import akka.remote.testkit.MultiNodeConfig
|
|
|
|
|
import akka.remote.testkit.MultiNodeSpec
|
|
|
|
|
import akka.remote.testkit.STMultiNodeSpec
|
|
|
|
|
import akka.testkit._
|
|
|
|
|
import com.typesafe.config.ConfigFactory
|
|
|
|
|
|
|
|
|
|
object HandshakeRestartReceiverSpec extends MultiNodeConfig {
|
|
|
|
|
val first = role("first")
|
|
|
|
|
val second = role("second")
|
|
|
|
|
|
|
|
|
|
commonConfig(debugConfig(on = false).withFallback(
|
|
|
|
|
ConfigFactory.parseString(s"""
|
|
|
|
|
akka {
|
|
|
|
|
loglevel = INFO
|
2016-06-10 15:04:13 +02:00
|
|
|
actor.provider = remote
|
2016-05-09 07:31:41 +02:00
|
|
|
remote.artery {
|
|
|
|
|
enabled = on
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
""")))
|
|
|
|
|
|
|
|
|
|
class Subject extends Actor {
|
|
|
|
|
def receive = {
|
|
|
|
|
case "shutdown" ⇒ context.system.terminate()
|
2016-06-03 11:59:00 +02:00
|
|
|
case "identify" ⇒ sender() ! (AddressUidExtension(context.system).addressUid → self)
|
2016-05-09 07:31:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class HandshakeRestartReceiverSpecMultiJvmNode1 extends HandshakeRestartReceiverSpec
|
|
|
|
|
class HandshakeRestartReceiverSpecMultiJvmNode2 extends HandshakeRestartReceiverSpec
|
|
|
|
|
|
|
|
|
|
abstract class HandshakeRestartReceiverSpec
|
|
|
|
|
extends MultiNodeSpec(HandshakeRestartReceiverSpec)
|
|
|
|
|
with STMultiNodeSpec with ImplicitSender {
|
|
|
|
|
|
|
|
|
|
import HandshakeRestartReceiverSpec._
|
|
|
|
|
|
|
|
|
|
override def initialParticipants = roles.size
|
|
|
|
|
|
|
|
|
|
override def afterAll(): Unit = {
|
|
|
|
|
super.afterAll()
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-13 15:34:37 +02:00
|
|
|
def identifyWithUid(rootPath: ActorPath, actorName: String, timeout: FiniteDuration = remainingOrDefault): (Int, ActorRef) = {
|
|
|
|
|
within(timeout) {
|
|
|
|
|
system.actorSelection(rootPath / "user" / actorName) ! "identify"
|
|
|
|
|
expectMsgType[(Int, ActorRef)]
|
|
|
|
|
}
|
2016-05-09 07:31:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"Artery Handshake" must {
|
|
|
|
|
|
|
|
|
|
"detect restarted receiver and initiate new handshake" in {
|
|
|
|
|
runOn(second) {
|
|
|
|
|
system.actorOf(Props[Subject], "subject")
|
|
|
|
|
}
|
|
|
|
|
enterBarrier("subject-started")
|
|
|
|
|
|
|
|
|
|
runOn(first) {
|
|
|
|
|
val secondRootPath = node(second)
|
2016-05-13 15:34:37 +02:00
|
|
|
val (secondUid, _) = identifyWithUid(secondRootPath, "subject", 5.seconds)
|
2016-05-09 07:31:41 +02:00
|
|
|
|
|
|
|
|
val secondAddress = node(second).address
|
|
|
|
|
val secondAssociation = RARP(system).provider.transport.asInstanceOf[ArteryTransport].association(secondAddress)
|
2016-05-13 08:06:13 +02:00
|
|
|
val secondUniqueRemoteAddress = Await.result(secondAssociation.associationState.uniqueRemoteAddress, 3.seconds)
|
2016-05-09 07:31:41 +02:00
|
|
|
secondUniqueRemoteAddress.address should ===(secondAddress)
|
|
|
|
|
secondUniqueRemoteAddress.uid should ===(secondUid)
|
|
|
|
|
|
|
|
|
|
enterBarrier("before-shutdown")
|
|
|
|
|
testConductor.shutdown(second).await
|
|
|
|
|
|
|
|
|
|
within(30.seconds) {
|
|
|
|
|
awaitAssert {
|
2016-05-13 15:34:37 +02:00
|
|
|
identifyWithUid(secondRootPath, "subject2", 1.second)
|
2016-05-09 07:31:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
val (secondUid2, subject2) = identifyWithUid(secondRootPath, "subject2")
|
|
|
|
|
secondUid2 should !==(secondUid)
|
2016-05-13 08:06:13 +02:00
|
|
|
val secondUniqueRemoteAddress2 = Await.result(secondAssociation.associationState.uniqueRemoteAddress, 3.seconds)
|
|
|
|
|
secondUniqueRemoteAddress2.uid should ===(secondUid2)
|
|
|
|
|
secondUniqueRemoteAddress2.address should ===(secondAddress)
|
|
|
|
|
secondUniqueRemoteAddress2 should !==(secondUniqueRemoteAddress)
|
2016-05-09 07:31:41 +02:00
|
|
|
|
|
|
|
|
subject2 ! "shutdown"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runOn(second) {
|
|
|
|
|
val addr = system.asInstanceOf[ExtendedActorSystem].provider.getDefaultAddress
|
|
|
|
|
enterBarrier("before-shutdown")
|
|
|
|
|
|
|
|
|
|
Await.result(system.whenTerminated, 10.seconds)
|
|
|
|
|
|
|
|
|
|
val freshSystem = ActorSystem(system.name, ConfigFactory.parseString(s"""
|
2016-09-09 13:46:50 +03:00
|
|
|
akka.remote.artery.canonical.port = ${addr.port.get}
|
2016-05-09 07:31:41 +02:00
|
|
|
""").withFallback(system.settings.config))
|
|
|
|
|
freshSystem.actorOf(Props[Subject], "subject2")
|
|
|
|
|
|
|
|
|
|
Await.result(freshSystem.whenTerminated, 45.seconds)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|