// Copyright (c) 2017 PSForever package control import org.specs2.mutable._ import net.psforever.packet.control.{ControlSync, MultiPacketBundle, MultiPacketCollector} import net.psforever.packet.crypto.{ClientFinished, ServerFinished} import net.psforever.packet.game.ObjectDeleteMessage import net.psforever.types.PlanetSideGUID class MultiPacketCollectorTest extends Specification { val packet1 = ObjectDeleteMessage(PlanetSideGUID(1103), 2) "MultiPacketBundle" should { import scodec.bits._ val packet2 = ControlSync(21096, 0x4d, 0x52, 0x4d, 0x7c, 0x4d, 0x276, 0x275) "construct" in { MultiPacketBundle(List(packet1)) ok } "fail to construct if not initialized with PlanetSidePackets" in { MultiPacketBundle(Nil) must throwA[IllegalArgumentException] } "concatenate bundles into a new bundle" in { val obj1 = MultiPacketBundle(List(packet1)) val obj2 = MultiPacketBundle(List(packet2)) val obj3 = obj1 + obj2 obj3 match { case MultiPacketBundle(list) => list.size mustEqual 2 list.head mustEqual packet1 list(1) mustEqual packet2 case _ => ko } } "accept PlanetSideGamePackets and PlanetSideControlPackets" in { MultiPacketBundle(List(packet2, packet1)) match { case MultiPacketBundle(list) => list.size mustEqual 2 list.head mustEqual packet2 list(1) mustEqual packet1 case _ => ko } } "ignore other types of PlanetSideContainerPackets" in { val param = List(packet2, ClientFinished(hex"", hex""), packet1, ServerFinished(hex"")) MultiPacketBundle(param) match { //warning message will display in log case MultiPacketBundle(list) => list.size mustEqual 2 list.head mustEqual param.head list(1) mustEqual param(2) case _ => ko } } } "MultiPacketCollector" should { val packet2 = ObjectDeleteMessage(PlanetSideGUID(1105), 2) val packet3 = ObjectDeleteMessage(PlanetSideGUID(1107), 2) "construct" in { new MultiPacketCollector() ok } "construct with initial packets" in { MultiPacketCollector(List(packet1, packet2)) ok } "can retrieve a bundle packets" in { val obj = MultiPacketCollector(List(packet1, packet2)) obj.Bundle match { case Some(MultiPacketBundle(list)) => list.size mustEqual 2 list.head mustEqual packet1 list(1) mustEqual packet2 case _ => ko } } "can retrieve a bundle of potential packets" in { val obj1 = new MultiPacketCollector() obj1.Bundle match { case Some(_) => ko case _ => ; } val obj2 = MultiPacketCollector(List(packet1, packet2)) obj2.Bundle match { case None => ko case Some(MultiPacketBundle(list)) => list.size mustEqual 2 list.head mustEqual packet1 list(1) mustEqual packet2 } } "clear packets after being asked to bundle" in { val list = List(packet1, packet2) val obj = MultiPacketCollector(list) obj.Bundle match { case Some(MultiPacketBundle(bundle)) => bundle mustEqual list case _ => ko } obj.Bundle match { case Some(MultiPacketBundle(_)) => ko case _ => ok } } "add a packet" in { val obj = new MultiPacketCollector() obj.Add(packet1) obj.Bundle match { case Some(MultiPacketBundle(list)) => list.size mustEqual 1 list.head mustEqual packet1 case _ => ko } } "add packets" in { val obj = new MultiPacketCollector() obj.Add(List(packet1, packet2)) obj.Bundle match { case Some(MultiPacketBundle(list)) => list.size mustEqual 2 list.head mustEqual packet1 list(1) mustEqual packet2 case _ => ko } } "concatenate bundles (1)" in { val obj1 = new MultiPacketCollector() obj1.Add(List(packet1, packet2)) obj1.Bundle match { case Some(MultiPacketBundle(bundle1)) => val obj2 = MultiPacketCollector(bundle1) obj2.Add(packet3) obj2.Bundle match { case Some(MultiPacketBundle(list)) => list.size mustEqual 3 list.head mustEqual packet1 list(1) mustEqual packet2 list(2) mustEqual packet3 case _ => ko } case _ => ko } } "concatenate bundles (2)" in { val obj1 = new MultiPacketCollector() obj1.Add(List(packet1, packet2)) obj1.Bundle match { case Some(MultiPacketBundle(bundle1)) => val obj2 = new MultiPacketCollector() obj2.Add(packet3) obj2.Add(bundle1) obj2.Bundle match { case Some(MultiPacketBundle(list)) => list.size mustEqual 3 list.head mustEqual packet3 list(1) mustEqual packet1 list(2) mustEqual packet2 case _ => ko } case _ => ko } } } }