Restructure repository

* Move /common/src to /src
* Move services to net.psforever package
* Move /pslogin to /server
This commit is contained in:
Jakob Gillich 2020-08-23 03:26:06 +02:00
parent 89a30ae6f6
commit f4fd78fc5d
958 changed files with 527 additions and 725 deletions

View file

@ -0,0 +1,81 @@
// Copyright (c) 2017 PSForever
package base
import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit}
import com.typesafe.config.ConfigFactory
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import org.specs2.specification.Scope
import scala.collection.mutable
import scala.concurrent.duration.FiniteDuration
abstract class ActorTest(sys: ActorSystem = ActorSystem("system", ConfigFactory.parseMap(ActorTest.LoggingConfig)))
extends TestKit(sys)
with Scope
with ImplicitSender
with AnyWordSpecLike
with Matchers
with BeforeAndAfterAll {
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
}
object ActorTest {
import scala.jdk.CollectionConverters._
private val LoggingConfig = Map(
"akka.loggers" -> List("akka.testkit.TestEventListener").asJava,
"akka.loglevel" -> "OFF",
"akka.stdout-loglevel" -> "OFF",
"akka.log-dead-letters" -> "OFF"
).asJava
/**
* A (potential) workaround to a Travis CI issue involving polling a series of messages over a period of time.
* Running the test in isolation works every time.
* Running the test as part of a series produces mixed results.
* Travis CI fails the test every time by not getting any messages.
* @see TestKit.receiveN
* @param n the number of messages to poll
* @param timeout how long to wait for each message
* @param sys what to poll
* @return a list of messages
*/
def receiveMultiple(n: Int, timeout: FiniteDuration, sys: TestKit): List[Any] = {
assert(0 < n, s"number of expected messages must be positive non-zero integer - $n")
val out = {
val msgs = mutable.ListBuffer[Any]()
(0 until n).foreach(_ => {
msgs += sys.receiveOne(timeout)
})
msgs.toList
}
out
}
/**
* A middleman Actor that accepts a `Props` object to instantiate and accepts messages back from it.
* The purpose is to bypass a message receive issue with the `ActorTest` / `TestKit` class
* that does not properly queue messages dispatched to it
* when messages may be sent to it via a `context.parent` call.
* Please do not wrap and parameterize Props objects like this during normal Ops.
* @param actorProps the uninitialized `Actor` that uses `context.parent` to direct communication
* @param sendTo where to send mesages that have originated from an `actorProps` object;
* typically should point back to the test environment constructed by `TestKit`
*/
class SupportActorInterface(actorProps: Props, sendTo: ActorRef) extends Actor {
val test = context.actorOf(actorProps, "support-actor")
def receive: Receive = {
case msg =>
(if (sender() == test) {
sendTo
} else {
test
}) ! msg
}
}
}

View file

@ -0,0 +1,54 @@
// Copyright (c) 2020 PSForever
package base
import akka.actor.{Actor, ActorContext, ActorRef, Props}
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.Await
/**
* Create an `ActorTest` environment that has an `ActorContext` object.
*/
abstract class FreedContextActorTest extends ActorTest {
/*
Never do this in actual production code!
ActorSystem and ActorContext offer similar mechanisms for instantiating actors.
This is a consequence of their shared inheritance of the ActorRefFactory trait.
They are not equivalent enough to be able to pass one as the other as a parameter.
Because the ActorSystem has no context of its own,
various bizarre mechanisms have to be developed to use any methods that would pass in a context object.
We create a middleman Actor whose main purpose is to surrender its context object to the test environment directly
and then direct all messages sent to that object to the test environment.
*/
private val _testContextHandler = system.actorOf(Props(classOf[ContextSensitive]), "actor-test-cs")
private implicit val timeout = Timeout(5 seconds)
private val _testContextHandlerResult = ask(_testContextHandler, message = "", self)
implicit val context = Await.result(_testContextHandlerResult, timeout.duration).asInstanceOf[ActorContext]
}
/**
* Surrender your `context` object for a greater good!
*/
private class ContextSensitive extends Actor {
var output: ActorRef = ActorRef.noSender
def receive: Receive = {
case _ =>
context.become(PassThroughBehavior)
output = sender()
sender() ! context
}
/**
* Once the `context` object has been leased,
* this `Actor` becomes transparent.
* Calling `context.parent` from whatever `Actor` was spurned by the previously provided `context`,
* will now refer to whatever was the contact to gain access to it - the test environment.
* @return something to `become`
*/
def PassThroughBehavior: Receive = {
case msg => output forward msg
}
}