2014-03-13 79 views
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) 
    } 

    } 

} 

回答

2

您只需靜音的具體消息,而不是聲稱它會到達:

import akka.testkit.TestEvent.Mute 
system.eventStream.publish(Mute(
    EventFilter.warning(pattern = "received dead system message")))