PSF-BotServer/common/src/test/scala/objects/number/UniqueNumberSystemTest.scala

350 lines
15 KiB
Scala
Raw Normal View History

// Copyright (c) 2017 PSForever
package objects.number
import akka.actor.{ActorRef, ActorSystem, Props}
Facility Turrets (#223) * object class, actor class, and definitions for base turrets; untested * wired base turrets into existence, with hoop jumping; created interface for objects with mounted weapons (vehicles and turrets); working example phalanx_sgl_hevgatcan in Anguta, Ceryshen * re-wiring manned turrets so that the turreted weapon itself never changes externally but merely identifies different and changes internally; workflow for upgrading wall turrets in place (30s); clarifications and documentation for HackMessage and UseItemMessage; getting rid of orphaned packages from previous location of services * added a simple task that reverts upgraded manned turrets to their None state after a certain amount of time has passed; it works but need improvement * turret weapon upgrades now last for a duration of 30 minutes before reverting; created a service support actor base actor that underlies all current support actors; nano-dispenser now properly loads 1 unit of upgrade canister, rather than 100 units; all canister types have appropriate 2x3 inventory size * forgot to hurry; moved over the Services tests from main/test folder into the common/test folder and needed to change the location of ActorTest to accommodate it; test and documentation for MannedTurret; codecov ignore update * wired facility turrets in Anguta, Ceryshen; Akna tower, Ceryshen; and S.Villa tower, home3 (Anguta tower is a watchtower); attempted workaround for Travis CI issues with receiveN; re-introduced RemoveActorTest, at least the first test; expanded how ZoneActor performs tests on MannedTurret setup * getting rid of useless commented-out code; making common operations for mounting and dismounting * removed outdated comment; added ResourceSilo tests; added extra test for Zone
2018-07-14 21:25:44 -04:00
import base.ActorTest
import net.psforever.objects.entity.IdentifiableEntity
import net.psforever.objects.guid.NumberPoolHub
import net.psforever.objects.guid.actor.{NumberPoolActor, Register, UniqueNumberSystem, Unregister}
import net.psforever.objects.guid.selector.RandomSelector
import net.psforever.objects.guid.source.LimitedNumberSource
import net.psforever.types.PlanetSideGUID
Deployables (#230) * functions for certifcation ui updates (that don't work) * initialization of combat engineering deployables ui on load and certification change * representation classes for ACE and FDU; ability to pull ACE and FDU from equipment terminals * ammo change functionality and fire mode change functionality for ConstructionItems refactored from Tool operations and supported properly (switch between deployable options) * zone-specific structure for keeping track of deployables; abaility to dismiss deployables from the map screen (previous functionality); local client creation of explosive-type deployables * refactored MannedTurret into FacilityTurret and lesser traits to be used in the deployable spitfires and the OMFT's; all ACE deployables are available for placement; partial management of the construction items after the deployable is placed; boomers create boomer triggers * Avatar-specific storage for deployables and for updating UI elements * refactored quite a bit of code in WSA for the benefit of deployable management; refinements to deployable creation; server messages about deployable quantities; corrected the FDU encoding pattern; lots of work dedicated just to synchronizing BoomerTrigger objects * added RemoverActor for deployables and redistributed deconstruction functionality away from WSA to new DeployableRemover; added events to facilitate activities not inheritable with this model * refactored and distributed Deployables classes; copious amounts of testing and document-writing * boomers now explode from trigger; support for deployables being destroyed by weapon discharge, including individual health, soure identification, and damage model; shuffled deployable classes to build different hierarchy * sensor_shield was skipped by accident * identified stray object in Hanish, Ishundar, and added Irkalla, Ishundar's capture console; fixed issue with Warp command and 'Irkalla'; modified building amenity setup and setup testing in Zone; players load and die properly when seated in an omft; reserve ammunition in omft properly registered * added local service channel, capture consoles, fixed tests as much as posible * fixed LocalService tests by booting the ServiceManager; added avatar and local tests * a simple attempt to refactor Actor messages in a way that is acceptable to Travis CI * making the explosive deployables vanish upon explosion; sensor health bars are now supported
2018-09-23 08:00:58 -04:00
import scala.concurrent.duration._
import scala.util.{Failure, Success}
Facility Turrets (#223) * object class, actor class, and definitions for base turrets; untested * wired base turrets into existence, with hoop jumping; created interface for objects with mounted weapons (vehicles and turrets); working example phalanx_sgl_hevgatcan in Anguta, Ceryshen * re-wiring manned turrets so that the turreted weapon itself never changes externally but merely identifies different and changes internally; workflow for upgrading wall turrets in place (30s); clarifications and documentation for HackMessage and UseItemMessage; getting rid of orphaned packages from previous location of services * added a simple task that reverts upgraded manned turrets to their None state after a certain amount of time has passed; it works but need improvement * turret weapon upgrades now last for a duration of 30 minutes before reverting; created a service support actor base actor that underlies all current support actors; nano-dispenser now properly loads 1 unit of upgrade canister, rather than 100 units; all canister types have appropriate 2x3 inventory size * forgot to hurry; moved over the Services tests from main/test folder into the common/test folder and needed to change the location of ActorTest to accommodate it; test and documentation for MannedTurret; codecov ignore update * wired facility turrets in Anguta, Ceryshen; Akna tower, Ceryshen; and S.Villa tower, home3 (Anguta tower is a watchtower); attempted workaround for Travis CI issues with receiveN; re-introduced RemoveActorTest, at least the first test; expanded how ZoneActor performs tests on MannedTurret setup * getting rid of useless commented-out code; making common operations for mounting and dismounting * removed outdated comment; added ResourceSilo tests; added extra test for Zone
2018-07-14 21:25:44 -04:00
class AllocateNumberPoolActors extends ActorTest {
"AllocateNumberPoolActors" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList)
guid.AddPool("pool2", (3001 to 4000).toList)
guid.AddPool("pool3", (5001 to 6000).toList)
val actorMap = UniqueNumberSystemTest.AllocateNumberPoolActors(guid)
assert(actorMap.size == 4)
assert(actorMap.get("generic").isDefined) //automatically generated
assert(actorMap.get("pool1").isDefined)
assert(actorMap.get("pool2").isDefined)
assert(actorMap.get("pool3").isDefined)
}
}
class UniqueNumberSystemTest extends ActorTest() {
"UniqueNumberSystem" should {
"constructor" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList)
guid.AddPool("pool2", (3001 to 4000).toList)
guid.AddPool("pool3", (5001 to 6000).toList)
system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
//as long as it constructs ...
}
}
}
class UniqueNumberSystemTest1 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Register (success)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
val pool1 = (1001 to 2000).toList
val pool2 = (3001 to 4000).toList
val pool3 = (5001 to 6000).toList
guid.AddPool("pool1", pool1).Selector = new RandomSelector
guid.AddPool("pool2", pool2).Selector = new RandomSelector
guid.AddPool("pool3", pool3).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
assert(src.CountUsed == 0)
//pool1
for(_ <- 1 to 100) {
val testObj = new EntityTestClass()
uns ! Register(testObj, "pool1")
val msg = receiveOne(Duration.create(500, "ms"))
assert(msg.isInstanceOf[Success[_]])
assert(pool1.contains(testObj.GUID.guid))
}
//pool2
for(_ <- 1 to 100) {
val testObj = new EntityTestClass()
uns ! Register(testObj, "pool2")
val msg = receiveOne(Duration.create(500, "ms"))
assert(msg.isInstanceOf[Success[_]])
assert(pool2.contains(testObj.GUID.guid))
}
//pool3
for(_ <- 1 to 100) {
val testObj = new EntityTestClass()
uns ! Register(testObj, "pool3")
val msg = receiveOne(Duration.create(500, "ms"))
assert(msg.isInstanceOf[Success[_]])
assert(pool3.contains(testObj.GUID.guid))
}
assert(src.CountUsed == 300)
}
}
}
class UniqueNumberSystemTest2 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Register (success; already registered)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj = new EntityTestClass()
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
uns ! Register(testObj, "pool1")
val msg1 = receiveOne(Duration.create(500, "ms"))
assert(msg1.isInstanceOf[Success[_]])
assert(testObj.HasGUID)
assert(src.CountUsed == 1)
val id = testObj.GUID.guid
uns ! Register(testObj, "pool2") //different pool; makes no difference
val msg2 = receiveOne(Duration.create(500, "ms"))
assert(msg2.isInstanceOf[Success[_]])
assert(testObj.HasGUID)
assert(src.CountUsed == 1)
assert(testObj.GUID.guid == id) //unchanged
}
}
//a log.warn should have been generated during this test
}
class UniqueNumberSystemTest3 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Register (failure; no pool)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj = new EntityTestClass()
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
uns ! Register(testObj, "pool4")
val msg1 = receiveOne(Duration.create(500, "ms"))
assert(msg1.isInstanceOf[Failure[_]])
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
}
}
}
class UniqueNumberSystemTest4 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Register (failure; empty pool)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
guid.AddPool("pool4", 50 :: Nil).Selector = new RandomSelector //list of one element; can not add an empty list
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj1 = new EntityTestClass()
uns ! Register(testObj1, "pool4")
val msg1 = receiveOne(Duration.create(500, "ms"))
assert(msg1.isInstanceOf[Success[_]]) //pool4 is now empty
val testObj2 = new EntityTestClass()
uns ! Register(testObj2, "pool4")
val msg2 = receiveOne(Duration.create(500, "ms"))
assert(msg2.isInstanceOf[Failure[_]])
}
}
}
class UniqueNumberSystemTest5 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Unregister (success)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
val pool2 = (3001 to 4000).toList
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", pool2).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj = new EntityTestClass()
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
uns ! Register(testObj, "pool2")
val msg1 = receiveOne(Duration.create(2000, "ms"))
assert(msg1.isInstanceOf[Success[_]])
assert(testObj.HasGUID)
assert(pool2.contains(testObj.GUID.guid))
assert(src.CountUsed == 1)
uns ! Unregister(testObj)
val msg2 = receiveOne(Duration.create(2000, "ms"))
assert(msg2.isInstanceOf[Success[_]])
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
}
}
}
class UniqueNumberSystemTest6 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Unregister (success; object not registered at all)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj = new EntityTestClass()
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
uns ! Unregister(testObj)
val msg1 = receiveOne(Duration.create(500, "ms"))
assert(msg1.isInstanceOf[Success[_]])
assert(!testObj.HasGUID)
assert(src.CountUsed == 0)
}
}
}
class UniqueNumberSystemTest7 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Unregister (failure; number not in system)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj = new EntityTestClass()
testObj.GUID =PlanetSideGUID(6001) //fake registering; number too high
assert(testObj.HasGUID)
assert(src.CountUsed == 0)
uns ! Unregister(testObj)
val msg1 = receiveOne(Duration.create(500, "ms"))
assert(msg1.isInstanceOf[Failure[_]])
assert(testObj.HasGUID)
assert(src.CountUsed == 0)
}
}
}
class UniqueNumberSystemTest8 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Unregister (failure; object is not registered to that number)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val testObj = new EntityTestClass()
testObj.GUID = PlanetSideGUID(3500) //fake registering
assert(testObj.HasGUID)
assert(src.CountUsed == 0)
uns ! Unregister(testObj)
val msg1 = receiveOne(Duration.create(500, "ms"))
assert(msg1.isInstanceOf[Failure[_]])
assert(testObj.HasGUID)
assert(src.CountUsed == 0)
}
}
}
class UniqueNumberSystemTest9 extends ActorTest() {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"Failures (manually walking the failure cases)" in {
val src : LimitedNumberSource = LimitedNumberSource(6000)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
guid.AddPool("pool3", (5001 to 6000).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
val excp = new Exception("EXCEPTION MESSAGE")
expectNoMsg(Duration.create(200, "ms"))
//GiveNumber
uns ! NumberPoolActor.GiveNumber(1001, Some("test")) //no task associated with id="test"
uns ! NumberPoolActor.GiveNumber(1000, Some("test")) //no task associated with id="test" and number is not pooled
uns ! NumberPoolActor.GiveNumber(1000, Some(1)) //the task could theoretically exist, but does not
//NoNumber
uns ! NumberPoolActor.NoNumber(excp, Some(1))
uns ! NumberPoolActor.NoNumber(excp, None)
uns ! NumberPoolActor.NoNumber(excp, Some("test"))
//ReturnNumberResult A
uns ! NumberPoolActor.ReturnNumberResult(1001, None, Some("test"))
uns ! NumberPoolActor.ReturnNumberResult(1000, None, Some("test"))
uns ! NumberPoolActor.ReturnNumberResult(1001, None, Some(1))
uns ! NumberPoolActor.ReturnNumberResult(1000, None, Some(1))
//ReturnNumberResult B
uns ! NumberPoolActor.ReturnNumberResult(1001, Some(excp), Some("test"))
uns ! NumberPoolActor.ReturnNumberResult(1001, Some(excp), Some(1))
}
}
}
Deployables (#230) * functions for certifcation ui updates (that don't work) * initialization of combat engineering deployables ui on load and certification change * representation classes for ACE and FDU; ability to pull ACE and FDU from equipment terminals * ammo change functionality and fire mode change functionality for ConstructionItems refactored from Tool operations and supported properly (switch between deployable options) * zone-specific structure for keeping track of deployables; abaility to dismiss deployables from the map screen (previous functionality); local client creation of explosive-type deployables * refactored MannedTurret into FacilityTurret and lesser traits to be used in the deployable spitfires and the OMFT's; all ACE deployables are available for placement; partial management of the construction items after the deployable is placed; boomers create boomer triggers * Avatar-specific storage for deployables and for updating UI elements * refactored quite a bit of code in WSA for the benefit of deployable management; refinements to deployable creation; server messages about deployable quantities; corrected the FDU encoding pattern; lots of work dedicated just to synchronizing BoomerTrigger objects * added RemoverActor for deployables and redistributed deconstruction functionality away from WSA to new DeployableRemover; added events to facilitate activities not inheritable with this model * refactored and distributed Deployables classes; copious amounts of testing and document-writing * boomers now explode from trigger; support for deployables being destroyed by weapon discharge, including individual health, soure identification, and damage model; shuffled deployable classes to build different hierarchy * sensor_shield was skipped by accident * identified stray object in Hanish, Ishundar, and added Irkalla, Ishundar's capture console; fixed issue with Warp command and 'Irkalla'; modified building amenity setup and setup testing in Zone; players load and die properly when seated in an omft; reserve ammunition in omft properly registered * added local service channel, capture consoles, fixed tests as much as posible * fixed LocalService tests by booting the ServiceManager; added avatar and local tests * a simple attempt to refactor Actor messages in a way that is acceptable to Travis CI * making the explosive deployables vanish upon explosion; sensor health bars are now supported
2018-09-23 08:00:58 -04:00
class UniqueNumberSystemTestA extends ActorTest {
class EntityTestClass extends IdentifiableEntity
"UniqueNumberSystem" should {
"remain consistent between registrations" in {
val src : LimitedNumberSource = LimitedNumberSource(10)
val guid : NumberPoolHub = new NumberPoolHub(src)
guid.AddPool("pool1", (0 until 10).toList).Selector = new RandomSelector
val uns = system.actorOf(Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)), "uns")
expectNoMsg(Duration.create(200, "ms"))
assert(src.CountUsed == 0)
(0 to 4).foreach(i => { assert(guid.register(new EntityTestClass(), i).isSuccess) })
assert(src.CountUsed == 5)
(0 to 5).foreach(_ => { uns ! Register(new EntityTestClass(), "pool1") })
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //6th
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //7th
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //8th
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //9th
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //10th
assert(receiveOne(200 milliseconds).isInstanceOf[Failure[_]]) //no more
assert(src.CountUsed == 10)
}
}
}
object UniqueNumberSystemTest {
/**
* @see `UniqueNumberSystem.AllocateNumberPoolActors(NumberPoolHub)(implicit ActorContext)`
*/
def AllocateNumberPoolActors(poolSource : NumberPoolHub)(implicit system : ActorSystem) : Map[String, ActorRef] = {
poolSource.Pools.map({ case (pname, pool) =>
pname -> system.actorOf(Props(classOf[NumberPoolActor], pool), pname)
}).toMap
}
}