From c7641fc1172e279a88e18e3839f766b56ef865f1 Mon Sep 17 00:00:00 2001 From: FateJH Date: Sun, 27 May 2018 02:24:20 -0400 Subject: [PATCH] modified zone ground actor operation to include no-callback item removal message; adjusted tests for Zone and wrote tests for RemoverActor --- .../net/psforever/objects/zones/Zone.scala | 8 +- .../objects/zones/ZoneGroundActor.scala | 25 +- .../src/test/scala/objects/PlayerTest.scala | 6 + common/src/test/scala/objects/ZoneTest.scala | 203 +++++-- pslogin/src/main/scala/PsLogin.scala | 2 +- .../src/main/scala/WorldSessionActor.scala | 39 +- .../main/scala/services/RemoverActor.scala | 2 +- pslogin/src/test/scala/RemoverActorTest.scala | 537 ++++++++++++++++++ 8 files changed, 754 insertions(+), 68 deletions(-) create mode 100644 pslogin/src/test/scala/RemoverActorTest.scala diff --git a/common/src/main/scala/net/psforever/objects/zones/Zone.scala b/common/src/main/scala/net/psforever/objects/zones/Zone.scala index 4ac4d109c..930ac574c 100644 --- a/common/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/common/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -89,7 +89,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) { if(accessor == ActorRef.noSender) { implicit val guid : NumberPoolHub = this.guid //passed into builderObject.Build implicitly accessor = context.actorOf(RandomPool(25).props(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystem.AllocateNumberPoolActors(guid))), s"$Id-uns") - ground = context.actorOf(Props(classOf[ZoneGroundActor], equipmentOnGround), s"$Id-ground") + ground = context.actorOf(Props(classOf[ZoneGroundActor], this, equipmentOnGround), s"$Id-ground") transport = context.actorOf(Props(classOf[ZoneVehicleActor], this, vehicles), s"$Id-vehicles") population = context.actorOf(Props(classOf[ZonePopulationActor], this, players, corpses), s"$Id-players") @@ -389,11 +389,13 @@ object Zone { object Ground { final case class DropItem(item : Equipment, pos : Vector3, orient : Vector3) final case class ItemOnGround(item : Equipment, pos : Vector3, orient : Vector3) - final case class CanNotDropItem(item : Equipment) + final case class CanNotDropItem(zone : Zone, item : Equipment, reason : String) final case class PickupItem(item_guid : PlanetSideGUID) final case class ItemInHand(item : Equipment) - final case class CanNotPickupItem(item_guid : PlanetSideGUID) + final case class CanNotPickupItem(zone : Zone, item_guid : PlanetSideGUID, reason : String) + + final case class RemoveItem(item_guid : PlanetSideGUID) } object Vehicle { diff --git a/common/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala b/common/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala index b44be2c30..5b4f3e676 100644 --- a/common/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala +++ b/common/src/main/scala/net/psforever/objects/zones/ZoneGroundActor.scala @@ -12,17 +12,23 @@ import scala.collection.mutable.ListBuffer * na * @param equipmentOnGround a `List` of items (`Equipment`) dropped by players on the ground and can be collected again */ -class ZoneGroundActor(equipmentOnGround : ListBuffer[Equipment]) extends Actor { +class ZoneGroundActor(zone : Zone, equipmentOnGround : ListBuffer[Equipment]) extends Actor { //private[this] val log = org.log4s.getLogger def receive : Receive = { case Zone.Ground.DropItem(item, pos, orient) => - sender ! (FindItemOnGround(item.GUID) match { - case None => - equipmentOnGround += item - Zone.Ground.ItemOnGround(item, pos, orient) - case Some(_) => - Zone.Ground.CanNotDropItem(item) + sender ! (if(!item.HasGUID) { + Zone.Ground.CanNotDropItem(zone, item, "not registered yet") + } + else if(zone.GUID(item.GUID).isEmpty) { + Zone.Ground.CanNotDropItem(zone, item, "registered to some other zone") + } + else if(equipmentOnGround.contains(item)) { + Zone.Ground.CanNotDropItem(zone, item, "already dropped") + } + else { + equipmentOnGround += item + Zone.Ground.ItemOnGround(item, pos, orient) }) case Zone.Ground.PickupItem(item_guid) => @@ -30,9 +36,12 @@ class ZoneGroundActor(equipmentOnGround : ListBuffer[Equipment]) extends Actor { case Some(item) => Zone.Ground.ItemInHand(item) case None => - Zone.Ground.CanNotPickupItem(item_guid) + Zone.Ground.CanNotPickupItem(zone, item_guid, "can not find") }) + case Zone.Ground.RemoveItem(item_guid) => + FindItemOnGround(item_guid) //intentionally no callback + case _ => ; } diff --git a/common/src/test/scala/objects/PlayerTest.scala b/common/src/test/scala/objects/PlayerTest.scala index 560b1c524..416eba4d7 100644 --- a/common/src/test/scala/objects/PlayerTest.scala +++ b/common/src/test/scala/objects/PlayerTest.scala @@ -155,7 +155,13 @@ class PlayerTest extends Specification { "has visible slots" in { val obj = TestPlayer("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) + obj.VisibleSlots mustEqual Set(0,2,4) //Standard + obj.ExoSuit = ExoSuitType.Agile + obj.VisibleSlots mustEqual Set(0,1,2,4) + obj.ExoSuit = ExoSuitType.Reinforced obj.VisibleSlots mustEqual Set(0,1,2,3,4) + obj.ExoSuit = ExoSuitType.Infiltration + obj.VisibleSlots mustEqual Set(0,4) obj.ExoSuit = ExoSuitType.MAX obj.VisibleSlots mustEqual Set(0) } diff --git a/common/src/test/scala/objects/ZoneTest.scala b/common/src/test/scala/objects/ZoneTest.scala index 84868f234..bec2e3847 100644 --- a/common/src/test/scala/objects/ZoneTest.scala +++ b/common/src/test/scala/objects/ZoneTest.scala @@ -18,7 +18,7 @@ import net.psforever.objects.zones.{Zone, ZoneActor, ZoneMap} import net.psforever.objects.Vehicle import org.specs2.mutable.Specification -import scala.concurrent.duration.Duration +import scala.concurrent.duration._ class ZoneTest extends Specification { def test(a: Int, b : Zone, c : ActorContext) : Building = { Building.NoBuilding } @@ -464,55 +464,184 @@ class ZonePopulationTest extends ActorTest { } } -class ZoneGroundTest extends ActorTest { +class ZoneGroundDropItemTest extends ActorTest { val item = AmmoBox(GlobalDefinitions.bullet_9mm) - item.GUID = PlanetSideGUID(10) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + hub.register(item, 10) + val zone = new Zone("test", new ZoneMap("test-map"), 0) + zone.GUID(hub) + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + receiveOne(200 milliseconds) //consume - "ZoneGroundActor" should { + "DropItem" should { "drop item on ground" in { - val zone = new Zone("test", new ZoneMap(""), 0) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "drop-item-test") ! "!" - receiveOne(Duration.create(200, "ms")) //consume - - assert(zone.EquipmentOnGround.isEmpty) - assert(item.Position == Vector3.Zero) - assert(item.Orientation == Vector3.Zero) + assert(!zone.EquipmentOnGround.contains(item)) zone.Ground ! Zone.Ground.DropItem(item, Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f)) - expectNoMsg(Duration.create(100, "ms")) - assert(zone.EquipmentOnGround == List(item)) - assert(item.Position == Vector3(1.1f, 2.2f, 3.3f)) - assert(item.Orientation == Vector3(4.4f, 5.5f, 6.6f)) + val reply = receiveOne(200 milliseconds) + assert(reply.isInstanceOf[Zone.Ground.ItemOnGround]) + assert(reply.asInstanceOf[Zone.Ground.ItemOnGround].item == item) + assert(reply.asInstanceOf[Zone.Ground.ItemOnGround].pos == Vector3(1.1f, 2.2f, 3.3f)) + assert(reply.asInstanceOf[Zone.Ground.ItemOnGround].orient == Vector3(4.4f, 5.5f, 6.6f)) + assert(zone.EquipmentOnGround.contains(item)) } + } +} - "get item from ground (success)" in { - val zone = new Zone("test", new ZoneMap(""), 0) - val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-good") ! "!" - receiveOne(Duration.create(200, "ms")) //consume +class ZoneGroundCanNotDropItem1Test extends ActorTest { + val item = AmmoBox(GlobalDefinitions.bullet_9mm) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + //hub.register(item, 10) //!important + val zone = new Zone("test", new ZoneMap("test-map"), 0) + zone.GUID(hub) + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + + "DropItem" should { + "not drop an item that is not registered" in { + assert(!zone.EquipmentOnGround.contains(item)) zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero) - expectNoMsg(Duration.create(100, "ms")) - assert(zone.EquipmentOnGround == List(item)) - zone.Ground ! Zone.Ground.PickupItem(PlanetSideGUID(10)) - val reply = receiveOne(Duration.create(100, "ms")) + val reply = receiveOne(300 milliseconds) + assert(reply.isInstanceOf[Zone.Ground.CanNotDropItem]) + assert(reply.asInstanceOf[Zone.Ground.CanNotDropItem].item == item) + assert(reply.asInstanceOf[Zone.Ground.CanNotDropItem].zone == zone) + assert(reply.asInstanceOf[Zone.Ground.CanNotDropItem].reason == "not registered yet") + assert(!zone.EquipmentOnGround.contains(item)) + } + } +} +class ZoneGroundCanNotDropItem2Test extends ActorTest { + val item = AmmoBox(GlobalDefinitions.bullet_9mm) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + hub.register(item, 10) //!important + val zone = new Zone("test", new ZoneMap("test-map"), 0) + //zone.GUID(hub) //!important + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + + "DropItem" should { + "not drop an item that is not registered to the zone" in { + assert(!zone.EquipmentOnGround.contains(item)) + zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero) + + val reply = receiveOne(300 milliseconds) + assert(reply.isInstanceOf[Zone.Ground.CanNotDropItem]) + assert(reply.asInstanceOf[Zone.Ground.CanNotDropItem].item == item) + assert(reply.asInstanceOf[Zone.Ground.CanNotDropItem].zone == zone) + assert(reply.asInstanceOf[Zone.Ground.CanNotDropItem].reason == "registered to some other zone") + assert(!zone.EquipmentOnGround.contains(item)) + } + } +} + +class ZoneGroundCanNotDropItem3Test extends ActorTest { + val item = AmmoBox(GlobalDefinitions.bullet_9mm) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + hub.register(item, 10) //!important + val zone = new Zone("test", new ZoneMap("test-map"), 0) + zone.GUID(hub) //!important + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + + "DropItem" should { + "not drop an item that has already been dropped" in { + assert(!zone.EquipmentOnGround.contains(item)) assert(zone.EquipmentOnGround.isEmpty) - assert(reply.isInstanceOf[Zone.Ground.ItemInHand]) - assert(reply.asInstanceOf[Zone.Ground.ItemInHand].item == item) - } - - "get item from ground (failure)" in { - val zone = new Zone("test", new ZoneMap(""), 0) - val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)) - system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-fail") ! "!" - receiveOne(Duration.create(200, "ms")) //consume zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero) - expectNoMsg(Duration.create(100, "ms")) - assert(zone.EquipmentOnGround == List(item)) - zone.Ground ! Zone.Ground.PickupItem(PlanetSideGUID(11)) //wrong guid - expectNoMsg(Duration.create(500, "ms")) + val reply1 = receiveOne(300 milliseconds) + assert(reply1.isInstanceOf[Zone.Ground.ItemOnGround]) + assert(reply1.asInstanceOf[Zone.Ground.ItemOnGround].item == item) + assert(zone.EquipmentOnGround.contains(item)) + assert(zone.EquipmentOnGround.size == 1) + zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero) + + val reply2 = receiveOne(300 milliseconds) + assert(reply2.isInstanceOf[Zone.Ground.CanNotDropItem]) + assert(reply2.asInstanceOf[Zone.Ground.CanNotDropItem].item == item) + assert(reply2.asInstanceOf[Zone.Ground.CanNotDropItem].zone == zone) + assert(reply2.asInstanceOf[Zone.Ground.CanNotDropItem].reason == "already dropped") + assert(zone.EquipmentOnGround.size == 1) + } + } +} + +class ZoneGroundPickupItemTest extends ActorTest { + val item = AmmoBox(GlobalDefinitions.bullet_9mm) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + hub.register(item, 10) + val zone = new Zone("test", new ZoneMap("test-map"), 0) + zone.GUID(hub) + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + + "PickupItem" should { + "pickup an item from ground" in { + assert(!zone.EquipmentOnGround.contains(item)) + zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero) + + val reply1 = receiveOne(200 milliseconds) + assert(reply1.isInstanceOf[Zone.Ground.ItemOnGround]) + assert(zone.EquipmentOnGround.contains(item)) + zone.Ground ! Zone.Ground.PickupItem(item.GUID) + + val reply2 = receiveOne(200 milliseconds) + assert(reply2.isInstanceOf[Zone.Ground.ItemInHand]) + assert(reply2.asInstanceOf[Zone.Ground.ItemInHand].item == item) + assert(!zone.EquipmentOnGround.contains(item)) + } + } +} + +class ZoneGroundCanNotPickupItemTest extends ActorTest { + val item = AmmoBox(GlobalDefinitions.bullet_9mm) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + hub.register(item, 10) + val zone = new Zone("test", new ZoneMap("test-map"), 0) + zone.GUID(hub) //still registered to this zone + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + + "PickupItem" should { + "not pickup an item if it can not be found" in { + assert(!zone.EquipmentOnGround.contains(item)) + zone.Ground ! Zone.Ground.PickupItem(item.GUID) + + val reply2 = receiveOne(200 milliseconds) + assert(reply2.isInstanceOf[Zone.Ground.CanNotPickupItem]) + assert(reply2.asInstanceOf[Zone.Ground.CanNotPickupItem].item_guid == item.GUID) + assert(reply2.asInstanceOf[Zone.Ground.CanNotPickupItem].zone == zone) + assert(reply2.asInstanceOf[Zone.Ground.CanNotPickupItem].reason == "can not find") + } + } +} + +class ZoneGroundRemoveItemTest extends ActorTest { + val item = AmmoBox(GlobalDefinitions.bullet_9mm) + val hub = new NumberPoolHub(new LimitedNumberSource(20)) + hub.register(item, 10) + val zone = new Zone("test", new ZoneMap("test-map"), 0) + zone.GUID(hub) //still registered to this zone + zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "drop-test-zone") + zone.Actor ! Zone.Init() + + "RemoveItem" should { + "remove an item from the ground without callback (even if the item is not found)" in { + assert(!zone.EquipmentOnGround.contains(item)) + zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero) + receiveOne(200 milliseconds) + assert(zone.EquipmentOnGround.contains(item)) //dropped + + zone.Ground ! Zone.Ground.RemoveItem(item.GUID) + expectNoMsg(500 milliseconds) + assert(!zone.EquipmentOnGround.contains(item)) + + zone.Ground ! Zone.Ground.RemoveItem(item.GUID) //repeat + expectNoMsg(500 milliseconds) + assert(!zone.EquipmentOnGround.contains(item)) } } } diff --git a/pslogin/src/main/scala/PsLogin.scala b/pslogin/src/main/scala/PsLogin.scala index e689aa9ef..ebbbfdfb2 100644 --- a/pslogin/src/main/scala/PsLogin.scala +++ b/pslogin/src/main/scala/PsLogin.scala @@ -217,7 +217,7 @@ object PsLogin { import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import scala.util.{Failure, Success} - implicit val timeout = Timeout(200 milliseconds) + implicit val timeout = Timeout(500 milliseconds) val requestVehicleEventBus : Future[ServiceManager.LookupResult] = (ServiceManager.serviceManager ask ServiceManager.Lookup("vehicle")).mapTo[ServiceManager.LookupResult] requestVehicleEventBus.onComplete { diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 9633cac29..c4ff7e362 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -1364,13 +1364,8 @@ class WorldSessionActor extends Actor with MDCContextAware { } avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.DropItem(exclusionId, item, continent)) - case Zone.Ground.CanNotDropItem(item) => - log.warn(s"DropItem: $player tried to drop a $item on the ground, but he missed") - player.Find(item) match { - case None => //item in limbo - taskResolver ! GUIDTask.UnregisterEquipment(item)(continent.GUID) - case Some(_) => ; - } + case Zone.Ground.CanNotDropItem(zone, item, reason) => + log.warn(s"DropItem: $player tried to drop a $item on the ground, but $reason") case Zone.Ground.ItemInHand(item) => player.Fit(item) match { @@ -1392,8 +1387,8 @@ class WorldSessionActor extends Actor with MDCContextAware { continent.Ground ! Zone.Ground.DropItem(item, item.Position, item.Orientation) //restore previous state } - case Zone.Ground.CanNotPickupItem(item_guid) => - continent.GUID(item_guid) match { + case Zone.Ground.CanNotPickupItem(zone, item_guid, _) => + zone.GUID(item_guid) match { case Some(item) => log.warn(s"DropItem: finding a $item on the ground was suggested, but $player can not reach it") case None => @@ -2283,10 +2278,10 @@ class WorldSessionActor extends Actor with MDCContextAware { && ((vehicle.Owner.isEmpty || continent.GUID(vehicle.Owner.get).isEmpty) || vehicle.Health == 0))) { vehicleService ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(vehicle), continent)) vehicleService ! VehicleServiceMessage.Decon(RemoverActor.AddTask(vehicle, continent, Some(0 seconds))) - log.info(s"RequestDestroy: vehicle $object_guid") + log.info(s"RequestDestroy: vehicle $vehicle") } else { - log.info(s"RequestDestroy: must own vehicle $object_guid in order to deconstruct it") + log.info(s"RequestDestroy: must own vehicle in order to deconstruct it") } case Some(obj : Equipment) => @@ -2308,20 +2303,28 @@ class WorldSessionActor extends Actor with MDCContextAware { }) match { case Some((parent, Some(slot))) => + obj.Position = Vector3.Zero taskResolver ! RemoveEquipmentFromSlot(parent, obj, slot) - log.info(s"RequestDestroy: equipment $object_guid") + log.info(s"RequestDestroy: equipment $obj") case _ => - //TODO search for item on ground - sendResponse(ObjectDeleteMessage(object_guid, 0)) - log.warn(s"RequestDestroy: object $object_guid not found") + if(continent.EquipmentOnGround.contains(obj)) { + obj.Position = Vector3.Zero + continent.Ground ! Zone.Ground.RemoveItem(object_guid) + avatarService ! AvatarServiceMessage.Ground(RemoverActor.ClearSpecific(List(obj), continent)) + avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(PlanetSideGUID(0), object_guid)) + log.info(s"RequestDestroy: equipment $obj on ground") + } + else { + log.warn(s"RequestDestroy: equipment $obj exists, but can not be reached") + } } + case Some(thing) => + log.warn(s"RequestDestroy: not allowed to delete object $thing") + case None => log.warn(s"RequestDestroy: object $object_guid not found") - - case _ => - log.warn(s"RequestDestroy: not allowed to delete object $object_guid") } case msg @ ObjectDeleteMessage(object_guid, unk1) => diff --git a/pslogin/src/main/scala/services/RemoverActor.scala b/pslogin/src/main/scala/services/RemoverActor.scala index be695d05d..85e211e02 100644 --- a/pslogin/src/main/scala/services/RemoverActor.scala +++ b/pslogin/src/main/scala/services/RemoverActor.scala @@ -163,7 +163,7 @@ abstract class RemoverActor extends Actor { trace(s"item removal task has removed ${in.size} items") case RemoverActor.FailureToWork(entry, ex) => - log.error(s"${entry.obj} from ${entry.zone} not properly unregistered - $ex") + log.error(s"${entry.obj} from ${entry.zone} not properly deleted - $ex") case _ => ; } diff --git a/pslogin/src/test/scala/RemoverActorTest.scala b/pslogin/src/test/scala/RemoverActorTest.scala new file mode 100644 index 000000000..c38159240 --- /dev/null +++ b/pslogin/src/test/scala/RemoverActorTest.scala @@ -0,0 +1,537 @@ +// Copyright (c) 2017 PSForever +import akka.actor.{ActorRef, Props} +import akka.routing.RandomPool +import akka.testkit.TestProbe +import net.psforever.objects.PlanetSideGameObject +import net.psforever.objects.definition.{EquipmentDefinition, ObjectDefinition} +import net.psforever.objects.equipment.Equipment +import net.psforever.objects.guid.TaskResolver +import net.psforever.objects.zones.{Zone, ZoneMap} +import net.psforever.packet.game.PlanetSideGUID +import services.{RemoverActor, ServiceManager} + +import scala.concurrent.duration._ + +class StandardRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + + "RemoverActor" should { + "handle a simple task" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere) + + val reply1 = probe.receiveOne(100 milliseconds) + assert(reply1.isInstanceOf[RemoverActorTest.InclusionTestAlert]) + val reply2 = probe.receiveOne(100 milliseconds) + assert(reply2.isInstanceOf[RemoverActorTest.InitialJobAlert]) + probe.expectNoMsg(1 seconds) //delay + val reply3 = probe.receiveOne(300 milliseconds) + assert(reply3.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4 = probe.receiveOne(300 milliseconds) + assert(reply4.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5 = probe.receiveOne(300 milliseconds) + assert(reply5.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6 = probe.receiveOne(300 milliseconds) + assert(reply6.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7 = probe.receiveOne(300 milliseconds) + assert(reply7.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + } + } +} + +class DelayedRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + + "RemoverActor" should { + "handle a simple task (timed)" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(100 milliseconds)) + + val reply1 = probe.receiveOne(100 milliseconds) + assert(reply1.isInstanceOf[RemoverActorTest.InclusionTestAlert]) + val reply2 = probe.receiveOne(100 milliseconds) + assert(reply2.isInstanceOf[RemoverActorTest.InitialJobAlert]) + //no delay + val reply3 = probe.receiveOne(300 milliseconds) + assert(reply3.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4 = probe.receiveOne(300 milliseconds) + assert(reply4.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5 = probe.receiveOne(300 milliseconds) + assert(reply5.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6 = probe.receiveOne(300 milliseconds) + assert(reply6.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7 = probe.receiveOne(300 milliseconds) + assert(reply7.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + } + } +} + +class ExcludedRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + val AlternateTestObject = new PlanetSideGameObject() { def Definition = new ObjectDefinition(0) { } } + + "RemoverActor" should { + "allow only specific objects" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(AlternateTestObject, Zone.Nowhere) + + val reply1 = probe.receiveOne(100 milliseconds) + assert(reply1.isInstanceOf[RemoverActorTest.InclusionTestAlert]) + expectNoMsg(2 seconds) + //RemoverActor is stalled because it received an object that it was not allowed to act upon + } + } +} + +class MultipleRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + + "RemoverActor" should { + "work on parallel tasks" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere) + + val replies = probe.receiveN(14, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + var fja : Int = 0 + var cta : Int = 0 + var sja : Int = 0 + var dta : Int = 0 + var dtr : Int = 0 + replies.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case RemoverActorTest.FirstJobAlert() => fja += 1 + case RemoverActorTest.ClearanceTestAlert() => cta += 1 + case RemoverActorTest.SecondJobAlert() => sja += 1 + case RemoverActorTest.DeletionTaskAlert() => dta += 1 + case RemoverActorTest.DeletionTaskRunAlert() => dtr += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 2 && ija == 2 && fja == 2 && cta == 2 && sja == 2 && dta == 2 && dtr == 2) + } + } +} + +class HurrySpecificRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + + "RemoverActor" should { + "be able to hurry certain tasks" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(10 minutes)) //TEN MINUTE WAIT + + val reply1 = probe.receiveOne(100 milliseconds) + assert(reply1.isInstanceOf[RemoverActorTest.InclusionTestAlert]) + val reply2 = probe.receiveOne(100 milliseconds) + assert(reply2.isInstanceOf[RemoverActorTest.InitialJobAlert]) + probe.expectNoMsg(3 seconds) //long delay, longer than standard but not yet 10 minutes + remover ! RemoverActor.HurrySpecific(List(RemoverActorTest.TestObject), Zone.Nowhere) //hurried + val reply3 = probe.receiveOne(300 milliseconds) + assert(reply3.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4 = probe.receiveOne(300 milliseconds) + assert(reply4.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5 = probe.receiveOne(300 milliseconds) + assert(reply5.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6 = probe.receiveOne(300 milliseconds) + assert(reply6.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7 = probe.receiveOne(300 milliseconds) + assert(reply7.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + } + } +} + +class HurrySelectionRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + + "RemoverActor" should { + "be able to hurry certain tasks" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere, Some(10 seconds)) + + val replies = probe.receiveN(4, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 2 && ija == 2) + probe.expectNoMsg(3 seconds) //long delay, longer than standard but not yet 5 seconds + remover ! RemoverActor.HurrySpecific(List(RemoverActorTest.TestObject), Zone.Nowhere) //hurried + //first + val reply3a = probe.receiveOne(300 milliseconds) + assert(reply3a.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4a = probe.receiveOne(300 milliseconds) + assert(reply4a.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5a = probe.receiveOne(300 milliseconds) + assert(reply5a.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6a = probe.receiveOne(300 milliseconds) + assert(reply6a.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7a = probe.receiveOne(300 milliseconds) + assert(reply7a.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + //second + remover ! RemoverActor.HurrySpecific(List(TestObject2), Zone.Nowhere) //hurried + val reply3b = probe.receiveOne(300 milliseconds) + assert(reply3b.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4b = probe.receiveOne(300 milliseconds) + assert(reply4b.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5b = probe.receiveOne(300 milliseconds) + assert(reply5b.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6b = probe.receiveOne(300 milliseconds) + assert(reply6b.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7b = probe.receiveOne(300 milliseconds) + assert(reply7b.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + } + } +} + +class HurryMultipleRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + final val TestObject3 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(3) } } + + "RemoverActor" should { + "be able to hurry certain tasks, but only valid ones" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere, Some(5 seconds)) + + val replies = probe.receiveN(4, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 2 && ija == 2) + probe.expectNoMsg(3 seconds) //long delay, longer than standard but not yet 5 seconds + remover ! RemoverActor.HurrySpecific(List(RemoverActorTest.TestObject, TestObject3), Zone.Nowhere) //multiple hurried, only one valid + //first + val reply3a = probe.receiveOne(300 milliseconds) + assert(reply3a.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4a = probe.receiveOne(300 milliseconds) + assert(reply4a.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5a = probe.receiveOne(300 milliseconds) + assert(reply5a.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6a = probe.receiveOne(300 milliseconds) + assert(reply6a.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7a = probe.receiveOne(300 milliseconds) + assert(reply7a.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + //second + remover ! RemoverActor.HurrySpecific(List(TestObject2), Zone.Nowhere) //hurried + val reply3b = probe.receiveOne(300 milliseconds) + assert(reply3b.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4b = probe.receiveOne(300 milliseconds) + assert(reply4b.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5b = probe.receiveOne(300 milliseconds) + assert(reply5b.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6b = probe.receiveOne(300 milliseconds) + assert(reply6b.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7b = probe.receiveOne(300 milliseconds) + assert(reply7b.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + } + } +} + +class HurryByZoneRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + final val TestObject3 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(3) } } + final val zone = new Zone("test", new ZoneMap("test-map"), 11) + + "RemoverActor" should { + "be able to hurry certain tasks by their zone" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject2, zone, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject3, Zone.Nowhere, Some(5 seconds)) + + val replies1 = probe.receiveN(6, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies1.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 3 && ija == 3) + probe.expectNoMsg(3 seconds) //long delay, longer than standard but not yet 5 seconds + remover ! RemoverActor.HurrySpecific(List(), Zone.Nowhere) //multiple hurried, only the two entries with Zone.Nowhere + // + val replies2 = probe.receiveN(10, 3 seconds) + var fja : Int = 0 + var cta : Int = 0 + var sja : Int = 0 + var dta : Int = 0 + var dtr : Int = 0 + replies2.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case RemoverActorTest.FirstJobAlert() => fja += 1 + case RemoverActorTest.ClearanceTestAlert() => cta += 1 + case RemoverActorTest.SecondJobAlert() => sja += 1 + case RemoverActorTest.DeletionTaskAlert() => dta += 1 + case RemoverActorTest.DeletionTaskRunAlert() => dtr += 1 + case msg => assert(false, s"$msg") + } + assert(fja == 2 && cta == 2 && sja == 2 && dta == 2 && dtr == 2) + //final + remover ! RemoverActor.HurrySpecific(List(), zone) //hurried + val reply3b = probe.receiveOne(300 milliseconds) + assert(reply3b.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4b = probe.receiveOne(300 milliseconds) + assert(reply4b.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5b = probe.receiveOne(300 milliseconds) + assert(reply5b.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6b = probe.receiveOne(300 milliseconds) + assert(reply6b.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7b = probe.receiveOne(300 milliseconds) + assert(reply7b.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + } + } +} + +class HurryAllRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + final val TestObject3 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(3) } } + + "RemoverActor" should { + "be able to hurry all tasks to completion" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(20 seconds)) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere, Some(15 seconds)) + remover ! RemoverActor.AddTask(TestObject3, Zone.Nowhere, Some(10 seconds)) + + val replies1 = probe.receiveN(6, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies1.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 3 && ija == 3) + probe.expectNoMsg(3 seconds) //long delay, longer than standard but not yet longer than any of the tasks + remover ! RemoverActor.HurryAll() //all hurried + // + val replies2 = probe.receiveN(15, 3 seconds) + var fja : Int = 0 + var cta : Int = 0 + var sja : Int = 0 + var dta : Int = 0 + var dtr : Int = 0 + replies2.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case RemoverActorTest.FirstJobAlert() => fja += 1 + case RemoverActorTest.ClearanceTestAlert() => cta += 1 + case RemoverActorTest.SecondJobAlert() => sja += 1 + case RemoverActorTest.DeletionTaskAlert() => dta += 1 + case RemoverActorTest.DeletionTaskRunAlert() => dtr += 1 + case msg => assert(false, s"$msg") + } + assert(fja == 3 && cta == 3 && sja == 3 && dta == 3 && dtr == 3) + } + } +} + +class ClearSelectionRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + + "RemoverActor" should { + "be able to clear certain tasks" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere, Some(5 seconds)) + + val replies = probe.receiveN(4, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 2 && ija == 2) + probe.expectNoMsg(4 seconds) //long delay, longer than standard but not yet 5 seconds + remover ! RemoverActor.ClearSpecific(List(RemoverActorTest.TestObject), Zone.Nowhere) //cleared + // + val reply3 = probe.receiveOne(2 seconds) + assert(reply3.isInstanceOf[RemoverActorTest.FirstJobAlert]) + val reply4 = probe.receiveOne(300 milliseconds) + assert(reply4.isInstanceOf[RemoverActorTest.ClearanceTestAlert]) + val reply5 = probe.receiveOne(300 milliseconds) + assert(reply5.isInstanceOf[RemoverActorTest.SecondJobAlert]) + val reply6 = probe.receiveOne(300 milliseconds) + assert(reply6.isInstanceOf[RemoverActorTest.DeletionTaskAlert]) + val reply7 = probe.receiveOne(300 milliseconds) + assert(reply7.isInstanceOf[RemoverActorTest.DeletionTaskRunAlert]) + //wait + probe.expectNoMsg(2 seconds) //nothing more to do + } + } +} + +class ClearAllRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + + "RemoverActor" should { + "be able to clear all tasks, with no more work on them" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere, Some(5 seconds)) + + val replies = probe.receiveN(4, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 2 && ija == 2) + probe.expectNoMsg(4 seconds) //long delay, longer than standard but not yet 5 seconds + remover ! RemoverActor.ClearAll() //cleared + //wait + probe.expectNoMsg(3 seconds) //nothing more to do + } + } +} + +class EarlyDeathRemoverActorTest extends ActorTest { + ServiceManager.boot ! ServiceManager.Register(RandomPool(2).props(Props[TaskResolver]), "taskResolver") + final val TestObject2 = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(2) } } + + "RemoverActor" should { + "be able to hurry certain tasks" in { + expectNoMsg(200 milliseconds) + val probe = TestProbe() + val remover = system.actorOf(Props(classOf[RemoverActorTest.TestRemover], probe), "test-remover") + remover ! RemoverActor.AddTask(RemoverActorTest.TestObject, Zone.Nowhere, Some(5 seconds)) + remover ! RemoverActor.AddTask(TestObject2, Zone.Nowhere, Some(5 seconds)) + + val replies = probe.receiveN(4, 3 seconds) + var ita : Int = 0 + var ija : Int = 0 + replies.collect { + case RemoverActorTest.InclusionTestAlert() => ita += 1 + case RemoverActorTest.InitialJobAlert() => ija += 1 + case msg => assert(false, s"$msg") + } + assert(ita == 2 && ija == 2) + probe.expectNoMsg(2 seconds) + remover ! akka.actor.PoisonPill + // + val replies2 = probe.receiveN(8, 2 seconds) + var fja : Int = 0 + var cta : Int = 0 + var sja : Int = 0 + var dta : Int = 0 + var dtr : Int = 0 + replies2.collect { + case RemoverActorTest.FirstJobAlert() => fja += 1 + case RemoverActorTest.ClearanceTestAlert() => cta += 1 + case RemoverActorTest.SecondJobAlert() => sja += 1 + case RemoverActorTest.DeletionTaskAlert() => dta += 1 + case RemoverActorTest.DeletionTaskRunAlert() => dtr += 1 + case msg => assert(false, s"$msg") + } + assert(fja == 2 && cta == 0 && sja == 2 && dta == 2 && dtr == 2) //no clearance tests + } + } +} + +object RemoverActorTest { + final val TestObject = new Equipment() { def Definition = new EquipmentDefinition(0) { GUID = PlanetSideGUID(1) } } + + final case class InclusionTestAlert() + + final case class InitialJobAlert() + + final case class FirstJobAlert() + + final case class SecondJobAlert() + + final case class ClearanceTestAlert() + + final case class DeletionTaskAlert() + + final case class DeletionTaskRunAlert() + + class TestRemover(probe : TestProbe) extends RemoverActor { + import net.psforever.objects.guid.{Task, TaskResolver} + val FirstStandardDuration = 1 seconds + + val SecondStandardDuration = 100 milliseconds + + def InclusionTest(entry : RemoverActor.Entry) : Boolean = { + probe.ref ! InclusionTestAlert() + entry.obj.isInstanceOf[Equipment] + } + + def InitialJob(entry : RemoverActor.Entry) : Unit = { + probe.ref ! InitialJobAlert() + } + + def FirstJob(entry : RemoverActor.Entry) : Unit = { + probe.ref ! FirstJobAlert() + } + + override def SecondJob(entry : RemoverActor.Entry) : Unit = { + probe.ref ! SecondJobAlert() + super.SecondJob(entry) + } + + def ClearanceTest(entry : RemoverActor.Entry) : Boolean = { + probe.ref ! ClearanceTestAlert() + true + } + + def DeletionTask(entry : RemoverActor.Entry) : TaskResolver.GiveTask = { + probe.ref ! DeletionTaskAlert() + TaskResolver.GiveTask(new Task() { + private val localProbe = probe + + override def isComplete = Task.Resolution.Success + + def Execute(resolver : ActorRef) : Unit = { + localProbe.ref ! DeletionTaskRunAlert() + resolver ! scala.util.Success(this) + } + }) + } + } +}