Fix 27338 - Allow passing an actor system to the typed.ActorTestKit (#28871)
* Add apply methods for typed ActorTestKit allowing for passing an ActorSystem
This commit is contained in:
parent
a26d7ef91d
commit
6d843efbf8
6 changed files with 138 additions and 60 deletions
|
|
@ -0,0 +1,3 @@
|
|||
# #27338 allow passing ActorSystem to ActorTestKit
|
||||
ProblemFilters.exclude[IncompatibleSignatureProblem]("akka.actor.testkit.typed.scaladsl.ActorTestKit.internalSystem")
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.actor.testkit.typed.scaladsl.ActorTestKit.this")
|
||||
|
|
@ -21,10 +21,8 @@ import akka.util.JavaDurationConverters._
|
|||
object ActorTestKit {
|
||||
|
||||
/**
|
||||
* Create a testkit named from the class that is calling this method.
|
||||
* Create a testkit named from the ActorTestKit class.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*
|
||||
|
|
@ -36,7 +34,19 @@ object ActorTestKit {
|
|||
new ActorTestKit(scaladsl.ActorTestKit(TestKitUtils.testNameFromCallStack(classOf[ActorTestKit])))
|
||||
|
||||
/**
|
||||
* Create a named testkit.
|
||||
* Create a testkit from the provided actor system.
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*
|
||||
* Config loaded from the provided actor if that exists, otherwise
|
||||
* using default configuration from the reference.conf resources that ship with the Akka libraries.
|
||||
*/
|
||||
def create(system: ActorSystem[_]): ActorTestKit =
|
||||
new ActorTestKit(scaladsl.ActorTestKit(system))
|
||||
|
||||
/**
|
||||
* Create a testkit using the provided name.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
|
|
@ -51,11 +61,11 @@ object ActorTestKit {
|
|||
new ActorTestKit(scaladsl.ActorTestKit(name))
|
||||
|
||||
/**
|
||||
* Create a testkit named from the class that is calling this method,
|
||||
* Create a testkit named from the ActorTestKit class,
|
||||
* and use a custom config for the actor system.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
* It will also used the provided customConfig provided to create the `ActorSystem`
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
|
|
@ -63,10 +73,14 @@ object ActorTestKit {
|
|||
new ActorTestKit(scaladsl.ActorTestKit(TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]), customConfig))
|
||||
|
||||
/**
|
||||
* Create a named testkit, and use a custom config for the actor system.
|
||||
* Create a test kit named based on the provided name,
|
||||
* and uses the provided custom config for the actor system.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
*
|
||||
* It will also used the provided customConfig provided to create the `ActorSystem`
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
|
|
@ -74,11 +88,14 @@ object ActorTestKit {
|
|||
new ActorTestKit(scaladsl.ActorTestKit(name, customConfig))
|
||||
|
||||
/**
|
||||
* Create a named testkit, and use a custom config for the actor system,
|
||||
* and a custom [[akka.actor.testkit.typed.TestKitSettings]]
|
||||
* Create an [[akka.actor.typed.ActorSystem]] named based on the provided name,
|
||||
* use the provided custom config for the actor system, and the testkit will use the provided setting.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
*
|
||||
* It will also used the provided customConfig provided to create the `ActorSystem`, and provided setting.
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ final class TestKitJunitResource(_kit: ActorTestKit) extends ExternalResource {
|
|||
*/
|
||||
def this() = this(ActorTestKit.create(TestKitUtils.testNameFromCallStack(classOf[TestKitJunitResource])))
|
||||
|
||||
/**
|
||||
* Use a custom [[akka.actor.typed.ActorSystem]] for the actor system.
|
||||
*/
|
||||
def this(system: ActorSystem[_]) = this(ActorTestKit.create(system))
|
||||
|
||||
/**
|
||||
* Use a custom config for the actor system.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,7 +26,39 @@ import org.slf4j.LoggerFactory
|
|||
object ActorTestKit {
|
||||
|
||||
/**
|
||||
* Create a testkit named from the class that is calling this method.
|
||||
* Create a testkit named from the ActorTestKit class.
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*
|
||||
* Config loaded from `application-test.conf` if that exists, otherwise
|
||||
* using default configuration from the reference.conf resources that ship with the Akka libraries.
|
||||
* The application.conf of your project is not used in this case.
|
||||
*/
|
||||
def apply(): ActorTestKit = {
|
||||
val system = ActorSystem(
|
||||
ActorTestKitGuardian.testKitGuardian,
|
||||
TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]),
|
||||
ApplicationTestConfig)
|
||||
new ActorTestKit(system, system, settings = None)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a testkit from the provided actor system.
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*
|
||||
* Config loaded from the provided actor if that exists, otherwise
|
||||
* using default configuration from the reference.conf resources that ship with the Akka libraries.
|
||||
*/
|
||||
def apply(system: ActorSystem[_]): ActorTestKit = {
|
||||
val testKitGuardian = system.systemActorOf(ActorTestKitGuardian.testKitGuardian, "test")
|
||||
new ActorTestKit(system, testKitGuardian, settings = None)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a testkit using the provided name.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
|
|
@ -37,64 +69,64 @@ object ActorTestKit {
|
|||
* using default configuration from the reference.conf resources that ship with the Akka libraries.
|
||||
* The application.conf of your project is not used in this case.
|
||||
*/
|
||||
def apply(): ActorTestKit =
|
||||
new ActorTestKit(
|
||||
name = TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]),
|
||||
config = ApplicationTestConfig,
|
||||
settings = None)
|
||||
def apply(name: String): ActorTestKit = {
|
||||
val system =
|
||||
ActorSystem(ActorTestKitGuardian.testKitGuardian, TestKitUtils.scrubActorSystemName(name), ApplicationTestConfig)
|
||||
new ActorTestKit(system, system, settings = None)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a named testkit.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*
|
||||
* Config loaded from `application-test.conf` if that exists, otherwise
|
||||
* using default configuration from the reference.conf resources that ship with the Akka libraries.
|
||||
* The application.conf of your project is not used in this case.
|
||||
*/
|
||||
def apply(name: String): ActorTestKit =
|
||||
new ActorTestKit(name = TestKitUtils.scrubActorSystemName(name), config = ApplicationTestConfig, settings = None)
|
||||
|
||||
/**
|
||||
* Create a testkit named from the class that is calling this method,
|
||||
* Create a testkit named from the ActorTestKit class,
|
||||
* and use a custom config for the actor system.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
* It will also used the provided customConfig provided to create the `ActorSystem`
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
def apply(customConfig: Config): ActorTestKit =
|
||||
new ActorTestKit(
|
||||
name = TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]),
|
||||
config = customConfig,
|
||||
settings = None)
|
||||
def apply(customConfig: Config): ActorTestKit = {
|
||||
val system = ActorSystem(
|
||||
ActorTestKitGuardian.testKitGuardian,
|
||||
TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]),
|
||||
customConfig)
|
||||
new ActorTestKit(system, system, settings = None)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a named testkit, and use a custom config for the actor system.
|
||||
* Create a test kit named based on the provided name,
|
||||
* and uses the provided custom config for the actor system.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
*
|
||||
* It will also used the provided customConfig provided to create the `ActorSystem`
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
def apply(name: String, customConfig: Config): ActorTestKit =
|
||||
new ActorTestKit(name = TestKitUtils.scrubActorSystemName(name), config = customConfig, settings = None)
|
||||
def apply(name: String, customConfig: Config): ActorTestKit = {
|
||||
val system =
|
||||
ActorSystem(ActorTestKitGuardian.testKitGuardian, TestKitUtils.scrubActorSystemName(name), customConfig)
|
||||
new ActorTestKit(system, system, settings = None)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a named testkit, and use a custom config for the actor system,
|
||||
* and a custom [[akka.actor.testkit.typed.TestKitSettings]]
|
||||
* Create an [[akka.actor.typed.ActorSystem]] named based on the provided name,
|
||||
* use the provided custom config for the actor system, and the testkit will use the provided setting.
|
||||
*
|
||||
* It will create an [[akka.actor.typed.ActorSystem]] with this name,
|
||||
* e.g. threads will include the name.
|
||||
*
|
||||
* It will also used the provided customConfig provided to create the `ActorSystem`, and provided setting.
|
||||
*
|
||||
* When the test has completed you should terminate the `ActorSystem` and
|
||||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
def apply(name: String, customConfig: Config, settings: TestKitSettings): ActorTestKit =
|
||||
new ActorTestKit(name = TestKitUtils.scrubActorSystemName(name), config = customConfig, settings = Some(settings))
|
||||
def apply(name: String, customConfig: Config, settings: TestKitSettings): ActorTestKit = {
|
||||
val system =
|
||||
ActorSystem(ActorTestKitGuardian.testKitGuardian, TestKitUtils.scrubActorSystemName(name), customConfig)
|
||||
new ActorTestKit(system, system, settings = Some(settings))
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the given [[akka.actor.typed.ActorSystem]] and block until it shuts down,
|
||||
|
|
@ -131,10 +163,17 @@ object ActorTestKit {
|
|||
*
|
||||
* For synchronous testing of a `Behavior` see [[BehaviorTestKit]]
|
||||
*/
|
||||
final class ActorTestKit private[akka] (val name: String, val config: Config, settings: Option[TestKitSettings]) {
|
||||
final class ActorTestKit private[akka] (
|
||||
val internalSystem: ActorSystem[_],
|
||||
internalTestKitGuardian: ActorRef[ActorTestKitGuardian.TestKitCommand],
|
||||
settings: Option[TestKitSettings]) {
|
||||
|
||||
val name = internalSystem.name
|
||||
|
||||
val config = internalSystem.settings.config
|
||||
|
||||
// avoid slf4j noise by touching it first from single thread #28673
|
||||
LoggerFactory.getLogger(name).debug("Starting ActorTestKit")
|
||||
LoggerFactory.getLogger(internalSystem.name).debug("Starting ActorTestKit")
|
||||
|
||||
implicit def testKitSettings: TestKitSettings =
|
||||
settings.getOrElse(TestKitSettings(system))
|
||||
|
|
@ -142,9 +181,6 @@ final class ActorTestKit private[akka] (val name: String, val config: Config, se
|
|||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi private[akka] val internalSystem: ActorSystem[ActorTestKitGuardian.TestKitCommand] =
|
||||
ActorSystem(ActorTestKitGuardian.testKitGuardian, name, config)
|
||||
|
||||
implicit def system: ActorSystem[Nothing] = internalSystem
|
||||
|
||||
private val childName: Iterator[String] = Iterator.from(0).map(_.toString)
|
||||
|
|
@ -172,7 +208,9 @@ final class ActorTestKit private[akka] (val name: String, val config: Config, se
|
|||
* guardian
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], props: Props): ActorRef[T] =
|
||||
Await.result(internalSystem.ask(ActorTestKitGuardian.SpawnActorAnonymous(behavior, _, props)), timeout.duration)
|
||||
Await.result(
|
||||
internalTestKitGuardian.ask(ActorTestKitGuardian.SpawnActorAnonymous(behavior, _, props)),
|
||||
timeout.duration)
|
||||
|
||||
/**
|
||||
* Spawn the given behavior. This is created as a child of the test kit
|
||||
|
|
@ -186,7 +224,9 @@ final class ActorTestKit private[akka] (val name: String, val config: Config, se
|
|||
* guardian
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], name: String, props: Props): ActorRef[T] =
|
||||
Await.result(internalSystem.ask(ActorTestKitGuardian.SpawnActor(name, behavior, _, props)), timeout.duration)
|
||||
Await.result(
|
||||
internalTestKitGuardian.ask(ActorTestKitGuardian.SpawnActor(name, behavior, _, props)),
|
||||
timeout.duration)
|
||||
|
||||
/**
|
||||
* Stop the actor under test and wait until it terminates.
|
||||
|
|
@ -195,7 +235,7 @@ final class ActorTestKit private[akka] (val name: String, val config: Config, se
|
|||
*/
|
||||
def stop[T](ref: ActorRef[T], max: FiniteDuration = timeout.duration): Unit =
|
||||
try {
|
||||
Await.result(internalSystem.ask { x: ActorRef[ActorTestKitGuardian.Ack.type] =>
|
||||
Await.result(internalTestKitGuardian.ask { x: ActorRef[ActorTestKitGuardian.Ack.type] =>
|
||||
ActorTestKitGuardian.StopActor(ref, x)
|
||||
}, max)
|
||||
} catch {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
package akka.actor.testkit.typed.scaladsl
|
||||
|
||||
import akka.actor.testkit.typed.TestKitSettings
|
||||
import akka.actor.typed.ActorSystem
|
||||
import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import org.scalatest.{ BeforeAndAfterAll, TestSuite }
|
||||
|
|
@ -41,6 +42,11 @@ abstract class ScalaTestWithActorTestKit(testKit: ActorTestKit)
|
|||
*/
|
||||
def this() = this(ActorTestKit(ActorTestKitBase.testNameFromCallStack()))
|
||||
|
||||
/**
|
||||
* Use a custom [[akka.actor.typed.ActorSystem]] for the actor system.
|
||||
*/
|
||||
def this(system: ActorSystem[_]) = this(ActorTestKit(system))
|
||||
|
||||
/**
|
||||
* Use a custom config for the actor system.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
package akka.actor.testkit.typed.scaladsl
|
||||
|
||||
import akka.Done
|
||||
import scala.concurrent.Promise
|
||||
import akka.actor.testkit.typed.internal.ActorTestKitGuardian
|
||||
import akka.actor.typed.ActorSystem
|
||||
|
||||
import scala.concurrent.Promise
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import org.scalatest.BeforeAndAfterAll
|
||||
|
|
@ -21,6 +23,16 @@ class ActorTestKitSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike wi
|
|||
system.name should ===("ActorTestKitSpec")
|
||||
}
|
||||
|
||||
"generate a test kit from the provided actor system" in {
|
||||
val config = ConfigFactory.parseString("test.specific-config = yes")
|
||||
val system = ActorSystem(ActorTestKitGuardian.testKitGuardian, "TestActor", config)
|
||||
val testkit2 = ActorTestKit(system)
|
||||
try {
|
||||
testkit2.internalSystem should ===(system)
|
||||
testkit2.system should ===(system)
|
||||
} finally testkit2.shutdownTestKit()
|
||||
}
|
||||
|
||||
"generate a default name from the test class" in {
|
||||
val testkit2 = ActorTestKit()
|
||||
try {
|
||||
|
|
@ -64,23 +76,18 @@ class ActorTestKitSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike wi
|
|||
}
|
||||
|
||||
"load application-test.conf by default" in {
|
||||
testKit.config.getString("test.from-application-test") should ===("yes")
|
||||
testKit.system.settings.config.getString("test.from-application-test") should ===("yes")
|
||||
testKit.system.settings.config.hasPath("test.from-application") should ===(false)
|
||||
}
|
||||
|
||||
"not load application-test.conf if specific Config given" in {
|
||||
val testKit2 = ActorTestKit(ConfigFactory.parseString("test.specific-config = yes"))
|
||||
testKit2.config.getString("test.specific-config") should ===("yes")
|
||||
testKit2.system.settings.config.getString("test.specific-config") should ===("yes")
|
||||
testKit2.config.hasPath("test.from-application-test") should ===(false)
|
||||
testKit2.system.settings.config.hasPath("test.from-application-test") should ===(false)
|
||||
testKit2.system.settings.config.hasPath("test.from-application") should ===(false)
|
||||
|
||||
// same if via ScalaTestWithActorTestKit
|
||||
val scalaTestWithActorTestKit2 = new ScalaTestWithActorTestKit("test.specific-config = yes") {}
|
||||
scalaTestWithActorTestKit2.testKit.config.getString("test.specific-config") should ===("yes")
|
||||
scalaTestWithActorTestKit2.testKit.config.hasPath("test.from-application-test") should ===(false)
|
||||
scalaTestWithActorTestKit2.system.settings.config.hasPath("test.from-application-test") should ===(false)
|
||||
scalaTestWithActorTestKit2.testKit.system.settings.config.hasPath("test.from-application") should ===(false)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue