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捕獲它,但問題在於似乎存在爭用條件,並且有時候發送的消息是而不是,並且測試隨後出現預期失敗。 (簡化版)我的代碼和測試如下。避免這個問題的任何提示?忽略阿卡演員測試中的偶爾使用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)
}
}
}