format source with scalafmt
This commit is contained in:
parent
0f40491d42
commit
ce404e4f53
1669 changed files with 43208 additions and 35404 deletions
|
|
@ -17,8 +17,7 @@ import scala.compat.java8.OptionConverters._
|
|||
/**
|
||||
* Representation of a Log Event issued by a [[akka.actor.typed.Behavior]]
|
||||
*/
|
||||
final case class CapturedLogEvent(
|
||||
logLevel: LogLevel,
|
||||
final case class CapturedLogEvent(logLevel: LogLevel,
|
||||
message: String,
|
||||
cause: Option[Throwable],
|
||||
marker: Option[LogMarker],
|
||||
|
|
@ -27,7 +26,11 @@ final case class CapturedLogEvent(
|
|||
/**
|
||||
* Constructor for Java API
|
||||
*/
|
||||
def this(logLevel: LogLevel, message: String, errorCause: Optional[Throwable], marker: Optional[LogMarker], mdc: java.util.Map[String, Any]) {
|
||||
def this(logLevel: LogLevel,
|
||||
message: String,
|
||||
errorCause: Optional[Throwable],
|
||||
marker: Optional[LogMarker],
|
||||
mdc: java.util.Map[String, Any]) {
|
||||
this(logLevel, message, errorCause.asScala, marker.asScala, mdc.asScala.toMap)
|
||||
}
|
||||
|
||||
|
|
@ -76,9 +79,7 @@ object CapturedLogEvent {
|
|||
case _ => None
|
||||
}
|
||||
|
||||
def apply(
|
||||
logLevel: LogLevel,
|
||||
message: String): CapturedLogEvent = {
|
||||
def apply(logLevel: LogLevel, message: String): CapturedLogEvent = {
|
||||
CapturedLogEvent(logLevel, message, None, None, Map.empty[String, Any])
|
||||
}
|
||||
|
||||
|
|
@ -87,8 +88,7 @@ object CapturedLogEvent {
|
|||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi
|
||||
private[akka] def apply(
|
||||
logLevel: LogLevel,
|
||||
private[akka] def apply(logLevel: LogLevel,
|
||||
message: String,
|
||||
errorCause: OptionVal[Throwable],
|
||||
logMarker: OptionVal[LogMarker],
|
||||
|
|
|
|||
|
|
@ -25,11 +25,14 @@ import scala.concurrent.duration.FiniteDuration
|
|||
abstract class Effect private[akka] ()
|
||||
|
||||
object Effect {
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior (and optionally specific props)
|
||||
*/
|
||||
final class Spawned[T](val behavior: Behavior[T], val childName: String, val props: Props, val ref: ActorRef[T])
|
||||
extends Effect with Product3[Behavior[T], String, Props] with Serializable {
|
||||
extends Effect
|
||||
with Product3[Behavior[T], String, Props]
|
||||
with Serializable {
|
||||
|
||||
override def equals(other: Any) = other match {
|
||||
case o: Spawned[_] =>
|
||||
|
|
@ -49,7 +52,8 @@ object Effect {
|
|||
}
|
||||
|
||||
object Spawned {
|
||||
def apply[T](behavior: Behavior[T], childName: String, props: Props = Props.empty): Spawned[T] = new Spawned(behavior, childName, props, null)
|
||||
def apply[T](behavior: Behavior[T], childName: String, props: Props = Props.empty): Spawned[T] =
|
||||
new Spawned(behavior, childName, props, null)
|
||||
def unapply[T](s: Spawned[T]): Option[(Behavior[T], String, Props)] = Some((s.behavior, s.childName, s.props))
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +61,9 @@ object Effect {
|
|||
* The behavior spawned an anonymous child with the given behavior (and optionally specific props)
|
||||
*/
|
||||
final class SpawnedAnonymous[T](val behavior: Behavior[T], val props: Props, val ref: ActorRef[T])
|
||||
extends Effect with Product2[Behavior[T], Props] with Serializable {
|
||||
extends Effect
|
||||
with Product2[Behavior[T], Props]
|
||||
with Serializable {
|
||||
|
||||
override def equals(other: Any) = other match {
|
||||
case o: SpawnedAnonymous[_] => this.behavior == o.behavior && this.props == o.props
|
||||
|
|
@ -73,7 +79,8 @@ object Effect {
|
|||
}
|
||||
|
||||
object SpawnedAnonymous {
|
||||
def apply[T](behavior: Behavior[T], props: Props = Props.empty): SpawnedAnonymous[T] = new SpawnedAnonymous(behavior, props, null)
|
||||
def apply[T](behavior: Behavior[T], props: Props = Props.empty): SpawnedAnonymous[T] =
|
||||
new SpawnedAnonymous(behavior, props, null)
|
||||
def unapply[T](s: SpawnedAnonymous[T]): Option[(Behavior[T], Props)] = Some((s.behavior, s.props))
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +90,9 @@ object Effect {
|
|||
*/
|
||||
@InternalApi
|
||||
private[akka] final class SpawnedAdapter[T](val name: String, val ref: ActorRef[T])
|
||||
extends Effect with Product1[String] with Serializable {
|
||||
extends Effect
|
||||
with Product1[String]
|
||||
with Serializable {
|
||||
|
||||
override def equals(other: Any) = other match {
|
||||
case o: SpawnedAdapter[_] => this.name == o.name
|
||||
|
|
@ -113,7 +122,9 @@ object Effect {
|
|||
*/
|
||||
@InternalApi
|
||||
private[akka] final class SpawnedAnonymousAdapter[T](val ref: ActorRef[T])
|
||||
extends Effect with Product with Serializable {
|
||||
extends Effect
|
||||
with Product
|
||||
with Serializable {
|
||||
|
||||
override def equals(other: Any): Boolean = other match {
|
||||
case _: SpawnedAnonymousAdapter[_] => true
|
||||
|
|
@ -142,6 +153,7 @@ object Effect {
|
|||
* The behavior create a message adapter for the messages of type clazz
|
||||
*/
|
||||
final case class MessageAdapter[A, T](messageClass: Class[A], adapt: A => T) extends Effect {
|
||||
|
||||
/**
|
||||
* JAVA API
|
||||
*/
|
||||
|
|
@ -167,6 +179,7 @@ object Effect {
|
|||
* The behavior set a new receive timeout, with `message` as timeout notification
|
||||
*/
|
||||
final case class ReceiveTimeoutSet[T](d: FiniteDuration, message: T) extends Effect {
|
||||
|
||||
/**
|
||||
* Java API
|
||||
*/
|
||||
|
|
@ -195,4 +208,3 @@ object Effect {
|
|||
*/
|
||||
sealed abstract class NoEffects extends Effect
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,4 +10,3 @@ import scala.util.control.NoStackTrace
|
|||
* A predefined exception that can be used in tests. It doesn't include a stack trace.
|
||||
*/
|
||||
final case class TestException(message: String) extends RuntimeException(message) with NoStackTrace
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import akka.util.Timeout
|
|||
import akka.actor.typed.ActorSystem
|
||||
|
||||
object TestKitSettings {
|
||||
|
||||
/**
|
||||
* Reads configuration settings from `akka.actor.testkit.typed` section.
|
||||
*/
|
||||
|
|
@ -43,15 +44,19 @@ final class TestKitSettings(val config: Config) {
|
|||
|
||||
import akka.util.Helpers._
|
||||
|
||||
val TestTimeFactor = config.getDouble("timefactor").
|
||||
requiring(tf => !tf.isInfinite && tf > 0, "timefactor must be positive finite double")
|
||||
val TestTimeFactor = config
|
||||
.getDouble("timefactor")
|
||||
.requiring(tf => !tf.isInfinite && tf > 0, "timefactor must be positive finite double")
|
||||
|
||||
/** dilated with `TestTimeFactor` */
|
||||
val SingleExpectDefaultTimeout: FiniteDuration = dilated(config.getMillisDuration("single-expect-default"))
|
||||
|
||||
/** dilated with `TestTimeFactor` */
|
||||
val ExpectNoMessageDefaultTimeout: FiniteDuration = dilated(config.getMillisDuration("expect-no-message-default"))
|
||||
|
||||
/** dilated with `TestTimeFactor` */
|
||||
val DefaultTimeout: Timeout = Timeout(dilated(config.getMillisDuration("default-timeout")))
|
||||
|
||||
/** dilated with `TestTimeFactor` */
|
||||
val DefaultActorSystemShutdownTimeout: FiniteDuration = dilated(config.getMillisDuration("system-shutdown-default"))
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,19 @@ package akka.actor.testkit.typed.internal
|
|||
import java.util.concurrent.{ CompletionStage, ThreadFactory }
|
||||
|
||||
import akka.actor.typed.internal.ActorRefImpl
|
||||
import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, DispatcherSelector, Dispatchers, Extension, ExtensionId, Logger, Props, Settings, Terminated }
|
||||
import akka.actor.typed.{
|
||||
ActorRef,
|
||||
ActorSystem,
|
||||
Behavior,
|
||||
DispatcherSelector,
|
||||
Dispatchers,
|
||||
Extension,
|
||||
ExtensionId,
|
||||
Logger,
|
||||
Props,
|
||||
Settings,
|
||||
Terminated
|
||||
}
|
||||
import akka.annotation.InternalApi
|
||||
import akka.util.Timeout
|
||||
import akka.{ actor => untyped }
|
||||
|
|
@ -22,13 +34,17 @@ import akka.actor.typed.internal.InternalRecipientRef
|
|||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi private[akka] final class ActorSystemStub(val name: String)
|
||||
extends ActorSystem[Nothing] with ActorRef[Nothing] with ActorRefImpl[Nothing] with InternalRecipientRef[Nothing] {
|
||||
extends ActorSystem[Nothing]
|
||||
with ActorRef[Nothing]
|
||||
with ActorRefImpl[Nothing]
|
||||
with InternalRecipientRef[Nothing] {
|
||||
|
||||
override val path: untyped.ActorPath = untyped.RootActorPath(untyped.Address("akka", name)) / "user"
|
||||
|
||||
override val settings: Settings = new Settings(getClass.getClassLoader, ConfigFactory.empty, name)
|
||||
|
||||
override def tell(message: Nothing): Unit = throw new UnsupportedOperationException("must not send message to ActorSystemStub")
|
||||
override def tell(message: Nothing): Unit =
|
||||
throw new UnsupportedOperationException("must not send message to ActorSystemStub")
|
||||
|
||||
// impl ActorRefImpl
|
||||
override def isLocal: Boolean = true
|
||||
|
|
@ -72,7 +88,8 @@ import akka.actor.typed.internal.InternalRecipientRef
|
|||
|
||||
override def printTree: String = "no tree for ActorSystemStub"
|
||||
|
||||
def systemActorOf[U](behavior: Behavior[U], name: String, props: Props)(implicit timeout: Timeout): Future[ActorRef[U]] = {
|
||||
def systemActorOf[U](behavior: Behavior[U], name: String, props: Props)(
|
||||
implicit timeout: Timeout): Future[ActorRef[U]] = {
|
||||
Future.failed(new UnsupportedOperationException("ActorSystemStub cannot create system actors"))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@ private[akka] final class BehaviorTestKitImpl[T](_path: ActorPath, _initialBehav
|
|||
def expectEffectClass[E <: Effect](effectClass: Class[E]): E = {
|
||||
context.effectQueue.poll() match {
|
||||
case null if effectClass.isAssignableFrom(NoEffects.getClass) => effectClass.cast(NoEffects)
|
||||
case null => throw new AssertionError(s"expected: effect type ${effectClass.getName} but no effects were recorded")
|
||||
case null =>
|
||||
throw new AssertionError(s"expected: effect type ${effectClass.getName} but no effects were recorded")
|
||||
case effect if effectClass.isAssignableFrom(effect.getClass) => effect.asInstanceOf[E]
|
||||
case other => throw new AssertionError(s"expected: effect class ${effectClass.getName} but found $other")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ import akka.actor.typed.internal.InternalRecipientRef
|
|||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi private[akka] final class DebugRef[T](override val path: untyped.ActorPath, override val isLocal: Boolean)
|
||||
extends ActorRef[T] with ActorRefImpl[T] with InternalRecipientRef[T] {
|
||||
extends ActorRef[T]
|
||||
with ActorRefImpl[T]
|
||||
with InternalRecipientRef[T] {
|
||||
|
||||
private val q = new ConcurrentLinkedQueue[Either[SystemMessage, T]]
|
||||
|
||||
|
|
|
|||
|
|
@ -83,4 +83,3 @@ import scala.compat.java8.FunctionConverters._
|
|||
super.scheduleOnce(delay, target, message)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ import akka.actor.ActorRefProvider
|
|||
* This reference cannot watch other references.
|
||||
*/
|
||||
@InternalApi
|
||||
private[akka] final class FunctionRef[-T](
|
||||
override val path: ActorPath,
|
||||
send: (T, FunctionRef[T]) => Unit)
|
||||
extends ActorRef[T] with ActorRefImpl[T] with InternalRecipientRef[T] {
|
||||
private[akka] final class FunctionRef[-T](override val path: ActorPath, send: (T, FunctionRef[T]) => Unit)
|
||||
extends ActorRef[T]
|
||||
with ActorRefImpl[T]
|
||||
with InternalRecipientRef[T] {
|
||||
|
||||
override def tell(message: T): Unit = {
|
||||
if (message == null) throw InvalidMessageException("[null] is not an allowed message")
|
||||
|
|
@ -69,9 +69,13 @@ private[akka] final class FunctionRef[-T](
|
|||
override def isInfoEnabled(marker: LogMarker): Boolean = true
|
||||
override def isDebugEnabled(marker: LogMarker): Boolean = true
|
||||
|
||||
override private[akka] def notifyError(message: String, cause: OptionVal[Throwable], marker: OptionVal[LogMarker]): Unit =
|
||||
override private[akka] def notifyError(message: String,
|
||||
cause: OptionVal[Throwable],
|
||||
marker: OptionVal[LogMarker]): Unit =
|
||||
logBuffer = CapturedLogEvent(Logging.ErrorLevel, message, cause, marker, mdc) :: logBuffer
|
||||
override private[akka] def notifyWarning(message: String, cause: OptionVal[Throwable], marker: OptionVal[LogMarker]): Unit =
|
||||
override private[akka] def notifyWarning(message: String,
|
||||
cause: OptionVal[Throwable],
|
||||
marker: OptionVal[LogMarker]): Unit =
|
||||
logBuffer = CapturedLogEvent(Logging.WarningLevel, message, OptionVal.None, marker, mdc) :: logBuffer
|
||||
|
||||
override private[akka] def notifyInfo(message: String, marker: OptionVal[LogMarker]): Unit =
|
||||
|
|
@ -107,14 +111,18 @@ private[akka] final class FunctionRef[-T](
|
|||
override def isInfoEnabled(marker: LogMarker): Boolean = actual.isInfoEnabled(marker)
|
||||
override def isDebugEnabled(marker: LogMarker): Boolean = actual.isDebugEnabled(marker)
|
||||
|
||||
override private[akka] def notifyError(message: String, cause: OptionVal[Throwable], marker: OptionVal[LogMarker]): Unit = {
|
||||
override private[akka] def notifyError(message: String,
|
||||
cause: OptionVal[Throwable],
|
||||
marker: OptionVal[LogMarker]): Unit = {
|
||||
val original = actual.mdc
|
||||
actual.mdc = mdc
|
||||
actual.notifyError(message, cause, marker)
|
||||
actual.mdc = original
|
||||
}
|
||||
|
||||
override private[akka] def notifyWarning(message: String, cause: OptionVal[Throwable], marker: OptionVal[LogMarker]): Unit = {
|
||||
override private[akka] def notifyWarning(message: String,
|
||||
cause: OptionVal[Throwable],
|
||||
marker: OptionVal[LogMarker]): Unit = {
|
||||
val original = actual.mdc
|
||||
actual.mdc = mdc
|
||||
actual.notifyWarning(message, cause, marker)
|
||||
|
|
@ -147,11 +155,10 @@ private[akka] final class FunctionRef[-T](
|
|||
* provides only stubs for the effects an Actor can perform and replaces
|
||||
* created child Actors by a synchronous Inbox (see `Inbox.sync`).
|
||||
*/
|
||||
@InternalApi private[akka] class StubbedActorContext[T](
|
||||
val path: ActorPath) extends ActorContextImpl[T] {
|
||||
@InternalApi private[akka] class StubbedActorContext[T](val path: ActorPath) extends ActorContextImpl[T] {
|
||||
|
||||
def this(name: String) = {
|
||||
this(TestInbox.address / name withUid rnd().nextInt())
|
||||
this((TestInbox.address / name).withUid(rnd().nextInt()))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -162,24 +169,24 @@ private[akka] final class FunctionRef[-T](
|
|||
override val self = selfInbox.ref
|
||||
override val system = new ActorSystemStub("StubbedActorContext")
|
||||
private var _children = TreeMap.empty[String, BehaviorTestKitImpl[_]]
|
||||
private val childName = Iterator from 0 map (Helpers.base64(_))
|
||||
private val childName = Iterator.from(0).map(Helpers.base64(_))
|
||||
private val loggingAdapter = new StubbedLogger
|
||||
|
||||
override def children: Iterable[ActorRef[Nothing]] = _children.values map (_.context.self)
|
||||
override def children: Iterable[ActorRef[Nothing]] = _children.values.map(_.context.self)
|
||||
def childrenNames: Iterable[String] = _children.keys
|
||||
|
||||
override def child(name: String): Option[ActorRef[Nothing]] = _children get name map (_.context.self)
|
||||
override def child(name: String): Option[ActorRef[Nothing]] = _children.get(name).map(_.context.self)
|
||||
|
||||
override def spawnAnonymous[U](behavior: Behavior[U], props: Props = Props.empty): ActorRef[U] = {
|
||||
val btk = new BehaviorTestKitImpl[U](path / childName.next() withUid rnd().nextInt(), behavior)
|
||||
val btk = new BehaviorTestKitImpl[U]((path / childName.next()).withUid(rnd().nextInt()), behavior)
|
||||
_children += btk.context.self.path.name -> btk
|
||||
btk.context.self
|
||||
}
|
||||
override def spawn[U](behavior: Behavior[U], name: String, props: Props = Props.empty): ActorRef[U] =
|
||||
_children get name match {
|
||||
_children.get(name) match {
|
||||
case Some(_) => throw untyped.InvalidActorNameException(s"actor name $name is already taken")
|
||||
case None =>
|
||||
val btk = new BehaviorTestKitImpl[U](path / name withUid rnd().nextInt(), behavior)
|
||||
val btk = new BehaviorTestKitImpl[U]((path / name).withUid(rnd().nextInt()), behavior)
|
||||
_children += name -> btk
|
||||
btk.context.self
|
||||
}
|
||||
|
|
@ -189,7 +196,8 @@ private[akka] final class FunctionRef[-T](
|
|||
* Removal is asynchronous, explicit removeInbox is needed from outside afterwards.
|
||||
*/
|
||||
override def stop[U](child: ActorRef[U]): Unit = {
|
||||
if (child.path.parent != self.path) throw new IllegalArgumentException(
|
||||
if (child.path.parent != self.path)
|
||||
throw new IllegalArgumentException(
|
||||
"Only direct children of an actor can be stopped through the actor context, " +
|
||||
s"but [$child] is not a child of [$self]. Stopping other actors has to be expressed as " +
|
||||
"an explicit stop message that the actor accepts.")
|
||||
|
|
@ -203,7 +211,8 @@ private[akka] final class FunctionRef[-T](
|
|||
override def setReceiveTimeout(d: FiniteDuration, message: T): Unit = ()
|
||||
override def cancelReceiveTimeout(): Unit = ()
|
||||
|
||||
override def scheduleOnce[U](delay: FiniteDuration, target: ActorRef[U], message: U): untyped.Cancellable = new untyped.Cancellable {
|
||||
override def scheduleOnce[U](delay: FiniteDuration, target: ActorRef[U], message: U): untyped.Cancellable =
|
||||
new untyped.Cancellable {
|
||||
override def cancel() = false
|
||||
override def isCancelled = true
|
||||
}
|
||||
|
|
@ -217,13 +226,16 @@ private[akka] final class FunctionRef[-T](
|
|||
@InternalApi private[akka] def internalSpawnMessageAdapter[U](f: U => T, name: String): ActorRef[U] = {
|
||||
|
||||
val n = if (name != "") s"${childName.next()}-$name" else childName.next()
|
||||
val p = path / n withUid rnd().nextInt()
|
||||
val p = (path / n).withUid(rnd().nextInt())
|
||||
val i = new BehaviorTestKitImpl[U](p, Behavior.ignore)
|
||||
_children += p.name -> i
|
||||
|
||||
new FunctionRef[U](
|
||||
p,
|
||||
(message, _) => { val m = f(message); if (m != null) { selfInbox.ref ! m; i.selfInbox.ref ! message } })
|
||||
new FunctionRef[U](p, (message, _) => {
|
||||
val m = f(message);
|
||||
if (m != null) {
|
||||
selfInbox.ref ! m; i.selfInbox.ref ! message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ import scala.concurrent.duration.Duration
|
|||
@InternalApi
|
||||
private[akka] object ActorTestKitGuardian {
|
||||
sealed trait TestKitCommand
|
||||
final case class SpawnActor[T](name: String, behavior: Behavior[T], replyTo: ActorRef[ActorRef[T]], props: Props) extends TestKitCommand
|
||||
final case class SpawnActorAnonymous[T](behavior: Behavior[T], replyTo: ActorRef[ActorRef[T]], props: Props) extends TestKitCommand
|
||||
final case class SpawnActor[T](name: String, behavior: Behavior[T], replyTo: ActorRef[ActorRef[T]], props: Props)
|
||||
extends TestKitCommand
|
||||
final case class SpawnActorAnonymous[T](behavior: Behavior[T], replyTo: ActorRef[ActorRef[T]], props: Props)
|
||||
extends TestKitCommand
|
||||
final case class StopActor[T](ref: ActorRef[T], replyTo: ActorRef[Ack.type]) extends TestKitCommand
|
||||
final case class ActorStopped[T](replyTo: ActorRef[Ack.type]) extends TestKitCommand
|
||||
|
||||
|
|
@ -94,12 +96,10 @@ private[akka] object TestKitUtils {
|
|||
.replaceAll("[^a-zA-Z_0-9]", "_")
|
||||
}
|
||||
|
||||
def shutdown(
|
||||
system: ActorSystem[_],
|
||||
timeout: Duration,
|
||||
throwIfShutdownTimesOut: Boolean): Unit = {
|
||||
def shutdown(system: ActorSystem[_], timeout: Duration, throwIfShutdownTimesOut: Boolean): Unit = {
|
||||
system.terminate()
|
||||
try Await.ready(system.whenTerminated, timeout) catch {
|
||||
try Await.ready(system.whenTerminated, timeout)
|
||||
catch {
|
||||
case _: TimeoutException =>
|
||||
val message = "Failed to stop [%s] within [%s] \n%s".format(system.name, timeout, system.printTree)
|
||||
if (throwIfShutdownTimesOut) throw new RuntimeException(message)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ private[akka] object TestProbeImpl {
|
|||
private case object Stop
|
||||
|
||||
private def testActor[M](queue: BlockingDeque[M], terminations: BlockingDeque[Terminated]): Behavior[M] =
|
||||
Behaviors.receive[M] { (context, msg) =>
|
||||
Behaviors
|
||||
.receive[M] { (context, msg) =>
|
||||
msg match {
|
||||
case WatchActor(ref) =>
|
||||
context.watch(ref)
|
||||
|
|
@ -54,7 +55,8 @@ private[akka] object TestProbeImpl {
|
|||
queue.offerLast(other)
|
||||
Behaviors.same
|
||||
}
|
||||
}.receiveSignal {
|
||||
}
|
||||
.receiveSignal {
|
||||
case (_, t: Terminated) =>
|
||||
terminations.offerLast(t)
|
||||
Behaviors.same
|
||||
|
|
@ -62,7 +64,9 @@ private[akka] object TestProbeImpl {
|
|||
}
|
||||
|
||||
@InternalApi
|
||||
private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_]) extends JavaTestProbe[M] with ScalaTestProbe[M] {
|
||||
private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
||||
extends JavaTestProbe[M]
|
||||
with ScalaTestProbe[M] {
|
||||
|
||||
import TestProbeImpl._
|
||||
protected implicit val settings: TestKitSettings = TestKitSettings(system)
|
||||
|
|
@ -80,7 +84,8 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
private val testActor: ActorRef[M] = {
|
||||
// FIXME arbitrary timeout?
|
||||
implicit val timeout: Timeout = Timeout(3.seconds)
|
||||
val futRef = system.systemActorOf(TestProbeImpl.testActor(queue, terminations), s"$name-${testActorId.incrementAndGet()}")
|
||||
val futRef =
|
||||
system.systemActorOf(TestProbeImpl.testActor(queue, terminations), s"$name-${testActorId.incrementAndGet()}")
|
||||
Await.result(futRef, timeout.duration + 1.second)
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +134,8 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
val prevEnd = end
|
||||
end = start + maxDiff
|
||||
|
||||
val ret = try f finally end = prevEnd
|
||||
val ret = try f
|
||||
finally end = prevEnd
|
||||
|
||||
val diff = now - start
|
||||
assert(min <= diff, s"block took ${diff.pretty}, should at least have been $min")
|
||||
|
|
@ -170,8 +176,7 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
override def receiveMessage(max: FiniteDuration): M = receiveMessage_internal(max.dilated)
|
||||
|
||||
def receiveMessage_internal(max: FiniteDuration): M =
|
||||
receiveOne_internal(max).
|
||||
getOrElse(assertFail(s"Timeout ($max) during receiveMessage while waiting for message."))
|
||||
receiveOne_internal(max).getOrElse(assertFail(s"Timeout ($max) during receiveMessage while waiting for message."))
|
||||
|
||||
/**
|
||||
* Receive one message from the internal queue of the TestActor. If the given
|
||||
|
|
@ -180,13 +185,11 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
* This method does NOT automatically scale its Duration parameter!
|
||||
*/
|
||||
private def receiveOne_internal(max: FiniteDuration): Option[M] = {
|
||||
val message = Option(
|
||||
if (max == Duration.Zero) {
|
||||
val message = Option(if (max == Duration.Zero) {
|
||||
queue.pollFirst
|
||||
} else {
|
||||
queue.pollFirst(max.length, max.unit)
|
||||
}
|
||||
)
|
||||
})
|
||||
lastWasNoMessage = false
|
||||
message
|
||||
}
|
||||
|
|
@ -224,7 +227,7 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
val o = receiveOne_internal(max)
|
||||
val bt = BoxedType(c)
|
||||
o match {
|
||||
case Some(m) if bt isInstance m => m.asInstanceOf[C]
|
||||
case Some(m) if bt.isInstance(m) => m.asInstanceOf[C]
|
||||
case Some(m) => assertFail(s"Expected $c, found ${m.getClass} ($m)")
|
||||
case None => assertFail(s"Timeout ($max) during expectMessageClass waiting for $c")
|
||||
}
|
||||
|
|
@ -263,7 +266,9 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
override def fishForMessage(max: JDuration, fisher: java.util.function.Function[M, FishingOutcome]): JList[M] =
|
||||
fishForMessage(max, "", fisher)
|
||||
|
||||
override def fishForMessage(max: JDuration, hint: String, fisher: java.util.function.Function[M, FishingOutcome]): JList[M] =
|
||||
override def fishForMessage(max: JDuration,
|
||||
hint: String,
|
||||
fisher: java.util.function.Function[M, FishingOutcome]): JList[M] =
|
||||
fishForMessage_internal(max.asScala.dilated, hint, fisher.apply).asJava
|
||||
|
||||
private def fishForMessage_internal(max: FiniteDuration, hint: String, fisher: M => FishingOutcome): List[M] = {
|
||||
|
|
@ -273,10 +278,12 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
maybeMsg match {
|
||||
case Some(message) =>
|
||||
val outcome =
|
||||
try fisher(message) catch {
|
||||
case ex: MatchError => throw new AssertionError(
|
||||
s"Unexpected message $message while fishing for messages, " +
|
||||
s"seen messages ${seen.reverse}, hint: $hint", ex)
|
||||
try fisher(message)
|
||||
catch {
|
||||
case ex: MatchError =>
|
||||
throw new AssertionError(s"Unexpected message $message while fishing for messages, " +
|
||||
s"seen messages ${seen.reverse}, hint: $hint",
|
||||
ex)
|
||||
}
|
||||
outcome match {
|
||||
case FishingOutcome.Complete => (message :: seen).reverse
|
||||
|
|
|
|||
|
|
@ -89,11 +89,7 @@ object ActorTestKit {
|
|||
*/
|
||||
def shutdown(system: ActorSystem[_]): Unit = {
|
||||
val settings = TestKitSettings.create(system)
|
||||
shutdown(
|
||||
system,
|
||||
settings.DefaultActorSystemShutdownTimeout.asJava,
|
||||
settings.ThrowOnShutdownTimeout
|
||||
)
|
||||
shutdown(system, settings.DefaultActorSystemShutdownTimeout.asJava, settings.ThrowOnShutdownTimeout)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -136,27 +132,32 @@ final class ActorTestKit private[akka] (delegate: akka.actor.testkit.typed.scala
|
|||
* Spawn a new auto-named actor under the testkit user guardian and return the ActorRef for the spawned actor
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T]): ActorRef[T] = delegate.spawn(behavior)
|
||||
|
||||
/**
|
||||
* Spawn a new named actor under the testkit user guardian and return the ActorRef for the spawned actor,
|
||||
* note that spawning actors with the same name in multiple test cases will cause failures.
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], name: String): ActorRef[T] = delegate.spawn(behavior, name)
|
||||
|
||||
/**
|
||||
* Spawn a new auto-named actor under the testkit user guardian with the given props
|
||||
* and return the ActorRef for the spawned actor
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], props: Props): ActorRef[T] = delegate.spawn(behavior, props)
|
||||
|
||||
/**
|
||||
* Spawn a new named actor under the testkit user guardian with the given props and return the ActorRef
|
||||
* for the spawned actor, note that spawning actors with the same name in multiple test cases will cause failures.
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], name: String, props: Props): ActorRef[T] = delegate.spawn(behavior, name, props)
|
||||
|
||||
/**
|
||||
* Stop the actor under test and wait until it terminates.
|
||||
* It can only be used for actors that were spawned by this `ActorTestKit`.
|
||||
* Other actors will not be stopped by this method.
|
||||
*/
|
||||
def stop[T](ref: ActorRef[T]): Unit = delegate.stop(ref)
|
||||
|
||||
/**
|
||||
* Stop the actor under test and wait `max` until it terminates.
|
||||
* It can only be used for actors that were spawned by this `ActorTestKit`.
|
||||
|
|
@ -169,6 +170,7 @@ final class ActorTestKit private[akka] (delegate: akka.actor.testkit.typed.scala
|
|||
* @tparam M the type of messages the probe should accept
|
||||
*/
|
||||
def createTestProbe[M](): TestProbe[M] = TestProbe.create(system)
|
||||
|
||||
/**
|
||||
* Shortcut for creating a new test probe for the testkit actor system
|
||||
* @tparam M the type of messages the probe should accept
|
||||
|
|
@ -180,6 +182,7 @@ final class ActorTestKit private[akka] (delegate: akka.actor.testkit.typed.scala
|
|||
* @tparam M the type of messages the probe should accept
|
||||
*/
|
||||
def createTestProbe[M](name: String): TestProbe[M] = TestProbe.create(name, system)
|
||||
|
||||
/**
|
||||
* Shortcut for creating a new named test probe for the testkit actor system
|
||||
* @tparam M the type of messages the probe should accept
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ object BehaviorTestKit {
|
|||
*/
|
||||
def create[T](initialBehavior: Behavior[T], name: String): BehaviorTestKit[T] = {
|
||||
val uid = ThreadLocalRandom.current().nextInt()
|
||||
new BehaviorTestKitImpl(address / name withUid (uid), initialBehavior)
|
||||
new BehaviorTestKitImpl((address / name).withUid(uid), initialBehavior)
|
||||
}
|
||||
|
||||
/**
|
||||
* JAVA API
|
||||
*/
|
||||
|
|
@ -39,6 +40,7 @@ object BehaviorTestKit {
|
|||
*/
|
||||
@DoNotInherit
|
||||
abstract class BehaviorTestKit[T] {
|
||||
|
||||
/**
|
||||
* Requests the oldest [[Effect]] or [[akka.actor.testkit.typed.javadsl.Effects.noEffects]] if no effects
|
||||
* have taken place. The effect is consumed, subsequent calls won't
|
||||
|
|
|
|||
|
|
@ -20,38 +20,52 @@ object Effects {
|
|||
* The behavior spawned a named child with the given behavior with no specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String): Spawned[T] = Spawned(behavior, childName)
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior with no specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String, ref: ActorRef[T]): Spawned[T] = new Spawned(behavior, childName, Props.empty, ref)
|
||||
def spawned[T](behavior: Behavior[T], childName: String, ref: ActorRef[T]): Spawned[T] =
|
||||
new Spawned(behavior, childName, Props.empty, ref)
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior and specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props): Spawned[T] = Spawned(behavior, childName, props)
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props): Spawned[T] =
|
||||
Spawned(behavior, childName, props)
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior and specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props, ref: ActorRef[T]): Spawned[T] = new Spawned(behavior, childName, props, ref)
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props, ref: ActorRef[T]): Spawned[T] =
|
||||
new Spawned(behavior, childName, props, ref)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with no specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T]): SpawnedAnonymous[T] = SpawnedAnonymous(behavior)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with no specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], ref: ActorRef[T]): SpawnedAnonymous[T] = new SpawnedAnonymous(behavior, Props.empty, ref)
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], ref: ActorRef[T]): SpawnedAnonymous[T] =
|
||||
new SpawnedAnonymous(behavior, Props.empty, ref)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], props: Props): SpawnedAnonymous[T] = SpawnedAnonymous(behavior, props)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], props: Props, ref: ActorRef[T]): SpawnedAnonymous[T] = new SpawnedAnonymous(behavior, props, ref)
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], props: Props, ref: ActorRef[T]): SpawnedAnonymous[T] =
|
||||
new SpawnedAnonymous(behavior, props, ref)
|
||||
|
||||
/**
|
||||
* The behavior stopped `childName`
|
||||
*/
|
||||
def stopped(childName: String): Stopped = Stopped(childName)
|
||||
|
||||
/**
|
||||
* The behavior started watching `other`, through `context.watch(other)`
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ object ManualTime {
|
|||
def get[A](system: ActorSystem[A]): ManualTime =
|
||||
system.scheduler match {
|
||||
case sc: akka.testkit.ExplicitlyTriggeredScheduler => new ManualTime(sc)
|
||||
case _ => throw new IllegalArgumentException("ActorSystem not configured with explicitly triggered scheduler, " +
|
||||
case _ =>
|
||||
throw new IllegalArgumentException(
|
||||
"ActorSystem not configured with explicitly triggered scheduler, " +
|
||||
"make sure to include akka.actor.testkit.typed.javadsl.ManualTime.config() when setting up the test")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ object TestInbox {
|
|||
|
||||
def create[T](name: String): TestInbox[T] = {
|
||||
val uid = ThreadLocalRandom.current().nextInt()
|
||||
new TestInboxImpl(address / name withUid (uid))
|
||||
new TestInboxImpl((address / name).withUid(uid))
|
||||
}
|
||||
def create[T](): TestInbox[T] = {
|
||||
val uid = ThreadLocalRandom.current().nextInt()
|
||||
new TestInboxImpl(address / "inbox" withUid (uid))
|
||||
new TestInboxImpl((address / "inbox").withUid(uid))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ object TestInbox {
|
|||
*/
|
||||
@DoNotInherit
|
||||
abstract class TestInbox[T] {
|
||||
|
||||
/**
|
||||
* The actor ref of the inbox
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ final class TestKitJunitResource(_kit: ActorTestKit) extends ExternalResource {
|
|||
* Use a custom config for the actor system.
|
||||
*/
|
||||
def this(customConfig: String) =
|
||||
this(ActorTestKit.create(
|
||||
TestKitUtils.testNameFromCallStack(classOf[TestKitJunitResource]),
|
||||
this(
|
||||
ActorTestKit.create(TestKitUtils.testNameFromCallStack(classOf[TestKitJunitResource]),
|
||||
ConfigFactory.parseString(customConfig)))
|
||||
|
||||
/**
|
||||
|
|
@ -67,14 +67,17 @@ final class TestKitJunitResource(_kit: ActorTestKit) extends ExternalResource {
|
|||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def system: ActorSystem[Void] = testKit.system
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def testKitSettings: TestKitSettings = testKit.testKitSettings
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def timeout: Timeout = testKit.timeout
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
|
|
@ -84,14 +87,17 @@ final class TestKitJunitResource(_kit: ActorTestKit) extends ExternalResource {
|
|||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T]): ActorRef[T] = testKit.spawn(behavior)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], name: String): ActorRef[T] = testKit.spawn(behavior, name)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], props: Props): ActorRef[T] = testKit.spawn(behavior, props)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
|
|
@ -101,14 +107,17 @@ final class TestKitJunitResource(_kit: ActorTestKit) extends ExternalResource {
|
|||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def createTestProbe[M](): TestProbe[M] = testKit.createTestProbe[M]()
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def createTestProbe[M](clazz: Class[M]): TestProbe[M] = testKit.createTestProbe(clazz)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def createTestProbe[M](name: String, clazz: Class[M]): TestProbe[M] = testKit.createTestProbe(name, clazz)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import akka.annotation.DoNotInherit
|
|||
import akka.util.unused
|
||||
|
||||
object FishingOutcomes {
|
||||
|
||||
/**
|
||||
* Consume this message and continue with the next
|
||||
*/
|
||||
|
|
@ -214,7 +215,9 @@ abstract class TestProbe[M] {
|
|||
/**
|
||||
* Same as the other `fishForMessage` but includes the provided hint in all error messages
|
||||
*/
|
||||
def fishForMessage(max: Duration, hint: String, fisher: java.util.function.Function[M, FishingOutcome]): java.util.List[M]
|
||||
def fishForMessage(max: Duration,
|
||||
hint: String,
|
||||
fisher: java.util.function.Function[M, FishingOutcome]): java.util.List[M]
|
||||
|
||||
/**
|
||||
* Expect the given actor to be stopped or stop within the given timeout or
|
||||
|
|
|
|||
|
|
@ -29,11 +29,9 @@ object ActorTestKit {
|
|||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
def apply(): ActorTestKit =
|
||||
new ActorTestKit(
|
||||
name = TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]),
|
||||
new ActorTestKit(name = TestKitUtils.testNameFromCallStack(classOf[ActorTestKit]),
|
||||
config = noConfigSet,
|
||||
settings = None
|
||||
)
|
||||
settings = None)
|
||||
|
||||
/**
|
||||
* Create a named testkit.
|
||||
|
|
@ -44,11 +42,7 @@ object ActorTestKit {
|
|||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
def apply(name: String): ActorTestKit =
|
||||
new ActorTestKit(
|
||||
name = TestKitUtils.scrubActorSystemName(name),
|
||||
config = noConfigSet,
|
||||
settings = None
|
||||
)
|
||||
new ActorTestKit(name = TestKitUtils.scrubActorSystemName(name), config = noConfigSet, settings = None)
|
||||
|
||||
/**
|
||||
* Create a named testkit, and use a custom config for the actor system.
|
||||
|
|
@ -59,11 +53,7 @@ object ActorTestKit {
|
|||
* the testkit with [[ActorTestKit#shutdownTestKit]].
|
||||
*/
|
||||
def apply(name: String, customConfig: Config): ActorTestKit =
|
||||
new ActorTestKit(
|
||||
name = TestKitUtils.scrubActorSystemName(name),
|
||||
config = customConfig,
|
||||
settings = None
|
||||
)
|
||||
new ActorTestKit(name = TestKitUtils.scrubActorSystemName(name), config = customConfig, settings = None)
|
||||
|
||||
/**
|
||||
* Create a named testkit, and use a custom config for the actor system,
|
||||
|
|
@ -75,11 +65,7 @@ object ActorTestKit {
|
|||
* 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)
|
||||
)
|
||||
new ActorTestKit(name = TestKitUtils.scrubActorSystemName(name), config = customConfig, settings = Some(settings))
|
||||
|
||||
/**
|
||||
* Shutdown the given [[akka.actor.typed.ActorSystem]] and block until it shuts down,
|
||||
|
|
@ -87,21 +73,14 @@ object ActorTestKit {
|
|||
*/
|
||||
def shutdown(system: ActorSystem[_]): Unit = {
|
||||
val settings = TestKitSettings(system)
|
||||
TestKitUtils.shutdown(
|
||||
system,
|
||||
settings.DefaultActorSystemShutdownTimeout,
|
||||
settings.ThrowOnShutdownTimeout
|
||||
)
|
||||
TestKitUtils.shutdown(system, settings.DefaultActorSystemShutdownTimeout, settings.ThrowOnShutdownTimeout)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the given [[akka.actor.typed.ActorSystem]] and block until it shuts down
|
||||
* or the `duration` hits. If the timeout hits `verifySystemShutdown` decides
|
||||
*/
|
||||
def shutdown(
|
||||
system: ActorSystem[_],
|
||||
timeout: Duration,
|
||||
throwIfShutdownFails: Boolean = false): Unit =
|
||||
def shutdown(system: ActorSystem[_], timeout: Duration, throwIfShutdownFails: Boolean = false): Unit =
|
||||
TestKitUtils.shutdown(system, timeout, throwIfShutdownFails)
|
||||
|
||||
// place holder for no custom config specified to avoid the boilerplate
|
||||
|
|
@ -140,11 +119,9 @@ final class ActorTestKit private[akka] (val name: String, val config: Config, se
|
|||
implicit val timeout: Timeout = testKitSettings.DefaultTimeout
|
||||
|
||||
def shutdownTestKit(): Unit = {
|
||||
ActorTestKit.shutdown(
|
||||
system,
|
||||
ActorTestKit.shutdown(system,
|
||||
testKitSettings.DefaultActorSystemShutdownTimeout,
|
||||
testKitSettings.ThrowOnShutdownTimeout
|
||||
)
|
||||
testKitSettings.ThrowOnShutdownTimeout)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -180,8 +157,11 @@ final class ActorTestKit private[akka] (val name: String, val config: Config, se
|
|||
* It can only be used for actors that were spawned by this `ActorTestKit`.
|
||||
* Other actors will not be stopped by this method.
|
||||
*/
|
||||
def stop[T](ref: ActorRef[T], max: FiniteDuration = timeout.duration): Unit = try {
|
||||
Await.result(internalSystem.ask { x: ActorRef[ActorTestKitGuardian.Ack.type] => ActorTestKitGuardian.StopActor(ref, x) }, max)
|
||||
def stop[T](ref: ActorRef[T], max: FiniteDuration = timeout.duration): Unit =
|
||||
try {
|
||||
Await.result(internalSystem.ask { x: ActorRef[ActorTestKitGuardian.Ack.type] =>
|
||||
ActorTestKitGuardian.StopActor(ref, x)
|
||||
}, max)
|
||||
} catch {
|
||||
case _: TimeoutException =>
|
||||
assert(false, s"timeout ($max) during stop() waiting for actor [${ref.path}] to stop")
|
||||
|
|
|
|||
|
|
@ -54,14 +54,17 @@ abstract class ActorTestKitBase(val testKit: ActorTestKit) {
|
|||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
implicit def system: ActorSystem[Nothing] = testKit.system
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
implicit def testKitSettings: TestKitSettings = testKit.testKitSettings
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
implicit def timeout: Timeout = testKit.timeout
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
|
|
@ -71,14 +74,17 @@ abstract class ActorTestKitBase(val testKit: ActorTestKit) {
|
|||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T]): ActorRef[T] = testKit.spawn(behavior)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], name: String): ActorRef[T] = testKit.spawn(behavior, name)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def spawn[T](behavior: Behavior[T], props: Props): ActorRef[T] = testKit.spawn(behavior, props)
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
|
|
@ -88,6 +94,7 @@ abstract class ActorTestKitBase(val testKit: ActorTestKit) {
|
|||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
def createTestProbe[M](): TestProbe[M] = testKit.createTestProbe[M]()
|
||||
|
||||
/**
|
||||
* See corresponding method on [[ActorTestKit]]
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ object BehaviorTestKit {
|
|||
|
||||
def apply[T](initialBehavior: Behavior[T], name: String): BehaviorTestKit[T] = {
|
||||
val uid = ThreadLocalRandom.current().nextInt()
|
||||
new BehaviorTestKitImpl(address / name withUid (uid), initialBehavior)
|
||||
new BehaviorTestKitImpl((address / name).withUid(uid), initialBehavior)
|
||||
}
|
||||
def apply[T](initialBehavior: Behavior[T]): BehaviorTestKit[T] =
|
||||
apply(initialBehavior, "testkit")
|
||||
|
|
|
|||
|
|
@ -19,38 +19,52 @@ object Effects {
|
|||
* The behavior spawned a named child with the given behavior with no specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String): Spawned[T] = Spawned(behavior, childName)
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior with no specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String, ref: ActorRef[T]): Spawned[T] = new Spawned(behavior, childName, Props.empty, ref)
|
||||
def spawned[T](behavior: Behavior[T], childName: String, ref: ActorRef[T]): Spawned[T] =
|
||||
new Spawned(behavior, childName, Props.empty, ref)
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior and specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props): Spawned[T] = Spawned(behavior, childName, props)
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props): Spawned[T] =
|
||||
Spawned(behavior, childName, props)
|
||||
|
||||
/**
|
||||
* The behavior spawned a named child with the given behavior and specific props
|
||||
*/
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props, ref: ActorRef[T]): Spawned[T] = new Spawned(behavior, childName, props, ref)
|
||||
def spawned[T](behavior: Behavior[T], childName: String, props: Props, ref: ActorRef[T]): Spawned[T] =
|
||||
new Spawned(behavior, childName, props, ref)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with no specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T]): SpawnedAnonymous[T] = SpawnedAnonymous(behavior)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with no specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], ref: ActorRef[T]): SpawnedAnonymous[T] = new SpawnedAnonymous(behavior, Props.empty, ref)
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], ref: ActorRef[T]): SpawnedAnonymous[T] =
|
||||
new SpawnedAnonymous(behavior, Props.empty, ref)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], props: Props): SpawnedAnonymous[T] = SpawnedAnonymous(behavior, props)
|
||||
|
||||
/**
|
||||
* The behavior spawned an anonymous child with the given behavior with specific props
|
||||
*/
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], props: Props, ref: ActorRef[T]): SpawnedAnonymous[T] = new SpawnedAnonymous(behavior, props, ref)
|
||||
def spawnedAnonymous[T](behavior: Behavior[T], props: Props, ref: ActorRef[T]): SpawnedAnonymous[T] =
|
||||
new SpawnedAnonymous(behavior, props, ref)
|
||||
|
||||
/**
|
||||
* The behavior stopped `childName`
|
||||
*/
|
||||
def stopped(childName: String): Stopped = Stopped(childName)
|
||||
|
||||
/**
|
||||
* The behavior started watching `other`, through `context.watch(other)`
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@ import scala.concurrent.duration.{ Duration, FiniteDuration }
|
|||
* scheduler control through [[ManualTime.apply()]]
|
||||
*/
|
||||
object ManualTime {
|
||||
|
||||
/**
|
||||
* Config needed to use the `ExplicitlyTriggeredScheduler`
|
||||
*/
|
||||
val config: Config = ConfigFactory.parseString("""akka.scheduler.implementation = "akka.testkit.ExplicitlyTriggeredScheduler"""")
|
||||
val config: Config =
|
||||
ConfigFactory.parseString("""akka.scheduler.implementation = "akka.testkit.ExplicitlyTriggeredScheduler"""")
|
||||
|
||||
/**
|
||||
* Access the manual scheduler, note that you need to setup the actor system/testkit with [[config()]] for this to
|
||||
|
|
@ -29,7 +31,9 @@ object ManualTime {
|
|||
def apply()(implicit system: ActorSystem[_]): ManualTime =
|
||||
system.scheduler match {
|
||||
case sc: akka.testkit.ExplicitlyTriggeredScheduler => new ManualTime(sc)
|
||||
case _ => throw new IllegalArgumentException("ActorSystem not configured with explicitly triggered scheduler, " +
|
||||
case _ =>
|
||||
throw new IllegalArgumentException(
|
||||
"ActorSystem not configured with explicitly triggered scheduler, " +
|
||||
"make sure to include akka.actor.testkit.typed.scaladsl.ManualTime.config() when setting up the test")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,13 @@ import org.scalatest.time.Span
|
|||
* Note that ScalaTest is not provided as a transitive dependency of the testkit module but must be added explicitly
|
||||
* to your project to use this.
|
||||
*/
|
||||
abstract class ScalaTestWithActorTestKit(testKit: ActorTestKit) extends ActorTestKitBase(testKit)
|
||||
with TestSuite with Matchers with BeforeAndAfterAll with ScalaFutures with Eventually {
|
||||
abstract class ScalaTestWithActorTestKit(testKit: ActorTestKit)
|
||||
extends ActorTestKitBase(testKit)
|
||||
with TestSuite
|
||||
with Matchers
|
||||
with BeforeAndAfterAll
|
||||
with ScalaFutures
|
||||
with Eventually {
|
||||
|
||||
def this() = this(ActorTestKit(ActorTestKitBase.testNameFromCallStack()))
|
||||
|
||||
|
|
@ -57,4 +62,3 @@ abstract class ScalaTestWithActorTestKit(testKit: ActorTestKit) extends ActorTes
|
|||
testKit.shutdownTestKit()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import scala.collection.immutable
|
|||
object TestInbox {
|
||||
def apply[T](name: String = "inbox"): TestInbox[T] = {
|
||||
val uid = ThreadLocalRandom.current().nextInt()
|
||||
new TestInboxImpl(address / name withUid uid)
|
||||
new TestInboxImpl((address / name).withUid(uid))
|
||||
}
|
||||
|
||||
private[akka] val address = RootActorPath(Address("akka.actor.typed.inbox", "anonymous"))
|
||||
|
|
@ -36,6 +36,7 @@ object TestInbox {
|
|||
*/
|
||||
@DoNotInherit
|
||||
trait TestInbox[T] {
|
||||
|
||||
/**
|
||||
* The actor ref of the inbox
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,18 +16,22 @@ import akka.actor.typed.ActorSystem
|
|||
import akka.annotation.DoNotInherit
|
||||
|
||||
object FishingOutcomes {
|
||||
|
||||
/**
|
||||
* Complete fishing and return all messages up until this
|
||||
*/
|
||||
val complete: FishingOutcome = FishingOutcome.Complete
|
||||
|
||||
/**
|
||||
* Consume this message, collect it into the result, and continue with the next message
|
||||
*/
|
||||
val continue: FishingOutcome = FishingOutcome.Continue
|
||||
|
||||
/**
|
||||
* Consume this message, but do not collect it into the result, and continue with the next message
|
||||
*/
|
||||
val continueAndIgnore: FishingOutcome = FishingOutcome.ContinueAndIgnore
|
||||
|
||||
/**
|
||||
* Fail fishing with a custom error message
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ class ActorTestKitSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
|||
val testkit2 = ActorTestKit()
|
||||
try {
|
||||
testkit2.system.name should ===("ActorTestKitSpec")
|
||||
} finally
|
||||
testkit2.shutdownTestKit()
|
||||
} finally testkit2.shutdownTestKit()
|
||||
}
|
||||
|
||||
"use name from given class name" in {
|
||||
|
|
@ -34,8 +33,7 @@ class ActorTestKitSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
|||
try {
|
||||
// removing package name and such
|
||||
testkit2.system.name should ===("Vector")
|
||||
} finally
|
||||
testkit2.shutdownTestKit()
|
||||
} finally testkit2.shutdownTestKit()
|
||||
}
|
||||
|
||||
"spawn an actor" in {
|
||||
|
|
@ -81,16 +79,14 @@ class MyConcreteDerivateSpec extends MyBaseSpec {
|
|||
val testkit2 = ActorTestKit()
|
||||
try {
|
||||
testkit2.system.name should ===("MyConcreteDerivateSpec")
|
||||
} finally
|
||||
testkit2.shutdownTestKit()
|
||||
} finally testkit2.shutdownTestKit()
|
||||
}
|
||||
|
||||
"use name from given class name" in {
|
||||
val testkit2 = ActorTestKit(classOf[Vector[_]].getName)
|
||||
try {
|
||||
testkit2.system.name should ===("Vector")
|
||||
} finally
|
||||
testkit2.shutdownTestKit()
|
||||
} finally testkit2.shutdownTestKit()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,4 +103,3 @@ class CompositionSpec extends WordSpec with Matchers with BeforeAndAfterAll {
|
|||
testKit.system.name should ===("CompositionSpec")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,13 +67,13 @@ object BehaviorTestKitSpec {
|
|||
context.stop(child)
|
||||
Behaviors.same
|
||||
case SpawnAdapter =>
|
||||
context.spawnMessageAdapter {
|
||||
r: Reproduce => SpawnAnonymous(r.times)
|
||||
context.spawnMessageAdapter { r: Reproduce =>
|
||||
SpawnAnonymous(r.times)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAdapterWithName(name) =>
|
||||
context.spawnMessageAdapter({
|
||||
r: Reproduce => SpawnAnonymous(r.times)
|
||||
context.spawnMessageAdapter({ r: Reproduce =>
|
||||
SpawnAnonymous(r.times)
|
||||
}, name)
|
||||
Behaviors.same
|
||||
case SpawnAndWatchUnwatch(name) =>
|
||||
|
|
@ -253,7 +253,7 @@ class BehaviorTestKitSpec extends WordSpec with Matchers {
|
|||
}
|
||||
}
|
||||
|
||||
"BehaviorTestkit's run" can {
|
||||
"BehaviorTestkit's run".can {
|
||||
"run behaviors with messages without canonicalization" in {
|
||||
val testkit = BehaviorTestKit[Father.Command](Father.init)
|
||||
testkit.run(SpawnAdapterWithName("adapter"))
|
||||
|
|
@ -267,21 +267,16 @@ class BehaviorTestKitSpec extends WordSpec with Matchers {
|
|||
val testkit = BehaviorTestKit(Father.init)
|
||||
testkit.run(SpawnAndWatchUnwatch("hello"))
|
||||
val child = testkit.childInbox("hello").ref
|
||||
testkit.retrieveAllEffects() should be(Seq(
|
||||
Effects.spawned(Child.initial, "hello", Props.empty),
|
||||
Effects.watched(child),
|
||||
Effects.unwatched(child)
|
||||
))
|
||||
testkit.retrieveAllEffects() should be(
|
||||
Seq(Effects.spawned(Child.initial, "hello", Props.empty), Effects.watched(child), Effects.unwatched(child)))
|
||||
}
|
||||
|
||||
"record effects for watchWith" in {
|
||||
val testkit = BehaviorTestKit(Father.init)
|
||||
testkit.run(SpawnAndWatchWith("hello"))
|
||||
val child = testkit.childInbox("hello").ref
|
||||
testkit.retrieveAllEffects() should be(Seq(
|
||||
Effects.spawned(Child.initial, "hello", Props.empty),
|
||||
Effects.watched(child)
|
||||
))
|
||||
testkit.retrieveAllEffects() should be(
|
||||
Seq(Effects.spawned(Child.initial, "hello", Props.empty), Effects.watched(child)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,11 +47,8 @@ class TestProbeSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
|||
Behaviors.withTimers { (timer) =>
|
||||
timer.startSingleTimer("key", Stop, 300.millis)
|
||||
|
||||
Behaviors.receive((context, stop) =>
|
||||
Behaviors.stopped
|
||||
)
|
||||
}
|
||||
))
|
||||
Behaviors.receive((context, stop) => Behaviors.stopped)
|
||||
}))
|
||||
ref ! Stop
|
||||
// race, but not sure how to test in any other way
|
||||
probe.expectTerminated(ref, 500.millis)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ object ActorConfigurationVerificationSpec {
|
|||
"""
|
||||
}
|
||||
|
||||
class ActorConfigurationVerificationSpec extends AkkaSpec(ActorConfigurationVerificationSpec.config) with DefaultTimeout with BeforeAndAfterEach {
|
||||
class ActorConfigurationVerificationSpec
|
||||
extends AkkaSpec(ActorConfigurationVerificationSpec.config)
|
||||
with DefaultTimeout
|
||||
with BeforeAndAfterEach {
|
||||
import ActorConfigurationVerificationSpec._
|
||||
|
||||
override def atStartup: Unit = {
|
||||
|
|
@ -64,8 +67,10 @@ class ActorConfigurationVerificationSpec extends AkkaSpec(ActorConfigurationVeri
|
|||
}
|
||||
"fail verification with a ConfigurationException if also configured with a ScatterGatherFirstCompletedPool" in {
|
||||
intercept[ConfigurationException] {
|
||||
system.actorOf(ScatterGatherFirstCompletedPool(nrOfInstances = 2, within = 2 seconds).
|
||||
withDispatcher("balancing-dispatcher").props(Props[TestActor]))
|
||||
system.actorOf(
|
||||
ScatterGatherFirstCompletedPool(nrOfInstances = 2, within = 2 seconds)
|
||||
.withDispatcher("balancing-dispatcher")
|
||||
.props(Props[TestActor]))
|
||||
}
|
||||
}
|
||||
"not fail verification with a ConfigurationException also not configured with a Router" in {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package akka.actor
|
|||
|
||||
import scala.language.postfixOps
|
||||
|
||||
import akka.testkit.{ PerformanceTest, ImplicitSender, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, ImplicitSender, PerformanceTest }
|
||||
import scala.concurrent.duration._
|
||||
import akka.testkit.metrics._
|
||||
import org.scalatest.BeforeAndAfterAll
|
||||
|
|
@ -58,7 +58,6 @@ object ActorCreationPerfSpec {
|
|||
case IsAlive =>
|
||||
sender() ! Alive
|
||||
case Create(number, propsCreator) =>
|
||||
|
||||
for (i <- 1 to number) {
|
||||
val start = System.nanoTime()
|
||||
context.actorOf(propsCreator.apply())
|
||||
|
|
@ -117,8 +116,11 @@ object ActorCreationPerfSpec {
|
|||
}
|
||||
}
|
||||
|
||||
class ActorCreationPerfSpec extends AkkaSpec(ActorCreationPerfSpec.config) with ImplicitSender
|
||||
with MetricsKit with BeforeAndAfterAll {
|
||||
class ActorCreationPerfSpec
|
||||
extends AkkaSpec(ActorCreationPerfSpec.config)
|
||||
with ImplicitSender
|
||||
with MetricsKit
|
||||
with BeforeAndAfterAll {
|
||||
|
||||
import ActorCreationPerfSpec._
|
||||
|
||||
|
|
@ -175,7 +177,7 @@ class ActorCreationPerfSpec extends AkkaSpec(ActorCreationPerfSpec.config) with
|
|||
watch(driver)
|
||||
expectTerminated(driver, 15.seconds)
|
||||
|
||||
after diff before
|
||||
after.diff(before)
|
||||
}
|
||||
|
||||
def registerTests(name: String, propsCreator: () => Props): Unit = {
|
||||
|
|
|
|||
|
|
@ -49,19 +49,21 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
actor(new Act {})
|
||||
//#watch
|
||||
val i = inbox()
|
||||
i watch target
|
||||
i.watch(target)
|
||||
//#watch
|
||||
target ! PoisonPill
|
||||
i receive 1.second should ===(Terminated(target)(true, false))
|
||||
i.receive(1.second) should ===(Terminated(target)(true, false))
|
||||
}
|
||||
|
||||
"support queueing multiple queries" in {
|
||||
val i = inbox()
|
||||
import system.dispatcher
|
||||
val res = Future.sequence(Seq(
|
||||
Future { i.receive() } recover { case x => x },
|
||||
Future { Thread.sleep(100); i.select() { case "world" => 1 } } recover { case x => x },
|
||||
Future { Thread.sleep(200); i.select() { case "hello" => 2 } } recover { case x => x }))
|
||||
val res =
|
||||
Future.sequence(Seq(Future { i.receive() }.recover { case x => x }, Future {
|
||||
Thread.sleep(100); i.select() { case "world" => 1 }
|
||||
}.recover { case x => x }, Future { Thread.sleep(200); i.select() { case "hello" => 2 } }.recover {
|
||||
case x => x
|
||||
}))
|
||||
Thread.sleep(1000)
|
||||
res.isCompleted should ===(false)
|
||||
i.receiver ! 42
|
||||
|
|
@ -87,14 +89,14 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
try {
|
||||
for (_ <- 1 to 1000) i.receiver ! 0
|
||||
expectNoMsg(1 second)
|
||||
EventFilter.warning(start = "dropping message", occurrences = 1) intercept {
|
||||
EventFilter.warning(start = "dropping message", occurrences = 1).intercept {
|
||||
i.receiver ! 42
|
||||
}
|
||||
expectMsgType[Warning]
|
||||
i.receiver ! 42
|
||||
expectNoMsg(1 second)
|
||||
val gotit = for (_ <- 1 to 1000) yield i.receive()
|
||||
gotit should ===((1 to 1000) map (_ => 0))
|
||||
gotit should ===((1 to 1000).map(_ => 0))
|
||||
intercept[TimeoutException] {
|
||||
i.receive(1 second)
|
||||
}
|
||||
|
|
@ -165,7 +167,7 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
})
|
||||
//#simple-start-stop
|
||||
|
||||
system stop a
|
||||
system.stop(a)
|
||||
expectMsg("started")
|
||||
expectMsg("stopped")
|
||||
}
|
||||
|
|
@ -177,11 +179,13 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
case "die" => throw new Exception
|
||||
}
|
||||
whenFailing { case m @ (cause, msg) => testActor ! m }
|
||||
whenRestarted { cause => testActor ! cause }
|
||||
whenRestarted { cause =>
|
||||
testActor ! cause
|
||||
}
|
||||
})
|
||||
//#failing-actor
|
||||
|
||||
EventFilter[Exception](occurrences = 1) intercept {
|
||||
EventFilter[Exception](occurrences = 1).intercept {
|
||||
a ! "die"
|
||||
}
|
||||
expectMsgPF() { case (x: Exception, Some("die")) => }
|
||||
|
|
@ -198,7 +202,8 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
})
|
||||
//#supervise-with
|
||||
val child = actor("child")(new Act {
|
||||
whenFailing { (_, _) => }
|
||||
whenFailing { (_, _) =>
|
||||
}
|
||||
become {
|
||||
case ref: ActorRef => whenStopping(ref ! "stopped")
|
||||
case ex: Exception => throw ex
|
||||
|
|
@ -209,11 +214,11 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
}
|
||||
})
|
||||
a ! testActor
|
||||
EventFilter.warning("hi", occurrences = 1) intercept {
|
||||
EventFilter.warning("hi", occurrences = 1).intercept {
|
||||
a ! new Exception("hi")
|
||||
}
|
||||
expectNoMsg(1 second)
|
||||
EventFilter[Exception]("hello", occurrences = 1) intercept {
|
||||
EventFilter[Exception]("hello", occurrences = 1).intercept {
|
||||
a ! new Exception("hello")
|
||||
}
|
||||
expectMsg("stopped")
|
||||
|
|
@ -242,7 +247,8 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
become {
|
||||
case 1 => stash()
|
||||
case 2 =>
|
||||
testActor ! 2; unstashAll(); becomeStacked {
|
||||
testActor ! 2; unstashAll();
|
||||
becomeStacked {
|
||||
case 1 => testActor ! 1; unbecome()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@ object ActorLifeCycleSpec {
|
|||
|
||||
}
|
||||
|
||||
class ActorLifeCycleSpec extends AkkaSpec("akka.actor.serialize-messages=off") with BeforeAndAfterEach with ImplicitSender with DefaultTimeout {
|
||||
class ActorLifeCycleSpec
|
||||
extends AkkaSpec("akka.actor.serialize-messages=off")
|
||||
with BeforeAndAfterEach
|
||||
with ImplicitSender
|
||||
with DefaultTimeout {
|
||||
import ActorLifeCycleSpec._
|
||||
|
||||
"An Actor" must {
|
||||
|
|
@ -37,7 +41,8 @@ class ActorLifeCycleSpec extends AkkaSpec("akka.actor.serialize-messages=off") w
|
|||
"invoke preRestart, preStart, postRestart when using OneForOneStrategy" in {
|
||||
filterException[ActorKilledException] {
|
||||
val id = newUuid.toString
|
||||
val supervisor = system.actorOf(Props(classOf[Supervisor], OneForOneStrategy(maxNrOfRetries = 3)(List(classOf[Exception]))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(classOf[Supervisor], OneForOneStrategy(maxNrOfRetries = 3)(List(classOf[Exception]))))
|
||||
val gen = new AtomicInteger(0)
|
||||
val restarterProps = Props(new LifeCycleTestActor(testActor, id, gen) {
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit = { report("preRestart") }
|
||||
|
|
@ -71,7 +76,8 @@ class ActorLifeCycleSpec extends AkkaSpec("akka.actor.serialize-messages=off") w
|
|||
"default for preRestart and postRestart is to call postStop and preStart respectively" in {
|
||||
filterException[ActorKilledException] {
|
||||
val id = newUuid().toString
|
||||
val supervisor = system.actorOf(Props(classOf[Supervisor], OneForOneStrategy(maxNrOfRetries = 3)(List(classOf[Exception]))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(classOf[Supervisor], OneForOneStrategy(maxNrOfRetries = 3)(List(classOf[Exception]))))
|
||||
val gen = new AtomicInteger(0)
|
||||
val restarterProps = Props(classOf[LifeCycleTestActor], testActor, id, gen)
|
||||
val restarter = Await.result((supervisor ? restarterProps).mapTo[ActorRef], timeout.duration)
|
||||
|
|
@ -101,9 +107,8 @@ class ActorLifeCycleSpec extends AkkaSpec("akka.actor.serialize-messages=off") w
|
|||
|
||||
"not invoke preRestart and postRestart when never restarted using OneForOneStrategy" in {
|
||||
val id = newUuid().toString
|
||||
val supervisor = system.actorOf(Props(
|
||||
classOf[Supervisor],
|
||||
OneForOneStrategy(maxNrOfRetries = 3)(List(classOf[Exception]))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(classOf[Supervisor], OneForOneStrategy(maxNrOfRetries = 3)(List(classOf[Exception]))))
|
||||
val gen = new AtomicInteger(0)
|
||||
val props = Props(classOf[LifeCycleTestActor], testActor, id, gen)
|
||||
val a = Await.result((supervisor ? props).mapTo[ActorRef], timeout.duration)
|
||||
|
|
@ -121,7 +126,7 @@ class ActorLifeCycleSpec extends AkkaSpec("akka.actor.serialize-messages=off") w
|
|||
def receive = Actor.emptyBehavior
|
||||
override def postStop: Unit = { throw new Exception("hurrah") }
|
||||
}))
|
||||
EventFilter[Exception]("hurrah", occurrences = 1) intercept {
|
||||
EventFilter[Exception]("hurrah", occurrences = 1).intercept {
|
||||
a ! PoisonPill
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +148,7 @@ class ActorLifeCycleSpec extends AkkaSpec("akka.actor.serialize-messages=off") w
|
|||
expectMsg("ok")
|
||||
a ! "hello"
|
||||
expectMsg(43)
|
||||
EventFilter[RuntimeException]("buh", occurrences = 1) intercept {
|
||||
EventFilter[RuntimeException]("buh", occurrences = 1).intercept {
|
||||
a ! "fail"
|
||||
}
|
||||
a ! "hello"
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
system.actorFor(system / "c1") should ===(c1)
|
||||
system.actorFor(system / "c2") should ===(c2)
|
||||
system.actorFor(system / "c2" / "c21") should ===(c21)
|
||||
system.actorFor(system child "c2" child "c21") should ===(c21) // test Java API
|
||||
system.actorFor(system.child("c2").child("c21")) should ===(c21) // test Java API
|
||||
system.actorFor(system / Seq("c2", "c21")) should ===(c21)
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
system.actorFor(system descendant Seq("c2", "c21").asJava) // test Java API
|
||||
system.actorFor(system.descendant(Seq("c2", "c21").asJava)) // test Java API
|
||||
}
|
||||
|
||||
"find actors by looking up their string representation" in {
|
||||
|
|
@ -201,7 +201,8 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
"find actors by looking up their root-anchored relative path" in {
|
||||
def check(looker: ActorRef, pathOf: ActorRef, result: ActorRef): Unit = {
|
||||
Await.result(looker ? LookupString(pathOf.path.toStringWithoutAddress), timeout.duration) should ===(result)
|
||||
Await.result(looker ? LookupString(pathOf.path.elements.mkString("/", "/", "/")), timeout.duration) should ===(result)
|
||||
Await.result(looker ? LookupString(pathOf.path.elements.mkString("/", "/", "/")), timeout.duration) should ===(
|
||||
result)
|
||||
}
|
||||
for {
|
||||
looker <- all
|
||||
|
|
@ -212,8 +213,8 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
"find actors by looking up their relative path" in {
|
||||
def check(looker: ActorRef, result: ActorRef, elems: String*): Unit = {
|
||||
Await.result(looker ? LookupElems(elems), timeout.duration) should ===(result)
|
||||
Await.result(looker ? LookupString(elems mkString "/"), timeout.duration) should ===(result)
|
||||
Await.result(looker ? LookupString(elems mkString ("", "/", "/")), timeout.duration) should ===(result)
|
||||
Await.result(looker ? LookupString(elems.mkString("/")), timeout.duration) should ===(result)
|
||||
Await.result(looker ? LookupString(elems.mkString("", "/", "/")), timeout.duration) should ===(result)
|
||||
}
|
||||
check(c1, user, "..")
|
||||
for {
|
||||
|
|
@ -232,7 +233,9 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
Await.result(looker ? LookupString(target.path.toString), timeout.duration) should ===(target)
|
||||
Await.result(looker ? LookupString(target.path.toString + "/"), timeout.duration) should ===(target)
|
||||
Await.result(looker ? LookupString(target.path.toStringWithoutAddress), timeout.duration) should ===(target)
|
||||
if (target != root) Await.result(looker ? LookupString(target.path.elements.mkString("/", "/", "/")), timeout.duration) should ===(target)
|
||||
if (target != root)
|
||||
Await.result(looker ? LookupString(target.path.elements.mkString("/", "/", "/")), timeout.duration) should ===(
|
||||
target)
|
||||
}
|
||||
}
|
||||
for (target <- Seq(root, syst, user, system.deadLetters)) check(target)
|
||||
|
|
@ -248,17 +251,14 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
|
|||
}
|
||||
def check(looker: ActorRef): Unit = {
|
||||
val lookname = looker.path.elements.mkString("", "/", "/")
|
||||
for (
|
||||
(l, r) <- Seq(
|
||||
LookupString("a/b/c") -> empty(lookname + "a/b/c"),
|
||||
for ((l, r) <- Seq(LookupString("a/b/c") -> empty(lookname + "a/b/c"),
|
||||
LookupString("") -> system.deadLetters,
|
||||
LookupString("akka://all-systems/Nobody") -> system.deadLetters,
|
||||
LookupPath(system / "hallo") -> empty("user/hallo"),
|
||||
LookupPath(looker.path child "hallo") -> empty(lookname + "hallo"), // test Java API
|
||||
LookupPath(looker.path descendant Seq("a", "b").asJava) -> empty(lookname + "a/b"), // test Java API
|
||||
LookupPath(looker.path.child("hallo")) -> empty(lookname + "hallo"), // test Java API
|
||||
LookupPath(looker.path.descendant(Seq("a", "b").asJava)) -> empty(lookname + "a/b"), // test Java API
|
||||
LookupElems(Seq()) -> system.deadLetters,
|
||||
LookupElems(Seq("a")) -> empty(lookname + "a"))
|
||||
) checkOne(looker, l, r)
|
||||
LookupElems(Seq("a")) -> empty(lookname + "a"))) checkOne(looker, l, r)
|
||||
}
|
||||
for (looker <- all) check(looker)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,10 +174,12 @@ object ActorMailboxSpec {
|
|||
|
||||
class BoundedQueueReportingActor extends QueueReportingActor with RequiresMessageQueue[BoundedMessageQueueSemantics]
|
||||
|
||||
class BoundedControlAwareQueueReportingActor extends QueueReportingActor
|
||||
class BoundedControlAwareQueueReportingActor
|
||||
extends QueueReportingActor
|
||||
with RequiresMessageQueue[BoundedControlAwareMessageQueueSemantics]
|
||||
|
||||
class UnboundedControlAwareQueueReportingActor extends QueueReportingActor
|
||||
class UnboundedControlAwareQueueReportingActor
|
||||
extends QueueReportingActor
|
||||
with RequiresMessageQueue[UnboundedControlAwareMessageQueueSemantics]
|
||||
|
||||
class StashQueueReportingActor extends QueueReportingActor with Stash
|
||||
|
|
@ -187,32 +189,28 @@ object ActorMailboxSpec {
|
|||
val UnboundedMailboxTypes = Seq(classOf[UnboundedMessageQueueSemantics])
|
||||
val BoundedMailboxTypes = Seq(classOf[BoundedMessageQueueSemantics])
|
||||
|
||||
val UnboundedDeqMailboxTypes = Seq(
|
||||
classOf[DequeBasedMessageQueueSemantics],
|
||||
val UnboundedDeqMailboxTypes = Seq(classOf[DequeBasedMessageQueueSemantics],
|
||||
classOf[UnboundedMessageQueueSemantics],
|
||||
classOf[UnboundedDequeBasedMessageQueueSemantics])
|
||||
|
||||
val BoundedDeqMailboxTypes = Seq(
|
||||
classOf[DequeBasedMessageQueueSemantics],
|
||||
val BoundedDeqMailboxTypes = Seq(classOf[DequeBasedMessageQueueSemantics],
|
||||
classOf[BoundedMessageQueueSemantics],
|
||||
classOf[BoundedDequeBasedMessageQueueSemantics])
|
||||
|
||||
val BoundedControlAwareMailboxTypes = Seq(
|
||||
classOf[BoundedMessageQueueSemantics],
|
||||
val BoundedControlAwareMailboxTypes = Seq(classOf[BoundedMessageQueueSemantics],
|
||||
classOf[ControlAwareMessageQueueSemantics],
|
||||
classOf[BoundedControlAwareMessageQueueSemantics])
|
||||
val UnboundedControlAwareMailboxTypes = Seq(
|
||||
classOf[UnboundedMessageQueueSemantics],
|
||||
val UnboundedControlAwareMailboxTypes = Seq(classOf[UnboundedMessageQueueSemantics],
|
||||
classOf[ControlAwareMessageQueueSemantics],
|
||||
classOf[UnboundedControlAwareMessageQueueSemantics])
|
||||
|
||||
trait MCBoundedMessageQueueSemantics extends MessageQueue with MultipleConsumerSemantics
|
||||
final case class MCBoundedMailbox(val capacity: Int, val pushTimeOut: FiniteDuration)
|
||||
extends MailboxType with ProducesMessageQueue[MCBoundedMessageQueueSemantics] {
|
||||
extends MailboxType
|
||||
with ProducesMessageQueue[MCBoundedMessageQueueSemantics] {
|
||||
|
||||
def this(settings: ActorSystem.Settings, config: Config) = this(
|
||||
config.getInt("mailbox-capacity"),
|
||||
config.getNanosDuration("mailbox-push-timeout-time"))
|
||||
def this(settings: ActorSystem.Settings, config: Config) =
|
||||
this(config.getInt("mailbox-capacity"), config.getNanosDuration("mailbox-push-timeout-time"))
|
||||
|
||||
final override def create(owner: Option[ActorRef], system: Option[ActorSystem]): MessageQueue =
|
||||
new BoundedMailbox.MessageQueue(capacity, pushTimeOut)
|
||||
|
|
@ -231,7 +229,7 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
|
||||
actor ! "ping"
|
||||
val q = expectMsgType[MessageQueue]
|
||||
types foreach (t => assert(t isInstance q, s"Type [${q.getClass.getName}] is not assignable to [${t.getName}]"))
|
||||
types.foreach(t => assert(t.isInstance(q), s"Type [${q.getClass.getName}] is not assignable to [${t.getName}]"))
|
||||
q
|
||||
}
|
||||
|
||||
|
|
@ -242,30 +240,24 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"get an unbounded deque message queue when it is only configured on the props" in {
|
||||
checkMailboxQueue(
|
||||
Props[QueueReportingActor].withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
"default-override-from-props", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(Props[QueueReportingActor].withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
"default-override-from-props",
|
||||
UnboundedDeqMailboxTypes)
|
||||
}
|
||||
|
||||
"get an bounded message queue when it's only configured with RequiresMailbox" in {
|
||||
checkMailboxQueue(
|
||||
Props[BoundedQueueReportingActor],
|
||||
"default-override-from-trait", BoundedMailboxTypes)
|
||||
checkMailboxQueue(Props[BoundedQueueReportingActor], "default-override-from-trait", BoundedMailboxTypes)
|
||||
}
|
||||
|
||||
"get an unbounded deque message queue when it's only mixed with Stash" in {
|
||||
checkMailboxQueue(
|
||||
Props[StashQueueReportingActor],
|
||||
"default-override-from-stash", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(
|
||||
Props(new StashQueueReportingActor),
|
||||
"default-override-from-stash2", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(
|
||||
Props(classOf[StashQueueReportingActorWithParams], 17, "hello"),
|
||||
"default-override-from-stash3", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(
|
||||
Props(new StashQueueReportingActorWithParams(17, "hello")),
|
||||
"default-override-from-stash4", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(Props[StashQueueReportingActor], "default-override-from-stash", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(Props(new StashQueueReportingActor), "default-override-from-stash2", UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(Props(classOf[StashQueueReportingActorWithParams], 17, "hello"),
|
||||
"default-override-from-stash3",
|
||||
UnboundedDeqMailboxTypes)
|
||||
checkMailboxQueue(Props(new StashQueueReportingActorWithParams(17, "hello")),
|
||||
"default-override-from-stash4",
|
||||
UnboundedDeqMailboxTypes)
|
||||
}
|
||||
|
||||
"get a bounded message queue when it's configured as mailbox" in {
|
||||
|
|
@ -281,23 +273,26 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"get an unbounded control aware message queue when it's configured as mailbox" in {
|
||||
checkMailboxQueue(Props[QueueReportingActor], "default-unbounded-control-aware", UnboundedControlAwareMailboxTypes)
|
||||
checkMailboxQueue(Props[QueueReportingActor],
|
||||
"default-unbounded-control-aware",
|
||||
UnboundedControlAwareMailboxTypes)
|
||||
}
|
||||
|
||||
"get an bounded control aware message queue when it's only configured with RequiresMailbox" in {
|
||||
checkMailboxQueue(
|
||||
Props[BoundedControlAwareQueueReportingActor],
|
||||
"default-override-from-trait-bounded-control-aware", BoundedControlAwareMailboxTypes)
|
||||
checkMailboxQueue(Props[BoundedControlAwareQueueReportingActor],
|
||||
"default-override-from-trait-bounded-control-aware",
|
||||
BoundedControlAwareMailboxTypes)
|
||||
}
|
||||
|
||||
"get an unbounded control aware message queue when it's only configured with RequiresMailbox" in {
|
||||
checkMailboxQueue(
|
||||
Props[UnboundedControlAwareQueueReportingActor],
|
||||
"default-override-from-trait-unbounded-control-aware", UnboundedControlAwareMailboxTypes)
|
||||
checkMailboxQueue(Props[UnboundedControlAwareQueueReportingActor],
|
||||
"default-override-from-trait-unbounded-control-aware",
|
||||
UnboundedControlAwareMailboxTypes)
|
||||
}
|
||||
|
||||
"fail to create actor when an unbounded dequeu message queue is configured as mailbox overriding RequestMailbox" in {
|
||||
intercept[ConfigurationException](system.actorOf(Props[BoundedQueueReportingActor], "default-unbounded-deque-override-trait"))
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[BoundedQueueReportingActor], "default-unbounded-deque-override-trait"))
|
||||
}
|
||||
|
||||
"get an unbounded message queue when defined in dispatcher" in {
|
||||
|
|
@ -305,7 +300,8 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"fail to create actor when an unbounded message queue is defined in dispatcher overriding RequestMailbox" in {
|
||||
intercept[ConfigurationException](system.actorOf(Props[BoundedQueueReportingActor], "unbounded-default-override-trait"))
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[BoundedQueueReportingActor], "unbounded-default-override-trait"))
|
||||
}
|
||||
|
||||
"get a bounded message queue when it's configured as mailbox overriding unbounded in dispatcher" in {
|
||||
|
|
@ -317,7 +313,9 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"get a bounded message queue with 0 push timeout when defined in dispatcher" in {
|
||||
val q = checkMailboxQueue(Props[QueueReportingActor], "default-bounded-mailbox-with-zero-pushtimeout", BoundedMailboxTypes)
|
||||
val q = checkMailboxQueue(Props[QueueReportingActor],
|
||||
"default-bounded-mailbox-with-zero-pushtimeout",
|
||||
BoundedMailboxTypes)
|
||||
q.asInstanceOf[BoundedMessageQueueSemantics].pushTimeOut should ===(Duration.Zero)
|
||||
}
|
||||
|
||||
|
|
@ -326,21 +324,25 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"get an unbounded message queue overriding configuration on the props" in {
|
||||
checkMailboxQueue(
|
||||
Props[QueueReportingActor].withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
"bounded-unbounded-override-props", UnboundedMailboxTypes)
|
||||
checkMailboxQueue(Props[QueueReportingActor].withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
"bounded-unbounded-override-props",
|
||||
UnboundedMailboxTypes)
|
||||
}
|
||||
|
||||
"get a bounded deque-based message queue if configured and required" in {
|
||||
checkMailboxQueue(Props[StashQueueReportingActor], "bounded-deque-requirements-configured", BoundedDeqMailboxTypes)
|
||||
checkMailboxQueue(Props[StashQueueReportingActor],
|
||||
"bounded-deque-requirements-configured",
|
||||
BoundedDeqMailboxTypes)
|
||||
}
|
||||
|
||||
"fail with a unbounded deque-based message queue if configured and required" in {
|
||||
intercept[ConfigurationException](system.actorOf(Props[StashQueueReportingActor], "bounded-deque-require-unbounded-configured"))
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor], "bounded-deque-require-unbounded-configured"))
|
||||
}
|
||||
|
||||
"fail with a bounded deque-based message queue if not configured" in {
|
||||
intercept[ConfigurationException](system.actorOf(Props[StashQueueReportingActor], "bounded-deque-require-unbounded-unconfigured"))
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor], "bounded-deque-require-unbounded-unconfigured"))
|
||||
}
|
||||
|
||||
"get a bounded deque-based message queue if configured and required with Props" in {
|
||||
|
|
@ -353,7 +355,8 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"fail with a unbounded deque-based message queue if configured and required with Props" in {
|
||||
intercept[ConfigurationException](system.actorOf(
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(
|
||||
Props[StashQueueReportingActor]
|
||||
.withDispatcher("requiring-bounded-dispatcher")
|
||||
.withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
|
|
@ -361,71 +364,62 @@ class ActorMailboxSpec(conf: Config) extends AkkaSpec(conf) with DefaultTimeout
|
|||
}
|
||||
|
||||
"fail with a bounded deque-based message queue if not configured with Props" in {
|
||||
intercept[ConfigurationException](system.actorOf(
|
||||
Props[StashQueueReportingActor]
|
||||
.withDispatcher("requiring-bounded-dispatcher"),
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor].withDispatcher("requiring-bounded-dispatcher"),
|
||||
"bounded-deque-require-unbounded-unconfigured-props"))
|
||||
}
|
||||
|
||||
"get a bounded deque-based message queue if configured and required with Props (dispatcher)" in {
|
||||
checkMailboxQueue(
|
||||
Props[StashQueueReportingActor]
|
||||
.withDispatcher("requiring-bounded-dispatcher"),
|
||||
checkMailboxQueue(Props[StashQueueReportingActor].withDispatcher("requiring-bounded-dispatcher"),
|
||||
"bounded-deque-requirements-configured-props-disp",
|
||||
BoundedDeqMailboxTypes)
|
||||
}
|
||||
|
||||
"fail with a unbounded deque-based message queue if configured and required with Props (dispatcher)" in {
|
||||
intercept[ConfigurationException](system.actorOf(
|
||||
Props[StashQueueReportingActor]
|
||||
.withDispatcher("requiring-bounded-dispatcher"),
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor].withDispatcher("requiring-bounded-dispatcher"),
|
||||
"bounded-deque-require-unbounded-configured-props-disp"))
|
||||
}
|
||||
|
||||
"fail with a bounded deque-based message queue if not configured with Props (dispatcher)" in {
|
||||
intercept[ConfigurationException](system.actorOf(
|
||||
Props[StashQueueReportingActor]
|
||||
.withDispatcher("requiring-bounded-dispatcher"),
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor].withDispatcher("requiring-bounded-dispatcher"),
|
||||
"bounded-deque-require-unbounded-unconfigured-props-disp"))
|
||||
}
|
||||
|
||||
"get a bounded deque-based message queue if configured and required with Props (mailbox)" in {
|
||||
checkMailboxQueue(
|
||||
Props[StashQueueReportingActor]
|
||||
.withMailbox("akka.actor.mailbox.bounded-deque-based"),
|
||||
checkMailboxQueue(Props[StashQueueReportingActor].withMailbox("akka.actor.mailbox.bounded-deque-based"),
|
||||
"bounded-deque-requirements-configured-props-mail",
|
||||
BoundedDeqMailboxTypes)
|
||||
}
|
||||
|
||||
"fail with a unbounded deque-based message queue if configured and required with Props (mailbox)" in {
|
||||
intercept[ConfigurationException](system.actorOf(
|
||||
Props[StashQueueReportingActor]
|
||||
.withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor].withMailbox("akka.actor.mailbox.unbounded-deque-based"),
|
||||
"bounded-deque-require-unbounded-configured-props-mail"))
|
||||
}
|
||||
|
||||
"fail with a bounded deque-based message queue if not configured with Props (mailbox)" in {
|
||||
intercept[ConfigurationException](system.actorOf(
|
||||
Props[StashQueueReportingActor],
|
||||
"bounded-deque-require-unbounded-unconfigured-props-mail"))
|
||||
intercept[ConfigurationException](
|
||||
system.actorOf(Props[StashQueueReportingActor], "bounded-deque-require-unbounded-unconfigured-props-mail"))
|
||||
}
|
||||
|
||||
"get an unbounded message queue with a balancing dispatcher" in {
|
||||
checkMailboxQueue(
|
||||
Props[QueueReportingActor].withDispatcher("balancing-dispatcher"),
|
||||
"unbounded-balancing", UnboundedMailboxTypes)
|
||||
checkMailboxQueue(Props[QueueReportingActor].withDispatcher("balancing-dispatcher"),
|
||||
"unbounded-balancing",
|
||||
UnboundedMailboxTypes)
|
||||
}
|
||||
|
||||
"get a bounded message queue with a balancing bounded dispatcher" in {
|
||||
checkMailboxQueue(
|
||||
Props[QueueReportingActor].withDispatcher("balancing-bounded-dispatcher"),
|
||||
"bounded-balancing", BoundedMailboxTypes)
|
||||
checkMailboxQueue(Props[QueueReportingActor].withDispatcher("balancing-bounded-dispatcher"),
|
||||
"bounded-balancing",
|
||||
BoundedMailboxTypes)
|
||||
}
|
||||
|
||||
"get a bounded message queue with a requiring balancing bounded dispatcher" in {
|
||||
checkMailboxQueue(
|
||||
Props[QueueReportingActor].withDispatcher("requiring-balancing-bounded-dispatcher"),
|
||||
"requiring-bounded-balancing", BoundedMailboxTypes)
|
||||
checkMailboxQueue(Props[QueueReportingActor].withDispatcher("requiring-balancing-bounded-dispatcher"),
|
||||
"requiring-bounded-balancing",
|
||||
BoundedMailboxTypes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ class ActorPathSpec extends WordSpec with Matchers {
|
|||
}
|
||||
|
||||
"have correct path elements" in {
|
||||
(RootActorPath(Address("akka.tcp", "mysys")) / "user" / "foo" / "bar").elements.toSeq should ===(Seq("user", "foo", "bar"))
|
||||
(RootActorPath(Address("akka.tcp", "mysys")) / "user" / "foo" / "bar").elements.toSeq should ===(
|
||||
Seq("user", "foo", "bar"))
|
||||
}
|
||||
|
||||
"create correct toStringWithoutAddress" in {
|
||||
|
|
@ -51,7 +52,8 @@ class ActorPathSpec extends WordSpec with Matchers {
|
|||
}
|
||||
|
||||
"validate path elements" in {
|
||||
intercept[InvalidActorNameException](ActorPath.validatePathElement("")).getMessage should include("must not be empty")
|
||||
intercept[InvalidActorNameException](ActorPath.validatePathElement("")).getMessage should include(
|
||||
"must not be empty")
|
||||
}
|
||||
|
||||
"create correct toStringWithAddress" in {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ object ActorRefSpec {
|
|||
class OuterActor(val inner: ActorRef) extends Actor {
|
||||
def receive = {
|
||||
case "self" => sender() ! self
|
||||
case x => inner forward x
|
||||
case x => inner.forward(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ object ActorRefSpec {
|
|||
|
||||
def receive = {
|
||||
case "self" => sender() ! self
|
||||
case x => inner forward x
|
||||
case x => inner.forward(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +112,8 @@ object ActorRefSpec {
|
|||
class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
||||
import akka.actor.ActorRefSpec._
|
||||
|
||||
def promiseIntercept(f: => Actor)(to: Promise[Actor]): Actor = try {
|
||||
def promiseIntercept(f: => Actor)(to: Promise[Actor]): Actor =
|
||||
try {
|
||||
val r = f
|
||||
to.success(r)
|
||||
r
|
||||
|
|
@ -139,7 +140,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
|
||||
def contextStackMustBeEmpty(): Unit = ActorCell.contextStack.get.headOption should ===(None)
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new Actor {
|
||||
|
|
@ -151,25 +152,25 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(promiseIntercept(new FailingOuterActor(actorOf(Props(new InnerActor))))(result))))
|
||||
wrap(
|
||||
result => actorOf(Props(promiseIntercept(new FailingOuterActor(actorOf(Props(new InnerActor))))(result))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept(new FailingInnerActor)(result)))))))
|
||||
wrap(
|
||||
result => actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept(new FailingInnerActor)(result)))))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(promiseIntercept(new FailingInheritingOuterActor(actorOf(Props(new InnerActor))))(result))))
|
||||
|
|
@ -178,34 +179,38 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 2) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 2).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new FailingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
actorOf(
|
||||
Props(new FailingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 2) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 2).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new FailingInheritingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
wrap(
|
||||
result =>
|
||||
actorOf(Props(new FailingInheritingOuterActor(
|
||||
actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 2) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 2).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new FailingInheritingOuterActor(actorOf(Props(promiseIntercept(new FailingInnerActor)(result)))))))
|
||||
actorOf(
|
||||
Props(new FailingInheritingOuterActor(actorOf(Props(promiseIntercept(new FailingInnerActor)(result)))))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new OuterActor(actorOf(Props(new InnerActor {
|
||||
|
|
@ -216,16 +221,17 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 2) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 2).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new FailingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
actorOf(
|
||||
Props(new FailingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result)))))))
|
||||
|
|
@ -234,19 +240,23 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
intercept[akka.actor.ActorInitializationException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept({ new InnerActor; new InnerActor })(result)))))))
|
||||
wrap(
|
||||
result =>
|
||||
actorOf(
|
||||
Props(new OuterActor(actorOf(Props(promiseIntercept({ new InnerActor; new InnerActor })(result)))))))
|
||||
}
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1) intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
(intercept[java.lang.IllegalStateException] {
|
||||
wrap(result =>
|
||||
actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept({ throw new IllegalStateException("Ur state be b0rked"); new InnerActor })(result)))))))
|
||||
actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept({
|
||||
throw new IllegalStateException("Ur state be b0rked"); new InnerActor
|
||||
})(result)))))))
|
||||
}).getMessage should ===("Ur state be b0rked")
|
||||
|
||||
contextStackMustBeEmpty()
|
||||
|
|
@ -254,7 +264,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
}
|
||||
|
||||
"insert its path in a ActorInitializationException" in {
|
||||
EventFilter[ActorInitializationException](occurrences = 1, pattern = "/user/failingActor:") intercept {
|
||||
EventFilter[ActorInitializationException](occurrences = 1, pattern = "/user/failingActor:").intercept {
|
||||
intercept[java.lang.IllegalStateException] {
|
||||
wrap(result =>
|
||||
system.actorOf(Props(promiseIntercept({
|
||||
|
|
@ -312,7 +322,8 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
|
||||
(intercept[java.lang.IllegalStateException] {
|
||||
in.readObject
|
||||
}).getMessage should ===("Trying to deserialize a serialized ActorRef without an ActorSystem in scope." +
|
||||
}).getMessage should ===(
|
||||
"Trying to deserialize a serialized ActorRef without an ActorSystem in scope." +
|
||||
" Use 'akka.serialization.JavaSerializer.currentSystem.withValue(system) { ... }'")
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +405,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
val a = system.actorOf(NonPublicClass.createProps())
|
||||
a.tell("pigdog", testActor)
|
||||
expectMsg("pigdog")
|
||||
system stop a
|
||||
system.stop(a)
|
||||
}
|
||||
|
||||
"stop when sent a poison pill" in {
|
||||
|
|
@ -426,8 +437,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
override val supervisorStrategy =
|
||||
OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 1 second)(List(classOf[Throwable]))
|
||||
|
||||
val ref = context.actorOf(
|
||||
Props(new Actor {
|
||||
val ref = context.actorOf(Props(new Actor {
|
||||
def receive = { case _ => }
|
||||
override def preRestart(reason: Throwable, msg: Option[Any]) = latch.countDown()
|
||||
override def postRestart(reason: Throwable) = latch.countDown()
|
||||
|
|
@ -444,8 +454,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout {
|
|||
"be able to check for existence of children" in {
|
||||
val parent = system.actorOf(Props(new Actor {
|
||||
|
||||
val child = context.actorOf(
|
||||
Props(new Actor {
|
||||
val child = context.actorOf(Props(new Actor {
|
||||
def receive = { case _ => }
|
||||
}), "child")
|
||||
|
||||
|
|
|
|||
|
|
@ -66,9 +66,8 @@ class ActorSelectionSpec extends AkkaSpec with DefaultTimeout {
|
|||
asked.correlationId should ===(selection)
|
||||
|
||||
implicit val ec = system.dispatcher
|
||||
val resolved = Await.result(
|
||||
selection.resolveOne(timeout.duration).mapTo[ActorRef] recover { case _ => null },
|
||||
timeout.duration)
|
||||
val resolved =
|
||||
Await.result(selection.resolveOne(timeout.duration).mapTo[ActorRef].recover { case _ => null }, timeout.duration)
|
||||
Option(resolved) should ===(result)
|
||||
|
||||
result
|
||||
|
|
@ -93,11 +92,11 @@ class ActorSelectionSpec extends AkkaSpec with DefaultTimeout {
|
|||
identify(system / "c1") should ===(Some(c1))
|
||||
identify(system / "c2") should ===(Some(c2))
|
||||
identify(system / "c2" / "c21") should ===(Some(c21))
|
||||
identify(system child "c2" child "c21") should ===(Some(c21)) // test Java API
|
||||
identify(system.child("c2").child("c21")) should ===(Some(c21)) // test Java API
|
||||
identify(system / Seq("c2", "c21")) should ===(Some(c21))
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
identify(system descendant Seq("c2", "c21").asJava) // test Java API
|
||||
identify(system.descendant(Seq("c2", "c21").asJava)) // test Java API
|
||||
}
|
||||
|
||||
"select actors by their string path representation" in {
|
||||
|
|
@ -218,8 +217,8 @@ class ActorSelectionSpec extends AkkaSpec with DefaultTimeout {
|
|||
|
||||
"select actors by their relative path" in {
|
||||
def check(looker: ActorRef, result: ActorRef, elems: String*): Unit = {
|
||||
askNode(looker, SelectString(elems mkString "/")) should ===(Some(result))
|
||||
askNode(looker, SelectString(elems mkString ("", "/", "/"))) should ===(Some(result))
|
||||
askNode(looker, SelectString(elems.mkString("/"))) should ===(Some(result))
|
||||
askNode(looker, SelectString(elems.mkString("", "/", "/"))) should ===(Some(result))
|
||||
}
|
||||
check(c1, user, "..")
|
||||
for {
|
||||
|
|
@ -253,13 +252,11 @@ class ActorSelectionSpec extends AkkaSpec with DefaultTimeout {
|
|||
}
|
||||
def check(looker: ActorRef): Unit = {
|
||||
val lookname = looker.path.elements.mkString("", "/", "/")
|
||||
for (
|
||||
(l, r) <- Seq(
|
||||
SelectString("a/b/c") -> None,
|
||||
for ((l, r) <- Seq(SelectString("a/b/c") -> None,
|
||||
SelectString("akka://all-systems/Nobody") -> None,
|
||||
SelectPath(system / "hallo") -> None,
|
||||
SelectPath(looker.path child "hallo") -> None, // test Java API
|
||||
SelectPath(looker.path descendant Seq("a", "b").asJava) -> None) // test Java API
|
||||
SelectPath(looker.path.child("hallo")) -> None, // test Java API
|
||||
SelectPath(looker.path.descendant(Seq("a", "b").asJava)) -> None) // test Java API
|
||||
) checkOne(looker, l, r)
|
||||
}
|
||||
for (looker <- all) check(looker)
|
||||
|
|
@ -341,7 +338,8 @@ class ActorSelectionSpec extends AkkaSpec with DefaultTimeout {
|
|||
|
||||
"have a stringly serializable path" in {
|
||||
system.actorSelection(system / "c2").toSerializationFormat should ===("akka://ActorSelectionSpec/user/c2")
|
||||
system.actorSelection(system / "c2" / "c21").toSerializationFormat should ===("akka://ActorSelectionSpec/user/c2/c21")
|
||||
system.actorSelection(system / "c2" / "c21").toSerializationFormat should ===(
|
||||
"akka://ActorSelectionSpec/user/c2/c21")
|
||||
ActorSelection(c2, "/").toSerializationFormat should ===("akka://ActorSelectionSpec/user/c2")
|
||||
ActorSelection(c2, "../*/hello").toSerializationFormat should ===("akka://ActorSelectionSpec/user/c2/../*/hello")
|
||||
ActorSelection(c2, "/../*/hello").toSerializationFormat should ===("akka://ActorSelectionSpec/user/c2/../*/hello")
|
||||
|
|
@ -368,7 +366,8 @@ class ActorSelectionSpec extends AkkaSpec with DefaultTimeout {
|
|||
|
||||
val probe = TestProbe()
|
||||
system.actorSelection("/user/a/*").tell(Identify(1), probe.ref)
|
||||
probe.receiveN(2).map { case ActorIdentity(1, r) => r }.toSet should ===(Set[Option[ActorRef]](Some(b1), Some(b2)))
|
||||
probe.receiveN(2).map { case ActorIdentity(1, r) => r }.toSet should ===(
|
||||
Set[Option[ActorRef]](Some(b1), Some(b2)))
|
||||
probe.expectNoMsg(200.millis)
|
||||
|
||||
system.actorSelection("/user/a/b1/*").tell(Identify(2), probe.ref)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ object ActorSystemSpec {
|
|||
terminaters -= child
|
||||
if (terminaters.isEmpty) {
|
||||
master ! "done"
|
||||
context stop self
|
||||
context.stop(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ object ActorSystemSpec {
|
|||
if (master ne null) {
|
||||
master ! "failed with " + cause + " while processing " + msg
|
||||
}
|
||||
context stop self
|
||||
context.stop(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,16 +73,18 @@ object ActorSystemSpec {
|
|||
}
|
||||
}
|
||||
|
||||
class SlowDispatcher(_config: Config, _prerequisites: DispatcherPrerequisites) extends MessageDispatcherConfigurator(_config, _prerequisites) {
|
||||
private val instance = new Dispatcher(
|
||||
this,
|
||||
class SlowDispatcher(_config: Config, _prerequisites: DispatcherPrerequisites)
|
||||
extends MessageDispatcherConfigurator(_config, _prerequisites) {
|
||||
private val instance = new Dispatcher(this,
|
||||
config.getString("id"),
|
||||
config.getInt("throughput"),
|
||||
config.getNanosDuration("throughput-deadline-time"),
|
||||
configureExecutor(),
|
||||
config.getMillisDuration("shutdown-timeout")) {
|
||||
val doneIt = new Switch
|
||||
override protected[akka] def registerForExecution(mbox: Mailbox, hasMessageHint: Boolean, hasSystemMessageHint: Boolean): Boolean = {
|
||||
override protected[akka] def registerForExecution(mbox: Mailbox,
|
||||
hasMessageHint: Boolean,
|
||||
hasSystemMessageHint: Boolean): Boolean = {
|
||||
val ret = super.registerForExecution(mbox, hasMessageHint, hasSystemMessageHint)
|
||||
doneIt.switchOn {
|
||||
TestKit.awaitCond(mbox.actor.actor != null, 1.second)
|
||||
|
|
@ -127,21 +129,19 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
"An ActorSystem" must {
|
||||
|
||||
"use scala.concurrent.Future's InternalCallbackEC" in {
|
||||
system.asInstanceOf[ActorSystemImpl].internalCallingThreadExecutionContext.getClass.getName should ===("scala.concurrent.Future$InternalCallbackExecutor$")
|
||||
system.asInstanceOf[ActorSystemImpl].internalCallingThreadExecutionContext.getClass.getName should ===(
|
||||
"scala.concurrent.Future$InternalCallbackExecutor$")
|
||||
}
|
||||
|
||||
"reject invalid names" in {
|
||||
for (
|
||||
n <- Seq(
|
||||
"-hallowelt",
|
||||
for (n <- Seq("-hallowelt",
|
||||
"_hallowelt",
|
||||
"hallo*welt",
|
||||
"hallo@welt",
|
||||
"hallo#welt",
|
||||
"hallo$welt",
|
||||
"hallo%welt",
|
||||
"hallo/welt")
|
||||
) intercept[IllegalArgumentException] {
|
||||
"hallo/welt")) intercept[IllegalArgumentException] {
|
||||
ActorSystem(n)
|
||||
}
|
||||
}
|
||||
|
|
@ -151,15 +151,21 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
}
|
||||
|
||||
"log dead letters" in {
|
||||
val sys = ActorSystem("LogDeadLetters", ConfigFactory.parseString("akka.loglevel=INFO").withFallback(AkkaSpec.testConf))
|
||||
val sys =
|
||||
ActorSystem("LogDeadLetters", ConfigFactory.parseString("akka.loglevel=INFO").withFallback(AkkaSpec.testConf))
|
||||
try {
|
||||
val probe = TestProbe()(sys)
|
||||
val a = sys.actorOf(Props[ActorSystemSpec.Terminater])
|
||||
probe.watch(a)
|
||||
a.tell("run", probe.ref)
|
||||
probe.expectTerminated(a)
|
||||
EventFilter.info(pattern = """from Actor\[akka://LogDeadLetters/system/testProbe.*not delivered""", occurrences = 1).intercept {
|
||||
EventFilter.warning(pattern = """received dead letter from Actor\[akka://LogDeadLetters/system/testProbe""", occurrences = 1).intercept {
|
||||
EventFilter
|
||||
.info(pattern = """from Actor\[akka://LogDeadLetters/system/testProbe.*not delivered""", occurrences = 1)
|
||||
.intercept {
|
||||
EventFilter
|
||||
.warning(pattern = """received dead letter from Actor\[akka://LogDeadLetters/system/testProbe""",
|
||||
occurrences = 1)
|
||||
.intercept {
|
||||
a.tell("boom", probe.ref)
|
||||
}(sys)
|
||||
}(sys)
|
||||
|
|
@ -168,15 +174,20 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
}
|
||||
|
||||
"log dead letters sent without sender reference" in {
|
||||
val sys = ActorSystem("LogDeadLetters", ConfigFactory.parseString("akka.loglevel=INFO").withFallback(AkkaSpec.testConf))
|
||||
val sys =
|
||||
ActorSystem("LogDeadLetters", ConfigFactory.parseString("akka.loglevel=INFO").withFallback(AkkaSpec.testConf))
|
||||
try {
|
||||
val probe = TestProbe()(sys)
|
||||
val a = sys.actorOf(Props[ActorSystemSpec.Terminater])
|
||||
probe.watch(a)
|
||||
a.tell("run", probe.ref)
|
||||
probe.expectTerminated(a)
|
||||
EventFilter.info(pattern = "without sender.*not delivered", occurrences = 1).intercept {
|
||||
EventFilter.warning(pattern = "received dead letter without sender", occurrences = 1).intercept {
|
||||
EventFilter
|
||||
.info(pattern = "without sender.*not delivered", occurrences = 1)
|
||||
.intercept {
|
||||
EventFilter
|
||||
.warning(pattern = "received dead letter without sender", occurrences = 1)
|
||||
.intercept {
|
||||
a.tell("boom", ActorRef.noSender)
|
||||
}(sys)
|
||||
}(sys)
|
||||
|
|
@ -193,7 +204,7 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
for (i <- 1 to count) {
|
||||
system2.registerOnTermination {
|
||||
Thread.sleep((i % 3).millis.dilated.toMillis)
|
||||
result add i
|
||||
result.add(i)
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +243,7 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
terminated.actor should ===(system.provider.rootGuardian)
|
||||
terminated.addressTerminated should ===(true)
|
||||
terminated.existenceConfirmed should ===(true)
|
||||
terminated should be theSameInstanceAs Await.result(f, 10 seconds)
|
||||
(terminated should be).theSameInstanceAs(Await.result(f, 10 seconds))
|
||||
}
|
||||
|
||||
"throw RejectedExecutionException when shutdown" in {
|
||||
|
|
@ -295,21 +306,24 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
}
|
||||
}
|
||||
|
||||
created filter (ref => !ref.isTerminated && !ref.asInstanceOf[ActorRefWithCell].underlying.isInstanceOf[UnstartedCell]) should ===(Seq.empty[ActorRef])
|
||||
created.filter(ref =>
|
||||
!ref.isTerminated && !ref.asInstanceOf[ActorRefWithCell].underlying.isInstanceOf[UnstartedCell]) should ===(
|
||||
Seq.empty[ActorRef])
|
||||
}
|
||||
|
||||
"shut down when /user fails" in {
|
||||
implicit val system = ActorSystem("Stop", AkkaSpec.testConf)
|
||||
EventFilter[ActorKilledException]() intercept {
|
||||
EventFilter[ActorKilledException]().intercept {
|
||||
system.actorSelection("/user") ! Kill
|
||||
Await.ready(system.whenTerminated, Duration.Inf)
|
||||
}
|
||||
}
|
||||
|
||||
"allow configuration of guardian supervisor strategy" in {
|
||||
implicit val system = ActorSystem(
|
||||
"Stop",
|
||||
ConfigFactory.parseString("akka.actor.guardian-supervisor-strategy=akka.actor.StoppingSupervisorStrategy")
|
||||
implicit val system =
|
||||
ActorSystem("Stop",
|
||||
ConfigFactory
|
||||
.parseString("akka.actor.guardian-supervisor-strategy=akka.actor.StoppingSupervisorStrategy")
|
||||
.withFallback(AkkaSpec.testConf))
|
||||
val a = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
|
|
@ -318,7 +332,7 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
}))
|
||||
val probe = TestProbe()
|
||||
probe.watch(a)
|
||||
EventFilter[Exception]("hello", occurrences = 1) intercept {
|
||||
EventFilter[Exception]("hello", occurrences = 1).intercept {
|
||||
a ! "die"
|
||||
}
|
||||
val t = probe.expectMsg(Terminated(a)(existenceConfirmed = true, addressTerminated = false))
|
||||
|
|
@ -328,16 +342,17 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
}
|
||||
|
||||
"shut down when /user escalates" in {
|
||||
implicit val system = ActorSystem(
|
||||
"Stop",
|
||||
ConfigFactory.parseString("akka.actor.guardian-supervisor-strategy=\"akka.actor.ActorSystemSpec$Strategy\"")
|
||||
implicit val system =
|
||||
ActorSystem("Stop",
|
||||
ConfigFactory
|
||||
.parseString("akka.actor.guardian-supervisor-strategy=\"akka.actor.ActorSystemSpec$Strategy\"")
|
||||
.withFallback(AkkaSpec.testConf))
|
||||
val a = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "die" => throw new Exception("hello")
|
||||
}
|
||||
}))
|
||||
EventFilter[Exception]("hello") intercept {
|
||||
EventFilter[Exception]("hello").intercept {
|
||||
a ! "die"
|
||||
Await.ready(system.whenTerminated, Duration.Inf)
|
||||
}
|
||||
|
|
@ -388,8 +403,12 @@ class ActorSystemSpec extends AkkaSpec(ActorSystemSpec.config) with ImplicitSend
|
|||
}
|
||||
|
||||
"not allow top-level actor creation with custom guardian" in {
|
||||
val sys = new ActorSystemImpl("custom", ConfigFactory.defaultReference(),
|
||||
getClass.getClassLoader, None, Some(Props.empty), ActorSystemSetup.empty)
|
||||
val sys = new ActorSystemImpl("custom",
|
||||
ConfigFactory.defaultReference(),
|
||||
getClass.getClassLoader,
|
||||
None,
|
||||
Some(Props.empty),
|
||||
ActorSystemSetup.empty)
|
||||
sys.start()
|
||||
try {
|
||||
intercept[UnsupportedOperationException] {
|
||||
|
|
|
|||
|
|
@ -40,11 +40,13 @@ object ActorWithBoundedStashSpec {
|
|||
def receive = {
|
||||
case msg: String if msg.startsWith("hello") =>
|
||||
numStashed += 1
|
||||
try { stash(); sender() ! "ok" } catch {
|
||||
try {
|
||||
stash(); sender() ! "ok"
|
||||
} catch {
|
||||
case _: StashOverflowException =>
|
||||
if (numStashed == 21) {
|
||||
sender() ! "STASHOVERFLOW"
|
||||
context stop self
|
||||
context.stop(self)
|
||||
} else {
|
||||
sender() ! "Unexpected StashOverflowException: " + numStashed
|
||||
}
|
||||
|
|
@ -82,7 +84,11 @@ object ActorWithBoundedStashSpec {
|
|||
""")
|
||||
}
|
||||
|
||||
class ActorWithBoundedStashSpec extends AkkaSpec(ActorWithBoundedStashSpec.testConf) with BeforeAndAfterEach with DefaultTimeout with ImplicitSender {
|
||||
class ActorWithBoundedStashSpec
|
||||
extends AkkaSpec(ActorWithBoundedStashSpec.testConf)
|
||||
with BeforeAndAfterEach
|
||||
with DefaultTimeout
|
||||
with ImplicitSender {
|
||||
import ActorWithBoundedStashSpec._
|
||||
|
||||
override def atStartup: Unit = {
|
||||
|
|
|
|||
|
|
@ -142,8 +142,9 @@ class ActorWithStashSpec extends AkkaSpec(ActorWithStashSpec.testConf) with Defa
|
|||
}
|
||||
|
||||
"process stashed messages after restart" in {
|
||||
val boss = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 1 second)(List(classOf[Throwable])))))
|
||||
val boss = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 1 second)(List(classOf[Throwable])))))
|
||||
|
||||
val restartLatch = new TestLatch
|
||||
val hasMsgLatch = new TestLatch
|
||||
|
|
@ -196,7 +197,7 @@ class ActorWithStashSpec extends AkkaSpec(ActorWithStashSpec.testConf) with Defa
|
|||
testActor ! "restarted"
|
||||
}
|
||||
})
|
||||
EventFilter[RuntimeException]("dying", occurrences = 1) intercept {
|
||||
EventFilter[RuntimeException]("dying", occurrences = 1).intercept {
|
||||
a ! "die"
|
||||
}
|
||||
expectMsg("restarted")
|
||||
|
|
|
|||
|
|
@ -47,19 +47,22 @@ object Chameneos {
|
|||
}
|
||||
|
||||
def complement(otherColour: Colour): Colour = colour match {
|
||||
case RED => otherColour match {
|
||||
case RED =>
|
||||
otherColour match {
|
||||
case RED => RED
|
||||
case YELLOW => BLUE
|
||||
case BLUE => YELLOW
|
||||
case FADED => FADED
|
||||
}
|
||||
case YELLOW => otherColour match {
|
||||
case YELLOW =>
|
||||
otherColour match {
|
||||
case RED => BLUE
|
||||
case YELLOW => YELLOW
|
||||
case BLUE => RED
|
||||
case FADED => FADED
|
||||
}
|
||||
case BLUE => otherColour match {
|
||||
case BLUE =>
|
||||
otherColour match {
|
||||
case RED => YELLOW
|
||||
case YELLOW => RED
|
||||
case BLUE => BLUE
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ object ConsistencySpec {
|
|||
var lastStep = -1L
|
||||
def receive = {
|
||||
case step: Long =>
|
||||
|
||||
if (lastStep != (step - 1))
|
||||
sender() ! "Test failed: Last step %s, this step %s".format(lastStep, step)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import scala.collection.JavaConverters._
|
|||
import scala.concurrent.Promise
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
||||
"""
|
||||
class CoordinatedShutdownSpec
|
||||
extends AkkaSpec(ConfigFactory.parseString("""
|
||||
akka.loglevel=INFO
|
||||
akka.loggers = ["akka.testkit.TestEventListener"]
|
||||
""")) {
|
||||
|
|
@ -38,7 +38,8 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
phases.get(phase) match {
|
||||
case Some(Phase(dependsOn, _, _, _)) =>
|
||||
dependsOn.foreach { depPhase =>
|
||||
withClue(s"phase [$phase] depends on [$depPhase] but was ordered before it in topological sort result $result") {
|
||||
withClue(
|
||||
s"phase [$phase] depends on [$depPhase] but was ordered before it in topological sort result $result") {
|
||||
i should be > result.indexOf(depPhase)
|
||||
}
|
||||
}
|
||||
|
|
@ -55,38 +56,29 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
"sort phases in topological order" in {
|
||||
checkTopologicalSort(Map.empty) should ===(Nil)
|
||||
|
||||
checkTopologicalSort(Map(
|
||||
"a" -> emptyPhase)) should ===(List("a"))
|
||||
checkTopologicalSort(Map("a" -> emptyPhase)) should ===(List("a"))
|
||||
|
||||
checkTopologicalSort(Map(
|
||||
"b" -> phase("a"))) should ===(List("a", "b"))
|
||||
checkTopologicalSort(Map("b" -> phase("a"))) should ===(List("a", "b"))
|
||||
|
||||
val result1 = checkTopologicalSort(Map(
|
||||
"c" -> phase("a"), "b" -> phase("a")))
|
||||
val result1 = checkTopologicalSort(Map("c" -> phase("a"), "b" -> phase("a")))
|
||||
result1.head should ===("a")
|
||||
// b, c can be in any order
|
||||
result1.toSet should ===(Set("a", "b", "c"))
|
||||
|
||||
checkTopologicalSort(Map(
|
||||
"b" -> phase("a"), "c" -> phase("b"))) should ===(List("a", "b", "c"))
|
||||
checkTopologicalSort(Map("b" -> phase("a"), "c" -> phase("b"))) should ===(List("a", "b", "c"))
|
||||
|
||||
checkTopologicalSort(Map(
|
||||
"b" -> phase("a"), "c" -> phase("a", "b"))) should ===(List("a", "b", "c"))
|
||||
checkTopologicalSort(Map("b" -> phase("a"), "c" -> phase("a", "b"))) should ===(List("a", "b", "c"))
|
||||
|
||||
val result2 = checkTopologicalSort(Map(
|
||||
"c" -> phase("a", "b")))
|
||||
val result2 = checkTopologicalSort(Map("c" -> phase("a", "b")))
|
||||
result2.last should ===("c")
|
||||
// a, b can be in any order
|
||||
result2.toSet should ===(Set("a", "b", "c"))
|
||||
|
||||
checkTopologicalSort(Map(
|
||||
"b" -> phase("a"), "c" -> phase("b"), "d" -> phase("b", "c"),
|
||||
"e" -> phase("d"))) should ===(
|
||||
checkTopologicalSort(Map("b" -> phase("a"), "c" -> phase("b"), "d" -> phase("b", "c"), "e" -> phase("d"))) should ===(
|
||||
List("a", "b", "c", "d", "e"))
|
||||
|
||||
val result3 = checkTopologicalSort(Map(
|
||||
"a2" -> phase("a1"), "a3" -> phase("a2"),
|
||||
"b2" -> phase("b1"), "b3" -> phase("b2")))
|
||||
val result3 =
|
||||
checkTopologicalSort(Map("a2" -> phase("a1"), "a3" -> phase("a2"), "b2" -> phase("b1"), "b3" -> phase("b2")))
|
||||
val (a, b) = result3.partition(_.charAt(0) == 'a')
|
||||
a should ===(List("a1", "a2", "a3"))
|
||||
b should ===(List("b1", "b2", "b3"))
|
||||
|
|
@ -94,31 +86,28 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"detect cycles in phases (non-DAG)" in {
|
||||
intercept[IllegalArgumentException] {
|
||||
CoordinatedShutdown.topologicalSort(Map(
|
||||
"a" -> phase("a")))
|
||||
CoordinatedShutdown.topologicalSort(Map("a" -> phase("a")))
|
||||
}
|
||||
|
||||
intercept[IllegalArgumentException] {
|
||||
CoordinatedShutdown.topologicalSort(Map(
|
||||
"b" -> phase("a"), "a" -> phase("b")))
|
||||
CoordinatedShutdown.topologicalSort(Map("b" -> phase("a"), "a" -> phase("b")))
|
||||
}
|
||||
|
||||
intercept[IllegalArgumentException] {
|
||||
CoordinatedShutdown.topologicalSort(Map(
|
||||
"c" -> phase("a"), "c" -> phase("b"), "b" -> phase("c")))
|
||||
CoordinatedShutdown.topologicalSort(Map("c" -> phase("a"), "c" -> phase("b"), "b" -> phase("c")))
|
||||
}
|
||||
|
||||
intercept[IllegalArgumentException] {
|
||||
CoordinatedShutdown.topologicalSort(Map(
|
||||
"d" -> phase("a"), "d" -> phase("c"), "c" -> phase("b"), "b" -> phase("d")))
|
||||
CoordinatedShutdown.topologicalSort(
|
||||
Map("d" -> phase("a"), "d" -> phase("c"), "c" -> phase("b"), "b" -> phase("d")))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"have pre-defined phases from config" in {
|
||||
import CoordinatedShutdown._
|
||||
CoordinatedShutdown(system).orderedPhases should ===(List(
|
||||
PhaseBeforeServiceUnbind,
|
||||
CoordinatedShutdown(system).orderedPhases should ===(
|
||||
List(PhaseBeforeServiceUnbind,
|
||||
PhaseServiceUnbind,
|
||||
PhaseServiceRequestsDone,
|
||||
PhaseServiceStop,
|
||||
|
|
@ -134,10 +123,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"run ordered phases" in {
|
||||
import system.dispatcher
|
||||
val phases = Map(
|
||||
"a" -> emptyPhase,
|
||||
"b" -> phase("a"),
|
||||
"c" -> phase("b", "a"))
|
||||
val phases = Map("a" -> emptyPhase, "b" -> phase("a"), "c" -> phase("b", "a"))
|
||||
val co = new CoordinatedShutdown(extSys, phases)
|
||||
co.addTask("a", "a1") { () =>
|
||||
testActor ! "A"
|
||||
|
|
@ -164,10 +150,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
}
|
||||
|
||||
"run from a given phase" in {
|
||||
val phases = Map(
|
||||
"a" -> emptyPhase,
|
||||
"b" -> phase("a"),
|
||||
"c" -> phase("b", "a"))
|
||||
val phases = Map("a" -> emptyPhase, "b" -> phase("a"), "c" -> phase("b", "a"))
|
||||
val co = new CoordinatedShutdown(extSys, phases)
|
||||
co.addTask("a", "a1") { () =>
|
||||
testActor ! "A"
|
||||
|
|
@ -205,8 +188,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"continue after timeout or failure" in {
|
||||
import system.dispatcher
|
||||
val phases = Map(
|
||||
"a" -> emptyPhase,
|
||||
val phases = Map("a" -> emptyPhase,
|
||||
"b" -> Phase(dependsOn = Set("a"), timeout = 100.millis, recover = true, enabled = true),
|
||||
"c" -> phase("b", "a"))
|
||||
val co = new CoordinatedShutdown(extSys, phases)
|
||||
|
|
@ -231,7 +213,9 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
Future.successful(Done)
|
||||
}
|
||||
EventFilter.warning(message = "Task [a1] failed in phase [a]: boom", occurrences = 1).intercept {
|
||||
EventFilter.warning(message = "Coordinated shutdown phase [b] timed out after 100 milliseconds", occurrences = 1).intercept {
|
||||
EventFilter
|
||||
.warning(message = "Coordinated shutdown phase [b] timed out after 100 milliseconds", occurrences = 1)
|
||||
.intercept {
|
||||
Await.result(co.run(UnknownReason), remainingOrDefault)
|
||||
}
|
||||
}
|
||||
|
|
@ -242,8 +226,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
}
|
||||
|
||||
"abort if recover=off" in {
|
||||
val phases = Map(
|
||||
"a" -> emptyPhase,
|
||||
val phases = Map("a" -> emptyPhase,
|
||||
"b" -> Phase(dependsOn = Set("a"), timeout = 100.millis, recover = false, enabled = true),
|
||||
"c" -> phase("b", "a"))
|
||||
val co = new CoordinatedShutdown(extSys, phases)
|
||||
|
|
@ -264,8 +247,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
}
|
||||
|
||||
"skip tasks in disabled phase" in {
|
||||
val phases = Map(
|
||||
"a" -> emptyPhase,
|
||||
val phases = Map("a" -> emptyPhase,
|
||||
"b" -> Phase(dependsOn = Set("a"), timeout = 100.millis, recover = false, enabled = false),
|
||||
"c" -> phase("b", "a"))
|
||||
val co = new CoordinatedShutdown(extSys, phases)
|
||||
|
|
@ -285,9 +267,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
}
|
||||
|
||||
"be possible to add tasks in later phase from task in earlier phase" in {
|
||||
val phases = Map(
|
||||
"a" -> emptyPhase,
|
||||
"b" -> phase("a"))
|
||||
val phases = Map("a" -> emptyPhase, "b" -> phase("a"))
|
||||
val co = new CoordinatedShutdown(extSys, phases)
|
||||
co.addTask("a", "a1") { () =>
|
||||
testActor ! "A"
|
||||
|
|
@ -303,8 +283,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
}
|
||||
|
||||
"parse phases from config" in {
|
||||
CoordinatedShutdown.phasesFromConfig(ConfigFactory.parseString(
|
||||
"""
|
||||
CoordinatedShutdown.phasesFromConfig(ConfigFactory.parseString("""
|
||||
default-phase-timeout = 10s
|
||||
phases {
|
||||
a = {}
|
||||
|
|
@ -317,8 +296,8 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
recover = off
|
||||
}
|
||||
}
|
||||
""")) should ===(Map(
|
||||
"a" -> Phase(dependsOn = Set.empty, timeout = 10.seconds, recover = true, enabled = true),
|
||||
""")) should ===(
|
||||
Map("a" -> Phase(dependsOn = Set.empty, timeout = 10.seconds, recover = true, enabled = true),
|
||||
"b" -> Phase(dependsOn = Set("a"), timeout = 15.seconds, recover = true, enabled = true),
|
||||
"c" -> Phase(dependsOn = Set("a", "b"), timeout = 10.seconds, recover = false, enabled = true)))
|
||||
}
|
||||
|
|
@ -331,7 +310,8 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"default exit code to -1 when the Reason is ClusterDowning" in {
|
||||
lazy val conf = ConfigFactory.load().getConfig("akka.coordinated-shutdown")
|
||||
val confWithOverrides = CoordinatedShutdown.confWithOverrides(conf, Some(CoordinatedShutdown.ClusterDowningReason))
|
||||
val confWithOverrides =
|
||||
CoordinatedShutdown.confWithOverrides(conf, Some(CoordinatedShutdown.ClusterDowningReason))
|
||||
confWithOverrides.getInt("exit-code") should ===(-1)
|
||||
}
|
||||
|
||||
|
|
@ -344,16 +324,14 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"add and remove user JVM hooks with run-by-jvm-shutdown-hook = off, terminate-actor-system = off" in new JvmHookTest {
|
||||
lazy val systemName = s"CoordinatedShutdownSpec-JvmHooks-1-${System.currentTimeMillis()}"
|
||||
lazy val systemConfig = ConfigFactory.parseString(
|
||||
"""
|
||||
lazy val systemConfig = ConfigFactory.parseString("""
|
||||
akka.coordinated-shutdown.run-by-jvm-shutdown-hook = off
|
||||
akka.coordinated-shutdown.terminate-actor-system = off
|
||||
""")
|
||||
|
||||
override def withSystemRunning(newSystem: ActorSystem): Unit = {
|
||||
val cancellable = CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(
|
||||
println(s"User JVM hook from ${newSystem.name}")
|
||||
)
|
||||
val cancellable =
|
||||
CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(println(s"User JVM hook from ${newSystem.name}"))
|
||||
myHooksCount should ===(1) // one user, none from system
|
||||
cancellable.cancel()
|
||||
}
|
||||
|
|
@ -361,16 +339,14 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"add and remove user JVM hooks with run-by-jvm-shutdown-hook = on, terminate-actor-system = off" in new JvmHookTest {
|
||||
lazy val systemName = s"CoordinatedShutdownSpec-JvmHooks-2-${System.currentTimeMillis()}"
|
||||
lazy val systemConfig = ConfigFactory.parseString(
|
||||
"""
|
||||
lazy val systemConfig = ConfigFactory.parseString("""
|
||||
akka.coordinated-shutdown.run-by-jvm-shutdown-hook = on
|
||||
akka.coordinated-shutdown.terminate-actor-system = off
|
||||
""")
|
||||
|
||||
override def withSystemRunning(newSystem: ActorSystem): Unit = {
|
||||
val cancellable = CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(
|
||||
println(s"User JVM hook from ${newSystem.name}")
|
||||
)
|
||||
val cancellable =
|
||||
CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(println(s"User JVM hook from ${newSystem.name}"))
|
||||
myHooksCount should ===(2) // one user, one from system
|
||||
|
||||
cancellable.cancel()
|
||||
|
|
@ -379,16 +355,14 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"add and remove user JVM hooks with run-by-jvm-shutdown-hook = on, terminate-actor-system = on" in new JvmHookTest {
|
||||
lazy val systemName = s"CoordinatedShutdownSpec-JvmHooks-3-${System.currentTimeMillis()}"
|
||||
lazy val systemConfig = ConfigFactory.parseString(
|
||||
"""
|
||||
lazy val systemConfig = ConfigFactory.parseString("""
|
||||
akka.coordinated-shutdown.run-by-jvm-shutdown-hook = on
|
||||
akka.coordinated-shutdown.terminate-actor-system = on
|
||||
""")
|
||||
|
||||
def withSystemRunning(newSystem: ActorSystem): Unit = {
|
||||
val cancellable = CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(
|
||||
println(s"User JVM hook from ${newSystem.name}")
|
||||
)
|
||||
val cancellable =
|
||||
CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(println(s"User JVM hook from ${newSystem.name}"))
|
||||
myHooksCount should ===(2) // one user, one from actor system
|
||||
cancellable.cancel()
|
||||
}
|
||||
|
|
@ -396,16 +370,14 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"add and remove user JVM hooks with run-by-jvm-shutdown-hook = on, akka.jvm-shutdown-hooks = off" in new JvmHookTest {
|
||||
lazy val systemName = s"CoordinatedShutdownSpec-JvmHooks-4-${System.currentTimeMillis()}"
|
||||
lazy val systemConfig = ConfigFactory.parseString(
|
||||
"""
|
||||
lazy val systemConfig = ConfigFactory.parseString("""
|
||||
akka.jvm-shutdown-hooks = off
|
||||
akka.coordinated-shutdown.run-by-jvm-shutdown-hook = on
|
||||
""")
|
||||
|
||||
def withSystemRunning(newSystem: ActorSystem): Unit = {
|
||||
val cancellable = CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(
|
||||
println(s"User JVM hook from ${newSystem.name}")
|
||||
)
|
||||
val cancellable =
|
||||
CoordinatedShutdown(newSystem).addCancellableJvmShutdownHook(println(s"User JVM hook from ${newSystem.name}"))
|
||||
myHooksCount should ===(1) // one user, none from actor system
|
||||
cancellable.cancel()
|
||||
}
|
||||
|
|
@ -413,8 +385,7 @@ class CoordinatedShutdownSpec extends AkkaSpec(ConfigFactory.parseString(
|
|||
|
||||
"access extension after system termination" in new JvmHookTest {
|
||||
lazy val systemName = s"CoordinatedShutdownSpec-terminated-${System.currentTimeMillis()}"
|
||||
lazy val systemConfig = ConfigFactory.parseString(
|
||||
"""
|
||||
lazy val systemConfig = ConfigFactory.parseString("""
|
||||
akka.coordinated-shutdown.run-by-jvm-shutdown-hook = on
|
||||
akka.coordinated-shutdown.terminate-actor-system = on
|
||||
""")
|
||||
|
|
|
|||
|
|
@ -78,4 +78,3 @@ class DeadLetterSupressionSpec extends AkkaSpec with ImplicitSender {
|
|||
allListener.expectNoMsg(Duration.Zero)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ object DeathWatchSpec {
|
|||
class Watcher(target: ActorRef, testActor: ActorRef) extends Actor {
|
||||
context.watch(target)
|
||||
def receive = {
|
||||
case t: Terminated => testActor forward WrappedTerminated(t)
|
||||
case x => testActor forward x
|
||||
case t: Terminated => testActor.forward(WrappedTerminated(t))
|
||||
case x => testActor.forward(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,9 +36,11 @@ object DeathWatchSpec {
|
|||
class NKOTBWatcher(testActor: ActorRef) extends Actor {
|
||||
def receive = {
|
||||
case "NKOTB" =>
|
||||
val currentKid = context.watch(context.actorOf(Props(new Actor { def receive = { case "NKOTB" => context stop self } }), "kid"))
|
||||
currentKid forward "NKOTB"
|
||||
context become {
|
||||
val currentKid = context.watch(context.actorOf(Props(new Actor {
|
||||
def receive = { case "NKOTB" => context.stop(self) }
|
||||
}), "kid"))
|
||||
currentKid.forward("NKOTB")
|
||||
context.become {
|
||||
case Terminated(`currentKid`) =>
|
||||
testActor ! "GREEN"
|
||||
context unbecome
|
||||
|
|
@ -48,8 +50,8 @@ object DeathWatchSpec {
|
|||
|
||||
class WUWatcher extends Actor {
|
||||
def receive = {
|
||||
case W(ref) => context watch ref
|
||||
case U(ref) => context unwatch ref
|
||||
case W(ref) => context.watch(ref)
|
||||
case U(ref) => context.unwatch(ref)
|
||||
case Latches(t1: TestLatch, t2: TestLatch) =>
|
||||
t1.countDown()
|
||||
Await.ready(t2, 3.seconds)
|
||||
|
|
@ -78,7 +80,8 @@ trait DeathWatchSpec { this: AkkaSpec with ImplicitSender with DefaultTimeout =>
|
|||
def startWatching(target: ActorRef) = Await.result((supervisor ? props(target, testActor)).mapTo[ActorRef], 3 seconds)
|
||||
|
||||
"The Death Watch" must {
|
||||
def expectTerminationOf(actorRef: ActorRef) = expectMsgPF(5 seconds, actorRef + ": Stopped or Already terminated when linking") {
|
||||
def expectTerminationOf(actorRef: ActorRef) =
|
||||
expectMsgPF(5 seconds, actorRef + ": Stopped or Already terminated when linking") {
|
||||
case WrappedTerminated(Terminated(`actorRef`)) => true
|
||||
}
|
||||
|
||||
|
|
@ -144,8 +147,8 @@ trait DeathWatchSpec { this: AkkaSpec with ImplicitSender with DefaultTimeout =>
|
|||
|
||||
"notify with a Terminated message once when an Actor is stopped but not when restarted" in {
|
||||
filterException[ActorKilledException] {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 2)(List(classOf[Exception])))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(new Supervisor(OneForOneStrategy(maxNrOfRetries = 2)(List(classOf[Exception])))))
|
||||
val terminalProps = TestActors.echoActorProps
|
||||
val terminal = Await.result((supervisor ? terminalProps).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
|
|
@ -166,7 +169,11 @@ trait DeathWatchSpec { this: AkkaSpec with ImplicitSender with DefaultTimeout =>
|
|||
"fail a monitor which does not handle Terminated()" in {
|
||||
filterEvents(EventFilter[ActorKilledException](), EventFilter[DeathPactException]()) {
|
||||
val strategy = new OneForOneStrategy()(SupervisorStrategy.defaultStrategy.decider) {
|
||||
override def handleFailure(context: ActorContext, child: ActorRef, cause: Throwable, stats: ChildRestartStats, children: Iterable[ChildRestartStats]) = {
|
||||
override def handleFailure(context: ActorContext,
|
||||
child: ActorRef,
|
||||
cause: Throwable,
|
||||
stats: ChildRestartStats,
|
||||
children: Iterable[ChildRestartStats]) = {
|
||||
testActor.tell(FF(Failed(child, cause, 0)), child)
|
||||
super.handleFailure(context, child, cause, stats, children)
|
||||
}
|
||||
|
|
@ -174,7 +181,8 @@ trait DeathWatchSpec { this: AkkaSpec with ImplicitSender with DefaultTimeout =>
|
|||
val supervisor = system.actorOf(Props(new Supervisor(strategy)).withDeploy(Deploy.local))
|
||||
|
||||
val failed = Await.result((supervisor ? Props.empty).mapTo[ActorRef], timeout.duration)
|
||||
val brother = Await.result((supervisor ? Props(classOf[EmptyWatcher], failed)).mapTo[ActorRef], timeout.duration)
|
||||
val brother =
|
||||
Await.result((supervisor ? Props(classOf[EmptyWatcher], failed)).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
startWatching(brother)
|
||||
|
||||
|
|
@ -201,7 +209,8 @@ trait DeathWatchSpec { this: AkkaSpec with ImplicitSender with DefaultTimeout =>
|
|||
"only notify when watching" in {
|
||||
val subject = system.actorOf(Props[EmptyActor]())
|
||||
|
||||
testActor.asInstanceOf[InternalActorRef]
|
||||
testActor
|
||||
.asInstanceOf[InternalActorRef]
|
||||
.sendSystemMessage(DeathWatchNotification(subject, existenceConfirmed = true, addressTerminated = false))
|
||||
|
||||
// the testActor is not watching subject and will not receive a Terminated msg
|
||||
|
|
@ -216,7 +225,7 @@ trait DeathWatchSpec { this: AkkaSpec with ImplicitSender with DefaultTimeout =>
|
|||
w ! Latches(t1, t2)
|
||||
Await.ready(t1, 3.seconds)
|
||||
watch(p.ref)
|
||||
system stop p.ref
|
||||
system.stop(p.ref)
|
||||
expectTerminated(p.ref)
|
||||
w ! U(p.ref)
|
||||
t2.countDown()
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ object DeployerSpec {
|
|||
router = round-robin-pool
|
||||
}
|
||||
}
|
||||
""", ConfigParseOptions.defaults)
|
||||
""",
|
||||
ConfigParseOptions.defaults)
|
||||
|
||||
class RecipeActor extends Actor {
|
||||
def receive = { case _ => }
|
||||
|
|
@ -82,9 +83,9 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
val service = "/service1"
|
||||
val deployment = system.asInstanceOf[ExtendedActorSystem].provider.deployer.lookup(service.split("/").drop(1))
|
||||
|
||||
deployment should ===(Some(
|
||||
Deploy(
|
||||
service,
|
||||
deployment should ===(
|
||||
Some(
|
||||
Deploy(service,
|
||||
deployment.get.config,
|
||||
NoRouter,
|
||||
NoScopeGiven,
|
||||
|
|
@ -102,9 +103,9 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
val service = "/service3"
|
||||
val deployment = system.asInstanceOf[ExtendedActorSystem].provider.deployer.lookup(service.split("/").drop(1))
|
||||
|
||||
deployment should ===(Some(
|
||||
Deploy(
|
||||
service,
|
||||
deployment should ===(
|
||||
Some(
|
||||
Deploy(service,
|
||||
deployment.get.config,
|
||||
NoRouter,
|
||||
NoScopeGiven,
|
||||
|
|
@ -116,9 +117,9 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
val service = "/service4"
|
||||
val deployment = system.asInstanceOf[ExtendedActorSystem].provider.deployer.lookup(service.split("/").drop(1))
|
||||
|
||||
deployment should ===(Some(
|
||||
Deploy(
|
||||
service,
|
||||
deployment should ===(
|
||||
Some(
|
||||
Deploy(service,
|
||||
deployment.get.config,
|
||||
NoRouter,
|
||||
NoScopeGiven,
|
||||
|
|
@ -128,14 +129,17 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
|
||||
"detect invalid number-of-instances" in {
|
||||
intercept[com.typesafe.config.ConfigException.WrongType] {
|
||||
val invalidDeployerConf = ConfigFactory.parseString("""
|
||||
val invalidDeployerConf = ConfigFactory
|
||||
.parseString("""
|
||||
akka.actor.deployment {
|
||||
/service-invalid-number-of-instances {
|
||||
router = round-robin-pool
|
||||
nr-of-instances = boom
|
||||
}
|
||||
}
|
||||
""", ConfigParseOptions.defaults).withFallback(AkkaSpec.testConf)
|
||||
""",
|
||||
ConfigParseOptions.defaults)
|
||||
.withFallback(AkkaSpec.testConf)
|
||||
|
||||
shutdown(ActorSystem("invalid-number-of-instances", invalidDeployerConf))
|
||||
}
|
||||
|
|
@ -143,14 +147,17 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
|
||||
"detect invalid deployment path" in {
|
||||
val e = intercept[InvalidActorNameException] {
|
||||
val invalidDeployerConf = ConfigFactory.parseString("""
|
||||
val invalidDeployerConf = ConfigFactory
|
||||
.parseString("""
|
||||
akka.actor.deployment {
|
||||
/gul/ubåt {
|
||||
router = round-robin-pool
|
||||
nr-of-instances = 2
|
||||
}
|
||||
}
|
||||
""", ConfigParseOptions.defaults).withFallback(AkkaSpec.testConf)
|
||||
""",
|
||||
ConfigParseOptions.defaults)
|
||||
.withFallback(AkkaSpec.testConf)
|
||||
|
||||
shutdown(ActorSystem("invalid-path", invalidDeployerConf))
|
||||
}
|
||||
|
|
@ -175,7 +182,9 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
}
|
||||
|
||||
"be able to parse 'akka.actor.deployment._' with scatter-gather router" in {
|
||||
assertRouting("/service-scatter-gather", ScatterGatherFirstCompletedPool(nrOfInstances = 1, within = 2 seconds), "/service-scatter-gather")
|
||||
assertRouting("/service-scatter-gather",
|
||||
ScatterGatherFirstCompletedPool(nrOfInstances = 1, within = 2 seconds),
|
||||
"/service-scatter-gather")
|
||||
}
|
||||
|
||||
"be able to parse 'akka.actor.deployment._' with consistent-hashing router" in {
|
||||
|
|
@ -189,7 +198,9 @@ class DeployerSpec extends AkkaSpec(DeployerSpec.deployerConf) {
|
|||
|
||||
"be able to use wildcards" in {
|
||||
assertRouting("/some/wildcardmatch", RandomPool(1), "/some/*")
|
||||
assertRouting("/somewildcardmatch/some", ScatterGatherFirstCompletedPool(nrOfInstances = 1, within = 2 seconds), "/*/some")
|
||||
assertRouting("/somewildcardmatch/some",
|
||||
ScatterGatherFirstCompletedPool(nrOfInstances = 1, within = 2 seconds),
|
||||
"/*/some")
|
||||
}
|
||||
|
||||
"be able to use double wildcards" in {
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ class ExtensionSpec extends WordSpec with Matchers {
|
|||
|
||||
"fail the actor system if an extension listed in akka.extensions fails to start" in {
|
||||
intercept[RuntimeException] {
|
||||
val system = ActorSystem("failing", ConfigFactory.parseString(
|
||||
"""
|
||||
val system = ActorSystem("failing",
|
||||
ConfigFactory.parseString("""
|
||||
akka.extensions = ["akka.actor.FailingTestExtension"]
|
||||
"""))
|
||||
|
||||
|
|
@ -94,8 +94,8 @@ class ExtensionSpec extends WordSpec with Matchers {
|
|||
}
|
||||
|
||||
"log an error if an extension listed in akka.extensions cannot be loaded" in {
|
||||
val system = ActorSystem("failing", ConfigFactory.parseString(
|
||||
"""
|
||||
val system = ActorSystem("failing",
|
||||
ConfigFactory.parseString("""
|
||||
akka.extensions = ["akka.actor.MissingExtension"]
|
||||
"""))
|
||||
EventFilter.error("While trying to load extension [akka.actor.MissingExtension], skipping.").intercept(())(system)
|
||||
|
|
@ -114,8 +114,8 @@ class ExtensionSpec extends WordSpec with Matchers {
|
|||
|
||||
"fail the actor system if a library-extension fails to start" in {
|
||||
intercept[FailingTestExtension.TestException] {
|
||||
ActorSystem("failing", ConfigFactory.parseString(
|
||||
"""
|
||||
ActorSystem("failing",
|
||||
ConfigFactory.parseString("""
|
||||
akka.library-extensions += "akka.actor.FailingTestExtension"
|
||||
""").withFallback(ConfigFactory.load()).resolve())
|
||||
}
|
||||
|
|
@ -124,8 +124,8 @@ class ExtensionSpec extends WordSpec with Matchers {
|
|||
|
||||
"fail the actor system if a library-extension cannot be loaded" in {
|
||||
intercept[RuntimeException] {
|
||||
ActorSystem("failing", ConfigFactory.parseString(
|
||||
"""
|
||||
ActorSystem("failing",
|
||||
ConfigFactory.parseString("""
|
||||
akka.library-extensions += "akka.actor.MissingExtension"
|
||||
""").withFallback(ConfigFactory.load()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,17 +42,17 @@ object FSMActorSpec {
|
|||
case Event(digit: Char, CodeState(soFar, code)) => {
|
||||
soFar + digit match {
|
||||
case incomplete if incomplete.length < code.length =>
|
||||
stay using CodeState(incomplete, code)
|
||||
stay.using(CodeState(incomplete, code))
|
||||
case codeTry if (codeTry == code) => {
|
||||
doUnlock()
|
||||
goto(Open) using CodeState("", code) forMax timeout
|
||||
goto(Open).using(CodeState("", code)).forMax(timeout)
|
||||
}
|
||||
case wrong => {
|
||||
stay using CodeState("", code)
|
||||
stay.using(CodeState("", code))
|
||||
}
|
||||
}
|
||||
}
|
||||
case Event("hello", _) => stay replying "world"
|
||||
case Event("hello", _) => stay.replying("world")
|
||||
case Event("bye", _) => stop(FSM.Shutdown)
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
|
||||
"unlock the lock" in {
|
||||
|
||||
import FSM.{ Transition, CurrentState, SubscribeTransitionCallBack }
|
||||
import FSM.{ CurrentState, SubscribeTransitionCallBack, Transition }
|
||||
|
||||
val latches = new Latches
|
||||
import latches._
|
||||
|
|
@ -138,7 +138,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
Await.ready(transitionCallBackLatch, timeout.duration)
|
||||
Await.ready(lockedLatch, timeout.duration)
|
||||
|
||||
EventFilter.warning(start = "unhandled event", occurrences = 1) intercept {
|
||||
EventFilter.warning(start = "unhandled event", occurrences = 1).intercept {
|
||||
lock ! "not_handled"
|
||||
Await.ready(unhandledLatch, timeout.duration)
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
}
|
||||
})
|
||||
val name = fsm.path.toString
|
||||
EventFilter.error("Next state 2 does not exist", occurrences = 1) intercept {
|
||||
EventFilter.error("Next state 2 does not exist", occurrences = 1).intercept {
|
||||
system.eventStream.subscribe(testActor, classOf[Logging.Error])
|
||||
fsm ! "go"
|
||||
expectMsgPF(1 second, hint = "Next state 2 does not exist") {
|
||||
|
|
@ -218,7 +218,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
lazy val fsmref = TestFSMRef(new Actor with FSM[String, Null] {
|
||||
startWith("not-started", null)
|
||||
when("not-started") {
|
||||
case Event("start", _) => goto("started") replying "starting"
|
||||
case Event("start", _) => goto("started").replying("starting")
|
||||
}
|
||||
when("started", stateTimeout = 10 seconds) {
|
||||
case Event("stop", _) => stop()
|
||||
|
|
@ -252,12 +252,15 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
|
||||
"log events and transitions if asked to do so" in {
|
||||
import scala.collection.JavaConverters._
|
||||
val config = ConfigFactory.parseMap(Map("akka.loglevel" -> "DEBUG", "akka.actor.serialize-messages" -> "off",
|
||||
"akka.actor.debug.fsm" -> true).asJava).withFallback(system.settings.config)
|
||||
val config = ConfigFactory
|
||||
.parseMap(Map("akka.loglevel" -> "DEBUG",
|
||||
"akka.actor.serialize-messages" -> "off",
|
||||
"akka.actor.debug.fsm" -> true).asJava)
|
||||
.withFallback(system.settings.config)
|
||||
val fsmEventSystem = ActorSystem("fsmEvent", config)
|
||||
try {
|
||||
new TestKit(fsmEventSystem) {
|
||||
EventFilter.debug(occurrences = 5) intercept {
|
||||
EventFilter.debug(occurrences = 5).intercept {
|
||||
val fsm = TestActorRef(new Actor with LoggingFSM[Int, Null] {
|
||||
startWith(1, null)
|
||||
when(1) {
|
||||
|
|
@ -279,13 +282,17 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
system.eventStream.subscribe(testActor, classOf[Logging.Debug])
|
||||
fsm ! "go"
|
||||
expectMsgPF(1 second, hint = "processing Event(go,null)") {
|
||||
case Logging.Debug(`name`, `fsmClass`, s: String) if s.startsWith("processing Event(go,null) from Actor[") => true
|
||||
case Logging.Debug(`name`, `fsmClass`, s: String)
|
||||
if s.startsWith("processing Event(go,null) from Actor[") =>
|
||||
true
|
||||
}
|
||||
expectMsg(1 second, Logging.Debug(name, fsmClass, "setting timer 't'/1500 milliseconds: Shutdown"))
|
||||
expectMsg(1 second, Logging.Debug(name, fsmClass, "transition 1 -> 2"))
|
||||
fsm ! "stop"
|
||||
expectMsgPF(1 second, hint = "processing Event(stop,null)") {
|
||||
case Logging.Debug(`name`, `fsmClass`, s: String) if s.startsWith("processing Event(stop,null) from Actor[") => true
|
||||
case Logging.Debug(`name`, `fsmClass`, s: String)
|
||||
if s.startsWith("processing Event(stop,null) from Actor[") =>
|
||||
true
|
||||
}
|
||||
expectMsgAllOf(1 second, Logging.Debug(name, fsmClass, "canceling timer 't'"), FSM.Normal)
|
||||
expectNoMsg(1 second)
|
||||
|
|
@ -302,8 +309,8 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
override def logDepth = 3
|
||||
startWith(1, 0)
|
||||
when(1) {
|
||||
case Event("count", c) => stay using (c + 1)
|
||||
case Event("log", _) => stay replying getLog
|
||||
case Event("count", c) => stay.using(c + 1)
|
||||
case Event("log", _) => stay.replying(getLog)
|
||||
}
|
||||
})
|
||||
fsmref ! "log"
|
||||
|
|
@ -324,7 +331,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
startWith(0, 0)
|
||||
when(0)(transform {
|
||||
case Event("go", _) => stay
|
||||
} using {
|
||||
}.using {
|
||||
case x => goto(1)
|
||||
})
|
||||
when(1) {
|
||||
|
|
@ -354,7 +361,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
|
|||
|
||||
case Event(OverrideTimeoutToInf, _) =>
|
||||
p.ref ! OverrideTimeoutToInf
|
||||
stay() forMax Duration.Inf
|
||||
stay().forMax(Duration.Inf)
|
||||
}
|
||||
|
||||
initialize()
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ class FSMTimingSpec extends AkkaSpec with ImplicitSender {
|
|||
expectMsg(500 millis, Tick)
|
||||
Thread.sleep(200) // this is ugly: need to wait for StateTimeout to be queued
|
||||
resume(fsm)
|
||||
expectMsg(500 millis, Transition(fsm, TestCancelStateTimerInNamedTimerMessage, TestCancelStateTimerInNamedTimerMessage2))
|
||||
expectMsg(500 millis,
|
||||
Transition(fsm, TestCancelStateTimerInNamedTimerMessage, TestCancelStateTimerInNamedTimerMessage2))
|
||||
fsm ! Cancel
|
||||
within(500 millis) {
|
||||
expectMsg(Cancel) // if this is not received, that means StateTimeout was not properly discarded
|
||||
|
|
@ -122,7 +123,7 @@ class FSMTimingSpec extends AkkaSpec with ImplicitSender {
|
|||
val seq = receiveWhile(2 seconds) {
|
||||
case Tick => Tick
|
||||
}
|
||||
seq should have length 5
|
||||
(seq should have).length(5)
|
||||
within(500 millis) {
|
||||
expectMsg(Transition(fsm, TestRepeatedTimer, Initial))
|
||||
}
|
||||
|
|
@ -131,7 +132,9 @@ class FSMTimingSpec extends AkkaSpec with ImplicitSender {
|
|||
"notify unhandled messages" taggedAs TimingTest in {
|
||||
filterEvents(
|
||||
EventFilter.warning("unhandled event Tick in state TestUnhandled", source = fsm.path.toString, occurrences = 1),
|
||||
EventFilter.warning("unhandled event Unhandled(test) in state TestUnhandled", source = fsm.path.toString, occurrences = 1)) {
|
||||
EventFilter.warning("unhandled event Unhandled(test) in state TestUnhandled",
|
||||
source = fsm.path.toString,
|
||||
occurrences = 1)) {
|
||||
fsm ! TestUnhandled
|
||||
within(3 second) {
|
||||
fsm ! Tick
|
||||
|
|
@ -194,14 +197,14 @@ object FSMTimingSpec {
|
|||
goto(TestSingleTimer)
|
||||
case Event(TestRepeatedTimer, _) =>
|
||||
setTimer("tester", Tick, 100.millis.dilated, true)
|
||||
goto(TestRepeatedTimer) using 4
|
||||
goto(TestRepeatedTimer).using(4)
|
||||
case Event(TestStateTimeoutOverride, _) =>
|
||||
goto(TestStateTimeout) forMax (Duration.Inf)
|
||||
goto(TestStateTimeout).forMax(Duration.Inf)
|
||||
case Event(x: FSMTimingSpec.State, _) => goto(x)
|
||||
}
|
||||
when(TestStateTimeout, stateTimeout = 800.millis.dilated) {
|
||||
case Event(StateTimeout, _) => goto(Initial)
|
||||
case Event(Cancel, _) => goto(Initial) replying (Cancel)
|
||||
case Event(Cancel, _) => goto(Initial).replying(Cancel)
|
||||
}
|
||||
when(TestSingleTimer) {
|
||||
case Event(Tick, _) =>
|
||||
|
|
@ -242,7 +245,7 @@ object FSMTimingSpec {
|
|||
cancelTimer("tester")
|
||||
goto(Initial)
|
||||
} else {
|
||||
stay using (remaining - 1)
|
||||
stay.using(remaining - 1)
|
||||
}
|
||||
}
|
||||
when(TestCancelStateTimerInNamedTimerMessage) {
|
||||
|
|
@ -251,7 +254,7 @@ object FSMTimingSpec {
|
|||
suspend(self)
|
||||
setTimer("named", Tock, 1.millis.dilated)
|
||||
TestKit.awaitCond(context.asInstanceOf[ActorCell].mailbox.hasMessages, 1.second.dilated)
|
||||
stay forMax (1.millis.dilated) replying Tick
|
||||
stay.forMax(1.millis.dilated).replying(Tick)
|
||||
case Event(Tock, _) =>
|
||||
goto(TestCancelStateTimerInNamedTimerMessage2)
|
||||
}
|
||||
|
|
@ -259,7 +262,7 @@ object FSMTimingSpec {
|
|||
case Event(StateTimeout, _) =>
|
||||
goto(Initial)
|
||||
case Event(Cancel, _) =>
|
||||
goto(Initial) replying Cancel
|
||||
goto(Initial).replying(Cancel)
|
||||
}
|
||||
when(TestUnhandled) {
|
||||
case Event(SetHandler, _) =>
|
||||
|
|
@ -286,4 +289,3 @@ object FSMTimingSpec {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ object FSMTransitionSpec {
|
|||
case Event("tick", _) => goto(0)
|
||||
}
|
||||
whenUnhandled {
|
||||
case Event("reply", _) => stay replying "reply"
|
||||
case Event("reply", _) => stay.replying("reply")
|
||||
}
|
||||
initialize()
|
||||
override def preRestart(reason: Throwable, msg: Option[Any]): Unit = { target ! "restarted" }
|
||||
|
|
@ -45,7 +45,7 @@ object FSMTransitionSpec {
|
|||
class OtherFSM(target: ActorRef) extends Actor with FSM[Int, Int] {
|
||||
startWith(0, 0)
|
||||
when(0) {
|
||||
case Event("tick", _) => goto(1) using 1
|
||||
case Event("tick", _) => goto(1).using(1)
|
||||
case Event("stay", _) => stay()
|
||||
}
|
||||
when(1) {
|
||||
|
|
@ -150,7 +150,7 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender {
|
|||
val fsmref = system.actorOf(Props(new Actor with FSM[Int, ActorRef] {
|
||||
startWith(0, null)
|
||||
when(0) {
|
||||
case Event("switch", _) => goto(1) using sender()
|
||||
case Event("switch", _) => goto(1).using(sender())
|
||||
}
|
||||
onTransition {
|
||||
case x -> y => nextStateData ! (x -> y)
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ object ForwardActorSpec {
|
|||
def receive = { case x => sender() ! x }
|
||||
}))
|
||||
|
||||
def mkforwarder(forwardTo: ActorRef) = system.actorOf(Props(
|
||||
new Actor {
|
||||
def receive = { case x => forwardTo forward x }
|
||||
def mkforwarder(forwardTo: ActorRef) =
|
||||
system.actorOf(Props(new Actor {
|
||||
def receive = { case x => forwardTo.forward(x) }
|
||||
}))
|
||||
|
||||
mkforwarder(mkforwarder(mkforwarder(replier)))
|
||||
|
|
@ -33,7 +33,9 @@ class ForwardActorSpec extends AkkaSpec {
|
|||
"A Forward Actor" must {
|
||||
|
||||
"forward actor reference when invoking forward on tell" in {
|
||||
val replyTo = system.actorOf(Props(new Actor { def receive = { case ExpectedMessage => testActor ! ExpectedMessage } }))
|
||||
val replyTo = system.actorOf(Props(new Actor {
|
||||
def receive = { case ExpectedMessage => testActor ! ExpectedMessage }
|
||||
}))
|
||||
|
||||
val chain = createForwardingChain(system)
|
||||
|
||||
|
|
@ -43,7 +45,7 @@ class ForwardActorSpec extends AkkaSpec {
|
|||
|
||||
"forward actor reference when invoking forward on ask" in {
|
||||
val chain = createForwardingChain(system)
|
||||
chain.ask(ExpectedMessage)(5 seconds) pipeTo testActor
|
||||
chain.ask(ExpectedMessage)(5 seconds).pipeTo(testActor)
|
||||
expectMsg(5 seconds, ExpectedMessage)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,9 @@ class FunctionRefSpec extends AkkaSpec with ImplicitSender {
|
|||
"not be found" in {
|
||||
val provider = system.asInstanceOf[ExtendedActorSystem].provider
|
||||
val ref = new FunctionRef(testActor.path / "blabla", provider, system, (_, _) => ())
|
||||
EventFilter[SerializationCheckFailedException](start = "Failed to serialize and deserialize message of type akka.actor.FunctionRefSpec", occurrences = 1) intercept {
|
||||
EventFilter[SerializationCheckFailedException](
|
||||
start = "Failed to serialize and deserialize message of type akka.actor.FunctionRefSpec",
|
||||
occurrences = 1).intercept {
|
||||
// needs to be something that fails when the deserialized form is not a FunctionRef
|
||||
// this relies upon serialize-messages during tests
|
||||
testActor ! DropForwarder(ref)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@ package akka.actor
|
|||
import akka.testkit._
|
||||
|
||||
object HotSwapSpec {
|
||||
abstract class Becomer extends Actor {
|
||||
|
||||
}
|
||||
abstract class Becomer extends Actor {}
|
||||
}
|
||||
|
||||
class HotSwapSpec extends AkkaSpec with ImplicitSender {
|
||||
|
|
@ -79,7 +77,8 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender {
|
|||
val a = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "init" => sender() ! "init"
|
||||
case "swap" => context.become({
|
||||
case "swap" =>
|
||||
context.become({
|
||||
case "swapped" => sender() ! "swapped"
|
||||
case "revert" => context.unbecome()
|
||||
})
|
||||
|
|
@ -118,7 +117,7 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender {
|
|||
expectMsg("swapped")
|
||||
a ! "state"
|
||||
expectMsg("1")
|
||||
EventFilter[Exception](message = "Crash (expected)!", occurrences = 1) intercept { a ! "crash" }
|
||||
EventFilter[Exception](message = "Crash (expected)!", occurrences = 1).intercept { a ! "crash" }
|
||||
a ! "state"
|
||||
expectMsg("0")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,14 +108,14 @@ class LocalActorRefProviderSpec extends AkkaSpec(LocalActorRefProviderSpec.confi
|
|||
val child = expectMsgType[ActorRef]
|
||||
val childProps1 = child.asInstanceOf[LocalActorRef].underlying.props
|
||||
childProps1 should ===(Props.empty)
|
||||
system stop a
|
||||
system.stop(a)
|
||||
expectTerminated(a)
|
||||
// the fields are cleared after the Terminated message has been sent,
|
||||
// so we need to check for a reasonable time after we receive it
|
||||
awaitAssert({
|
||||
val childProps2 = child.asInstanceOf[LocalActorRef].underlying.props
|
||||
childProps2 should not be theSameInstanceAs(childProps1)
|
||||
childProps2 should be theSameInstanceAs ActorCell.terminatedProps
|
||||
(childProps2 should be).theSameInstanceAs(ActorCell.terminatedProps)
|
||||
}, 1 second)
|
||||
}
|
||||
}
|
||||
|
|
@ -131,8 +131,10 @@ class LocalActorRefProviderSpec extends AkkaSpec(LocalActorRefProviderSpec.confi
|
|||
for (i <- 0 until 100) {
|
||||
val address = "new-actor" + i
|
||||
implicit val timeout = Timeout(5 seconds)
|
||||
val actors = for (j <- 1 to 4) yield Future(system.actorOf(Props(new Actor { def receive = { case _ => } }), address))
|
||||
val set = Set() ++ actors.map(a => Await.ready(a, timeout.duration).value match {
|
||||
val actors = for (j <- 1 to 4)
|
||||
yield Future(system.actorOf(Props(new Actor { def receive = { case _ => } }), address))
|
||||
val set = Set() ++ actors.map(a =>
|
||||
Await.ready(a, timeout.duration).value match {
|
||||
case Some(Success(a: ActorRef)) => 1
|
||||
case Some(Failure(ex: InvalidActorNameException)) => 2
|
||||
case x => x
|
||||
|
|
@ -148,7 +150,7 @@ class LocalActorRefProviderSpec extends AkkaSpec(LocalActorRefProviderSpec.confi
|
|||
val a, b = context.actorOf(Props.empty, "duplicate")
|
||||
}
|
||||
}))
|
||||
EventFilter[InvalidActorNameException](occurrences = 1) intercept {
|
||||
EventFilter[InvalidActorNameException](occurrences = 1).intercept {
|
||||
supervisor ! ""
|
||||
}
|
||||
}
|
||||
|
|
@ -156,20 +158,33 @@ class LocalActorRefProviderSpec extends AkkaSpec(LocalActorRefProviderSpec.confi
|
|||
"throw suitable exceptions for malformed actor names" in {
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, null)).getMessage should include("null")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "")).getMessage should include("empty")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "$hallo")).getMessage should include("not start with `$`")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "a%")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%3")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%xx")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%0G")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%gg")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%1t")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "a?")).getMessage should include("Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "üß")).getMessage should include("include only ASCII")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "$hallo")).getMessage should include(
|
||||
"not start with `$`")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "a%")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%3")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%xx")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%0G")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%gg")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "%1t")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "a?")).getMessage should include(
|
||||
"Invalid actor path element")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, "üß")).getMessage should include(
|
||||
"include only ASCII")
|
||||
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, """he"llo""")).getMessage should include("""["] at position: 2""")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, """$hello""")).getMessage should include("""[$] at position: 0""")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, """hell>o""")).getMessage should include("""[>] at position: 4""")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, """he"llo""")).getMessage should include(
|
||||
"""["] at position: 2""")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, """$hello""")).getMessage should include(
|
||||
"""[$] at position: 0""")
|
||||
intercept[InvalidActorNameException](system.actorOf(Props.empty, """hell>o""")).getMessage should include(
|
||||
"""[>] at position: 4""")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@ class RestartStrategySpec extends AkkaSpec("akka.actor.serialize-messages = off"
|
|||
"A RestartStrategy" must {
|
||||
|
||||
"ensure that slave stays dead after max restarts within time range" in {
|
||||
val boss = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 1 second)(List(classOf[Throwable])))))
|
||||
val boss = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 1 second)(List(classOf[Throwable])))))
|
||||
|
||||
val restartLatch = new TestLatch
|
||||
val secondRestartLatch = new TestLatch
|
||||
|
|
@ -91,14 +92,16 @@ class RestartStrategySpec extends AkkaSpec("akka.actor.serialize-messages = off"
|
|||
})
|
||||
val slave = Await.result((boss ? slaveProps).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
(1 to 100) foreach { _ => slave ! Crash }
|
||||
(1 to 100).foreach { _ =>
|
||||
slave ! Crash
|
||||
}
|
||||
Await.ready(countDownLatch, 2 minutes)
|
||||
assert(!slave.isTerminated)
|
||||
}
|
||||
|
||||
"ensure that slave restarts after number of crashes not within time range" in {
|
||||
val boss = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 500 millis)(List(classOf[Throwable])))))
|
||||
val boss = system.actorOf(Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 500 millis)(List(classOf[Throwable])))))
|
||||
|
||||
val restartLatch = new TestLatch
|
||||
val secondRestartLatch = new TestLatch
|
||||
|
|
@ -261,4 +264,3 @@ class RestartStrategySpec extends AkkaSpec("akka.actor.serialize-messages = off"
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ package akka.actor
|
|||
import language.postfixOps
|
||||
import java.io.Closeable
|
||||
import java.util.concurrent._
|
||||
import atomic.{ AtomicReference, AtomicInteger }
|
||||
import scala.concurrent.{ Future, Await, ExecutionContext }
|
||||
import atomic.{ AtomicInteger, AtomicReference }
|
||||
import scala.concurrent.{ Await, ExecutionContext, Future }
|
||||
import scala.concurrent.duration._
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
import scala.util.Try
|
||||
|
|
@ -20,7 +20,8 @@ import akka.testkit._
|
|||
import scala.util.control.NoStackTrace
|
||||
|
||||
object SchedulerSpec {
|
||||
val testConfRevolver = ConfigFactory.parseString("""
|
||||
val testConfRevolver =
|
||||
ConfigFactory.parseString("""
|
||||
akka.scheduler.implementation = akka.actor.LightArrayRevolverScheduler
|
||||
akka.scheduler.ticks-per-wheel = 32
|
||||
akka.actor.serialize-messages = off
|
||||
|
|
@ -74,7 +75,7 @@ trait SchedulerSpec extends BeforeAndAfterEach with DefaultTimeout with Implicit
|
|||
expectMsg("msg")
|
||||
|
||||
// stop the actor and, hence, the continuous messaging from happening
|
||||
system stop actor
|
||||
system.stop(actor)
|
||||
|
||||
expectNoMsg(500 millis)
|
||||
}
|
||||
|
|
@ -194,7 +195,7 @@ trait SchedulerSpec extends BeforeAndAfterEach with DefaultTimeout with Implicit
|
|||
|
||||
collectCancellable(system.scheduler.schedule(500 milliseconds, 500 milliseconds, actor, Ping))
|
||||
// appx 2 pings before crash
|
||||
EventFilter[Exception]("CRASH", occurrences = 1) intercept {
|
||||
EventFilter[Exception]("CRASH", occurrences = 1).intercept {
|
||||
collectCancellable(system.scheduler.scheduleOnce(1000 milliseconds, actor, Crash))
|
||||
}
|
||||
|
||||
|
|
@ -292,11 +293,14 @@ trait SchedulerSpec extends BeforeAndAfterEach with DefaultTimeout with Implicit
|
|||
}
|
||||
}
|
||||
val latencies = within(10.seconds) {
|
||||
for (i <- 1 to N) yield try expectMsgType[Long] catch {
|
||||
for (i <- 1 to N)
|
||||
yield
|
||||
try expectMsgType[Long]
|
||||
catch {
|
||||
case NonFatal(e) => throw new Exception(s"failed expecting the $i-th latency", e)
|
||||
}
|
||||
}
|
||||
val histogram = latencies groupBy (_ / 100000000L)
|
||||
val histogram = latencies.groupBy(_ / 100000000L)
|
||||
for (k <- histogram.keys.toSeq.sorted) {
|
||||
system.log.info(f"${k * 100}%3d: ${histogram(k).size}")
|
||||
}
|
||||
|
|
@ -362,11 +366,14 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
val cancelled = cancellations.sum
|
||||
println(cancelled)
|
||||
val latencies = within(10.seconds) {
|
||||
for (i <- 1 to (N - cancelled)) yield try expectMsgType[Long] catch {
|
||||
for (i <- 1 to (N - cancelled))
|
||||
yield
|
||||
try expectMsgType[Long]
|
||||
catch {
|
||||
case NonFatal(e) => throw new Exception(s"failed expecting the $i-th latency", e)
|
||||
}
|
||||
}
|
||||
val histogram = latencies groupBy (_ / 100000000L)
|
||||
val histogram = latencies.groupBy(_ / 100000000L)
|
||||
for (k <- histogram.keys.toSeq.sorted) {
|
||||
system.log.info(f"${k * 100}%3d: ${histogram(k).size}")
|
||||
}
|
||||
|
|
@ -389,7 +396,7 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
}
|
||||
def delay = if (ThreadLocalRandom.current.nextBoolean) step * 2 else step
|
||||
val N = 1000000
|
||||
(1 to N) foreach (_ => sched.scheduleOnce(delay)(counter.incrementAndGet()))
|
||||
(1 to N).foreach(_ => sched.scheduleOnce(delay)(counter.incrementAndGet()))
|
||||
sched.close()
|
||||
Await.result(terminated, 3.seconds.dilated) should be > 10
|
||||
awaitCond(counter.get == N)
|
||||
|
|
@ -401,13 +408,13 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
implicit def ec = localEC
|
||||
import driver._
|
||||
val start = step / 2
|
||||
(0 to 3) foreach (i => sched.scheduleOnce(start + step * i, testActor, "hello"))
|
||||
(0 to 3).foreach(i => sched.scheduleOnce(start + step * i, testActor, "hello"))
|
||||
expectNoMsg(step)
|
||||
wakeUp(step)
|
||||
expectWait(step)
|
||||
wakeUp(step * 4 + step / 2)
|
||||
expectWait(step / 2)
|
||||
(0 to 3) foreach (_ => expectMsg(Duration.Zero, "hello"))
|
||||
(0 to 3).foreach(_ => expectMsg(Duration.Zero, "hello"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -431,7 +438,7 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
implicit def ec = localEC
|
||||
import driver._
|
||||
val start = step / 2
|
||||
(0 to 3) foreach (i => sched.scheduleOnce(start + step * i, probe.ref, "hello"))
|
||||
(0 to 3).foreach(i => sched.scheduleOnce(start + step * i, probe.ref, "hello"))
|
||||
probe.expectNoMsg(step)
|
||||
wakeUp(step)
|
||||
expectWait(step)
|
||||
|
|
@ -458,7 +465,7 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
implicit def ec = localEC
|
||||
import driver._
|
||||
val start = step / 2
|
||||
(0 to 3) foreach (i => sched.scheduleOnce(start + step * i, testActor, "hello"))
|
||||
(0 to 3).foreach(i => sched.scheduleOnce(start + step * i, testActor, "hello"))
|
||||
expectNoMsg(step)
|
||||
wakeUp(step)
|
||||
expectWait(step)
|
||||
|
|
@ -494,12 +501,12 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
probe.expectMsgType[Long]
|
||||
|
||||
val nums = 0 until numEvents
|
||||
nums foreach (i => sched.scheduleOnce(start + step * i, testActor, "hello-" + i))
|
||||
nums.foreach(i => sched.scheduleOnce(start + step * i, testActor, "hello-" + i))
|
||||
expectNoMsg(step)
|
||||
wakeUp(step)
|
||||
expectWait(step)
|
||||
|
||||
nums foreach { i =>
|
||||
nums.foreach { i =>
|
||||
wakeUp(step)
|
||||
expectMsg("hello-" + i)
|
||||
expectWait(step)
|
||||
|
|
@ -542,7 +549,8 @@ class LightArrayRevolverSchedulerSpec extends AkkaSpec(SchedulerSpec.testConfRev
|
|||
def reportFailure(t: Throwable): Unit = { t.printStackTrace() }
|
||||
}
|
||||
|
||||
def withScheduler(start: Long = 0L, _startTick: Int = 0, config: Config = ConfigFactory.empty)(thunk: (Scheduler with Closeable, Driver) => Unit): Unit = {
|
||||
def withScheduler(start: Long = 0L, _startTick: Int = 0, config: Config = ConfigFactory.empty)(
|
||||
thunk: (Scheduler with Closeable, Driver) => Unit): Unit = {
|
||||
import akka.actor.{ LightArrayRevolverScheduler => LARS }
|
||||
val lbq = new AtomicReference[LinkedBlockingQueue[Long]](new LinkedBlockingQueue[Long])
|
||||
val prb = TestProbe()
|
||||
|
|
|
|||
|
|
@ -5,18 +5,18 @@
|
|||
package akka.actor
|
||||
|
||||
import language.postfixOps
|
||||
import java.util.concurrent.{ TimeUnit, CountDownLatch }
|
||||
import java.util.concurrent.{ CountDownLatch, TimeUnit }
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.Random
|
||||
import scala.util.control.NoStackTrace
|
||||
import com.typesafe.config.{ ConfigFactory, Config }
|
||||
import SupervisorStrategy.{ Resume, Restart, Stop, Directive }
|
||||
import com.typesafe.config.{ Config, ConfigFactory }
|
||||
import SupervisorStrategy.{ Directive, Restart, Resume, Stop }
|
||||
import akka.actor.SupervisorStrategy.seqThrowable2Decider
|
||||
import akka.dispatch.{ MessageDispatcher, DispatcherPrerequisites, DispatcherConfigurator, Dispatcher }
|
||||
import akka.dispatch.{ Dispatcher, DispatcherConfigurator, DispatcherPrerequisites, MessageDispatcher }
|
||||
import akka.pattern.ask
|
||||
import akka.testkit.{ ImplicitSender, EventFilter, DefaultTimeout, AkkaSpec }
|
||||
import akka.testkit.{ filterException, filterEvents, TestDuration, TestLatch }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout, EventFilter, ImplicitSender }
|
||||
import akka.testkit.{ filterEvents, filterException, TestDuration, TestLatch }
|
||||
import akka.testkit.TestEvent.Mute
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.lang.ref.WeakReference
|
||||
|
|
@ -63,8 +63,15 @@ object SupervisorHierarchySpec {
|
|||
case object PongOfDeath
|
||||
final case class Event(msg: Any, identity: Long) { val time: Long = System.nanoTime }
|
||||
final case class ErrorLog(msg: String, log: Vector[Event])
|
||||
final case class Failure(directive: Directive, stop: Boolean, depth: Int, var failPre: Int, var failPost: Int, val failConstr: Int, stopKids: Int)
|
||||
extends RuntimeException("Failure") with NoStackTrace {
|
||||
final case class Failure(directive: Directive,
|
||||
stop: Boolean,
|
||||
depth: Int,
|
||||
var failPre: Int,
|
||||
var failPost: Int,
|
||||
val failConstr: Int,
|
||||
stopKids: Int)
|
||||
extends RuntimeException("Failure")
|
||||
with NoStackTrace {
|
||||
override def toString = productPrefix + productIterator.mkString("(", ",", ")")
|
||||
}
|
||||
final case class Dump(level: Int)
|
||||
|
|
@ -82,8 +89,7 @@ object SupervisorHierarchySpec {
|
|||
extends DispatcherConfigurator(config, prerequisites) {
|
||||
|
||||
private val instance: MessageDispatcher =
|
||||
new Dispatcher(
|
||||
this,
|
||||
new Dispatcher(this,
|
||||
config.getString("id"),
|
||||
config.getInt("throughput"),
|
||||
config.getNanosDuration("throughput-deadline-time"),
|
||||
|
|
@ -139,7 +145,7 @@ object SupervisorHierarchySpec {
|
|||
listener ! ErrorLog(msg, log)
|
||||
log = Vector(Event("log sent", identityHashCode(this)))
|
||||
context.parent ! Abort
|
||||
context stop self
|
||||
context.stop(self)
|
||||
}
|
||||
|
||||
def setFlags(directive: Directive): Unit = directive match {
|
||||
|
|
@ -161,8 +167,11 @@ object SupervisorHierarchySpec {
|
|||
var rest = s % kids
|
||||
val propsTemplate = Props.empty.withDispatcher("hierarchy")
|
||||
(1 to kids).iterator.map { (id) =>
|
||||
val kidSize = if (rest > 0) { rest -= 1; sizes + 1 } else sizes
|
||||
val props = Props(new Hierarchy(kidSize, breadth, listener, myLevel + 1, random)).withDeploy(propsTemplate.deploy)
|
||||
val kidSize = if (rest > 0) {
|
||||
rest -= 1; sizes + 1
|
||||
} else sizes
|
||||
val props =
|
||||
Props(new Hierarchy(kidSize, breadth, listener, myLevel + 1, random)).withDeploy(propsTemplate.deploy)
|
||||
(context.watch(context.actorOf(props, id.toString)).path, kidSize)
|
||||
}.toMap
|
||||
} else Map()
|
||||
|
|
@ -178,7 +187,7 @@ object SupervisorHierarchySpec {
|
|||
preRestartCalled = true
|
||||
cause match {
|
||||
case f: Failure =>
|
||||
context.children.take(f.stopKids) foreach { child =>
|
||||
context.children.take(f.stopKids).foreach { child =>
|
||||
log :+= Event("killing " + child, identityHashCode(this))
|
||||
context.unwatch(child)
|
||||
context.stop(child)
|
||||
|
|
@ -198,7 +207,7 @@ object SupervisorHierarchySpec {
|
|||
case x @ ActorInitializationException(_, _, f: Failure) => (f, x)
|
||||
case x => (x, x)
|
||||
}
|
||||
override val supervisorStrategy = OneForOneStrategy()(unwrap andThen {
|
||||
override val supervisorStrategy = OneForOneStrategy()(unwrap.andThen {
|
||||
case (_: Failure, _) if pongsToGo > 0 =>
|
||||
log :+= Event("pongOfDeath resuming " + sender(), identityHashCode(this))
|
||||
Resume
|
||||
|
|
@ -225,12 +234,13 @@ object SupervisorHierarchySpec {
|
|||
val state = stateCache.get(self.path)
|
||||
log = state.log
|
||||
log :+= Event("restarted " + suspendCount + " " + cause, identityHashCode(this))
|
||||
state.kids foreach {
|
||||
state.kids.foreach {
|
||||
case (childPath, kidSize) =>
|
||||
val name = childPath.name
|
||||
if (context.child(name).isEmpty) {
|
||||
listener ! Died(childPath)
|
||||
val props = Props(new Hierarchy(kidSize, breadth, listener, myLevel + 1, random)).withDispatcher("hierarchy")
|
||||
val props =
|
||||
Props(new Hierarchy(kidSize, breadth, listener, myLevel + 1, random)).withDispatcher("hierarchy")
|
||||
context.watch(context.actorOf(props, name))
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +275,8 @@ object SupervisorHierarchySpec {
|
|||
abort("processing message while suspended")
|
||||
false
|
||||
} else if (!Thread.currentThread.getName.startsWith("SupervisorHierarchySpec-hierarchy")) {
|
||||
abort("running on wrong thread " + Thread.currentThread + " dispatcher=" + context.props.dispatcher + "=>" +
|
||||
abort(
|
||||
"running on wrong thread " + Thread.currentThread + " dispatcher=" + context.props.dispatcher + "=>" +
|
||||
context.asInstanceOf[ActorCell].dispatcher.id)
|
||||
false
|
||||
} else true
|
||||
|
|
@ -281,7 +292,7 @@ object SupervisorHierarchySpec {
|
|||
throw f
|
||||
case "ping" => { Thread.sleep((random.nextFloat * 1.03).toLong); sender() ! "pong" }
|
||||
case Dump(0) => abort("dump")
|
||||
case Dump(level) => context.children foreach (_ ! Dump(level - 1))
|
||||
case Dump(level) => context.children.foreach(_ ! Dump(level - 1))
|
||||
case Terminated(ref) =>
|
||||
/*
|
||||
* It might be that we acted upon this death already in postRestart
|
||||
|
|
@ -306,15 +317,15 @@ object SupervisorHierarchySpec {
|
|||
if (size > 1) {
|
||||
pongsToGo = context.children.size
|
||||
log :+= Event("sending " + pongsToGo + " pingOfDeath", identityHashCode(Hierarchy.this))
|
||||
context.children foreach (_ ! PingOfDeath)
|
||||
context.children.foreach(_ ! PingOfDeath)
|
||||
} else {
|
||||
context stop self
|
||||
context.stop(self)
|
||||
context.parent ! PongOfDeath
|
||||
}
|
||||
case PongOfDeath =>
|
||||
pongsToGo -= 1
|
||||
if (pongsToGo == 0) {
|
||||
context stop self
|
||||
context.stop(self)
|
||||
context.parent ! PongOfDeath
|
||||
}
|
||||
}
|
||||
|
|
@ -450,7 +461,8 @@ object SupervisorHierarchySpec {
|
|||
|
||||
when(Idle) {
|
||||
case Event(Init, _) =>
|
||||
hierarchy = context.watch(context.actorOf(Props(new Hierarchy(size, breadth, self, 0, random)).withDispatcher("hierarchy"), "head"))
|
||||
hierarchy = context.watch(
|
||||
context.actorOf(Props(new Hierarchy(size, breadth, self, 0, random)).withDispatcher("hierarchy"), "head"))
|
||||
setTimer("phase", StateTimeout, 5 seconds, false)
|
||||
goto(Init)
|
||||
}
|
||||
|
|
@ -490,9 +502,9 @@ object SupervisorHierarchySpec {
|
|||
val deadGuy = path.elements
|
||||
val deadGuySize = deadGuy.size
|
||||
val isChild = (other: ActorRef) => other.path.elements.take(deadGuySize) == deadGuy
|
||||
activeChildren = activeChildren filterNot isChild
|
||||
idleChildren = idleChildren filterNot isChild
|
||||
pingChildren = pingChildren filterNot isChild
|
||||
activeChildren = activeChildren.filterNot(isChild)
|
||||
idleChildren = idleChildren.filterNot(isChild)
|
||||
pingChildren = pingChildren.filterNot(isChild)
|
||||
}
|
||||
|
||||
var ignoreNotResumedLogs = true
|
||||
|
|
@ -505,7 +517,12 @@ object SupervisorHierarchySpec {
|
|||
nextJob.next match {
|
||||
case Ping(ref) => ref ! "ping"
|
||||
case Fail(ref, dir) =>
|
||||
val f = Failure(dir, stop = random012 > 0, depth = random012, failPre = random012, failPost = random012, failConstr = random012,
|
||||
val f = Failure(dir,
|
||||
stop = random012 > 0,
|
||||
depth = random012,
|
||||
failPre = random012,
|
||||
failPost = random012,
|
||||
failConstr = random012,
|
||||
stopKids = random012 match {
|
||||
case 0 => 0
|
||||
case 1 => random.nextInt(breadth / 2)
|
||||
|
|
@ -515,7 +532,7 @@ object SupervisorHierarchySpec {
|
|||
}
|
||||
if (idleChildren.nonEmpty) self ! Work
|
||||
else context.system.scheduler.scheduleOnce(workSchedule, self, Work)(context.dispatcher)
|
||||
stay using (x - 1)
|
||||
stay.using(x - 1)
|
||||
case Event(Work, _) => if (pingChildren.isEmpty) goto(LastPing) else goto(Finishing)
|
||||
case Event(Died(path), _) =>
|
||||
bury(path)
|
||||
|
|
@ -526,10 +543,11 @@ object SupervisorHierarchySpec {
|
|||
stay
|
||||
case Event(StateTimeout, todo) =>
|
||||
log.info("dumping state due to StateTimeout")
|
||||
log.info("children: " + children.size + " pinged: " + pingChildren.size + " idle: " + idleChildren.size + " work: " + todo)
|
||||
pingChildren foreach println
|
||||
log.info(
|
||||
"children: " + children.size + " pinged: " + pingChildren.size + " idle: " + idleChildren.size + " work: " + todo)
|
||||
pingChildren.foreach(println)
|
||||
println(system.asInstanceOf[ActorSystemImpl].printTree)
|
||||
pingChildren foreach getErrorsUp
|
||||
pingChildren.foreach(getErrorsUp)
|
||||
ignoreNotResumedLogs = false
|
||||
hierarchy ! Dump(2)
|
||||
goto(Failed)
|
||||
|
|
@ -551,7 +569,7 @@ object SupervisorHierarchySpec {
|
|||
|
||||
onTransition {
|
||||
case _ -> LastPing =>
|
||||
idleChildren foreach (_ ! "ping")
|
||||
idleChildren.foreach(_ ! "ping")
|
||||
pingChildren ++= idleChildren
|
||||
idleChildren = Vector.empty
|
||||
}
|
||||
|
|
@ -575,7 +593,7 @@ object SupervisorHierarchySpec {
|
|||
when(Stopping, stateTimeout = 5.seconds.dilated) {
|
||||
case Event(PongOfDeath, _) => stay
|
||||
case Event(Terminated(r), _) if r == hierarchy =>
|
||||
val undead = children filterNot (_.isTerminated)
|
||||
val undead = children.filterNot(_.isTerminated)
|
||||
if (undead.nonEmpty) {
|
||||
log.info("undead:\n" + undead.mkString("\n"))
|
||||
testActor ! "stressTestFailed (" + undead.size + " undead)"
|
||||
|
|
@ -588,7 +606,7 @@ object SupervisorHierarchySpec {
|
|||
* failed. I’m leaving this code in so that manual inspection remains
|
||||
* an option (by setting the above condition to “true”).
|
||||
*/
|
||||
val weak = children map (new WeakReference(_))
|
||||
val weak = children.map(new WeakReference(_))
|
||||
children = Vector.empty
|
||||
pingChildren = Set.empty
|
||||
idleChildren = Vector.empty
|
||||
|
|
@ -604,7 +622,7 @@ object SupervisorHierarchySpec {
|
|||
println(system.asInstanceOf[ActorSystemImpl].printTree)
|
||||
getErrors(hierarchy, 10)
|
||||
printErrors()
|
||||
idleChildren foreach println
|
||||
idleChildren.foreach(println)
|
||||
testActor ! "timeout in Stopping"
|
||||
stop
|
||||
case Event(e: ErrorLog, _) =>
|
||||
|
|
@ -614,7 +632,7 @@ object SupervisorHierarchySpec {
|
|||
|
||||
when(GC, stateTimeout = 10 seconds) {
|
||||
case Event(GCcheck(weak), _) =>
|
||||
val next = weak filter (_.get ne null)
|
||||
val next = weak.filter(_.get ne null)
|
||||
if (next.nonEmpty) {
|
||||
println(next.size + " left")
|
||||
context.system.scheduler.scheduleOnce(workSchedule, self, GCcheck(next))(context.dispatcher)
|
||||
|
|
@ -658,7 +676,7 @@ object SupervisorHierarchySpec {
|
|||
case _ => errors :+= target -> ErrorLog("fetched", stateCache.get(target.path).log)
|
||||
}
|
||||
if (depth > 0) {
|
||||
l.underlying.children foreach (getErrors(_, depth - 1))
|
||||
l.underlying.children.foreach(getErrors(_, depth - 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -675,17 +693,17 @@ object SupervisorHierarchySpec {
|
|||
}
|
||||
|
||||
def printErrors(): Unit = {
|
||||
errors collect {
|
||||
errors.collect {
|
||||
case (origin, ErrorLog("dump", _)) => getErrors(origin, 1)
|
||||
case (origin, ErrorLog(msg, _)) if msg startsWith "not resumed" => getErrorsUp(origin)
|
||||
case (origin, ErrorLog(msg, _)) if msg.startsWith("not resumed") => getErrorsUp(origin)
|
||||
}
|
||||
val merged = errors.sortBy(_._1.toString) flatMap {
|
||||
val merged = errors.sortBy(_._1.toString).flatMap {
|
||||
case (ref, ErrorLog(msg, log)) =>
|
||||
println("Error: " + ref + " " + msg)
|
||||
log map (l => (l.time, ref, l.identity, l.msg.toString))
|
||||
log.map(l => (l.time, ref, l.identity, l.msg.toString))
|
||||
}
|
||||
println("random seed: " + randomSeed)
|
||||
merged.sorted.distinct foreach println
|
||||
merged.sorted.distinct.foreach(println)
|
||||
}
|
||||
|
||||
whenUnhandled {
|
||||
|
|
@ -707,7 +725,7 @@ object SupervisorHierarchySpec {
|
|||
// make sure that we get the logs of the remaining pingChildren
|
||||
pingChildren.foreach(getErrorsUp)
|
||||
// this will ensure that the error logs get printed and we stop the test
|
||||
context stop hierarchy
|
||||
context.stop(hierarchy)
|
||||
goto(Failed)
|
||||
case Event(Abort, _) =>
|
||||
log.info("received Abort")
|
||||
|
|
@ -757,7 +775,8 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
override val supervisorStrategy =
|
||||
OneForOneStrategy(maxNrOfRetries = 1, withinTimeRange = 5 seconds)(List(classOf[Throwable]))
|
||||
|
||||
val crasher = context.watch(context.actorOf(Props(new CountDownActor(countDownMessages, SupervisorStrategy.defaultStrategy))))
|
||||
val crasher = context.watch(
|
||||
context.actorOf(Props(new CountDownActor(countDownMessages, SupervisorStrategy.defaultStrategy))))
|
||||
|
||||
def receive = {
|
||||
case "killCrasher" => crasher ! Kill
|
||||
|
|
@ -782,7 +801,7 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
val worker = expectMsgType[ActorRef]
|
||||
worker ! "ping"
|
||||
expectMsg("pong")
|
||||
EventFilter.warning("expected", occurrences = 1) intercept {
|
||||
EventFilter.warning("expected", occurrences = 1).intercept {
|
||||
middle ! "fail"
|
||||
}
|
||||
middle ! "ping"
|
||||
|
|
@ -794,7 +813,9 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
"suspend children while failing" taggedAs LongRunningTest in {
|
||||
val latch = TestLatch()
|
||||
val slowResumer = system.actorOf(Props(new Actor {
|
||||
override def supervisorStrategy = OneForOneStrategy() { case _ => Await.ready(latch, 4.seconds.dilated); SupervisorStrategy.Resume }
|
||||
override def supervisorStrategy = OneForOneStrategy() {
|
||||
case _ => Await.ready(latch, 4.seconds.dilated); SupervisorStrategy.Resume
|
||||
}
|
||||
def receive = {
|
||||
case "spawn" => sender() ! context.actorOf(Props[Resumer])
|
||||
}
|
||||
|
|
@ -807,7 +828,7 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
val worker = expectMsgType[ActorRef]
|
||||
worker ! "ping"
|
||||
expectMsg("pong")
|
||||
EventFilter.warning("expected", occurrences = 1) intercept {
|
||||
EventFilter.warning("expected", occurrences = 1).intercept {
|
||||
boss ! "fail"
|
||||
awaitCond(worker.asInstanceOf[LocalActorRef].underlying.mailbox.isSuspended)
|
||||
worker ! "ping"
|
||||
|
|
@ -822,13 +843,14 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
val preStartCalled = new AtomicInteger(0)
|
||||
val postRestartCalled = new AtomicInteger(0)
|
||||
|
||||
filterEvents(
|
||||
EventFilter[Failure](),
|
||||
filterEvents(EventFilter[Failure](),
|
||||
EventFilter[ActorInitializationException](),
|
||||
EventFilter[IllegalArgumentException]("OH NO!"),
|
||||
EventFilter.error(start = "changing Recreate into Create"),
|
||||
EventFilter.error(start = "changing Resume into Create")) {
|
||||
val failResumer = system.actorOf(Props(new Actor {
|
||||
val failResumer =
|
||||
system.actorOf(
|
||||
Props(new Actor {
|
||||
override def supervisorStrategy = OneForOneStrategy() {
|
||||
case e: ActorInitializationException =>
|
||||
if (createAttempt.get % 2 == 0) SupervisorStrategy.Resume else SupervisorStrategy.Restart
|
||||
|
|
@ -857,7 +879,8 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
override def receive = {
|
||||
case m => child.forward(m)
|
||||
}
|
||||
}), "failResumer")
|
||||
}),
|
||||
"failResumer")
|
||||
|
||||
failResumer ! "blahonga"
|
||||
expectMsg("blahonga")
|
||||
|
|
@ -868,8 +891,8 @@ class SupervisorHierarchySpec extends AkkaSpec(SupervisorHierarchySpec.config) w
|
|||
}
|
||||
|
||||
"survive being stressed" taggedAs LongRunningTest in {
|
||||
system.eventStream.publish(Mute(
|
||||
EventFilter[Failure](),
|
||||
system.eventStream.publish(
|
||||
Mute(EventFilter[Failure](),
|
||||
EventFilter.warning("Failure"),
|
||||
EventFilter[ActorInitializationException](),
|
||||
EventFilter[NoSuchElementException]("head of empty list"),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import language.postfixOps
|
|||
|
||||
import akka.testkit.{ filterEvents, EventFilter }
|
||||
import scala.concurrent.Await
|
||||
import java.util.concurrent.{ TimeUnit, CountDownLatch }
|
||||
import java.util.concurrent.{ CountDownLatch, TimeUnit }
|
||||
import akka.testkit.AkkaSpec
|
||||
import akka.testkit.DefaultTimeout
|
||||
import akka.pattern.ask
|
||||
|
|
@ -35,8 +35,8 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
filterEvents(EventFilter[Exception]("Kill")) {
|
||||
val countDownLatch = new CountDownLatch(4)
|
||||
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 5 seconds)(List(classOf[Exception])))))
|
||||
val supervisor = system.actorOf(Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 5 seconds)(List(classOf[Exception])))))
|
||||
|
||||
val workerProps = Props(new Actor {
|
||||
override def postRestart(cause: Throwable): Unit = { countDownLatch.countDown() }
|
||||
|
|
@ -46,11 +46,14 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
}
|
||||
})
|
||||
|
||||
val actor1, actor2 = Await.result((supervisor ? workerProps.withDispatcher("pinned-dispatcher")).mapTo[ActorRef], timeout.duration)
|
||||
val actor1, actor2 =
|
||||
Await.result((supervisor ? workerProps.withDispatcher("pinned-dispatcher")).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
val actor3 = Await.result((supervisor ? workerProps.withDispatcher("test-dispatcher")).mapTo[ActorRef], timeout.duration)
|
||||
val actor3 =
|
||||
Await.result((supervisor ? workerProps.withDispatcher("test-dispatcher")).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
val actor4 = Await.result((supervisor ? workerProps.withDispatcher("pinned-dispatcher")).mapTo[ActorRef], timeout.duration)
|
||||
val actor4 =
|
||||
Await.result((supervisor ? workerProps.withDispatcher("pinned-dispatcher")).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
actor1 ! Kill
|
||||
actor2 ! Kill
|
||||
|
|
@ -59,9 +62,11 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
|
||||
countDownLatch.await(10, TimeUnit.SECONDS)
|
||||
|
||||
Seq("actor1" -> actor1, "actor2" -> actor2, "actor3" -> actor3, "actor4" -> actor4) map {
|
||||
Seq("actor1" -> actor1, "actor2" -> actor2, "actor3" -> actor3, "actor4" -> actor4)
|
||||
.map {
|
||||
case (id, ref) => (id, ref ? "status")
|
||||
} foreach {
|
||||
}
|
||||
.foreach {
|
||||
case (id, f) => (id, Await.result(f, timeout.duration)) should ===((id, "OK"))
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +79,7 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
override def preStart(): Unit = testActor ! "preStart"
|
||||
}))
|
||||
val m = "weird message"
|
||||
EventFilter[Exception](m, occurrences = 1) intercept {
|
||||
EventFilter[Exception](m, occurrences = 1).intercept {
|
||||
a ! new Exception(m)
|
||||
}
|
||||
expectMsg("preStart")
|
||||
|
|
@ -127,7 +132,9 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
"be able to create a similar kid in the fault handling strategy" in {
|
||||
val parent = system.actorOf(Props(new Actor {
|
||||
override val supervisorStrategy = new OneForOneStrategy()(SupervisorStrategy.defaultStrategy.decider) {
|
||||
override def handleChildTerminated(context: ActorContext, child: ActorRef, children: Iterable[ActorRef]): Unit = {
|
||||
override def handleChildTerminated(context: ActorContext,
|
||||
child: ActorRef,
|
||||
children: Iterable[ActorRef]): Unit = {
|
||||
val newKid = context.actorOf(Props.empty, child.path.name)
|
||||
testActor ! { if ((newKid ne child) && newKid.path == child.path) "green" else "red" }
|
||||
}
|
||||
|
|
@ -137,7 +144,7 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
}))
|
||||
parent ! "engage"
|
||||
expectMsg("green")
|
||||
EventFilter[IllegalStateException]("handleChildTerminated failed", occurrences = 1) intercept {
|
||||
EventFilter[IllegalStateException]("handleChildTerminated failed", occurrences = 1).intercept {
|
||||
system.stop(parent)
|
||||
}
|
||||
}
|
||||
|
|
@ -151,7 +158,7 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
case "doit" => context.actorOf(Props.empty, "child") ! Kill
|
||||
}
|
||||
}))
|
||||
EventFilter[ActorKilledException](occurrences = 1) intercept {
|
||||
EventFilter[ActorKilledException](occurrences = 1).intercept {
|
||||
parent ! "doit"
|
||||
}
|
||||
val p = expectMsgType[ActorRef].path
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ object SupervisorSpec {
|
|||
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 0)(List(classOf[Exception]))
|
||||
|
||||
def receive = {
|
||||
case Die => temp forward Die
|
||||
case Die => temp.forward(Die)
|
||||
case Terminated(`temp`) => sendTo ! "terminated"
|
||||
case Status.Failure(_) => /*Ignore*/
|
||||
}
|
||||
|
|
@ -101,7 +101,11 @@ error-mailbox {
|
|||
""")
|
||||
}
|
||||
|
||||
class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfterEach with ImplicitSender with DefaultTimeout {
|
||||
class SupervisorSpec
|
||||
extends AkkaSpec(SupervisorSpec.config)
|
||||
with BeforeAndAfterEach
|
||||
with ImplicitSender
|
||||
with DefaultTimeout {
|
||||
|
||||
import SupervisorSpec._
|
||||
|
||||
|
|
@ -111,17 +115,21 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
// Creating actors and supervisors
|
||||
// =====================================================
|
||||
|
||||
private def child(supervisor: ActorRef, props: Props): ActorRef = Await.result((supervisor ? props).mapTo[ActorRef], timeout.duration)
|
||||
private def child(supervisor: ActorRef, props: Props): ActorRef =
|
||||
Await.result((supervisor ? props).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
def temporaryActorAllForOne = {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(AllForOneStrategy(maxNrOfRetries = 0)(List(classOf[Exception])))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(new Supervisor(AllForOneStrategy(maxNrOfRetries = 0)(List(classOf[Exception])))))
|
||||
val temporaryActor = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
(temporaryActor, supervisor)
|
||||
}
|
||||
|
||||
def singleActorAllForOne = {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
val supervisor = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(
|
||||
AllForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(List(classOf[Exception])))))
|
||||
val pingpong = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
|
|
@ -129,7 +137,9 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
def singleActorOneForOne = {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
val supervisor = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(List(classOf[Exception])))))
|
||||
val pingpong = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
|
|
@ -137,7 +147,9 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
def multipleActorsAllForOne = {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
val supervisor = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(
|
||||
AllForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(List(classOf[Exception])))))
|
||||
val pingpong1, pingpong2, pingpong3 = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
|
|
@ -145,7 +157,9 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
def multipleActorsOneForOne = {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
val supervisor = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(List(classOf[Exception])))))
|
||||
val pingpong1, pingpong2, pingpong3 = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
|
|
@ -153,12 +167,15 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
def nestedSupervisorsAllForOne = {
|
||||
val topSupervisor = system.actorOf(Props(new Supervisor(
|
||||
val topSupervisor = system.actorOf(
|
||||
Props(
|
||||
new Supervisor(
|
||||
AllForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(List(classOf[Exception])))))
|
||||
val pingpong1 = child(topSupervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
val middleSupervisor = child(topSupervisor, Props(new Supervisor(
|
||||
AllForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(Nil))))
|
||||
val middleSupervisor = child(
|
||||
topSupervisor,
|
||||
Props(new Supervisor(AllForOneStrategy(maxNrOfRetries = 3, withinTimeRange = DilatedTimeout)(Nil))))
|
||||
val pingpong2, pingpong3 = child(middleSupervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
(pingpong1, pingpong2, pingpong3, topSupervisor)
|
||||
|
|
@ -168,9 +185,7 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
system.eventStream.publish(Mute(EventFilter[RuntimeException](ExceptionMessage)))
|
||||
}
|
||||
|
||||
override def beforeEach() = {
|
||||
|
||||
}
|
||||
override def beforeEach() = {}
|
||||
|
||||
def ping(pingPongActor: ActorRef) = {
|
||||
Await.result(pingPongActor.?(Ping)(DilatedTimeout), DilatedTimeout) should ===(PongMessage)
|
||||
|
|
@ -206,8 +221,12 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
var postRestarts = 0
|
||||
var preStarts = 0
|
||||
var postStops = 0
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit = { preRestarts += 1; testActor ! ("preRestart" + preRestarts) }
|
||||
override def postRestart(reason: Throwable): Unit = { postRestarts += 1; testActor ! ("postRestart" + postRestarts) }
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
|
||||
preRestarts += 1; testActor ! ("preRestart" + preRestarts)
|
||||
}
|
||||
override def postRestart(reason: Throwable): Unit = {
|
||||
postRestarts += 1; testActor ! ("postRestart" + postRestarts)
|
||||
}
|
||||
override def preStart(): Unit = { preStarts += 1; testActor ! ("preStart" + preStarts) }
|
||||
override def postStop(): Unit = { postStops += 1; testActor ! ("postStop" + postStops) }
|
||||
def receive = {
|
||||
|
|
@ -219,7 +238,7 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = restarts)(List(classOf[Exception]))
|
||||
val child = context.actorOf(Props(childInstance))
|
||||
def receive = {
|
||||
case msg => child forward msg
|
||||
case msg => child.forward(msg)
|
||||
}
|
||||
}))
|
||||
|
||||
|
|
@ -229,8 +248,7 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
expectMsg("pong")
|
||||
|
||||
filterEvents(EventFilter[RuntimeException]("Expected", occurrences = restarts + 1)) {
|
||||
(1 to restarts) foreach {
|
||||
i =>
|
||||
(1 to restarts).foreach { i =>
|
||||
master ! "crash"
|
||||
expectMsg("crashed")
|
||||
|
||||
|
|
@ -377,8 +395,8 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
|
||||
"attempt restart when exception during restart" in {
|
||||
val inits = new AtomicInteger(0)
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 10 seconds)(classOf[Exception] :: Nil))))
|
||||
val supervisor = system.actorOf(Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 10 seconds)(classOf[Exception] :: Nil))))
|
||||
|
||||
val dyingProps = Props(new Actor {
|
||||
val init = inits.getAndIncrement()
|
||||
|
|
@ -399,8 +417,7 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
supervisor ! dyingProps
|
||||
val dyingActor = expectMsgType[ActorRef]
|
||||
|
||||
filterEvents(
|
||||
EventFilter[RuntimeException]("Expected", occurrences = 1),
|
||||
filterEvents(EventFilter[RuntimeException]("Expected", occurrences = 1),
|
||||
EventFilter[PreRestartException]("Don't wanna!", occurrences = 1),
|
||||
EventFilter[PostRestartException]("Don't wanna!", occurrences = 1)) {
|
||||
intercept[RuntimeException] {
|
||||
|
|
@ -434,7 +451,7 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
|
||||
// Overriding to disable auto-unwatch
|
||||
override def preRestart(reason: Throwable, msg: Option[Any]): Unit = {
|
||||
context.children foreach context.stop
|
||||
context.children.foreach(context.stop)
|
||||
postStop()
|
||||
}
|
||||
|
||||
|
|
@ -442,8 +459,8 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
case Terminated(a) if a.path == child.path => testActor ! "child terminated"
|
||||
case l: TestLatch => child ! l
|
||||
case "test" => sender() ! "green"
|
||||
case "testchild" => child forward "test"
|
||||
case "testchildAndAck" => child forward "test"; sender() ! "ack"
|
||||
case "testchild" => child.forward("test")
|
||||
case "testchildAndAck" => child.forward("test"); sender() ! "ack"
|
||||
}
|
||||
}))
|
||||
|
||||
|
|
@ -451,8 +468,7 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
parent ! latch
|
||||
parent ! "testchildAndAck"
|
||||
expectMsg("ack")
|
||||
filterEvents(
|
||||
EventFilter[IllegalStateException]("OHNOES", occurrences = 1),
|
||||
filterEvents(EventFilter[IllegalStateException]("OHNOES", occurrences = 1),
|
||||
EventFilter.warning(pattern = "dead.*test", occurrences = 1)) {
|
||||
latch.countDown()
|
||||
}
|
||||
|
|
@ -504,7 +520,8 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
"restarts a child infinitely if maxNrOfRetries = -1 and withinTimeRange = Duration.Inf" in {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
val supervisor = system.actorOf(
|
||||
Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = -1, withinTimeRange = Duration.Inf)(classOf[Exception] :: Nil))))
|
||||
|
||||
val pingpong = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
|
@ -520,8 +537,8 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
"treats maxNrOfRetries = -1 as maxNrOfRetries = 1 if withinTimeRange is non-infinite Duration" in {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = -1, withinTimeRange = 10 seconds)(classOf[Exception] :: Nil))))
|
||||
val supervisor = system.actorOf(Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = -1, withinTimeRange = 10 seconds)(classOf[Exception] :: Nil))))
|
||||
|
||||
val pingpong = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
|
|
@ -532,8 +549,8 @@ class SupervisorSpec extends AkkaSpec(SupervisorSpec.config) with BeforeAndAfter
|
|||
}
|
||||
|
||||
"treats withinTimeRange = Duration.Inf as a single infinite restart window" in {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = Duration.Inf)(classOf[Exception] :: Nil))))
|
||||
val supervisor = system.actorOf(Props(
|
||||
new Supervisor(OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = Duration.Inf)(classOf[Exception] :: Nil))))
|
||||
|
||||
val pingpong = child(supervisor, Props(new PingPongActor(testActor)))
|
||||
|
||||
|
|
|
|||
|
|
@ -8,18 +8,22 @@ import language.postfixOps
|
|||
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
import akka.testkit.{ EventFilter, AkkaSpec, ImplicitSender, DefaultTimeout }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout, EventFilter, ImplicitSender }
|
||||
import akka.pattern.ask
|
||||
|
||||
class SupervisorTreeSpec extends AkkaSpec("akka.actor.serialize-messages = off") with ImplicitSender with DefaultTimeout {
|
||||
class SupervisorTreeSpec
|
||||
extends AkkaSpec("akka.actor.serialize-messages = off")
|
||||
with ImplicitSender
|
||||
with DefaultTimeout {
|
||||
|
||||
"In a 3 levels deep supervisor tree (linked in the constructor) we" must {
|
||||
|
||||
"be able to kill the middle actor and see itself and its child restarted" in {
|
||||
EventFilter[ActorKilledException](occurrences = 1) intercept {
|
||||
EventFilter[ActorKilledException](occurrences = 1).intercept {
|
||||
within(5 seconds) {
|
||||
val p = Props(new Actor {
|
||||
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 1 second)(List(classOf[Exception]))
|
||||
override val supervisorStrategy =
|
||||
OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 1 second)(List(classOf[Exception]))
|
||||
def receive = {
|
||||
case p: Props => sender() ! context.actorOf(p)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ class Ticket669Spec extends AkkaSpec with BeforeAndAfterAll with ImplicitSender
|
|||
"A supervised actor with lifecycle PERMANENT" should {
|
||||
"be able to reply on failure during preRestart" in {
|
||||
filterEvents(EventFilter[Exception]("test", occurrences = 1)) {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
AllForOneStrategy(5, 10 seconds)(List(classOf[Exception])))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(new Supervisor(AllForOneStrategy(5, 10 seconds)(List(classOf[Exception])))))
|
||||
val supervised = Await.result((supervisor ? Props[Supervised]).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
supervised.!("test")(testActor)
|
||||
|
|
@ -38,8 +38,8 @@ class Ticket669Spec extends AkkaSpec with BeforeAndAfterAll with ImplicitSender
|
|||
|
||||
"be able to reply on failure during postStop" in {
|
||||
filterEvents(EventFilter[Exception]("test", occurrences = 1)) {
|
||||
val supervisor = system.actorOf(Props(new Supervisor(
|
||||
AllForOneStrategy(maxNrOfRetries = 0)(List(classOf[Exception])))))
|
||||
val supervisor =
|
||||
system.actorOf(Props(new Supervisor(AllForOneStrategy(maxNrOfRetries = 0)(List(classOf[Exception])))))
|
||||
val supervised = Await.result((supervisor ? Props[Supervised]).mapTo[ActorRef], timeout.duration)
|
||||
|
||||
supervised.!("test")(testActor)
|
||||
|
|
|
|||
|
|
@ -15,13 +15,11 @@ object TimerSpec {
|
|||
sealed trait Command
|
||||
case class Tick(n: Int) extends Command
|
||||
case object Bump extends Command
|
||||
case class SlowThenBump(latch: TestLatch) extends Command
|
||||
with NoSerializationVerificationNeeded
|
||||
case class SlowThenBump(latch: TestLatch) extends Command with NoSerializationVerificationNeeded
|
||||
case object End extends Command
|
||||
case class Throw(e: Throwable) extends Command
|
||||
case object Cancel extends Command
|
||||
case class SlowThenThrow(latch: TestLatch, e: Throwable) extends Command
|
||||
with NoSerializationVerificationNeeded
|
||||
case class SlowThenThrow(latch: TestLatch, e: Throwable) extends Command with NoSerializationVerificationNeeded
|
||||
case object AutoReceive extends Command
|
||||
|
||||
sealed trait Event
|
||||
|
|
@ -34,7 +32,9 @@ object TimerSpec {
|
|||
def target(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int): Props =
|
||||
Props(new Target(monitor, interval, repeat, initial))
|
||||
|
||||
class Target(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int) extends Actor with Timers {
|
||||
class Target(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int)
|
||||
extends Actor
|
||||
with Timers {
|
||||
private var bumpCount = initial()
|
||||
|
||||
if (repeat)
|
||||
|
|
@ -86,7 +86,8 @@ object TimerSpec {
|
|||
|
||||
object TheState
|
||||
|
||||
class FsmTarget(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int) extends FSM[TheState.type, Int] {
|
||||
class FsmTarget(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int)
|
||||
extends FSM[TheState.type, Int] {
|
||||
|
||||
private var restarting = false
|
||||
|
||||
|
|
@ -104,7 +105,7 @@ object TimerSpec {
|
|||
|
||||
def bump(bumpCount: Int): State = {
|
||||
setTimer("T", Tick(bumpCount + 1), interval, repeat)
|
||||
stay using (bumpCount + 1)
|
||||
stay.using(bumpCount + 1)
|
||||
}
|
||||
|
||||
def autoReceive(): State = {
|
||||
|
|
@ -148,13 +149,19 @@ object TimerSpec {
|
|||
|
||||
class TimerSpec extends AbstractTimerSpec {
|
||||
override def testName: String = "Timers"
|
||||
override def target(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int = () => 1): Props =
|
||||
override def target(monitor: ActorRef,
|
||||
interval: FiniteDuration,
|
||||
repeat: Boolean,
|
||||
initial: () => Int = () => 1): Props =
|
||||
TimerSpec.target(monitor, interval, repeat, initial)
|
||||
}
|
||||
|
||||
class FsmTimerSpec extends AbstractTimerSpec {
|
||||
override def testName: String = "FSM Timers"
|
||||
override def target(monitor: ActorRef, interval: FiniteDuration, repeat: Boolean, initial: () => Int = () => 1): Props =
|
||||
override def target(monitor: ActorRef,
|
||||
interval: FiniteDuration,
|
||||
repeat: Boolean,
|
||||
initial: () => Int = () => 1): Props =
|
||||
TimerSpec.fsmTarget(monitor, interval, repeat, initial)
|
||||
}
|
||||
|
||||
|
|
@ -232,8 +239,8 @@ abstract class AbstractTimerSpec extends AkkaSpec {
|
|||
"discard timers from old incarnation after restart, alt 1" taggedAs TimingTest in {
|
||||
val probe = TestProbe()
|
||||
val startCounter = new AtomicInteger(0)
|
||||
val ref = system.actorOf(target(probe.ref, dilatedInterval, repeat = true,
|
||||
initial = () => startCounter.incrementAndGet()))
|
||||
val ref = system.actorOf(
|
||||
target(probe.ref, dilatedInterval, repeat = true, initial = () => startCounter.incrementAndGet()))
|
||||
probe.expectMsg(Tock(1))
|
||||
|
||||
val latch = new TestLatch(1)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import akka.japi.{ Option => JOption }
|
|||
import akka.pattern.ask
|
||||
import akka.routing.RoundRobinGroup
|
||||
import akka.serialization.{ JavaSerializer, SerializerWithStringManifest }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout, EventFilter, TimingTest, filterEvents }
|
||||
import akka.testkit.{ filterEvents, AkkaSpec, DefaultTimeout, EventFilter, TimingTest }
|
||||
import akka.util.Timeout
|
||||
import org.scalatest.{ BeforeAndAfterAll, BeforeAndAfterEach }
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ object TypedActorSpec {
|
|||
findNext
|
||||
}
|
||||
|
||||
override def exists(f: T => Boolean): Boolean = items exists f
|
||||
override def exists(f: T => Boolean): Boolean = items.exists(f)
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
|
|
@ -108,7 +108,8 @@ object TypedActorSpec {
|
|||
@throws(classOf[TimeoutException])
|
||||
def read(): Int
|
||||
|
||||
def testMethodCallSerialization(foo: Foo, s: String, i: Int, o: WithStringSerializedClass): Unit = throw new IllegalStateException("expected")
|
||||
def testMethodCallSerialization(foo: Foo, s: String, i: Int, o: WithStringSerializedClass): Unit =
|
||||
throw new IllegalStateException("expected")
|
||||
}
|
||||
|
||||
class Bar extends Foo with Serializable {
|
||||
|
|
@ -177,7 +178,13 @@ object TypedActorSpec {
|
|||
def crash(): Unit
|
||||
}
|
||||
|
||||
class LifeCyclesImpl(val latch: CountDownLatch) extends PreStart with PostStop with PreRestart with PostRestart with LifeCycles with Receiver {
|
||||
class LifeCyclesImpl(val latch: CountDownLatch)
|
||||
extends PreStart
|
||||
with PostStop
|
||||
with PreRestart
|
||||
with PostRestart
|
||||
with LifeCycles
|
||||
with Receiver {
|
||||
|
||||
private def ensureContextAvailable[T](f: => T): T = TypedActor.context match {
|
||||
case null => throw new IllegalStateException("TypedActor.context is null!")
|
||||
|
|
@ -190,13 +197,13 @@ object TypedActorSpec {
|
|||
|
||||
override def postStop(): Unit = ensureContextAvailable(for (i <- 1 to 3) latch.countDown())
|
||||
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit = ensureContextAvailable(for (i <- 1 to 5) latch.countDown())
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit =
|
||||
ensureContextAvailable(for (i <- 1 to 5) latch.countDown())
|
||||
|
||||
override def postRestart(reason: Throwable): Unit = ensureContextAvailable(for (i <- 1 to 7) latch.countDown())
|
||||
|
||||
override def onReceive(msg: Any, sender: ActorRef): Unit = {
|
||||
ensureContextAvailable(
|
||||
msg match {
|
||||
ensureContextAvailable(msg match {
|
||||
case "pigdog" => sender ! "dogpig"
|
||||
})
|
||||
}
|
||||
|
|
@ -233,8 +240,11 @@ object TypedActorSpec {
|
|||
|
||||
}
|
||||
|
||||
class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
||||
with BeforeAndAfterEach with BeforeAndAfterAll with DefaultTimeout {
|
||||
class TypedActorSpec
|
||||
extends AkkaSpec(TypedActorSpec.config)
|
||||
with BeforeAndAfterEach
|
||||
with BeforeAndAfterAll
|
||||
with DefaultTimeout {
|
||||
|
||||
import akka.actor.TypedActorSpec._
|
||||
|
||||
|
|
@ -244,7 +254,8 @@ class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
TypedActor(system).typedActorOf(TypedProps[Bar](classOf[Foo], classOf[Bar]).withTimeout(Timeout(d)))
|
||||
|
||||
def newFooBar(dispatcher: String, d: FiniteDuration): Foo =
|
||||
TypedActor(system).typedActorOf(TypedProps[Bar](classOf[Foo], classOf[Bar]).withTimeout(Timeout(d)).withDispatcher(dispatcher))
|
||||
TypedActor(system).typedActorOf(
|
||||
TypedProps[Bar](classOf[Foo], classOf[Bar]).withTimeout(Timeout(d)).withDispatcher(dispatcher))
|
||||
|
||||
def newStacked(): Stacked =
|
||||
TypedActor(system).typedActorOf(
|
||||
|
|
@ -292,7 +303,7 @@ class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
"be able to call equals" in {
|
||||
val t = newFooBar
|
||||
t should ===(t)
|
||||
t should not equal (null)
|
||||
(t should not).equal(null)
|
||||
mustStop(t)
|
||||
}
|
||||
|
||||
|
|
@ -382,13 +393,15 @@ class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
case p: TypedProps[_] => context.sender() ! TypedActor(context).typedActorOf(p)
|
||||
}
|
||||
}))
|
||||
val t = Await.result((boss ? TypedProps[Bar](classOf[Foo], classOf[Bar]).withTimeout(2 seconds)).mapTo[Foo], timeout.duration)
|
||||
val t = Await.result((boss ? TypedProps[Bar](classOf[Foo], classOf[Bar]).withTimeout(2 seconds)).mapTo[Foo],
|
||||
timeout.duration)
|
||||
|
||||
t.incr()
|
||||
t.failingPigdog()
|
||||
t.read() should ===(1) //Make sure state is not reset after failure
|
||||
|
||||
intercept[IllegalStateException] { Await.result(t.failingFuturePigdog, 2 seconds) }.getMessage should ===("expected")
|
||||
intercept[IllegalStateException] { Await.result(t.failingFuturePigdog, 2 seconds) }.getMessage should ===(
|
||||
"expected")
|
||||
t.read() should ===(1) //Make sure state is not reset after failure
|
||||
|
||||
(intercept[IllegalStateException] { t.failingJOptionPigdog }).getMessage should ===("expected")
|
||||
|
|
@ -474,7 +487,11 @@ class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
import java.io._
|
||||
val someFoo: Foo = new Bar
|
||||
JavaSerializer.currentSystem.withValue(system.asInstanceOf[ExtendedActorSystem]) {
|
||||
val m = TypedActor.MethodCall(classOf[Foo].getDeclaredMethod("testMethodCallSerialization", Array[Class[_]](classOf[Foo], classOf[String], classOf[Int], classOf[WithStringSerializedClass]): _*), Array[AnyRef](someFoo, null, 1.asInstanceOf[AnyRef], WithStringSerializedClass()))
|
||||
val m = TypedActor.MethodCall(
|
||||
classOf[Foo].getDeclaredMethod(
|
||||
"testMethodCallSerialization",
|
||||
Array[Class[_]](classOf[Foo], classOf[String], classOf[Int], classOf[WithStringSerializedClass]): _*),
|
||||
Array[AnyRef](someFoo, null, 1.asInstanceOf[AnyRef], WithStringSerializedClass()))
|
||||
val baos = new ByteArrayOutputStream(8192 * 4)
|
||||
val out = new ObjectOutputStream(baos)
|
||||
|
||||
|
|
@ -526,12 +543,12 @@ class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
val latch = new CountDownLatch(16)
|
||||
val ta = TypedActor(system)
|
||||
val t: LifeCycles = ta.typedActorOf(TypedProps[LifeCyclesImpl](classOf[LifeCycles], new LifeCyclesImpl(latch)))
|
||||
EventFilter[IllegalStateException]("Crash!", occurrences = 1) intercept {
|
||||
EventFilter[IllegalStateException]("Crash!", occurrences = 1).intercept {
|
||||
t.crash()
|
||||
}
|
||||
|
||||
//Sneak in a check for the Receiver override
|
||||
val ref = ta getActorRefFor t
|
||||
val ref = ta.getActorRefFor(t)
|
||||
|
||||
ref.tell("pigdog", testActor)
|
||||
|
||||
|
|
@ -545,8 +562,11 @@ class TypedActorSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
}
|
||||
}
|
||||
|
||||
class TypedActorRouterSpec extends AkkaSpec(TypedActorSpec.config)
|
||||
with BeforeAndAfterEach with BeforeAndAfterAll with DefaultTimeout {
|
||||
class TypedActorRouterSpec
|
||||
extends AkkaSpec(TypedActorSpec.config)
|
||||
with BeforeAndAfterEach
|
||||
with BeforeAndAfterAll
|
||||
with DefaultTimeout {
|
||||
|
||||
import akka.actor.TypedActorSpec._
|
||||
|
||||
|
|
@ -564,7 +584,9 @@ class TypedActorRouterSpec extends AkkaSpec(TypedActorSpec.config)
|
|||
val t2 = newFooBar
|
||||
val t3 = newFooBar
|
||||
val t4 = newFooBar
|
||||
val routees = List(t1, t2, t3, t4) map { t => TypedActor(system).getActorRefFor(t).path.toStringWithoutAddress }
|
||||
val routees = List(t1, t2, t3, t4).map { t =>
|
||||
TypedActor(system).getActorRefFor(t).path.toStringWithoutAddress
|
||||
}
|
||||
|
||||
TypedActor(system).isTypedActor(t1) should ===(true)
|
||||
TypedActor(system).isTypedActor(t2) should ===(true)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package akka.actor
|
||||
|
||||
import akka.testkit.{ TestProbe, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, TestProbe }
|
||||
import akka.actor.SupervisorStrategy.{ Restart, Stop }
|
||||
import akka.dispatch.sysmsg.SystemMessage
|
||||
import akka.event.EventStream
|
||||
|
|
@ -12,15 +12,16 @@ import scala.util.control.NoStackTrace
|
|||
|
||||
object UidClashTest {
|
||||
|
||||
class TerminatedForNonWatchedActor extends Exception("Received Terminated for actor that was not actually watched")
|
||||
class TerminatedForNonWatchedActor
|
||||
extends Exception("Received Terminated for actor that was not actually watched")
|
||||
with NoStackTrace
|
||||
|
||||
@volatile var oldActor: ActorRef = _
|
||||
|
||||
private[akka] class EvilCollidingActorRef(
|
||||
override val provider: ActorRefProvider,
|
||||
private[akka] class EvilCollidingActorRef(override val provider: ActorRefProvider,
|
||||
override val path: ActorPath,
|
||||
val eventStream: EventStream) extends MinimalActorRef {
|
||||
val eventStream: EventStream)
|
||||
extends MinimalActorRef {
|
||||
|
||||
//Ignore everything
|
||||
override def isTerminated: Boolean = true
|
||||
|
|
@ -52,7 +53,7 @@ object UidClashTest {
|
|||
}
|
||||
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
|
||||
context.children foreach { child =>
|
||||
context.children.foreach { child =>
|
||||
oldActor = child
|
||||
context.unwatch(child)
|
||||
context.stop(child)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ package akka.actor.dispatch
|
|||
import language.postfixOps
|
||||
|
||||
import java.rmi.RemoteException
|
||||
import java.util.concurrent.{ TimeUnit, CountDownLatch, ConcurrentHashMap }
|
||||
import java.util.concurrent.atomic.{ AtomicLong, AtomicInteger }
|
||||
import java.util.concurrent.{ ConcurrentHashMap, CountDownLatch, TimeUnit }
|
||||
import java.util.concurrent.atomic.{ AtomicInteger, AtomicLong }
|
||||
|
||||
import org.scalatest.Assertions._
|
||||
|
||||
|
|
@ -91,7 +91,10 @@ object ActorModelSpec {
|
|||
case Increment(count) => { ack(); count.incrementAndGet(); busy.switchOff(()) }
|
||||
case CountDownNStop(l) => { ack(); l.countDown(); context.stop(self); busy.switchOff(()) }
|
||||
case Restart => { ack(); busy.switchOff(()); throw new Exception("Restart requested") }
|
||||
case Interrupt => { ack(); sender() ! Status.Failure(new ActorInterruptedException(new InterruptedException("Ping!"))); busy.switchOff(()); throw new InterruptedException("Ping!") }
|
||||
case Interrupt => {
|
||||
ack(); sender() ! Status.Failure(new ActorInterruptedException(new InterruptedException("Ping!")));
|
||||
busy.switchOff(()); throw new InterruptedException("Ping!")
|
||||
}
|
||||
case InterruptNicely(msg) => { ack(); sender() ! msg; busy.switchOff(()); Thread.currentThread().interrupt() }
|
||||
case ThrowException(e: Throwable) => { ack(); busy.switchOff(()); throw e }
|
||||
case DoubleStop => { ack(); context.stop(self); context.stop(self); busy.switchOff }
|
||||
|
|
@ -106,7 +109,8 @@ object ActorModelSpec {
|
|||
val msgsReceived = new AtomicLong(0)
|
||||
val msgsProcessed = new AtomicLong(0)
|
||||
val restarts = new AtomicLong(0)
|
||||
override def toString = "InterceptorStats(susp=" + suspensions +
|
||||
override def toString =
|
||||
"InterceptorStats(susp=" + suspensions +
|
||||
",res=" + resumes + ",reg=" + registers + ",unreg=" + unregisters +
|
||||
",recv=" + msgsReceived + ",proc=" + msgsProcessed + ",restart=" + restarts
|
||||
}
|
||||
|
|
@ -160,14 +164,18 @@ object ActorModelSpec {
|
|||
}
|
||||
}
|
||||
|
||||
def assertDispatcher(dispatcher: MessageDispatcherInterceptor)(
|
||||
stops: Long = dispatcher.stops.get())(implicit system: ActorSystem): Unit = {
|
||||
def assertDispatcher(dispatcher: MessageDispatcherInterceptor)(stops: Long = dispatcher.stops.get())(
|
||||
implicit system: ActorSystem): Unit = {
|
||||
val deadline = System.currentTimeMillis + dispatcher.shutdownTimeout.toMillis * 5
|
||||
try {
|
||||
await(deadline)(stops == dispatcher.stops.get)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
system.eventStream.publish(Error(e, dispatcher.toString, dispatcher.getClass, "actual: stops=" + dispatcher.stops.get +
|
||||
system.eventStream.publish(
|
||||
Error(e,
|
||||
dispatcher.toString,
|
||||
dispatcher.getClass,
|
||||
"actual: stops=" + dispatcher.stops.get +
|
||||
" required: stops=" + stops))
|
||||
throw e
|
||||
}
|
||||
|
|
@ -194,14 +202,7 @@ object ActorModelSpec {
|
|||
msgsReceived: Long = 0,
|
||||
msgsProcessed: Long = 0,
|
||||
restarts: Long = 0)(implicit system: ActorSystem): Unit = {
|
||||
assertRef(actorRef, dispatcher)(
|
||||
suspensions,
|
||||
resumes,
|
||||
registers,
|
||||
unregisters,
|
||||
msgsReceived,
|
||||
msgsProcessed,
|
||||
restarts)
|
||||
assertRef(actorRef, dispatcher)(suspensions, resumes, registers, unregisters, msgsReceived, msgsProcessed, restarts)
|
||||
}
|
||||
|
||||
def assertRef(actorRef: ActorRef, dispatcher: MessageDispatcher = null)(
|
||||
|
|
@ -212,7 +213,9 @@ object ActorModelSpec {
|
|||
msgsReceived: Long = statsFor(actorRef, dispatcher).msgsReceived.get(),
|
||||
msgsProcessed: Long = statsFor(actorRef, dispatcher).msgsProcessed.get(),
|
||||
restarts: Long = statsFor(actorRef, dispatcher).restarts.get())(implicit system: ActorSystem): Unit = {
|
||||
val stats = statsFor(actorRef, Option(dispatcher).getOrElse(actorRef.asInstanceOf[ActorRefWithCell].underlying.asInstanceOf[ActorCell].dispatcher))
|
||||
val stats = statsFor(actorRef,
|
||||
Option(dispatcher).getOrElse(
|
||||
actorRef.asInstanceOf[ActorRefWithCell].underlying.asInstanceOf[ActorCell].dispatcher))
|
||||
val deadline = System.currentTimeMillis + 1000
|
||||
try {
|
||||
await(deadline)(stats.suspensions.get() == suspensions)
|
||||
|
|
@ -224,10 +227,10 @@ object ActorModelSpec {
|
|||
await(deadline)(stats.restarts.get() == restarts)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
system.eventStream.publish(Error(
|
||||
e,
|
||||
system.eventStream.publish(
|
||||
Error(e,
|
||||
Option(dispatcher).toString,
|
||||
(Option(dispatcher) getOrElse this).getClass,
|
||||
Option(dispatcher).getOrElse(this).getClass,
|
||||
"actual: " + stats + ", required: InterceptorStats(susp=" + suspensions +
|
||||
",res=" + resumes + ",reg=" + registers + ",unreg=" + unregisters +
|
||||
",recv=" + msgsReceived + ",proc=" + msgsProcessed + ",restart=" + restarts))
|
||||
|
|
@ -273,8 +276,7 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
assertDispatcher(dispatcher)(stops = 0)
|
||||
system.stop(a)
|
||||
assertDispatcher(dispatcher)(stops = 1)
|
||||
assertRef(a, dispatcher)(
|
||||
suspensions = 0,
|
||||
assertRef(a, dispatcher)(suspensions = 0,
|
||||
resumes = 0,
|
||||
registers = 1,
|
||||
unregisters = 1,
|
||||
|
|
@ -335,7 +337,8 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
def spawn(f: => Unit): Unit = {
|
||||
(new Thread {
|
||||
override def run(): Unit =
|
||||
try f catch {
|
||||
try f
|
||||
catch {
|
||||
case e: Throwable => system.eventStream.publish(Error(e, "spawn", this.getClass, "error in spawned thread"))
|
||||
}
|
||||
}).start()
|
||||
|
|
@ -353,12 +356,15 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
|
||||
a.resume(causedByFailure = null)
|
||||
assertCountDown(done, 3.seconds.dilated.toMillis, "Should resume processing of messages when resumed")
|
||||
assertRefDefaultZero(a)(registers = 1, msgsReceived = 1, msgsProcessed = 1,
|
||||
suspensions = 1, resumes = 1)
|
||||
assertRefDefaultZero(a)(registers = 1, msgsReceived = 1, msgsProcessed = 1, suspensions = 1, resumes = 1)
|
||||
|
||||
system.stop(a)
|
||||
assertRefDefaultZero(a)(registers = 1, unregisters = 1, msgsReceived = 1, msgsProcessed = 1,
|
||||
suspensions = 1, resumes = 1)
|
||||
assertRefDefaultZero(a)(registers = 1,
|
||||
unregisters = 1,
|
||||
msgsReceived = 1,
|
||||
msgsProcessed = 1,
|
||||
suspensions = 1,
|
||||
resumes = 1)
|
||||
}
|
||||
|
||||
"handle waves of actors" in {
|
||||
|
|
@ -381,7 +387,8 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
// the boss doesn't create children fast enough to keep the dispatcher from becoming empty
|
||||
// and it needs to be on a separate thread to not deadlock the calling thread dispatcher
|
||||
new Thread(new Runnable {
|
||||
def run() = Future {
|
||||
def run() =
|
||||
Future {
|
||||
keepAliveLatch.await(waitTime, TimeUnit.MILLISECONDS)
|
||||
}(dispatcher)
|
||||
}).start()
|
||||
|
|
@ -395,18 +402,18 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
val team = dispatcher.team
|
||||
val mq = dispatcher.messageQueue
|
||||
|
||||
System.err.println("Teammates left: " + team.size + " stopLatch: " + stopLatch.getCount + " inhab:" + dispatcher.inhabitants)
|
||||
System.err.println(
|
||||
"Teammates left: " + team.size + " stopLatch: " + stopLatch.getCount + " inhab:" + dispatcher.inhabitants)
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
team.asScala.toList
|
||||
.sortBy(_.self.path)
|
||||
.foreach { cell: ActorCell =>
|
||||
System.err.println(" - " + cell.self.path + " " + cell.isTerminated + " " + cell.mailbox.currentStatus + " "
|
||||
team.asScala.toList.sortBy(_.self.path).foreach { cell: ActorCell =>
|
||||
System.err.println(
|
||||
" - " + cell.self.path + " " + cell.isTerminated + " " + cell.mailbox.currentStatus + " "
|
||||
+ cell.mailbox.numberOfMessages + " " + cell.mailbox.systemDrain(SystemMessageList.LNil).size)
|
||||
}
|
||||
|
||||
System.err.println("Mailbox: " + mq.numberOfMessages + " " + mq.hasMessages)
|
||||
Iterator.continually(mq.dequeue) takeWhile (_ ne null) foreach System.err.println
|
||||
Iterator.continually(mq.dequeue).takeWhile(_ ne null).foreach(System.err.println)
|
||||
case _ =>
|
||||
}
|
||||
|
||||
|
|
@ -425,8 +432,7 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
}
|
||||
|
||||
"continue to process messages when a thread gets interrupted and throws an exception" in {
|
||||
filterEvents(
|
||||
EventFilter[InterruptedException](),
|
||||
filterEvents(EventFilter[InterruptedException](),
|
||||
EventFilter[ActorInterruptedException](),
|
||||
EventFilter[akka.event.Logging.LoggerException]()) {
|
||||
implicit val dispatcher = interceptedDispatcher()
|
||||
|
|
@ -442,10 +448,10 @@ abstract class ActorModelSpec(config: String) extends AkkaSpec(config) with Defa
|
|||
|
||||
val c = system.scheduler.scheduleOnce(2.seconds) {
|
||||
import collection.JavaConverters._
|
||||
Thread.getAllStackTraces().asScala foreach {
|
||||
Thread.getAllStackTraces().asScala.foreach {
|
||||
case (thread, stack) =>
|
||||
println(s"$thread:")
|
||||
stack foreach (s => println(s"\t$s"))
|
||||
stack.foreach(s => println(s"\t$s"))
|
||||
}
|
||||
}
|
||||
assert(Await.result(f1, timeout.duration) === "foo")
|
||||
|
|
@ -535,8 +541,7 @@ object DispatcherModelSpec {
|
|||
import akka.util.Helpers.ConfigOps
|
||||
|
||||
private val instance: MessageDispatcher =
|
||||
new Dispatcher(
|
||||
this,
|
||||
new Dispatcher(this,
|
||||
config.getString("id"),
|
||||
config.getInt("throughput"),
|
||||
config.getNanosDuration("throughput-deadline-time"),
|
||||
|
|
@ -554,7 +559,9 @@ class DispatcherModelSpec extends ActorModelSpec(DispatcherModelSpec.config) {
|
|||
|
||||
override def interceptedDispatcher(): MessageDispatcherInterceptor = {
|
||||
// use new id for each test, since the MessageDispatcherInterceptor holds state
|
||||
system.dispatchers.lookup("test-dispatcher-" + dispatcherCount.incrementAndGet()).asInstanceOf[MessageDispatcherInterceptor]
|
||||
system.dispatchers
|
||||
.lookup("test-dispatcher-" + dispatcherCount.incrementAndGet())
|
||||
.asInstanceOf[MessageDispatcherInterceptor]
|
||||
}
|
||||
|
||||
override def dispatcherType = "Dispatcher"
|
||||
|
|
@ -596,7 +603,8 @@ object BalancingDispatcherModelSpec {
|
|||
}
|
||||
""" +
|
||||
// use unique dispatcher id for each test, since MessageDispatcherInterceptor holds state
|
||||
(for (n <- 1 to 30) yield """
|
||||
(for (n <- 1 to 30)
|
||||
yield """
|
||||
test-balancing-dispatcher-%s {
|
||||
type = "akka.actor.dispatch.BalancingDispatcherModelSpec$BalancingMessageDispatcherInterceptorConfigurator"
|
||||
throughput=1
|
||||
|
|
@ -609,8 +617,7 @@ object BalancingDispatcherModelSpec {
|
|||
import akka.util.Helpers.ConfigOps
|
||||
|
||||
override protected def create(mailboxType: MailboxType): BalancingDispatcher =
|
||||
new BalancingDispatcher(
|
||||
this,
|
||||
new BalancingDispatcher(this,
|
||||
config.getString("id"),
|
||||
config.getInt("throughput"),
|
||||
config.getNanosDuration("throughput-deadline-time"),
|
||||
|
|
@ -628,7 +635,9 @@ class BalancingDispatcherModelSpec extends ActorModelSpec(BalancingDispatcherMod
|
|||
|
||||
override def interceptedDispatcher(): MessageDispatcherInterceptor = {
|
||||
// use new id for each test, since the MessageDispatcherInterceptor holds state
|
||||
system.dispatchers.lookup("test-balancing-dispatcher-" + dispatcherCount.incrementAndGet()).asInstanceOf[MessageDispatcherInterceptor]
|
||||
system.dispatchers
|
||||
.lookup("test-balancing-dispatcher-" + dispatcherCount.incrementAndGet())
|
||||
.asInstanceOf[MessageDispatcherInterceptor]
|
||||
}
|
||||
|
||||
override def dispatcherType = "Balancing Dispatcher"
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
package akka.actor.dispatch
|
||||
|
||||
import java.util.concurrent.{ TimeUnit, CountDownLatch }
|
||||
import java.util.concurrent.{ CountDownLatch, TimeUnit }
|
||||
|
||||
import akka.actor.{ Props, ActorRefWithCell, ActorCell, Actor }
|
||||
import akka.actor.{ Actor, ActorCell, ActorRefWithCell, Props }
|
||||
import akka.dispatch.Mailbox
|
||||
import akka.testkit.AkkaSpec
|
||||
|
||||
|
|
@ -48,15 +48,18 @@ class BalancingDispatcherSpec extends AkkaSpec(BalancingDispatcherSpec.config) {
|
|||
def receive = { case _ => {} }
|
||||
}
|
||||
|
||||
class ChildActor extends ParentActor {
|
||||
}
|
||||
class ChildActor extends ParentActor {}
|
||||
|
||||
"A BalancingDispatcher" must {
|
||||
"have fast actor stealing work from slow actor" in {
|
||||
val finishedCounter = new CountDownLatch(110)
|
||||
|
||||
val slow = system.actorOf(Props(new DelayableActor(50, finishedCounter)).withDispatcher(delayableActorDispatcher)).asInstanceOf[ActorRefWithCell]
|
||||
val fast = system.actorOf(Props(new DelayableActor(10, finishedCounter)).withDispatcher(delayableActorDispatcher)).asInstanceOf[ActorRefWithCell]
|
||||
val slow = system
|
||||
.actorOf(Props(new DelayableActor(50, finishedCounter)).withDispatcher(delayableActorDispatcher))
|
||||
.asInstanceOf[ActorRefWithCell]
|
||||
val fast = system
|
||||
.actorOf(Props(new DelayableActor(10, finishedCounter)).withDispatcher(delayableActorDispatcher))
|
||||
.asInstanceOf[ActorRefWithCell]
|
||||
|
||||
var sentToFast = 0
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import language.postfixOps
|
|||
import java.util.concurrent.{ CountDownLatch, TimeUnit }
|
||||
import java.util.concurrent.atomic.{ AtomicBoolean }
|
||||
import akka.testkit.{ AkkaSpec }
|
||||
import akka.actor.{ Props, Actor }
|
||||
import akka.actor.{ Actor, Props }
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
import akka.testkit.DefaultTimeout
|
||||
|
|
@ -80,11 +80,9 @@ class DispatcherActorSpec extends AkkaSpec(DispatcherActorSpec.config) with Defa
|
|||
val latch = new CountDownLatch(100)
|
||||
val start = new CountDownLatch(1)
|
||||
val fastOne = system.actorOf(
|
||||
Props(new Actor { def receive = { case "sabotage" => works.set(false) } })
|
||||
.withDispatcher(throughputDispatcher))
|
||||
Props(new Actor { def receive = { case "sabotage" => works.set(false) } }).withDispatcher(throughputDispatcher))
|
||||
|
||||
val slowOne = system.actorOf(
|
||||
Props(new Actor {
|
||||
val slowOne = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "hogexecutor" => { sender() ! "OK"; start.await }
|
||||
case "ping" => if (works.get) latch.countDown()
|
||||
|
|
@ -92,7 +90,9 @@ class DispatcherActorSpec extends AkkaSpec(DispatcherActorSpec.config) with Defa
|
|||
}).withDispatcher(throughputDispatcher))
|
||||
|
||||
assert(Await.result(slowOne ? "hogexecutor", timeout.duration) === "OK")
|
||||
(1 to 100) foreach { _ => slowOne ! "ping" }
|
||||
(1 to 100).foreach { _ =>
|
||||
slowOne ! "ping"
|
||||
}
|
||||
fastOne ! "sabotage"
|
||||
start.countDown()
|
||||
latch.await(10, TimeUnit.SECONDS)
|
||||
|
|
@ -110,15 +110,13 @@ class DispatcherActorSpec extends AkkaSpec(DispatcherActorSpec.config) with Defa
|
|||
val start = new CountDownLatch(1)
|
||||
val ready = new CountDownLatch(1)
|
||||
|
||||
val fastOne = system.actorOf(
|
||||
Props(new Actor {
|
||||
val fastOne = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "ping" => if (works.get) latch.countDown(); context.stop(self)
|
||||
}
|
||||
}).withDispatcher(throughputDispatcher))
|
||||
|
||||
val slowOne = system.actorOf(
|
||||
Props(new Actor {
|
||||
val slowOne = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "hogexecutor" => { ready.countDown(); start.await }
|
||||
case "ping" => { works.set(false); context.stop(self) }
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ object DispatchersSpec {
|
|||
}
|
||||
|
||||
class OneShotMailboxType(settings: ActorSystem.Settings, config: Config)
|
||||
extends MailboxType with ProducesMessageQueue[DoublingMailbox] {
|
||||
extends MailboxType
|
||||
with ProducesMessageQueue[DoublingMailbox] {
|
||||
val created = new AtomicBoolean(false)
|
||||
override def create(owner: Option[ActorRef], system: Option[ActorSystem]) =
|
||||
if (created.compareAndSet(false, true)) {
|
||||
|
|
@ -82,8 +83,8 @@ object DispatchersSpec {
|
|||
class DoublingMailbox(owner: Option[ActorRef]) extends UnboundedQueueBasedMessageQueue {
|
||||
final val queue = new ConcurrentLinkedQueue[Envelope]()
|
||||
override def enqueue(receiver: ActorRef, handle: Envelope): Unit = {
|
||||
queue add handle
|
||||
queue add handle
|
||||
queue.add(handle)
|
||||
queue.add(handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,19 +109,20 @@ class DispatchersSpec extends AkkaSpec(DispatchersSpec.config) with ImplicitSend
|
|||
val id = "id"
|
||||
|
||||
def instance(dispatcher: MessageDispatcher): (MessageDispatcher) => Boolean = _ == dispatcher
|
||||
def ofType[T <: MessageDispatcher: ClassTag]: (MessageDispatcher) => Boolean = _.getClass == implicitly[ClassTag[T]].runtimeClass
|
||||
def ofType[T <: MessageDispatcher: ClassTag]: (MessageDispatcher) => Boolean =
|
||||
_.getClass == implicitly[ClassTag[T]].runtimeClass
|
||||
|
||||
def typesAndValidators: Map[String, (MessageDispatcher) => Boolean] = Map(
|
||||
"PinnedDispatcher" -> ofType[PinnedDispatcher],
|
||||
"Dispatcher" -> ofType[Dispatcher])
|
||||
def typesAndValidators: Map[String, (MessageDispatcher) => Boolean] =
|
||||
Map("PinnedDispatcher" -> ofType[PinnedDispatcher], "Dispatcher" -> ofType[Dispatcher])
|
||||
|
||||
def validTypes = typesAndValidators.keys.toList
|
||||
|
||||
val defaultDispatcherConfig = settings.config.getConfig("akka.actor.default-dispatcher")
|
||||
|
||||
lazy val allDispatchers: Map[String, MessageDispatcher] = {
|
||||
validTypes.map(t => (t, from(ConfigFactory.parseMap(Map(tipe -> t, id -> t).asJava).
|
||||
withFallback(defaultDispatcherConfig)))).toMap
|
||||
validTypes
|
||||
.map(t => (t, from(ConfigFactory.parseMap(Map(tipe -> t, id -> t).asJava).withFallback(defaultDispatcherConfig))))
|
||||
.toMap
|
||||
}
|
||||
|
||||
def assertMyDispatcherIsUsed(actor: ActorRef): Unit = {
|
||||
|
|
@ -157,8 +159,10 @@ class DispatchersSpec extends AkkaSpec(DispatchersSpec.config) with ImplicitSend
|
|||
|
||||
"throw ConfigurationException if type does not exist" in {
|
||||
intercept[ConfigurationException] {
|
||||
from(ConfigFactory.parseMap(Map(tipe -> "typedoesntexist", id -> "invalid-dispatcher").asJava).
|
||||
withFallback(defaultDispatcherConfig))
|
||||
from(
|
||||
ConfigFactory
|
||||
.parseMap(Map(tipe -> "typedoesntexist", id -> "invalid-dispatcher").asJava)
|
||||
.withFallback(defaultDispatcherConfig))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package akka.actor.dispatch
|
|||
import java.util.concurrent.{ CountDownLatch, TimeUnit }
|
||||
|
||||
import akka.testkit._
|
||||
import akka.actor.{ Props, Actor }
|
||||
import akka.actor.{ Actor, Props }
|
||||
import akka.testkit.AkkaSpec
|
||||
import org.scalatest.BeforeAndAfterEach
|
||||
import scala.concurrent.Await
|
||||
|
|
@ -38,7 +38,8 @@ class PinnedActorSpec extends AkkaSpec(PinnedActorSpec.config) with BeforeAndAft
|
|||
|
||||
"support tell" in {
|
||||
var oneWay = new CountDownLatch(1)
|
||||
val actor = system.actorOf(Props(new Actor { def receive = { case "OneWay" => oneWay.countDown() } }).withDispatcher("pinned-dispatcher"))
|
||||
val actor = system.actorOf(
|
||||
Props(new Actor { def receive = { case "OneWay" => oneWay.countDown() } }).withDispatcher("pinned-dispatcher"))
|
||||
val result = actor ! "OneWay"
|
||||
assert(oneWay.await(1, TimeUnit.SECONDS))
|
||||
system.stop(actor)
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@ class DispatchSpec extends AkkaSpec("akka.actor.serialize-messages = on") with D
|
|||
"The dispatcher" should {
|
||||
"log an appropriate message when akka.actor.serialize-messages triggers a serialization error" in {
|
||||
val actor = system.actorOf(Props[EmptyActor])
|
||||
EventFilter[Exception](pattern = ".*NoSerializationVerificationNeeded.*", occurrences = 1) intercept {
|
||||
EventFilter[Exception](pattern = ".*NoSerializationVerificationNeeded.*", occurrences = 1).intercept {
|
||||
actor ! new UnserializableMessageClass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@ class ListenerSpec extends AkkaSpec {
|
|||
val barCount = new AtomicInteger(0)
|
||||
|
||||
val broadcast = system.actorOf(Props(new Actor with Listeners {
|
||||
def receive = listenerManagement orElse {
|
||||
def receive = listenerManagement.orElse {
|
||||
case "foo" => gossip("bar")
|
||||
}
|
||||
}))
|
||||
|
||||
def newListener = system.actorOf(Props(new Actor {
|
||||
def newListener =
|
||||
system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "bar" =>
|
||||
barCount.incrementAndGet
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ class ActorSystemSetupSpec extends WordSpec with Matchers {
|
|||
|
||||
"store and retrieve a setup" in {
|
||||
val setup = DummySetup("Al Dente")
|
||||
val setups = ActorSystemSetup()
|
||||
.withSetup(setup)
|
||||
val setups = ActorSystemSetup().withSetup(setup)
|
||||
|
||||
setups.get[DummySetup] should ===(Some(setup))
|
||||
setups.get[DummySetup2] should ===(None)
|
||||
|
|
@ -28,9 +27,7 @@ class ActorSystemSetupSpec extends WordSpec with Matchers {
|
|||
"replace setup if already defined" in {
|
||||
val setup1 = DummySetup("Al Dente")
|
||||
val setup2 = DummySetup("Earl E. Bird")
|
||||
val setups = ActorSystemSetup()
|
||||
.withSetup(setup1)
|
||||
.withSetup(setup2)
|
||||
val setups = ActorSystemSetup().withSetup(setup1).withSetup(setup2)
|
||||
|
||||
setups.get[DummySetup] should ===(Some(setup2))
|
||||
}
|
||||
|
|
@ -61,10 +58,7 @@ class ActorSystemSetupSpec extends WordSpec with Matchers {
|
|||
val setup = DummySetup("Tad Moore")
|
||||
system = ActorSystem("name", ActorSystemSetup(setup))
|
||||
|
||||
system
|
||||
.settings
|
||||
.setup
|
||||
.get[DummySetup] should ===(Some(setup))
|
||||
system.settings.setup.get[DummySetup] should ===(Some(setup))
|
||||
|
||||
} finally {
|
||||
TestKit.shutdownActorSystem(system)
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ class Future2ActorSpec extends AkkaSpec with DefaultTimeout {
|
|||
"The Future2Actor bridge" must {
|
||||
|
||||
"support convenient sending to multiple destinations" in {
|
||||
Future(42) pipeTo testActor pipeTo testActor
|
||||
Future(42).pipeTo(testActor).pipeTo(testActor)
|
||||
expectMsgAllOf(1 second, 42, 42)
|
||||
}
|
||||
|
||||
"support convenient sending to multiple destinations with implicit sender" in {
|
||||
implicit val someActor = system.actorOf(Props(new Actor { def receive = Actor.emptyBehavior }))
|
||||
Future(42) pipeTo testActor pipeTo testActor
|
||||
Future(42).pipeTo(testActor).pipeTo(testActor)
|
||||
expectMsgAllOf(1 second, 42, 42)
|
||||
lastSender should ===(someActor)
|
||||
}
|
||||
|
|
@ -40,8 +40,8 @@ class Future2ActorSpec extends AkkaSpec with DefaultTimeout {
|
|||
"support reply via sender" in {
|
||||
val actor = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case "do" => Future(31) pipeTo context.sender()
|
||||
case "ex" => Future(throw new AssertionError) pipeTo context.sender()
|
||||
case "do" => Future(31).pipeTo(context.sender())
|
||||
case "ex" => Future(throw new AssertionError).pipeTo(context.sender())
|
||||
}
|
||||
}))
|
||||
Await.result(actor ? "do", timeout.duration) should ===(31)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package akka.dispatch
|
||||
|
||||
import akka.testkit.{ DefaultTimeout, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout }
|
||||
import akka.actor.{ Actor, Props }
|
||||
|
||||
object ControlAwareDispatcherSpec {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ class DispatcherShutdownSpec extends WordSpec with Matchers {
|
|||
"eventually shutdown when used after system terminate" in {
|
||||
|
||||
val threads = ManagementFactory.getThreadMXBean()
|
||||
def threadCount = threads
|
||||
.dumpAllThreads(false, false).toList
|
||||
def threadCount =
|
||||
threads
|
||||
.dumpAllThreads(false, false)
|
||||
.toList
|
||||
.map(_.getThreadName)
|
||||
.filter(_.startsWith("DispatcherShutdownSpec-akka.actor.default"))
|
||||
.size
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
package akka.dispatch
|
||||
|
||||
import java.util.concurrent.{ ExecutorService, Executor, Executors }
|
||||
import java.util.concurrent.{ Executor, ExecutorService, Executors }
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutor, ExecutionContextExecutorService }
|
||||
import scala.concurrent.{ Await, blocking, Promise, Future }
|
||||
import scala.concurrent.{ blocking, Await, Future, Promise }
|
||||
import scala.concurrent.duration._
|
||||
import akka.testkit.{ TestLatch, AkkaSpec, DefaultTimeout }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout, TestLatch }
|
||||
import akka.util.SerializedSuspendableExecutionContext
|
||||
import akka.testkit.TestActorRef
|
||||
import akka.actor.Props
|
||||
|
|
@ -45,7 +45,8 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
|
||||
import system.dispatcher
|
||||
|
||||
def batchable[T](f: => T)(implicit ec: ExecutionContext): Unit = ec.execute(new Batchable {
|
||||
def batchable[T](f: => T)(implicit ec: ExecutionContext): Unit =
|
||||
ec.execute(new Batchable {
|
||||
override def isBatchable = true
|
||||
override def run: Unit = f
|
||||
})
|
||||
|
|
@ -54,12 +55,13 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
batchable {
|
||||
val lock, callingThreadLock, count = new AtomicInteger(0)
|
||||
callingThreadLock.compareAndSet(0, 1) // Enable the lock
|
||||
(1 to 100) foreach { i =>
|
||||
(1 to 100).foreach { i =>
|
||||
batchable {
|
||||
if (callingThreadLock.get != 0) p.tryFailure(new IllegalStateException("Batch was executed inline!"))
|
||||
else if (count.incrementAndGet == 100) p.trySuccess(()) //Done
|
||||
else if (lock.compareAndSet(0, 1)) {
|
||||
try Thread.sleep(10) finally lock.compareAndSet(1, 0)
|
||||
try Thread.sleep(10)
|
||||
finally lock.compareAndSet(1, 0)
|
||||
} else p.tryFailure(new IllegalStateException("Executed batch in parallel!"))
|
||||
}
|
||||
}
|
||||
|
|
@ -72,14 +74,15 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
system.dispatcher.isInstanceOf[BatchingExecutor] should ===(true)
|
||||
import system.dispatcher
|
||||
|
||||
def batchable[T](f: => T)(implicit ec: ExecutionContext): Unit = ec.execute(new Batchable {
|
||||
def batchable[T](f: => T)(implicit ec: ExecutionContext): Unit =
|
||||
ec.execute(new Batchable {
|
||||
override def isBatchable = true
|
||||
override def run: Unit = f
|
||||
})
|
||||
|
||||
val latch = TestLatch(101)
|
||||
batchable {
|
||||
(1 to 100) foreach { i =>
|
||||
(1 to 100).foreach { i =>
|
||||
batchable {
|
||||
val deadlock = TestLatch(1)
|
||||
batchable { deadlock.open() }
|
||||
|
|
@ -100,7 +103,9 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
// this needs to be within an OnCompleteRunnable so that things are added to the batch
|
||||
val p = Future.successful(42)
|
||||
// we need the callback list to be non-empty when the blocking{} call is executing
|
||||
p.onComplete { _ => () }
|
||||
p.onComplete { _ =>
|
||||
()
|
||||
}
|
||||
val r = p.map { _ =>
|
||||
// trigger the resubmitUnbatched() call
|
||||
blocking { () }
|
||||
|
|
@ -109,7 +114,9 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
// now try again to blockOn()
|
||||
blocking { () }
|
||||
}
|
||||
p.onComplete { _ => () }
|
||||
p.onComplete { _ =>
|
||||
()
|
||||
}
|
||||
r
|
||||
}
|
||||
Await.result(f, 3.seconds) should be(())
|
||||
|
|
@ -157,7 +164,7 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
}))
|
||||
val b = TestActorRef(Props(new Actor {
|
||||
def receive = {
|
||||
case msg => a forward msg
|
||||
case msg => a.forward(msg)
|
||||
}
|
||||
}))
|
||||
val p = TestProbe()
|
||||
|
|
@ -193,7 +200,7 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
"be suspendable and resumable" in {
|
||||
val sec = SerializedSuspendableExecutionContext(1)(ExecutionContext.global)
|
||||
val counter = new AtomicInteger(0)
|
||||
def perform(f: Int => Int) = sec execute new Runnable { def run = counter.set(f(counter.get)) }
|
||||
def perform(f: Int => Int) = sec.execute(new Runnable { def run = counter.set(f(counter.get)) })
|
||||
perform(_ + 1)
|
||||
perform(x => { sec.suspend(); x * 2 })
|
||||
awaitCond(counter.get == 2)
|
||||
|
|
@ -220,10 +227,12 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
val throughput = 25
|
||||
val sec = SerializedSuspendableExecutionContext(throughput)(underlying)
|
||||
sec.suspend()
|
||||
def perform(f: Int => Int) = sec execute new Runnable { def run = counter.set(f(counter.get)) }
|
||||
def perform(f: Int => Int) = sec.execute(new Runnable { def run = counter.set(f(counter.get)) })
|
||||
|
||||
val total = 1000
|
||||
1 to total foreach { _ => perform(_ + 1) }
|
||||
(1 to total).foreach { _ =>
|
||||
perform(_ + 1)
|
||||
}
|
||||
sec.size() should ===(total)
|
||||
sec.resume()
|
||||
awaitCond(counter.get == total)
|
||||
|
|
@ -235,9 +244,11 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
val sec = SerializedSuspendableExecutionContext(1)(ExecutionContext.global)
|
||||
val total = 10000
|
||||
val counter = new AtomicInteger(0)
|
||||
def perform(f: Int => Int) = sec execute new Runnable { def run = counter.set(f(counter.get)) }
|
||||
def perform(f: Int => Int) = sec.execute(new Runnable { def run = counter.set(f(counter.get)) })
|
||||
|
||||
1 to total foreach { i => perform(c => if (c == (i - 1)) c + 1 else c) }
|
||||
(1 to total).foreach { i =>
|
||||
perform(c => if (c == (i - 1)) c + 1 else c)
|
||||
}
|
||||
awaitCond(counter.get == total)
|
||||
sec.isEmpty should ===(true)
|
||||
}
|
||||
|
|
@ -252,9 +263,11 @@ class ExecutionContextSpec extends AkkaSpec with DefaultTimeout {
|
|||
val throughput = 25
|
||||
val sec = SerializedSuspendableExecutionContext(throughput)(underlying)
|
||||
sec.suspend()
|
||||
def perform(f: Int => Int) = sec execute new Runnable { def run = counter.set(f(counter.get)) }
|
||||
def perform(f: Int => Int) = sec.execute(new Runnable { def run = counter.set(f(counter.get)) })
|
||||
perform(_ + 1)
|
||||
1 to 10 foreach { _ => perform(identity) }
|
||||
(1 to 10).foreach { _ =>
|
||||
perform(identity)
|
||||
}
|
||||
perform(x => { sec.suspend(); x * 2 })
|
||||
perform(_ + 8)
|
||||
sec.size should ===(13)
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@
|
|||
package akka.dispatch
|
||||
|
||||
import akka.actor.{ Actor, Props }
|
||||
import akka.testkit.{ ImplicitSender, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, ImplicitSender }
|
||||
import com.typesafe.config.ConfigFactory
|
||||
|
||||
object ForkJoinPoolStarvationSpec {
|
||||
val config = ConfigFactory.parseString(
|
||||
"""
|
||||
val config = ConfigFactory.parseString("""
|
||||
|actorhang {
|
||||
|
|
||||
| task-dispatcher {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ package akka.dispatch
|
|||
|
||||
import language.postfixOps
|
||||
|
||||
import java.util.concurrent.{ ConcurrentLinkedQueue, BlockingQueue }
|
||||
import org.scalatest.{ BeforeAndAfterEach, BeforeAndAfterAll }
|
||||
import java.util.concurrent.{ BlockingQueue, ConcurrentLinkedQueue }
|
||||
import org.scalatest.{ BeforeAndAfterAll, BeforeAndAfterEach }
|
||||
import com.typesafe.config.{ Config, ConfigFactory }
|
||||
import akka.actor._
|
||||
import akka.testkit.{ EventFilter, AkkaSpec }
|
||||
import scala.concurrent.{ Future, Await, ExecutionContext }
|
||||
import akka.testkit.{ AkkaSpec, EventFilter }
|
||||
import scala.concurrent.{ Await, ExecutionContext, Future }
|
||||
import scala.concurrent.duration._
|
||||
|
||||
abstract class MailboxSpec extends AkkaSpec with BeforeAndAfterAll with BeforeAndAfterEach {
|
||||
|
|
@ -126,17 +126,16 @@ abstract class MailboxSpec extends AkkaSpec with BeforeAndAfterAll with BeforeAn
|
|||
q.hasMessages should ===(false)
|
||||
}
|
||||
|
||||
def testEnqueueDequeue(
|
||||
config: MailboxType,
|
||||
def testEnqueueDequeue(config: MailboxType,
|
||||
enqueueN: Int = 10000,
|
||||
dequeueN: Int = 10000,
|
||||
parallel: Boolean = true): Unit = within(10 seconds) {
|
||||
val q = factory(config)
|
||||
ensureInitialMailboxState(config, q)
|
||||
|
||||
EventFilter.warning(
|
||||
pattern = "received dead letter without sender",
|
||||
occurrences = (enqueueN - dequeueN)) intercept {
|
||||
EventFilter
|
||||
.warning(pattern = "received dead letter without sender", occurrences = (enqueueN - dequeueN))
|
||||
.intercept {
|
||||
|
||||
def createProducer(fromNum: Int, toNum: Int): Future[Vector[Envelope]] = spawn {
|
||||
val messages = Vector() ++ (for (i <- fromNum to toNum) yield createMessageInvocation(i))
|
||||
|
|
@ -149,7 +148,7 @@ abstract class MailboxSpec extends AkkaSpec with BeforeAndAfterAll with BeforeAn
|
|||
val ps = for (i <- (1 to enqueueN by step).toList) yield createProducer(i, Math.min(enqueueN, i + step - 1))
|
||||
|
||||
if (parallel == false)
|
||||
ps foreach { Await.ready(_, remainingOrDefault) }
|
||||
ps.foreach { Await.ready(_, remainingOrDefault) }
|
||||
|
||||
ps
|
||||
}
|
||||
|
|
@ -157,8 +156,9 @@ abstract class MailboxSpec extends AkkaSpec with BeforeAndAfterAll with BeforeAn
|
|||
def createConsumer: Future[Vector[Envelope]] = spawn {
|
||||
var r = Vector[Envelope]()
|
||||
|
||||
while (producers.exists(_.isCompleted == false) || q.hasMessages)
|
||||
Option(q.dequeue) foreach { message => r = r :+ message }
|
||||
while (producers.exists(_.isCompleted == false) || q.hasMessages) Option(q.dequeue).foreach { message =>
|
||||
r = r :+ message
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
|
@ -173,9 +173,9 @@ abstract class MailboxSpec extends AkkaSpec with BeforeAndAfterAll with BeforeAn
|
|||
//No message is allowed to be consumed by more than one consumer
|
||||
cs.flatten.distinct.size should ===(dequeueN)
|
||||
//All consumed messages should have been produced
|
||||
(cs.flatten diff ps.flatten).size should ===(0)
|
||||
cs.flatten.diff(ps.flatten).size should ===(0)
|
||||
//The ones that were produced and not consumed
|
||||
(ps.flatten diff cs.flatten).size should ===(enqueueN - dequeueN)
|
||||
ps.flatten.diff(cs.flatten).size should ===(enqueueN - dequeueN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -193,7 +193,8 @@ class PriorityMailboxSpec extends MailboxSpec {
|
|||
lazy val name = "The priority mailbox implementation"
|
||||
def factory = {
|
||||
case UnboundedMailbox() => new UnboundedPriorityMailbox(comparator).create(None, None)
|
||||
case BoundedMailbox(capacity, pushTimeOut) => new BoundedPriorityMailbox(comparator, capacity, pushTimeOut).create(None, None)
|
||||
case BoundedMailbox(capacity, pushTimeOut) =>
|
||||
new BoundedPriorityMailbox(comparator, capacity, pushTimeOut).create(None, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +203,8 @@ class StablePriorityMailboxSpec extends MailboxSpec {
|
|||
lazy val name = "The stable priority mailbox implementation"
|
||||
def factory = {
|
||||
case UnboundedMailbox() => new UnboundedStablePriorityMailbox(comparator).create(None, None)
|
||||
case BoundedMailbox(capacity, pushTimeOut) => new BoundedStablePriorityMailbox(comparator, capacity, pushTimeOut).create(None, None)
|
||||
case BoundedMailbox(capacity, pushTimeOut) =>
|
||||
new BoundedStablePriorityMailbox(comparator, capacity, pushTimeOut).create(None, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +212,8 @@ class ControlAwareMailboxSpec extends MailboxSpec {
|
|||
lazy val name = "The control aware mailbox implementation"
|
||||
def factory = {
|
||||
case UnboundedMailbox() => new UnboundedControlAwareMailbox().create(None, None)
|
||||
case BoundedMailbox(capacity, pushTimeOut) => new BoundedControlAwareMailbox(capacity, pushTimeOut).create(None, None)
|
||||
case BoundedMailbox(capacity, pushTimeOut) =>
|
||||
new BoundedControlAwareMailbox(capacity, pushTimeOut).create(None, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,26 +274,26 @@ object SingleConsumerOnlyMailboxVerificationSpec {
|
|||
}""")
|
||||
}
|
||||
|
||||
class SingleConsumerOnlyMailboxVerificationSpec extends AkkaSpec(SingleConsumerOnlyMailboxVerificationSpec.mailboxConf) {
|
||||
class SingleConsumerOnlyMailboxVerificationSpec
|
||||
extends AkkaSpec(SingleConsumerOnlyMailboxVerificationSpec.mailboxConf) {
|
||||
import SingleConsumerOnlyMailboxVerificationSpec.Ping
|
||||
|
||||
def pathologicalPingPong(dispatcherId: String): Unit = {
|
||||
val total = 2000000
|
||||
val runner = system.actorOf(Props(new Actor {
|
||||
val a, b = context.watch(
|
||||
context.actorOf(Props(new Actor {
|
||||
val a, b = context.watch(context.actorOf(Props(new Actor {
|
||||
var n = total / 2
|
||||
def receive = {
|
||||
case Ping =>
|
||||
n -= 1
|
||||
sender() ! Ping
|
||||
if (n == 0)
|
||||
context stop self
|
||||
context.stop(self)
|
||||
}
|
||||
}).withDispatcher(dispatcherId)))
|
||||
def receive = {
|
||||
case Ping => a.tell(Ping, b)
|
||||
case Terminated(`a` | `b`) => if (context.children.isEmpty) context stop self
|
||||
case Terminated(`a` | `b`) => if (context.children.isEmpty) context.stop(self)
|
||||
}
|
||||
}))
|
||||
watch(runner)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import language.postfixOps
|
|||
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import akka.actor.{ Props, ActorSystem, Actor }
|
||||
import akka.testkit.{ DefaultTimeout, AkkaSpec }
|
||||
import akka.actor.{ Actor, ActorSystem, Props }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout }
|
||||
import scala.concurrent.duration._
|
||||
|
||||
object PriorityDispatcherSpec {
|
||||
|
|
@ -22,12 +22,14 @@ object PriorityDispatcherSpec {
|
|||
}
|
||||
"""
|
||||
|
||||
class Unbounded(settings: ActorSystem.Settings, config: Config) extends UnboundedPriorityMailbox(PriorityGenerator({
|
||||
class Unbounded(settings: ActorSystem.Settings, config: Config)
|
||||
extends UnboundedPriorityMailbox(PriorityGenerator({
|
||||
case i: Int => i //Reverse order
|
||||
case 'Result => Int.MaxValue
|
||||
}: Any => Int))
|
||||
|
||||
class Bounded(settings: ActorSystem.Settings, config: Config) extends BoundedPriorityMailbox(PriorityGenerator({
|
||||
class Bounded(settings: ActorSystem.Settings, config: Config)
|
||||
extends BoundedPriorityMailbox(PriorityGenerator({
|
||||
case i: Int => i //Reverse order
|
||||
case 'Result => Int.MaxValue
|
||||
}: Any => Int), 1000, 10 seconds)
|
||||
|
|
@ -60,7 +62,9 @@ class PriorityDispatcherSpec extends AkkaSpec(PriorityDispatcherSpec.config) wit
|
|||
|
||||
val acc = scala.collection.mutable.ListBuffer[Int]()
|
||||
|
||||
scala.util.Random.shuffle(msgs) foreach { m => self ! m }
|
||||
scala.util.Random.shuffle(msgs).foreach { m =>
|
||||
self ! m
|
||||
}
|
||||
|
||||
self.tell('Result, testActor)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import language.postfixOps
|
|||
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import akka.actor.{ Props, ActorSystem, Actor }
|
||||
import akka.testkit.{ DefaultTimeout, AkkaSpec }
|
||||
import akka.actor.{ Actor, ActorSystem, Props }
|
||||
import akka.testkit.{ AkkaSpec, DefaultTimeout }
|
||||
import scala.concurrent.duration._
|
||||
|
||||
object StablePriorityDispatcherSpec {
|
||||
|
|
@ -22,13 +22,15 @@ object StablePriorityDispatcherSpec {
|
|||
}
|
||||
"""
|
||||
|
||||
class Unbounded(settings: ActorSystem.Settings, config: Config) extends UnboundedStablePriorityMailbox(PriorityGenerator({
|
||||
class Unbounded(settings: ActorSystem.Settings, config: Config)
|
||||
extends UnboundedStablePriorityMailbox(PriorityGenerator({
|
||||
case i: Int if i <= 100 => i // Small integers have high priority
|
||||
case i: Int => 101 // Don't care for other integers
|
||||
case 'Result => Int.MaxValue
|
||||
}: Any => Int))
|
||||
|
||||
class Bounded(settings: ActorSystem.Settings, config: Config) extends BoundedStablePriorityMailbox(PriorityGenerator({
|
||||
class Bounded(settings: ActorSystem.Settings, config: Config)
|
||||
extends BoundedStablePriorityMailbox(PriorityGenerator({
|
||||
case i: Int if i <= 100 => i // Small integers have high priority
|
||||
case i: Int => 101 // Don't care for other integers
|
||||
case 'Result => Int.MaxValue
|
||||
|
|
@ -64,7 +66,9 @@ class StablePriorityDispatcherSpec extends AkkaSpec(StablePriorityDispatcherSpec
|
|||
|
||||
val acc = scala.collection.mutable.ListBuffer[Int]()
|
||||
|
||||
shuffled foreach { m => self ! m }
|
||||
shuffled.foreach { m =>
|
||||
self ! m
|
||||
}
|
||||
|
||||
self.tell('Result, testActor)
|
||||
|
||||
|
|
@ -81,7 +85,7 @@ class StablePriorityDispatcherSpec extends AkkaSpec(StablePriorityDispatcherSpec
|
|||
// Low messages should come out first, and in priority order. High messages follow - they are equal priority and
|
||||
// should come out in the same order in which they were sent.
|
||||
val lo = (1 to 100) toList
|
||||
val hi = shuffled filter { _ > 100 }
|
||||
val hi = shuffled.filter { _ > 100 }
|
||||
expectMsgType[List[Int]] should ===(lo ++ hi)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,19 +10,21 @@ import org.scalatest.BeforeAndAfterEach
|
|||
import akka.testkit._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.actor.{ Props, Actor, ActorRef, ActorSystem, PoisonPill }
|
||||
import akka.actor.{ Actor, ActorRef, ActorSystem, PoisonPill, Props }
|
||||
import akka.japi.{ Procedure }
|
||||
import com.typesafe.config.{ Config, ConfigFactory }
|
||||
|
||||
object EventBusSpec {
|
||||
class TestActorWrapperActor(testActor: ActorRef) extends Actor {
|
||||
def receive = {
|
||||
case x => testActor forward x
|
||||
case x => testActor.forward(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class EventBusSpec(busName: String, conf: Config = ConfigFactory.empty()) extends AkkaSpec(conf) with BeforeAndAfterEach {
|
||||
abstract class EventBusSpec(busName: String, conf: Config = ConfigFactory.empty())
|
||||
extends AkkaSpec(conf)
|
||||
with BeforeAndAfterEach {
|
||||
type BusType <: EventBus
|
||||
|
||||
def createNewEventBus(): BusType
|
||||
|
|
@ -40,7 +42,8 @@ abstract class EventBusSpec(busName: String, conf: Config = ConfigFactory.empty(
|
|||
busName must {
|
||||
def createNewSubscriber() = createSubscriber(testActor).asInstanceOf[bus.Subscriber]
|
||||
def getClassifierFor(event: BusType#Event) = classifierFor(event).asInstanceOf[bus.Classifier]
|
||||
def createNewEvents(numberOfEvents: Int): Iterable[bus.Event] = createEvents(numberOfEvents).asInstanceOf[Iterable[bus.Event]]
|
||||
def createNewEvents(numberOfEvents: Int): Iterable[bus.Event] =
|
||||
createEvents(numberOfEvents).asInstanceOf[Iterable[bus.Event]]
|
||||
|
||||
val events = createNewEvents(100)
|
||||
val event = events.head
|
||||
|
|
@ -74,13 +77,15 @@ abstract class EventBusSpec(busName: String, conf: Config = ConfigFactory.empty(
|
|||
}
|
||||
|
||||
"allow to add multiple subscribers" in {
|
||||
val subscribers = (1 to 10) map { _ => createNewSubscriber() }
|
||||
val subscribers = (1 to 10).map { _ =>
|
||||
createNewSubscriber()
|
||||
}
|
||||
val events = createEvents(10)
|
||||
val classifiers = events map getClassifierFor
|
||||
subscribers.zip(classifiers) forall { case (s, c) => bus.subscribe(s, c) } should ===(true)
|
||||
subscribers.zip(classifiers) forall { case (s, c) => bus.unsubscribe(s, c) } should ===(true)
|
||||
val classifiers = events.map(getClassifierFor)
|
||||
subscribers.zip(classifiers).forall { case (s, c) => bus.subscribe(s, c) } should ===(true)
|
||||
subscribers.zip(classifiers).forall { case (s, c) => bus.unsubscribe(s, c) } should ===(true)
|
||||
|
||||
subscribers foreach (disposeSubscriber(system, _))
|
||||
subscribers.foreach(disposeSubscriber(system, _))
|
||||
}
|
||||
|
||||
"publishing events without any subscribers shouldn't be a problem" in {
|
||||
|
|
@ -109,11 +114,17 @@ abstract class EventBusSpec(busName: String, conf: Config = ConfigFactory.empty(
|
|||
|
||||
"publish the given event to all intended subscribers" in {
|
||||
val range = 0 until 10
|
||||
val subscribers = range map (_ => createNewSubscriber())
|
||||
subscribers foreach { s => bus.subscribe(s, classifier) should ===(true) }
|
||||
val subscribers = range.map(_ => createNewSubscriber())
|
||||
subscribers.foreach { s =>
|
||||
bus.subscribe(s, classifier) should ===(true)
|
||||
}
|
||||
bus.publish(event)
|
||||
range foreach { _ => expectMsg(event) }
|
||||
subscribers foreach { s => bus.unsubscribe(s, classifier) should ===(true); disposeSubscriber(system, s) }
|
||||
range.foreach { _ =>
|
||||
expectMsg(event)
|
||||
}
|
||||
subscribers.foreach { s =>
|
||||
bus.unsubscribe(s, classifier) should ===(true); disposeSubscriber(system, s)
|
||||
}
|
||||
}
|
||||
|
||||
"not publish the given event to any other subscribers than the intended ones" in {
|
||||
|
|
@ -142,8 +153,10 @@ abstract class EventBusSpec(busName: String, conf: Config = ConfigFactory.empty(
|
|||
}
|
||||
|
||||
object ActorEventBusSpec {
|
||||
class MyActorEventBus(protected val system: ActorSystem) extends ActorEventBus
|
||||
with ManagedActorClassification with ActorClassifier {
|
||||
class MyActorEventBus(protected val system: ActorSystem)
|
||||
extends ActorEventBus
|
||||
with ManagedActorClassification
|
||||
with ActorClassifier {
|
||||
|
||||
type Event = Notification
|
||||
|
||||
|
|
@ -261,7 +274,7 @@ class ActorEventBusSpec(conf: Config) extends EventBusSpec("ActorEventBus", conf
|
|||
private def expectUnsubscribedByUnsubscriber(p: TestProbe, a: ActorRef): Unit = {
|
||||
val expectedMsg = s"actor $a has terminated, unsubscribing it from $bus"
|
||||
p.fishForMessage(1 second, hint = expectedMsg) {
|
||||
case Logging.Debug(_, _, msg) if msg equals expectedMsg => true
|
||||
case Logging.Debug(_, _, msg) if msg.equals(expectedMsg) => true
|
||||
case other => false
|
||||
}
|
||||
}
|
||||
|
|
@ -269,7 +282,7 @@ class ActorEventBusSpec(conf: Config) extends EventBusSpec("ActorEventBus", conf
|
|||
private def expectUnregisterFromUnsubscriber(p: TestProbe, a: ActorRef): Unit = {
|
||||
val expectedMsg = s"unregistered watch of $a in $bus"
|
||||
p.fishForMessage(1 second, hint = expectedMsg) {
|
||||
case Logging.Debug(_, _, msg) if msg equals expectedMsg => true
|
||||
case Logging.Debug(_, _, msg) if msg.equals(expectedMsg) => true
|
||||
case other => false
|
||||
}
|
||||
}
|
||||
|
|
@ -282,7 +295,7 @@ object ScanningEventBusSpec {
|
|||
type Subscriber = Procedure[Int]
|
||||
type Classifier = String
|
||||
|
||||
protected def compareClassifiers(a: Classifier, b: Classifier): Int = a compareTo b
|
||||
protected def compareClassifiers(a: Classifier, b: Classifier): Int = a.compareTo(b)
|
||||
protected def compareSubscribers(a: Subscriber, b: Subscriber): Int = akka.util.Helpers.compareIdentityHash(a, b)
|
||||
|
||||
protected def matches(classifier: Classifier, event: Event): Boolean = event.toString == classifier
|
||||
|
|
@ -337,4 +350,3 @@ class LookupEventBusSpec extends EventBusSpec("LookupEventBus") {
|
|||
|
||||
def disposeSubscriber(system: ActorSystem, subscriber: BusType#Subscriber): Unit = ()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import language.postfixOps
|
|||
import scala.concurrent.duration._
|
||||
import akka.actor._
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import akka.testkit.{ TestProbe, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, TestProbe }
|
||||
|
||||
object EventStreamSpec {
|
||||
|
||||
|
|
@ -32,8 +32,7 @@ object EventStreamSpec {
|
|||
""")
|
||||
|
||||
val configUnhandledWithDebug =
|
||||
ConfigFactory.parseString("akka.actor.debug.event-stream = on")
|
||||
.withFallback(configUnhandled)
|
||||
ConfigFactory.parseString("akka.actor.debug.event-stream = on").withFallback(configUnhandled)
|
||||
|
||||
final case class M(i: Int)
|
||||
|
||||
|
|
@ -93,12 +92,14 @@ class EventStreamSpec extends AkkaSpec(EventStreamSpec.config) {
|
|||
|
||||
"not allow null as subscriber" in {
|
||||
val bus = new EventStream(system, true)
|
||||
intercept[IllegalArgumentException] { bus.subscribe(null, classOf[M]) }.getMessage should ===("subscriber is null")
|
||||
intercept[IllegalArgumentException] { bus.subscribe(null, classOf[M]) }.getMessage should ===(
|
||||
"subscriber is null")
|
||||
}
|
||||
|
||||
"not allow null as unsubscriber" in {
|
||||
val bus = new EventStream(system, true)
|
||||
intercept[IllegalArgumentException] { bus.unsubscribe(null, classOf[M]) }.getMessage should ===("subscriber is null")
|
||||
intercept[IllegalArgumentException] { bus.unsubscribe(null, classOf[M]) }.getMessage should ===(
|
||||
"subscriber is null")
|
||||
intercept[IllegalArgumentException] { bus.unsubscribe(null) }.getMessage should ===("subscriber is null")
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +109,10 @@ class EventStreamSpec extends AkkaSpec(EventStreamSpec.config) {
|
|||
sys.eventStream.subscribe(testActor, classOf[AnyRef])
|
||||
val m = UnhandledMessage(42, sys.deadLetters, sys.deadLetters)
|
||||
sys.eventStream.publish(m)
|
||||
expectMsgAllOf(m, Logging.Debug(sys.deadLetters.path.toString, sys.deadLetters.getClass, "unhandled message from " + sys.deadLetters + ": 42"))
|
||||
expectMsgAllOf(m,
|
||||
Logging.Debug(sys.deadLetters.path.toString,
|
||||
sys.deadLetters.getClass,
|
||||
"unhandled message from " + sys.deadLetters + ": 42"))
|
||||
sys.eventStream.unsubscribe(testActor)
|
||||
} finally {
|
||||
shutdown(sys)
|
||||
|
|
@ -289,7 +293,7 @@ class EventStreamSpec extends AkkaSpec(EventStreamSpec.config) {
|
|||
val tm = new A
|
||||
|
||||
val target = sys.actorOf(Props(new Actor {
|
||||
def receive = { case in => a1.ref forward in }
|
||||
def receive = { case in => a1.ref.forward(in) }
|
||||
}), "to-be-killed")
|
||||
|
||||
es.subscribe(a2.ref, classOf[Any])
|
||||
|
|
@ -317,7 +321,7 @@ class EventStreamSpec extends AkkaSpec(EventStreamSpec.config) {
|
|||
val a1, a2 = TestProbe()
|
||||
|
||||
val target = system.actorOf(Props(new Actor {
|
||||
def receive = { case in => a1.ref forward in }
|
||||
def receive = { case in => a1.ref.forward(in) }
|
||||
}), "to-be-killed")
|
||||
|
||||
watch(target)
|
||||
|
|
@ -408,15 +412,16 @@ class EventStreamSpec extends AkkaSpec(EventStreamSpec.config) {
|
|||
|
||||
private def verifyLevel(bus: LoggingBus, level: Logging.LogLevel): Unit = {
|
||||
import Logging._
|
||||
val allmsg = Seq(Debug("", null, "debug"), Info("", null, "info"), Warning("", null, "warning"), Error("", null, "error"))
|
||||
val msg = allmsg filter (_.level <= level)
|
||||
allmsg foreach bus.publish
|
||||
msg foreach (expectMsg(_))
|
||||
val allmsg =
|
||||
Seq(Debug("", null, "debug"), Info("", null, "info"), Warning("", null, "warning"), Error("", null, "error"))
|
||||
val msg = allmsg.filter(_.level <= level)
|
||||
allmsg.foreach(bus.publish)
|
||||
msg.foreach(expectMsg(_))
|
||||
}
|
||||
|
||||
private def fishForDebugMessage(a: TestProbe, messagePrefix: String, max: Duration = 3 seconds): Unit = {
|
||||
a.fishForMessage(max, hint = "expected debug message prefix: " + messagePrefix) {
|
||||
case Logging.Debug(_, _, msg: String) if msg startsWith messagePrefix => true
|
||||
case Logging.Debug(_, _, msg: String) if msg.startsWith(messagePrefix) => true
|
||||
case other => false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ object LoggerSpec {
|
|||
}
|
||||
""").withFallback(AkkaSpec.testConf)
|
||||
|
||||
val multipleConfig = ConfigFactory.parseString("""
|
||||
val multipleConfig =
|
||||
ConfigFactory.parseString("""
|
||||
akka {
|
||||
stdout-loglevel = "OFF"
|
||||
loglevel = "WARNING"
|
||||
|
|
@ -97,10 +98,10 @@ object LoggerSpec {
|
|||
ref ! ("OK")
|
||||
case event: LogEvent if !event.mdc.isEmpty =>
|
||||
print(event)
|
||||
target foreach { _ ! event }
|
||||
target.foreach { _ ! event }
|
||||
case event: LogEvent =>
|
||||
print(event)
|
||||
target foreach { _ ! event.message }
|
||||
target.foreach { _ ! event.message }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +249,8 @@ class LoggerSpec extends WordSpec with Matchers {
|
|||
|
||||
ref ! "Current Message in MDC"
|
||||
probe.expectMsgPF(max = 3.seconds) {
|
||||
case w @ Warning(_, _, "Current Message in MDC") if w.mdc.size == 3 &&
|
||||
case w @ Warning(_, _, "Current Message in MDC")
|
||||
if w.mdc.size == 3 &&
|
||||
w.mdc("requestId") == 3 &&
|
||||
w.mdc("currentMsg") == "Current Message in MDC" &&
|
||||
w.mdc("currentMsgLength") == 22 =>
|
||||
|
|
|
|||
|
|
@ -30,9 +30,14 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
akka.loglevel=DEBUG # test verifies debug
|
||||
akka.actor.serialize-messages = off # debug noise from serialization
|
||||
""").withFallback(AkkaSpec.testConf)
|
||||
val appLogging = ActorSystem("logging", ConfigFactory.parseMap(Map("akka.actor.debug.receive" -> true).asJava).withFallback(config))
|
||||
val appAuto = ActorSystem("autoreceive", ConfigFactory.parseMap(Map("akka.actor.debug.autoreceive" -> true).asJava).withFallback(config))
|
||||
val appLifecycle = ActorSystem("lifecycle", ConfigFactory.parseMap(Map("akka.actor.debug.lifecycle" -> true).asJava).withFallback(config))
|
||||
val appLogging =
|
||||
ActorSystem("logging", ConfigFactory.parseMap(Map("akka.actor.debug.receive" -> true).asJava).withFallback(config))
|
||||
val appAuto = ActorSystem(
|
||||
"autoreceive",
|
||||
ConfigFactory.parseMap(Map("akka.actor.debug.autoreceive" -> true).asJava).withFallback(config))
|
||||
val appLifecycle = ActorSystem(
|
||||
"lifecycle",
|
||||
ConfigFactory.parseMap(Map("akka.actor.debug.lifecycle" -> true).asJava).withFallback(config))
|
||||
|
||||
val filter = TestEvent.Mute(EventFilter.custom {
|
||||
case _: Logging.Debug => true
|
||||
|
|
@ -62,12 +67,15 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
system.eventStream.subscribe(testActor, classOf[Logging.Debug])
|
||||
system.eventStream.subscribe(testActor, classOf[UnhandledMessage])
|
||||
val a = system.actorOf(Props(new Actor {
|
||||
def receive = new LoggingReceive(Some("funky"), {
|
||||
def receive =
|
||||
new LoggingReceive(Some("funky"), {
|
||||
case null =>
|
||||
})
|
||||
}))
|
||||
a ! "hallo"
|
||||
expectMsg(1 second, Logging.Debug("funky", classOf[DummyClassForStringSources],
|
||||
expectMsg(1 second,
|
||||
Logging.Debug("funky",
|
||||
classOf[DummyClassForStringSources],
|
||||
"received unhandled message hallo from " + system.deadLetters))
|
||||
expectMsgType[UnhandledMessage](1 second)
|
||||
}
|
||||
|
|
@ -85,15 +93,17 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
|
||||
val actor = TestActorRef(new Actor {
|
||||
def switch: Actor.Receive = { case "becomenull" => context.become(r, false) }
|
||||
def receive = switch orElse LoggingReceive {
|
||||
def receive =
|
||||
switch.orElse(LoggingReceive {
|
||||
case x => sender() ! "x"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
val name = actor.path.toString
|
||||
actor ! "buh"
|
||||
expectMsg(Logging.Debug(actor.path.toString, actor.underlyingActor.getClass,
|
||||
"received handled message buh from " + self))
|
||||
expectMsg(
|
||||
Logging
|
||||
.Debug(actor.path.toString, actor.underlyingActor.getClass, "received handled message buh from " + self))
|
||||
expectMsg("x")
|
||||
|
||||
actor ! "becomenull"
|
||||
|
|
@ -109,13 +119,15 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
new TestKit(appLogging) with ImplicitSender {
|
||||
system.eventStream.subscribe(testActor, classOf[Logging.Debug])
|
||||
val actor = TestActorRef(new Actor {
|
||||
def receive = LoggingReceive(LoggingReceive {
|
||||
def receive =
|
||||
LoggingReceive(LoggingReceive {
|
||||
case _ => sender() ! "x"
|
||||
})
|
||||
})
|
||||
actor ! "buh"
|
||||
expectMsg(Logging.Debug(actor.path.toString, actor.underlyingActor.getClass,
|
||||
"received handled message buh from " + self))
|
||||
expectMsg(
|
||||
Logging
|
||||
.Debug(actor.path.toString, actor.underlyingActor.getClass, "received handled message buh from " + self))
|
||||
expectMsg("x")
|
||||
}
|
||||
}
|
||||
|
|
@ -146,8 +158,9 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
}
|
||||
})
|
||||
actor ! "buh"
|
||||
expectMsg(Logging.Info(actor.path.toString, actor.underlyingActor.getClass,
|
||||
"received handled message buh from " + self))
|
||||
expectMsg(
|
||||
Logging
|
||||
.Info(actor.path.toString, actor.underlyingActor.getClass, "received handled message buh from " + self))
|
||||
expectMsg("x")
|
||||
}
|
||||
}
|
||||
|
|
@ -167,7 +180,9 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
val name = actor.path.toString
|
||||
actor ! PoisonPill
|
||||
fishForMessage(hint = "received AutoReceiveMessage Envelope(PoisonPill") {
|
||||
case Logging.Debug(`name`, _, msg: String) if msg startsWith "received AutoReceiveMessage Envelope(PoisonPill" => true
|
||||
case Logging.Debug(`name`, _, msg: String)
|
||||
if msg.startsWith("received AutoReceiveMessage Envelope(PoisonPill") =>
|
||||
true
|
||||
case _ => false
|
||||
}
|
||||
awaitCond(actor.isTerminated)
|
||||
|
|
@ -184,14 +199,14 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
val sname = supervisor.path.toString
|
||||
|
||||
fishForMessage(hint = "now supervising") {
|
||||
case Logging.Debug(`lname`, _, msg: String) if msg startsWith "now supervising" => true
|
||||
case Logging.Debug(`lname`, _, msg: String) if msg.startsWith("now supervising") => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
TestActorRef[TestLogActor](Props[TestLogActor], supervisor, "none")
|
||||
|
||||
fishForMessage(hint = "now supervising") {
|
||||
case Logging.Debug(`sname`, _, msg: String) if msg startsWith "now supervising" => true
|
||||
case Logging.Debug(`sname`, _, msg: String) if msg.startsWith("now supervising") => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
|
@ -207,13 +222,13 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
val actor = TestActorRef[TestLogActor](Props[TestLogActor], supervisor, "none")
|
||||
val aname = actor.path.toString
|
||||
|
||||
supervisor watch actor
|
||||
supervisor.watch(actor)
|
||||
fishForMessage(hint = "now watched by") {
|
||||
case Logging.Debug(`aname`, `sclass`, msg: String) if msg.startsWith("now watched by") => true
|
||||
case m => false
|
||||
}
|
||||
|
||||
supervisor unwatch actor
|
||||
supervisor.unwatch(actor)
|
||||
fishForMessage(hint = "no longer watched by") {
|
||||
case Logging.Debug(`aname`, `sclass`, msg: String) if msg.startsWith("no longer watched by") => true
|
||||
case _ => false
|
||||
|
|
@ -232,8 +247,8 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
val sclass = classOf[TestLogActor]
|
||||
|
||||
expectMsgAllPF(messages = 2) {
|
||||
case Logging.Debug(`sname`, `sclass`, msg: String) if msg startsWith "started" => 0
|
||||
case Logging.Debug(_, _, msg: String) if msg startsWith "now supervising" => 1
|
||||
case Logging.Debug(`sname`, `sclass`, msg: String) if msg.startsWith("started") => 0
|
||||
case Logging.Debug(_, _, msg: String) if msg.startsWith("now supervising") => 1
|
||||
}
|
||||
|
||||
val actor = TestActorRef[TestLogActor](Props[TestLogActor], supervisor, "none")
|
||||
|
|
@ -241,11 +256,13 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
val aclass = classOf[TestLogActor]
|
||||
|
||||
expectMsgAllPF(messages = 2) {
|
||||
case Logging.Debug(`aname`, `aclass`, msg: String) if msg.startsWith("started (" + classOf[TestLogActor].getName) => 0
|
||||
case Logging.Debug(`aname`, `aclass`, msg: String)
|
||||
if msg.startsWith("started (" + classOf[TestLogActor].getName) =>
|
||||
0
|
||||
case Logging.Debug(`sname`, `sclass`, msg: String) if msg == s"now supervising TestActor[$aname]" => 1
|
||||
}
|
||||
|
||||
EventFilter[ActorKilledException](occurrences = 1) intercept {
|
||||
EventFilter[ActorKilledException](occurrences = 1).intercept {
|
||||
actor ! Kill
|
||||
expectMsgAllPF(messages = 3) {
|
||||
case Logging.Error(_: ActorKilledException, `aname`, _, "Kill") => 0
|
||||
|
|
@ -255,8 +272,7 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
}
|
||||
|
||||
system.stop(supervisor)
|
||||
expectMsgAllOf(
|
||||
Logging.Debug(aname, aclass, "stopped"),
|
||||
expectMsgAllOf(Logging.Debug(aname, aclass, "stopped"),
|
||||
Logging.Debug(sname, sclass, "stopping"),
|
||||
Logging.Debug(sname, sclass, "stopped"))
|
||||
}
|
||||
|
|
@ -269,7 +285,8 @@ class LoggingReceiveSpec extends WordSpec with BeforeAndAfterAll {
|
|||
else if (gotMatching.size == messages) gotMatching
|
||||
else {
|
||||
val msg = receiveOne(remainingOrDefault)
|
||||
assert(msg ne null, s"timeout ($max) during expectMsgAllPF, got matching " +
|
||||
assert(msg ne null,
|
||||
s"timeout ($max) during expectMsgAllPF, got matching " +
|
||||
s"[${gotMatching.mkString(", ")}], got unknown: [${unknown.mkString(", ")}]")
|
||||
if (matchers.isDefinedAt(msg)) receiveNMatching(gotMatching + matchers(msg), Vector.empty)
|
||||
else receiveNMatching(gotMatching, unknown :+ msg) // unknown message, just ignore
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ import akka.testkit._
|
|||
|
||||
class MarkerLoggingSpec extends AkkaSpec with ImplicitSender {
|
||||
"A MarkerLoggerAdapter" should {
|
||||
val markerLogging = new MarkerLoggingAdapter(system.eventStream, getClass.getName, this.getClass, new DefaultLoggingFilter(() => Logging.InfoLevel))
|
||||
val markerLogging = new MarkerLoggingAdapter(system.eventStream,
|
||||
getClass.getName,
|
||||
this.getClass,
|
||||
new DefaultLoggingFilter(() => Logging.InfoLevel))
|
||||
|
||||
"add markers to logging" in {
|
||||
system.eventStream.subscribe(self, classOf[Info])
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package akka.io
|
||||
|
||||
import akka.testkit.{ TestProbe, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, TestProbe }
|
||||
import akka.testkit.SocketUtil.temporaryServerAddresses
|
||||
import Tcp._
|
||||
|
||||
|
|
@ -12,12 +12,12 @@ class CapacityLimitSpec extends AkkaSpec("""
|
|||
akka.loglevel = ERROR
|
||||
akka.io.tcp.max-channels = 4
|
||||
akka.actor.serialize-creators = on
|
||||
""")
|
||||
with TcpIntegrationSpecSupport {
|
||||
""") with TcpIntegrationSpecSupport {
|
||||
|
||||
"The TCP transport implementation" should {
|
||||
|
||||
"reply with CommandFailed to a Bind or Connect command if max-channels capacity has been reached" in new TestSetup(runClientInExtraSystem = false) {
|
||||
"reply with CommandFailed to a Bind or Connect command if max-channels capacity has been reached" in new TestSetup(
|
||||
runClientInExtraSystem = false) {
|
||||
establishNewClientConnection()
|
||||
|
||||
// we now have three channels registered: a listener, a server connection and a client connection
|
||||
|
|
@ -31,11 +31,11 @@ class CapacityLimitSpec extends AkkaSpec("""
|
|||
|
||||
val bindToFail = Bind(bindHandler.ref, addresses(1))
|
||||
commander.send(IO(Tcp), bindToFail)
|
||||
commander.expectMsgType[CommandFailed].cmd should be theSameInstanceAs (bindToFail)
|
||||
(commander.expectMsgType[CommandFailed].cmd should be).theSameInstanceAs(bindToFail)
|
||||
|
||||
val connectToFail = Connect(endpoint)
|
||||
commander.send(IO(Tcp), connectToFail)
|
||||
commander.expectMsgType[CommandFailed].cmd should be theSameInstanceAs (connectToFail)
|
||||
(commander.expectMsgType[CommandFailed].cmd should be).theSameInstanceAs(connectToFail)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,11 +88,10 @@ class InetAddressDnsResolverSpec extends AkkaSpec("""
|
|||
private def secondsToMillis(seconds: Int) = TimeUnit.SECONDS.toMillis(seconds)
|
||||
|
||||
private def dnsResolver = {
|
||||
val actorRef = TestActorRef[InetAddressDnsResolver](Props(
|
||||
classOf[InetAddressDnsResolver],
|
||||
val actorRef = TestActorRef[InetAddressDnsResolver](
|
||||
Props(classOf[InetAddressDnsResolver],
|
||||
new SimpleDnsCache(),
|
||||
system.settings.config.getConfig("akka.io.dns.inet-address")
|
||||
))
|
||||
system.settings.config.getConfig("akka.io.dns.inet-address")))
|
||||
actorRef.underlyingActor
|
||||
}
|
||||
|
||||
|
|
@ -117,8 +116,7 @@ class InetAddressDnsResolverSpec extends AkkaSpec("""
|
|||
}
|
||||
|
||||
}
|
||||
class InetAddressDnsResolverConfigSpec extends AkkaSpec(
|
||||
"""
|
||||
class InetAddressDnsResolverConfigSpec extends AkkaSpec("""
|
||||
akka.io.dns.inet-address.positive-ttl = forever
|
||||
akka.io.dns.inet-address.negative-ttl = never
|
||||
akka.actor.serialize-creators = on
|
||||
|
|
@ -137,11 +135,10 @@ class InetAddressDnsResolverConfigSpec extends AkkaSpec(
|
|||
}
|
||||
|
||||
private def dnsResolver = {
|
||||
val actorRef = TestActorRef[InetAddressDnsResolver](Props(
|
||||
classOf[InetAddressDnsResolver],
|
||||
val actorRef = TestActorRef[InetAddressDnsResolver](
|
||||
Props(classOf[InetAddressDnsResolver],
|
||||
new SimpleDnsCache(),
|
||||
system.settings.config.getConfig("akka.io.dns.inet-address")
|
||||
))
|
||||
system.settings.config.getConfig("akka.io.dns.inet-address")))
|
||||
actorRef.underlyingActor
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
val connectionActor = createConnectionActor(options = Vector(SO.KeepAlive(false)))
|
||||
val clientChannel = connectionActor.underlyingActor.channel
|
||||
clientChannel.socket.getKeepAlive should ===(true) // only set after connection is established
|
||||
EventFilter.warning(pattern = "registration timeout", occurrences = 1) intercept {
|
||||
EventFilter.warning(pattern = "registration timeout", occurrences = 1).intercept {
|
||||
selector.send(connectionActor, ChannelConnectable)
|
||||
clientChannel.socket.getKeepAlive should ===(false)
|
||||
}
|
||||
|
|
@ -156,7 +156,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
interestCallReceiver.expectMsg(OP_CONNECT)
|
||||
|
||||
selector.send(connectionActor, ChannelConnectable)
|
||||
userHandler.expectMsg(Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
|
||||
userHandler.expectMsg(
|
||||
Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
|
||||
|
||||
userHandler.send(connectionActor, Register(userHandler.ref))
|
||||
interestCallReceiver.expectMsg(OP_READ)
|
||||
|
|
@ -304,7 +305,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
new EstablishedConnectionTest() {
|
||||
override lazy val connectionActor = createConnectionActor(options = List(Inet.SO.ReceiveBufferSize(1000000)))
|
||||
run {
|
||||
info("Currently ignored as SO_SNDBUF is usually a lower bound on the send buffer so the test fails as no real " +
|
||||
info(
|
||||
"Currently ignored as SO_SNDBUF is usually a lower bound on the send buffer so the test fails as no real " +
|
||||
"backpressure present.")
|
||||
pending
|
||||
ignoreIfWindows()
|
||||
|
|
@ -376,8 +378,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
"respect pull mode" in new EstablishedConnectionTest(pullMode = true) {
|
||||
// override config to decrease default buffer size
|
||||
def config =
|
||||
ConfigFactory.parseString("akka.io.tcp.direct-buffer-size = 1k")
|
||||
.withFallback(AkkaSpec.testConf)
|
||||
ConfigFactory.parseString("akka.io.tcp.direct-buffer-size = 1k").withFallback(AkkaSpec.testConf)
|
||||
override implicit lazy val system: ActorSystem = ActorSystem("respectPullModeTest", config)
|
||||
|
||||
try run {
|
||||
|
|
@ -415,8 +416,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
selector.send(connectionActor, ChannelReadable)
|
||||
|
||||
connectionHandler.expectMsgType[Received].data.decodeString("ASCII") should ===(vs)
|
||||
}
|
||||
finally shutdown(system)
|
||||
} finally shutdown(system)
|
||||
}
|
||||
|
||||
"close the connection and reply with `Closed` upon reception of a `Close` command" in
|
||||
|
|
@ -661,7 +661,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
|
||||
"report failed connection attempt when timing out" in
|
||||
new UnacceptedConnectionTest() {
|
||||
override lazy val connectionActor = createConnectionActor(serverAddress = UnboundAddress, timeout = Option(100.millis))
|
||||
override lazy val connectionActor =
|
||||
createConnectionActor(serverAddress = UnboundAddress, timeout = Option(100.millis))
|
||||
run {
|
||||
connectionActor.toString should not be ("")
|
||||
userHandler.expectMsg(CommandFailed(Connect(UnboundAddress, timeout = Option(100.millis))))
|
||||
|
|
@ -675,7 +676,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
localServerChannel.accept()
|
||||
|
||||
selector.send(connectionActor, ChannelConnectable)
|
||||
userHandler.expectMsg(Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
|
||||
userHandler.expectMsg(
|
||||
Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
|
||||
|
||||
watch(connectionActor)
|
||||
expectTerminated(connectionActor)
|
||||
|
|
@ -684,7 +686,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
|
||||
"close the connection when user handler dies while connecting" in new UnacceptedConnectionTest {
|
||||
run {
|
||||
EventFilter[DeathPactException](occurrences = 1) intercept {
|
||||
EventFilter[DeathPactException](occurrences = 1).intercept {
|
||||
userHandler.ref ! PoisonPill
|
||||
|
||||
watch(connectionActor)
|
||||
|
|
@ -697,7 +699,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
run {
|
||||
watch(connectionHandler.ref)
|
||||
watch(connectionActor)
|
||||
EventFilter[DeathPactException](occurrences = 1) intercept {
|
||||
EventFilter[DeathPactException](occurrences = 1).intercept {
|
||||
system.stop(connectionHandler.ref)
|
||||
val deaths = Set(expectMsgType[Terminated].actor, expectMsgType[Terminated].actor)
|
||||
deaths should ===(Set(connectionHandler.ref, connectionActor))
|
||||
|
|
@ -879,6 +881,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
}
|
||||
|
||||
abstract class LocalServerTest extends ChannelRegistry {
|
||||
|
||||
/** Allows overriding the system used */
|
||||
implicit def system: ActorSystem = thisSpecs.system
|
||||
|
||||
|
|
@ -909,8 +912,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
|
||||
def setServerSocketOptions() = ()
|
||||
|
||||
def createConnectionActor(
|
||||
serverAddress: InetSocketAddress = serverAddress,
|
||||
def createConnectionActor(serverAddress: InetSocketAddress = serverAddress,
|
||||
options: immutable.Seq[SocketOption] = Nil,
|
||||
timeout: Option[FiniteDuration] = None,
|
||||
pullMode: Boolean = false): TestActorRef[TcpOutgoingConnection] = {
|
||||
|
|
@ -928,13 +930,14 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
|
||||
protected def onCancelAndClose(andThen: () => Unit): Unit = andThen()
|
||||
|
||||
def createConnectionActorWithoutRegistration(
|
||||
serverAddress: InetSocketAddress = serverAddress,
|
||||
def createConnectionActorWithoutRegistration(serverAddress: InetSocketAddress = serverAddress,
|
||||
options: immutable.Seq[SocketOption] = Nil,
|
||||
timeout: Option[FiniteDuration] = None,
|
||||
pullMode: Boolean = false): TestActorRef[TcpOutgoingConnection] =
|
||||
TestActorRef(
|
||||
new TcpOutgoingConnection(Tcp(system), this, userHandler.ref,
|
||||
new TcpOutgoingConnection(Tcp(system),
|
||||
this,
|
||||
userHandler.ref,
|
||||
Connect(serverAddress, options = options, timeout = timeout, pullMode = pullMode)) {
|
||||
override def postRestart(reason: Throwable): Unit = context.stop(self) // ensure we never restart
|
||||
})
|
||||
|
|
@ -957,8 +960,7 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
}
|
||||
}
|
||||
|
||||
abstract class EstablishedConnectionTest(
|
||||
keepOpenOnPeerClosed: Boolean = false,
|
||||
abstract class EstablishedConnectionTest(keepOpenOnPeerClosed: Boolean = false,
|
||||
useResumeWriting: Boolean = true,
|
||||
pullMode: Boolean = false)
|
||||
extends UnacceptedConnectionTest(pullMode) {
|
||||
|
|
@ -991,7 +993,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
|
||||
interestCallReceiver.expectMsg(OP_CONNECT)
|
||||
selector.send(connectionActor, ChannelConnectable)
|
||||
userHandler.expectMsg(Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
|
||||
userHandler.expectMsg(
|
||||
Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
|
||||
|
||||
userHandler.send(connectionActor, Register(connectionHandler.ref, keepOpenOnPeerClosed, useResumeWriting))
|
||||
ignoreWindowsWorkaroundForTicket15766()
|
||||
|
|
@ -1051,7 +1054,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
/**
|
||||
* Tries to simultaneously act on client and server side to read from the server all pending data from the client.
|
||||
*/
|
||||
@tailrec final def pullFromServerSide(remaining: Int, remainingTries: Int = 1000,
|
||||
@tailrec final def pullFromServerSide(remaining: Int,
|
||||
remainingTries: Int = 1000,
|
||||
into: ByteBuffer = defaultbuffer): Unit =
|
||||
if (remainingTries <= 0)
|
||||
throw new AssertionError("Pulling took too many loops, remaining data: " + remaining)
|
||||
|
|
@ -1072,7 +1076,8 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
if (nioSelector.selectedKeys().contains(serverSelectionKey)) {
|
||||
if (into eq defaultbuffer) into.clear()
|
||||
serverSideChannel.read(into) match {
|
||||
case -1 => throw new IllegalStateException("Connection was closed unexpectedly with remaining bytes " + remaining)
|
||||
case -1 =>
|
||||
throw new IllegalStateException("Connection was closed unexpectedly with remaining bytes " + remaining)
|
||||
case 0 => throw new IllegalStateException("Made no progress")
|
||||
case other => other
|
||||
}
|
||||
|
|
@ -1104,10 +1109,11 @@ class TcpConnectionSpec extends AkkaSpec("""
|
|||
def selectedAs(interest: Int, duration: Duration): BeMatcher[SelectionKey] =
|
||||
new BeMatcher[SelectionKey] {
|
||||
def apply(key: SelectionKey) =
|
||||
MatchResult(
|
||||
checkFor(key, interest, duration.toMillis.toInt),
|
||||
"%s key was not selected for %s after %s" format (key.attachment(), interestsDesc(interest), duration),
|
||||
"%s key was selected for %s after %s" format (key.attachment(), interestsDesc(interest), duration))
|
||||
MatchResult(checkFor(key, interest, duration.toMillis.toInt),
|
||||
"%s key was not selected for %s after %s".format(key.attachment(),
|
||||
interestsDesc(interest),
|
||||
duration),
|
||||
"%s key was selected for %s after %s".format(key.attachment(), interestsDesc(interest), duration))
|
||||
}
|
||||
|
||||
val interestsNames =
|
||||
|
|
|
|||
|
|
@ -195,15 +195,14 @@ class TcpIntegrationSpec extends AkkaSpec("""
|
|||
}
|
||||
}
|
||||
|
||||
def chitchat(
|
||||
clientHandler: TestProbe,
|
||||
def chitchat(clientHandler: TestProbe,
|
||||
clientConnection: ActorRef,
|
||||
serverHandler: TestProbe,
|
||||
serverConnection: ActorRef,
|
||||
rounds: Int = 100) = {
|
||||
|
||||
val testData = ByteString(0)
|
||||
(1 to rounds) foreach { _ =>
|
||||
(1 to rounds).foreach { _ =>
|
||||
clientHandler.send(clientConnection, Write(testData))
|
||||
serverHandler.expectMsg(Received(testData))
|
||||
serverHandler.send(serverConnection, Write(testData))
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ trait TcpIntegrationSpecSupport { _: AkkaSpec =>
|
|||
if (runClientInExtraSystem) {
|
||||
val res = ActorSystem("TcpIntegrationSpec-client", system.settings.config)
|
||||
// terminate clientSystem after server system
|
||||
system.whenTerminated.onComplete { _ => res.terminate() }(ExecutionContexts.sameThreadExecutionContext)
|
||||
system.whenTerminated.onComplete { _ =>
|
||||
res.terminate()
|
||||
}(ExecutionContexts.sameThreadExecutionContext)
|
||||
res
|
||||
} else system
|
||||
val bindHandler = TestProbe()
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class TcpListenerSpec extends AkkaSpec("""
|
|||
listener ! ChannelAcceptable
|
||||
val channel = expectWorkerForCommand
|
||||
|
||||
EventFilter.warning(pattern = "selector capacity limit", occurrences = 1) intercept {
|
||||
EventFilter.warning(pattern = "selector capacity limit", occurrences = 1).intercept {
|
||||
listener ! FailedRegisterIncoming(channel)
|
||||
awaitCond(!channel.isOpen)
|
||||
}
|
||||
|
|
@ -175,12 +175,16 @@ class TcpListenerSpec extends AkkaSpec("""
|
|||
|
||||
private class ListenerParent(pullMode: Boolean) extends Actor with ChannelRegistry {
|
||||
val listener = context.actorOf(
|
||||
props = Props(classOf[TcpListener], selectorRouter.ref, Tcp(system), this, bindCommander.ref,
|
||||
props = Props(classOf[TcpListener],
|
||||
selectorRouter.ref,
|
||||
Tcp(system),
|
||||
this,
|
||||
bindCommander.ref,
|
||||
Bind(handler.ref, endpoint, 100, Nil, pullMode)).withDeploy(Deploy.local),
|
||||
name = "test-listener-" + counter.next())
|
||||
parent.watch(listener)
|
||||
def receive: Receive = {
|
||||
case msg => parent.ref forward msg
|
||||
case msg => parent.ref.forward(msg)
|
||||
}
|
||||
override def supervisorStrategy = SupervisorStrategy.stoppingStrategy
|
||||
|
||||
|
|
@ -191,5 +195,6 @@ class TcpListenerSpec extends AkkaSpec("""
|
|||
|
||||
}
|
||||
object TcpListenerSpec {
|
||||
final case class RegisterChannel(channel: SelectableChannel, initialOps: Int) extends NoSerializationVerificationNeeded
|
||||
final case class RegisterChannel(channel: SelectableChannel, initialOps: Int)
|
||||
extends NoSerializationVerificationNeeded
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package akka.io
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import akka.testkit.{ TestProbe, ImplicitSender, AkkaSpec }
|
||||
import akka.testkit.{ AkkaSpec, ImplicitSender, TestProbe }
|
||||
import akka.util.ByteString
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.SocketUtil.temporaryServerAddresses
|
||||
|
|
@ -24,7 +24,9 @@ class UdpConnectedIntegrationSpec extends AkkaSpec("""
|
|||
commander.sender()
|
||||
}
|
||||
|
||||
def connectUdp(localAddress: Option[InetSocketAddress], remoteAddress: InetSocketAddress, handler: ActorRef): ActorRef = {
|
||||
def connectUdp(localAddress: Option[InetSocketAddress],
|
||||
remoteAddress: InetSocketAddress,
|
||||
handler: ActorRef): ActorRef = {
|
||||
val commander = TestProbe()
|
||||
commander.send(IO(UdpConnected), UdpConnected.Connect(handler, remoteAddress, localAddress, Nil))
|
||||
commander.expectMsg(UdpConnected.Connected)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ The configuration to start a bind DNS server in Docker with this configuration
|
|||
is included, and the test will automatically start this container when the
|
||||
test starts and tear it down when it finishes.
|
||||
*/
|
||||
class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
||||
s"""
|
||||
class AsyncDnsResolverIntegrationSpec extends AkkaSpec(s"""
|
||||
akka.loglevel = DEBUG
|
||||
akka.loggers = ["akka.testkit.SilenceAllTestEventListener"]
|
||||
akka.io.dns.resolver = async-dns
|
||||
|
|
@ -62,17 +61,16 @@ class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
|||
val name = "a-double.foo.test"
|
||||
val answer = resolve(name)
|
||||
answer.name shouldEqual name
|
||||
answer.records.map(_.asInstanceOf[ARecord].ip).toSet shouldEqual Set(
|
||||
InetAddress.getByName("192.168.1.21"),
|
||||
InetAddress.getByName("192.168.1.22")
|
||||
)
|
||||
answer.records.map(_.asInstanceOf[ARecord].ip).toSet shouldEqual Set(InetAddress.getByName("192.168.1.21"),
|
||||
InetAddress.getByName("192.168.1.22"))
|
||||
}
|
||||
|
||||
"resolve single AAAA record" in {
|
||||
val name = "aaaa-single.foo.test"
|
||||
val answer = resolve(name)
|
||||
answer.name shouldEqual name
|
||||
answer.records.map(_.asInstanceOf[AAAARecord].ip) shouldEqual Seq(InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:1"))
|
||||
answer.records.map(_.asInstanceOf[AAAARecord].ip) shouldEqual Seq(
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:1"))
|
||||
}
|
||||
|
||||
"resolve double AAAA records" in {
|
||||
|
|
@ -81,8 +79,7 @@ class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
|||
answer.name shouldEqual name
|
||||
answer.records.map(_.asInstanceOf[AAAARecord].ip).toSet shouldEqual Set(
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:2"),
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:3")
|
||||
)
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:3"))
|
||||
}
|
||||
|
||||
"resolve mixed A/AAAA records" in {
|
||||
|
|
@ -90,40 +87,29 @@ class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
|||
val answer = resolve(name)
|
||||
answer.name shouldEqual name
|
||||
|
||||
answer.records.collect { case r: ARecord => r.ip }.toSet shouldEqual Set(
|
||||
InetAddress.getByName("192.168.1.23"),
|
||||
InetAddress.getByName("192.168.1.24")
|
||||
)
|
||||
answer.records.collect { case r: ARecord => r.ip }.toSet shouldEqual Set(InetAddress.getByName("192.168.1.23"),
|
||||
InetAddress.getByName("192.168.1.24"))
|
||||
|
||||
answer.records.collect { case r: AAAARecord => r.ip }.toSet shouldEqual Set(
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:4"),
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:5")
|
||||
)
|
||||
InetAddress.getByName("fd4d:36b2:3eca:a2d8:0:0:0:5"))
|
||||
}
|
||||
|
||||
"resolve external CNAME record" in {
|
||||
val name = "cname-ext.foo.test"
|
||||
val answer = (IO(Dns) ? DnsProtocol.Resolve(name)).mapTo[DnsProtocol.Resolved].futureValue
|
||||
answer.name shouldEqual name
|
||||
answer.records.collect { case r: CNameRecord => r.canonicalName }.toSet shouldEqual Set(
|
||||
"a-single.bar.example"
|
||||
)
|
||||
answer.records.collect { case r: ARecord => r.ip }.toSet shouldEqual Set(
|
||||
InetAddress.getByName("192.168.2.20")
|
||||
)
|
||||
answer.records.collect { case r: CNameRecord => r.canonicalName }.toSet shouldEqual Set("a-single.bar.example")
|
||||
answer.records.collect { case r: ARecord => r.ip }.toSet shouldEqual Set(InetAddress.getByName("192.168.2.20"))
|
||||
}
|
||||
|
||||
"resolve internal CNAME record" in {
|
||||
val name = "cname-in.foo.test"
|
||||
val answer = resolve(name)
|
||||
answer.name shouldEqual name
|
||||
answer.records.collect { case r: CNameRecord => r.canonicalName }.toSet shouldEqual Set(
|
||||
"a-double.foo.test"
|
||||
)
|
||||
answer.records.collect { case r: ARecord => r.ip }.toSet shouldEqual Set(
|
||||
InetAddress.getByName("192.168.1.21"),
|
||||
InetAddress.getByName("192.168.1.22")
|
||||
)
|
||||
answer.records.collect { case r: CNameRecord => r.canonicalName }.toSet shouldEqual Set("a-double.foo.test")
|
||||
answer.records.collect { case r: ARecord => r.ip }.toSet shouldEqual Set(InetAddress.getByName("192.168.1.21"),
|
||||
InetAddress.getByName("192.168.1.22"))
|
||||
}
|
||||
|
||||
"resolve SRV record" in {
|
||||
|
|
@ -133,13 +119,14 @@ class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
|||
answer.name shouldEqual name
|
||||
answer.records.collect { case r: SRVRecord => r }.toSet shouldEqual Set(
|
||||
SRVRecord("_service._tcp.foo.test", Ttl.fromPositive(86400.seconds), 10, 65534, 5060, "a-single.foo.test"),
|
||||
SRVRecord("_service._tcp.foo.test", Ttl.fromPositive(86400.seconds), 65533, 40, 65535, "a-double.foo.test")
|
||||
)
|
||||
SRVRecord("_service._tcp.foo.test", Ttl.fromPositive(86400.seconds), 65533, 40, 65535, "a-double.foo.test"))
|
||||
}
|
||||
|
||||
"resolve same address twice" in {
|
||||
resolve("a-single.foo.test").records.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(InetAddress.getByName("192.168.1.20"))
|
||||
resolve("a-single.foo.test").records.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(InetAddress.getByName("192.168.1.20"))
|
||||
resolve("a-single.foo.test").records.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(
|
||||
InetAddress.getByName("192.168.1.20"))
|
||||
resolve("a-single.foo.test").records.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(
|
||||
InetAddress.getByName("192.168.1.20"))
|
||||
}
|
||||
|
||||
"handle nonexistent domains" in {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
"DNS settings" must {
|
||||
|
||||
"use host servers if set to default" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "default"
|
||||
resolve-timeout = 1s
|
||||
search-domains = []
|
||||
|
|
@ -30,8 +30,8 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"parse a single name server" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "127.0.0.1"
|
||||
resolve-timeout = 1s
|
||||
search-domains = []
|
||||
|
|
@ -42,22 +42,21 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"parse a list of name servers" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = ["127.0.0.1", "127.0.0.2"]
|
||||
resolve-timeout = 1s
|
||||
search-domains = []
|
||||
ndots = 1
|
||||
"""))
|
||||
|
||||
dnsSettings.NameServers.map(_.getAddress) shouldEqual List(
|
||||
InetAddress.getByName("127.0.0.1"), InetAddress.getByName("127.0.0.2")
|
||||
)
|
||||
dnsSettings.NameServers.map(_.getAddress) shouldEqual List(InetAddress.getByName("127.0.0.1"),
|
||||
InetAddress.getByName("127.0.0.2"))
|
||||
}
|
||||
|
||||
"use host search domains if set to default" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "127.0.0.1"
|
||||
resolve-timeout = 1s
|
||||
search-domains = "default"
|
||||
|
|
@ -69,8 +68,8 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"parse a single search domain" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "127.0.0.1"
|
||||
resolve-timeout = 1s
|
||||
search-domains = "example.com"
|
||||
|
|
@ -81,8 +80,8 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"parse a single list of search domains" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "127.0.0.1"
|
||||
resolve-timeout = 1s
|
||||
search-domains = [ "example.com", "example.net" ]
|
||||
|
|
@ -93,8 +92,8 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"use host ndots if set to default" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "127.0.0.1"
|
||||
resolve-timeout = 1s
|
||||
search-domains = "example.com"
|
||||
|
|
@ -106,8 +105,8 @@ class DnsSettingsSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"parse ndots" in {
|
||||
val dnsSettings = new DnsSettings(eas, ConfigFactory.parseString(
|
||||
"""
|
||||
val dnsSettings = new DnsSettings(eas,
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = "127.0.0.1"
|
||||
resolve-timeout = 1s
|
||||
search-domains = "example.com"
|
||||
|
|
|
|||
|
|
@ -38,25 +38,30 @@ trait DockerBindDnsService extends Eventually { self: AkkaSpec =>
|
|||
return
|
||||
}
|
||||
|
||||
val containerConfig = ContainerConfig.builder()
|
||||
val containerConfig = ContainerConfig
|
||||
.builder()
|
||||
.image(image)
|
||||
.env("NO_CHOWN=true")
|
||||
.cmd("-4") // only listen on ipv4
|
||||
.hostConfig(
|
||||
HostConfig.builder()
|
||||
.portBindings(Map(
|
||||
"53/tcp" -> List(PortBinding.of("", hostPort)).asJava,
|
||||
"53/udp" -> List(PortBinding.of("", hostPort)).asJava
|
||||
).asJava)
|
||||
.binds(HostConfig.Bind.from(new java.io.File("akka-actor-tests/src/test/bind/").getAbsolutePath).to("/data/bind").build())
|
||||
.build()
|
||||
)
|
||||
HostConfig
|
||||
.builder()
|
||||
.portBindings(Map("53/tcp" -> List(PortBinding.of("", hostPort)).asJava,
|
||||
"53/udp" -> List(PortBinding.of("", hostPort)).asJava).asJava)
|
||||
.binds(HostConfig.Bind
|
||||
.from(new java.io.File("akka-actor-tests/src/test/bind/").getAbsolutePath)
|
||||
.to("/data/bind")
|
||||
.build())
|
||||
.build())
|
||||
.build()
|
||||
|
||||
val containerName = "akka-test-dns-" + getClass.getCanonicalName
|
||||
|
||||
client.listContainers(ListContainersParam.allContainers()).asScala
|
||||
.find(_.names().asScala.exists(_.contains(containerName))).foreach(c => {
|
||||
client
|
||||
.listContainers(ListContainersParam.allContainers())
|
||||
.asScala
|
||||
.find(_.names().asScala.exists(_.contains(containerName)))
|
||||
.foreach(c => {
|
||||
if ("running" == c.state()) {
|
||||
client.killContainer(c.id)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,17 @@ class NameserverAddressParserSpec extends WordSpec with Matchers {
|
|||
DnsSettings.parseNameserverAddress("8.8.8.8:153") shouldEqual new InetSocketAddress("8.8.8.8", 153)
|
||||
}
|
||||
"handle explicit port in IPv6 address" in {
|
||||
DnsSettings.parseNameserverAddress("[2001:4860:4860::8888]:153") shouldEqual new InetSocketAddress("2001:4860:4860::8888", 153)
|
||||
DnsSettings.parseNameserverAddress("[2001:4860:4860::8888]:153") shouldEqual new InetSocketAddress(
|
||||
"2001:4860:4860::8888",
|
||||
153)
|
||||
}
|
||||
"handle default port in IPv4 address" in {
|
||||
DnsSettings.parseNameserverAddress("8.8.8.8") shouldEqual new InetSocketAddress("8.8.8.8", 53)
|
||||
}
|
||||
"handle default port in IPv6 address" in {
|
||||
DnsSettings.parseNameserverAddress("[2001:4860:4860::8888]") shouldEqual new InetSocketAddress("2001:4860:4860::8888", 53)
|
||||
DnsSettings.parseNameserverAddress("[2001:4860:4860::8888]") shouldEqual new InetSocketAddress(
|
||||
"2001:4860:4860::8888",
|
||||
53)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ import akka.testkit.{ AkkaSpec, ImplicitSender }
|
|||
|
||||
import scala.collection.immutable.Seq
|
||||
|
||||
class AsyncDnsManagerSpec extends AkkaSpec(
|
||||
"""
|
||||
class AsyncDnsManagerSpec extends AkkaSpec("""
|
||||
akka.loglevel = DEBUG
|
||||
akka.loggers = ["akka.testkit.SilenceAllTestEventListener"]
|
||||
akka.io.dns.resolver = async-dns
|
||||
|
|
@ -46,7 +45,7 @@ class AsyncDnsManagerSpec extends AkkaSpec(
|
|||
|
||||
"provide access to cache" in {
|
||||
dns ! AsyncDnsManager.GetCache
|
||||
expectMsgType[AsyncDnsCache] should be theSameInstanceAs Dns(system).cache
|
||||
(expectMsgType[AsyncDnsCache] should be).theSameInstanceAs(Dns(system).cache)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ import akka.testkit.WithLogCapturing
|
|||
import scala.collection.{ immutable => im }
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class AsyncDnsResolverSpec extends AkkaSpec(
|
||||
"""
|
||||
class AsyncDnsResolverSpec extends AkkaSpec("""
|
||||
akka.loglevel = DEBUG
|
||||
akka.loggers = ["akka.testkit.SilenceAllTestEventListener"]
|
||||
""") with WithLogCapturing {
|
||||
|
|
@ -106,8 +105,7 @@ class AsyncDnsResolverSpec extends AkkaSpec(
|
|||
dnsClient1.expectNoMessage(50.millis)
|
||||
val answer = senderProbe.expectMsgType[Resolved]
|
||||
answer.records.collect { case r: ARecord => r }.toSet shouldEqual Set(
|
||||
ARecord("127.0.0.1", Ttl.effectivelyForever, InetAddress.getByName("127.0.0.1"))
|
||||
)
|
||||
ARecord("127.0.0.1", Ttl.effectivelyForever, InetAddress.getByName("127.0.0.1")))
|
||||
}
|
||||
|
||||
"response immediately for IPv6 address" in new Setup {
|
||||
|
|
@ -115,7 +113,9 @@ class AsyncDnsResolverSpec extends AkkaSpec(
|
|||
r ! Resolve(name)
|
||||
dnsClient1.expectNoMessage(50.millis)
|
||||
val answer = senderProbe.expectMsgType[Resolved]
|
||||
val Seq(AAAARecord("1:2:3:0:0:0:0:0", Ttl.effectivelyForever, _)) = answer.records.collect { case r: AAAARecord => r }
|
||||
val Seq(AAAARecord("1:2:3:0:0:0:0:0", Ttl.effectivelyForever, _)) = answer.records.collect {
|
||||
case r: AAAARecord => r
|
||||
}
|
||||
}
|
||||
|
||||
"return additional records for SRV requests" in new Setup {
|
||||
|
|
@ -134,8 +134,8 @@ class AsyncDnsResolverSpec extends AkkaSpec(
|
|||
}
|
||||
|
||||
def resolver(clients: List[ActorRef]): ActorRef = {
|
||||
val settings = new DnsSettings(system.asInstanceOf[ExtendedActorSystem], ConfigFactory.parseString(
|
||||
"""
|
||||
val settings = new DnsSettings(system.asInstanceOf[ExtendedActorSystem],
|
||||
ConfigFactory.parseString("""
|
||||
nameservers = ["one","two"]
|
||||
resolve-timeout = 300ms
|
||||
search-domains = []
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import org.scalatest.{ Matchers, WordSpec }
|
|||
class MessageSpec extends WordSpec with Matchers {
|
||||
"The Message" should {
|
||||
"parse a response that is truncated mid-message" in {
|
||||
val bytes = ByteString(0, 4, -125, -128, 0, 1, 0, 48, 0, 0, 0, 0, 4, 109, 97, 110, 121, 4, 98, 122, 122, 116, 3, 110, 101, 116, 0, 0, 28, 0, 1)
|
||||
val bytes = ByteString(0, 4, -125, -128, 0, 1, 0, 48, 0, 0, 0, 0, 4, 109, 97, 110, 121, 4, 98, 122, 122, 116, 3,
|
||||
110, 101, 116, 0, 0, 28, 0, 1)
|
||||
val msg = Message.parse(bytes)
|
||||
msg.id should be(4)
|
||||
msg.flags.isTruncated should be(true)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue