format source with scalafmt

This commit is contained in:
Auto Format 2019-03-11 10:38:24 +01:00 committed by Patrik Nordwall
parent 0f40491d42
commit ce404e4f53
1669 changed files with 43208 additions and 35404 deletions

View file

@ -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],

View file

@ -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
}

View file

@ -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

View file

@ -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"))

View file

@ -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"))
}

View file

@ -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")
}

View file

@ -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]]

View file

@ -83,4 +83,3 @@ import scala.compat.java8.FunctionConverters._
super.scheduleOnce(delay, target, message)
}
}

View file

@ -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
}
})
}
/**

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)`
*/

View file

@ -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")
}

View file

@ -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
*/

View file

@ -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]]
*/

View file

@ -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

View file

@ -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")

View file

@ -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]]
*/

View file

@ -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")

View file

@ -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)`
*/

View file

@ -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")
}

View file

@ -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()
}
}

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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")
}
}

View file

@ -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)))
}
}

View file

@ -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)

View file

@ -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 {

View file

@ -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 = {

View file

@ -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()
}
}

View file

@ -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"

View file

@ -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)
}

View file

@ -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)
}
}
}

View file

@ -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 {

View file

@ -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")

View file

@ -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)

View file

@ -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] {

View file

@ -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 = {

View file

@ -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")

View file

@ -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

View file

@ -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)

View file

@ -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
""")

View file

@ -78,4 +78,3 @@ class DeadLetterSupressionSpec extends AkkaSpec with ImplicitSender {
allListener.expectNoMsg(Duration.Zero)
}
}

View file

@ -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()

View file

@ -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 {

View file

@ -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()))
}

View file

@ -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()

View file

@ -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 {
}
}

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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)

View file

@ -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")
}

View file

@ -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""")
}
}

View file

@ -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"
}
}
}

View file

@ -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()

View file

@ -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. Im 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"),

View file

@ -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

View file

@ -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)))

View file

@ -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)
}

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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"

View file

@ -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

View file

@ -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) }

View file

@ -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))
}
}

View file

@ -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)

View file

@ -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
}
}
}
}

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -4,7 +4,7 @@
package akka.dispatch
import akka.testkit.{ DefaultTimeout, AkkaSpec }
import akka.testkit.{ AkkaSpec, DefaultTimeout }
import akka.actor.{ Actor, Props }
object ControlAwareDispatcherSpec {

View file

@ -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

View file

@ -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)

View file

@ -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 {

View file

@ -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)

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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 = ()
}

View file

@ -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
}
}

View file

@ -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 =>

View file

@ -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

View file

@ -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])

View file

@ -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)
}
}

View file

@ -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
}
}

View file

@ -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 =

View file

@ -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))

View file

@ -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()

View file

@ -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
}

View file

@ -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)

View file

@ -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 {

View file

@ -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"

View file

@ -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)
}

View file

@ -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)
}
}
}

View file

@ -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)
}
}

View file

@ -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 = []

View file

@ -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