pekko/akka-remote-tests/src/multi-jvm/scala/akka/remote/artery/HandshakeRestartReceiverSpec.scala

118 lines
3.6 KiB
Scala
Raw Normal View History

/**
* Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com>
*/
package akka.remote.artery
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit.NANOSECONDS
import scala.concurrent.duration._
import akka.actor._
import akka.remote.RemoteActorRefProvider
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
import java.net.InetAddress
import scala.concurrent.Await
import akka.remote.RARP
import akka.remote.AddressUidExtension
object HandshakeRestartReceiverSpec extends MultiNodeConfig {
val first = role("first")
val second = role("second")
commonConfig(debugConfig(on = false).withFallback(
ConfigFactory.parseString(s"""
akka {
loglevel = INFO
actor.provider = "akka.remote.RemoteActorRefProvider"
remote.artery {
enabled = on
}
}
""")))
class Subject extends Actor {
def receive = {
case "shutdown" context.system.terminate()
case "identify" sender() ! (AddressUidExtension(context.system).addressUid -> self)
}
}
}
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()
}
def identifyWithUid(rootPath: ActorPath, actorName: String): (Int, ActorRef) = {
system.actorSelection(rootPath / "user" / actorName) ! "identify"
expectMsgType[(Int, ActorRef)]
}
"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)
val (secondUid, _) = identifyWithUid(secondRootPath, "subject")
val secondAddress = node(second).address
val secondAssociation = RARP(system).provider.transport.asInstanceOf[ArteryTransport].association(secondAddress)
val secondUniqueRemoteAddress = Await.result(secondAssociation.uniqueRemoteAddress, 3.seconds)
secondUniqueRemoteAddress.address should ===(secondAddress)
secondUniqueRemoteAddress.uid should ===(secondUid)
enterBarrier("before-shutdown")
testConductor.shutdown(second).await
within(30.seconds) {
awaitAssert {
within(1.second) {
identifyWithUid(secondRootPath, "subject2")
}
}
}
val (secondUid2, subject2) = identifyWithUid(secondRootPath, "subject2")
secondUid2 should !==(secondUid)
// FIXME verify that UID in association was replaced (not implemented yet)
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"""
akka.remote.artery.port = ${addr.port.get}
""").withFallback(system.settings.config))
freshSystem.actorOf(Props[Subject], "subject2")
Await.result(freshSystem.whenTerminated, 45.seconds)
}
}
}
}