1
대부분의 경우에 [akka://TopLevelSpec/system/IO-TCP/selectors/$a/0] received dead system message: DeathWatchNotification(Actor[akka://TopLevelSpec/user/IO-HTTP/listener-0#413174611],true,false)
이라는 경고 메시지가 기록됩니다. EventFilter를 사용하여 캡처 할 수 있지만 문제는 경쟁 조건 인 것 같고 메시지가 이 아니고이 전송되지 않아 테스트가 예상대로 실패합니다. (내 코드와 테스트의 단순화 된 버전)은 아래와 같습니다. 이 문제를 피하기위한 도움말?Akka 액터 테스트에서 간혹 DeathWatchNotification을 무시합니다.
package com.netaporter.salad.lad
import akka.actor._
import akka.testkit.{ EventFilter, TestActorRef, ImplicitSender, TestKit }
import org.scalatest._
import spray.can.Http
import akka.actor.SupervisorStrategy.{ Restart, Stop }
import akka.actor.Terminated
import akka.actor.OneForOneStrategy
trait FooConfig {
def createBarActor: ActorRef
def createQuuxActor: ActorRef
}
trait Foo extends Actor {
this: FooConfig =>
val bar = createBarActor
context watch bar
val quux = createQuuxActor
context watch quux
override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy() {
case _ if context.child(sender.path.name).isDefined => Stop
}
def receive = {
case Http.CommandFailed(_) => context stop self
case Terminated(`bar`) | Terminated(`quux`) =>
context stop self
}
}
class ReallyDeadDuck extends Actor {
def receive = {
case Symbol(name) => throw new Exception(name)
}
}
class FooSpec extends TestKit(ActorSystem("FooSpec")) with WordSpecLike with BeforeAndAfter with OneInstancePerTest with ShouldMatchers with ImplicitSender {
after {
system.shutdown()
}
trait Case {
val top = TestActorRef(new Foo with FooConfig {
def createBarActor = context.actorOf(Props[ReallyDeadDuck])
def createQuuxActor = context.actorOf(Props[ReallyDeadDuck])
def interface: String = "localhost"
def port: Int = (10000 + math.random * 50000).toInt
})
watch(top)
}
"Foo" should {
"stop itself if bar dies" in new Case {
EventFilter.warning(pattern = "received dead system message", occurrences = 1) intercept {
EventFilter[Exception](message = "bar", occurrences = 1) intercept {
top.underlyingActor.bar ! 'bar
}
}
expectTerminated(top)
}
"stop itself if quux dies" in new Case {
EventFilter.warning(pattern = "received dead system message", occurrences = 1) intercept {
EventFilter[Exception](message = "quux", occurrences = 1) intercept {
top.underlyingActor.quux ! 'quux
}
}
expectTerminated(top)
}
}
}