I have following actor hierarchy parent -> child -> worker where child's life scope is tight to request - when request is completed child actor should be terminated. That I wanted to verify as a part of the test. I created StepParent as a for testing purposes as I want to validate the response for the given request which forwards to msg to testprobe.
class StepParent(child: Props, name: String, probe: ActorRef) extends Actor with ActorLogging {
context.watch(context.actorOf(props = child, name = name))
override def receive: Actor.Receive = {
case msg: PersistImages => context.children.foreach(child => child.tell(msg, sender))
case msg =>
log.debug(s"Msg forwarded to probe $msg")
probe.tell(msg, sender)
}
}
My test looks as follows:
class ImagesControllerActorTest extends TestKit(ActorSystem("testsystem"))
with WordSpecLike with MustMatchers with StopSystemAfterAll {
val id = "456"
"ControllerActor" must {
"distribute a work to dedicated dedicated workers and combine back results and then terminate" in {
val p = TestProbe()
val ica = system.actorOf(Props(classOf[StepParent], createActorWithMockedWorkers(id, p.ref), "ControllerActor", p.ref), "parent")
p.send(ica, PersistImages(Set(new URL("http://success"), new URL("http://fail"))))
p.expectMsgPF(2 seconds)(validMsgPersistImageActor)
p.expectMsgPF(2 seconds)(validMsgPersistImageActor)
p.expectMsg(2 seconds, ImagesProcessed(id, Set(new URI("file:/"))))
p.expectMsg(4 seconds, Terminated)
}
}
My test is failing because of the last check for expected message:
assertion failed: timeout (4 seconds) during expectMsg while waiting for Terminated
java.lang.AssertionError: assertion failed: timeout (4 seconds) during expectMsg while waiting for Terminated
at scala.Predef$.assert(Predef.scala:179)
at akka.testkit.TestKitBase$class.expectMsg_internal(TestKit.scala:338)
...
According to the detailed log Terminated msg is forwarded as well(as per last line)
2015-01-11 17:41:10,386 [WARN ] [testsystem-akka.actor.default-dispatcher-5] akka.tcp://testsystem@127.0.0.1:2555/user/parent/ControllerActor - id: 456 image url: http://fail FAILED
2015-01-11 17:41:10,386 [INFO ] [testsystem-akka.actor.default-dispatcher-5] akka.tcp://testsystem@127.0.0.1:2555/user/parent/ControllerActor - id: 456 Processing completed with 1 downloded and 1 failed
2015-01-11 17:41:10,387 [DEBUG] [testsystem-akka.actor.default-dispatcher-4] akka.tcp://testsystem@127.0.0.1:2555/user/parent - Msg forwarded to probe ImagesProcessed(456,Set(file:/))
2015-01-11 17:41:10,392 [DEBUG] [testsystem-akka.actor.default-dispatcher-2] akka://testsystem/user/parent/ControllerActor/$b - stopped
2015-01-11 17:41:10,394 [DEBUG] [testsystem-akka.actor.default-dispatcher-5] akka://testsystem/user/parent/ControllerActor - stopping
2015-01-11 17:41:10,396 [INFO ] [testsystem-akka.actor.default-dispatcher-4] akka://testsystem/user/parent/ControllerActor/$b - Message [akka.dispatch.sysmsg.Terminate] from Actor[akka://testsystem/user/parent/ImagesControllerActor/$b#-426862126] to Actor[akka://testsystem/user/parent/ControllerActor/$b#-426862126] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
2015-01-11 17:41:10,396 [INFO ] [testsystem-akka.actor.default-dispatcher-2] akka://testsystem/user/parent/ControllerActor/$a - Message [akka.dispatch.sysmsg.Terminate] from Actor[akka://testsystem/user/parent/ControllerActor/$a#1067345522] to Actor[akka://testsystem/user/parent/ControllerActor/$a#1067345522] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
2015-01-11 17:41:10,398 [DEBUG] [testsystem-akka.actor.default-dispatcher-2] akka://testsystem/user/parent/ControllerActor - stopped
2015-01-11 17:41:10,399 [DEBUG] [testsystem-akka.actor.default-dispatcher-16] akka://testsystem/user/parent/ControllerActor/$a - stopped
2015-01-11 17:41:10,399 [DEBUG] [testsystem-akka.actor.default-dispatcher-5] akka://testsystem/user/parent - received AutoReceiveMessage Envelope(Terminated(Actor[akka://testsystem/user/parent/ControllerActor#-770422232]),Actor[akka://testsystem/user/parent/ControllerActor#-770422232])
**2015-01-11 17:41:10,400 [DEBUG] [testsystem-akka.actor.default-dispatcher-5] akka.tcp://testsystem@127.0.0.1:2555/user/parent - Msg forwarded to probe Terminated(Actor[akka://testsystem/user/parent/ControllerActor#-770422232])**
...
I do not really understand why last expectedMsg check doesn't work here since the message is forwarded as usual. Is there any special handling for Auto recieved messages?
Can someone pleas bring some shed into this?
Thx
UPDATE: Tried to solve that as suggested - remove wrapper Envelope as follows:
class StepParent(child: Props, name: String, probe: ActorRef) extends Actor with ActorLogging {
context.watch(context.actorOf(props = child, name = name))
override def receive: Actor.Receive = {
case msg: PersistImages => context.children.foreach(child => child.tell(msg, sender))
case mssg: Envelope =>
log.debug(s"Envelope msg forwarded to probe $mssg")
probe.tell(mssg.message, sender)
case msg =>
log.debug(s"Msg forwarded to probe $msg")
probe.tell(msg, sender)
}
}
2015-01-11 23:52:16,352 [DEBUG] [testsystem-akka.actor.default-dispatcher-4] akka://testsystem/user/parent/ControllerActor - stopping
2015-01-11 23:52:16,354 [DEBUG] [testsystem-akka.actor.default-dispatcher-4] akka://testsystem/user/parent/ControllerActor - stopped
2015-01-11 23:52:16,358 [DEBUG] [testsystem-akka.actor.default-dispatcher-16] akka.tcp://testsystem@127.0.0.1:2555/user/parent - Msg forwarded to probe ImagesProcessed(456,Set(file:/))
2015-01-11 23:52:16,358 [DEBUG] [testsystem-akka.actor.default-dispatcher-16] akka://testsystem/user/parent - received AutoReceiveMessage Envelope(Terminated(Actor[akka://testsystem/user/parent/ControllerActor#-1965336139]),Actor[akka://testsystem/user/parent/ControllerActor#-1965336139])
2015-01-11 23:52:16,360 [DEBUG] [testsystem-akka.actor.default-dispatcher-16] akka.tcp://testsystem@127.0.0.1:2555/user/parent - Msg forwarded to probe Terminated(Actor[akka://testsystem/user/parent/ControllerActor#-1965336139])
2015-01-11 23:52:16,365 [DEBUG] [testsystem-akka.actor.default-dispatcher-16] akka://testsystem/system/testActor2 - received AutoReceiveMessage Envelope(Terminated(Actor[akka://testsystem/user/parent/ControllerActor#-1965336139]),Actor[akka://testsystem/user/parent/ControllerActor#-1965336139])
It is still failing and seems that something suspicious going on here:
2015-01-11 23:52:16,360 [DEBUG] [testsystem-akka.actor.default-dispatcher-16] akka.tcp://testsystem@127.0.0.1:2555/user/parent - Msg forwarded to probe Terminated(Actor[akka://testsystem/user/parent/ImagesControllerActor#-1965336139])
That is not correct message from StepParent but it gets somehow extracted.