The test below seems to have a race condition. What we do is: #1 send copilot a ReadyToGo message; #2 send pilot a PoisonPill;
#1 depends on pilot, which means that if pilot is killed before the copilot has got ref to the pilot, the copilot won't be able to watch the pilot's death.
class Copilot ... case ReadyToGo ⇒ implicit val timeout = Timeout(100 millis) pilot = Await.result[ActorRef](context.actorSelection(s"../$pilotName").resolveOne(), timeout.duration) context.watch(pilot) ... }
class PilotsSpec ... def pilotsReadyToGo(): ActorRef = { val a = system.actorOf(Props(new IsolatedStopSupervisor with OneForOneStrategyFactory { def childStarter(): Unit = { context.actorOf(Props(new FakePilot()), pilotName) context.actorOf(Props(new Copilot(testActor, nilActor)), copilotName) } }), "pilots") Await.result(a ? IsolatedLifeCycleSupervisor.WaitForStart, askTimeout.duration) system.actorSelection(copilotPath) ! Pilots.ReadyToGo a }
"Copilot" should { "take control when the pilot dies" in { pilotsReadyToGo() // race condition here? system.actorSelection(pilotPath) ! PoisonPill expectMsg(GiveMeControl) val ref = Await.result[ActorRef](system.actorSelection(copilotPath).resolveOne(), 100000 millis) lastSender should be(ref) } } }
Do I understand it right or have I missed anything? Thanks!