Cleanup Typed TestProbe implementation
* use a consistent api/impl technique * _internal methods are not dilating * add expectTerminated with default timeout * FiniteDuration in awaitAssert
This commit is contained in:
parent
463cdfe2a6
commit
19769e2a87
4 changed files with 226 additions and 171 deletions
|
|
@ -4,25 +4,37 @@
|
|||
|
||||
package akka.actor.testkit.typed.internal
|
||||
|
||||
import java.time.{ Duration ⇒ JDuration }
|
||||
import java.util.concurrent.BlockingDeque
|
||||
import java.util.concurrent.LinkedBlockingDeque
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.{ BlockingDeque, LinkedBlockingDeque }
|
||||
import java.util.function.Supplier
|
||||
import java.util.{ List ⇒ JList }
|
||||
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, Terminated }
|
||||
import akka.annotation.InternalApi
|
||||
import akka.actor.testkit.typed.javadsl.{ TestProbe ⇒ JavaTestProbe }
|
||||
import akka.actor.testkit.typed.scaladsl.{ TestDuration, TestProbe ⇒ ScalaTestProbe }
|
||||
import akka.actor.testkit.typed.{ FishingOutcome, TestKitSettings }
|
||||
import akka.util.PrettyDuration._
|
||||
import akka.util.{ BoxedType, Timeout }
|
||||
import akka.util.JavaDurationConverters._
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration._
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
import akka.actor.testkit.typed.FishingOutcome
|
||||
import akka.actor.testkit.typed.TestKitSettings
|
||||
import akka.actor.testkit.typed.javadsl.{ TestProbe ⇒ JavaTestProbe }
|
||||
import akka.actor.testkit.typed.scaladsl.TestDuration
|
||||
import akka.actor.testkit.typed.scaladsl.{ TestProbe ⇒ ScalaTestProbe }
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.ActorSystem
|
||||
import akka.actor.typed.Behavior
|
||||
import akka.actor.typed.Terminated
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import akka.annotation.InternalApi
|
||||
import akka.util.BoxedType
|
||||
import akka.util.JavaDurationConverters._
|
||||
import akka.util.PrettyDuration._
|
||||
import akka.util.Timeout
|
||||
|
||||
@InternalApi
|
||||
private[akka] object TestProbeImpl {
|
||||
private val testActorId = new AtomicInteger(0)
|
||||
|
|
@ -53,7 +65,7 @@ private[akka] object TestProbeImpl {
|
|||
private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_]) extends JavaTestProbe[M] with ScalaTestProbe[M] {
|
||||
|
||||
import TestProbeImpl._
|
||||
protected implicit val settings = TestKitSettings(system)
|
||||
protected implicit val settings: TestKitSettings = TestKitSettings(system)
|
||||
private val queue = new LinkedBlockingDeque[M]
|
||||
private val terminations = new LinkedBlockingDeque[Terminated]
|
||||
|
||||
|
|
@ -65,8 +77,6 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
*/
|
||||
private var lastWasNoMessage = false
|
||||
|
||||
private var lastMessage: Option[M] = None
|
||||
|
||||
private val testActor: ActorRef[M] = {
|
||||
// FIXME arbitrary timeout?
|
||||
implicit val timeout: Timeout = Timeout(3.seconds)
|
||||
|
|
@ -78,14 +88,14 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
|
||||
override def remainingOrDefault: FiniteDuration = remainingOr(settings.SingleExpectDefaultTimeout.dilated)
|
||||
|
||||
override def getRemainingOrDefault: java.time.Duration = remainingOrDefault.asJava
|
||||
override def getRemainingOrDefault: JDuration = remainingOrDefault.asJava
|
||||
|
||||
override def remaining: FiniteDuration = end match {
|
||||
case f: FiniteDuration ⇒ f - now
|
||||
case _ ⇒ assertFail("`remaining` may not be called outside of `within`")
|
||||
}
|
||||
|
||||
override def getRemaining: java.time.Duration = remaining.asJava
|
||||
override def getRemaining: JDuration = remaining.asJava
|
||||
|
||||
override def remainingOr(duration: FiniteDuration): FiniteDuration = end match {
|
||||
case x if x eq Duration.Undefined ⇒ duration
|
||||
|
|
@ -93,33 +103,38 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
case f: FiniteDuration ⇒ f - now
|
||||
}
|
||||
|
||||
override def getRemainingOr(duration: java.time.Duration): java.time.Duration =
|
||||
override def getRemainingOr(duration: JDuration): JDuration =
|
||||
remainingOr(duration.asScala).asJava
|
||||
|
||||
private def remainingOrDilated(max: Duration): FiniteDuration = max match {
|
||||
case x if x eq Duration.Undefined ⇒ remainingOrDefault
|
||||
case x if !x.isFinite ⇒ throw new IllegalArgumentException("max duration cannot be infinite")
|
||||
case f: FiniteDuration ⇒ f.dilated
|
||||
}
|
||||
override def within[T](min: FiniteDuration, max: FiniteDuration)(f: ⇒ T): T =
|
||||
within_internal(min, max.dilated, f)
|
||||
|
||||
override protected def within_internal[T](min: FiniteDuration, max: FiniteDuration, f: ⇒ T): T = {
|
||||
val _max = max.dilated
|
||||
override def within[T](max: FiniteDuration)(f: ⇒ T): T =
|
||||
within_internal(Duration.Zero, max.dilated, f)
|
||||
|
||||
override def within[T](min: JDuration, max: JDuration)(f: Supplier[T]): T =
|
||||
within_internal(min.asScala, max.asScala.dilated, f.get())
|
||||
|
||||
def within[T](max: JDuration)(f: Supplier[T]): T =
|
||||
within_internal(Duration.Zero, max.asScala.dilated, f.get())
|
||||
|
||||
private def within_internal[T](min: FiniteDuration, max: FiniteDuration, f: ⇒ T): T = {
|
||||
val start = now
|
||||
val rem = if (end == Duration.Undefined) Duration.Inf else end - start
|
||||
assert(rem >= min, s"required min time $min not possible, only ${rem.pretty} left")
|
||||
|
||||
lastWasNoMessage = false
|
||||
|
||||
val max_diff = _max min rem
|
||||
val prev_end = end
|
||||
end = start + max_diff
|
||||
val maxDiff = max min rem
|
||||
val prevEnd = end
|
||||
end = start + maxDiff
|
||||
|
||||
val ret = try f finally end = prev_end
|
||||
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")
|
||||
if (!lastWasNoMessage) {
|
||||
assert(diff <= max_diff, s"block took ${diff.pretty}, exceeding ${max_diff.pretty}")
|
||||
assert(diff <= maxDiff, s"block took ${diff.pretty}, exceeding ${maxDiff.pretty}")
|
||||
}
|
||||
|
||||
ret
|
||||
|
|
@ -129,13 +144,13 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
|
||||
override def expectMessage[T <: M](max: FiniteDuration, obj: T): T = expectMessage_internal(max.dilated, obj)
|
||||
|
||||
override def expectMessage[T <: M](max: java.time.Duration, obj: T): T =
|
||||
override def expectMessage[T <: M](max: JDuration, obj: T): T =
|
||||
expectMessage(max.asScala, obj)
|
||||
|
||||
override def expectMessage[T <: M](max: FiniteDuration, hint: String, obj: T): T =
|
||||
expectMessage_internal(max.dilated, obj, Some(hint))
|
||||
|
||||
override def expectMessage[T <: M](max: java.time.Duration, hint: String, obj: T): T =
|
||||
override def expectMessage[T <: M](max: JDuration, hint: String, obj: T): T =
|
||||
expectMessage(max.asScala, hint, obj)
|
||||
|
||||
private def expectMessage_internal[T <: M](max: Duration, obj: T, hint: Option[String] = None): T = {
|
||||
|
|
@ -150,7 +165,7 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
|
||||
override def receiveOne(): M = receiveOne(remainingOrDefault)
|
||||
|
||||
override def receiveOne(max: java.time.Duration): M = receiveOne(max.asScala)
|
||||
override def receiveOne(max: JDuration): M = receiveOne(max.asScala)
|
||||
|
||||
def receiveOne(max: FiniteDuration): M =
|
||||
receiveOne_internal(max.dilated).
|
||||
|
|
@ -173,14 +188,13 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
}
|
||||
)
|
||||
lastWasNoMessage = false
|
||||
lastMessage = message
|
||||
message
|
||||
}
|
||||
|
||||
override def expectNoMessage(max: FiniteDuration): Unit =
|
||||
expectNoMessage_internal(max)
|
||||
|
||||
override def expectNoMessage(max: java.time.Duration): Unit =
|
||||
override def expectNoMessage(max: JDuration): Unit =
|
||||
expectNoMessage(max.asScala)
|
||||
|
||||
override def expectNoMessage(): Unit =
|
||||
|
|
@ -194,7 +208,19 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
}
|
||||
}
|
||||
|
||||
override protected def expectMessageClass_internal[C](max: FiniteDuration, c: Class[C]): C = {
|
||||
override def expectMessageType[T <: M](implicit t: ClassTag[T]): T =
|
||||
expectMessageClass_internal(remainingOrDefault, t.runtimeClass.asInstanceOf[Class[T]])
|
||||
|
||||
override def expectMessageType[T <: M](max: FiniteDuration)(implicit t: ClassTag[T]): T =
|
||||
expectMessageClass_internal(max.dilated, t.runtimeClass.asInstanceOf[Class[T]])
|
||||
|
||||
override def expectMessageClass[T <: M](clazz: Class[T]): T =
|
||||
expectMessageClass_internal(getRemainingOrDefault.asScala, clazz)
|
||||
|
||||
override def expectMessageClass[T <: M](clazz: Class[T], max: JDuration): T =
|
||||
expectMessageClass_internal(max.asScala.dilated, clazz)
|
||||
|
||||
private def expectMessageClass_internal[C](max: FiniteDuration, c: Class[C]): C = {
|
||||
val o = receiveOne_internal(max)
|
||||
val bt = BoxedType(c)
|
||||
o match {
|
||||
|
|
@ -204,7 +230,19 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
}
|
||||
}
|
||||
|
||||
override protected def receiveN_internal(n: Int, max: FiniteDuration): immutable.Seq[M] = {
|
||||
override def receiveN(n: Int): immutable.Seq[M] =
|
||||
receiveN_internal(n, remainingOrDefault)
|
||||
|
||||
override def receiveN(n: Int, max: FiniteDuration): immutable.Seq[M] =
|
||||
receiveN_internal(n, max.dilated)
|
||||
|
||||
override def receiveMessages(n: Int): JList[M] =
|
||||
receiveN_internal(n, getRemainingOrDefault.asScala).asJava
|
||||
|
||||
override def receiveMessages(n: Int, max: JDuration): JList[M] =
|
||||
receiveN_internal(n, max.asScala.dilated).asJava
|
||||
|
||||
private def receiveN_internal(n: Int, max: FiniteDuration): immutable.Seq[M] = {
|
||||
val stop = max + now
|
||||
for (x ← 1 to n) yield {
|
||||
val timeout = stop - now
|
||||
|
|
@ -216,7 +254,19 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
}
|
||||
}
|
||||
|
||||
override protected def fishForMessage_internal(max: FiniteDuration, hint: String, fisher: M ⇒ FishingOutcome): List[M] = {
|
||||
override def fishForMessage(max: FiniteDuration, hint: String)(fisher: M ⇒ FishingOutcome): immutable.Seq[M] =
|
||||
fishForMessage_internal(max.dilated, hint, fisher)
|
||||
|
||||
override def fishForMessage(max: FiniteDuration)(fisher: M ⇒ FishingOutcome): immutable.Seq[M] =
|
||||
fishForMessage(max, "")(fisher)
|
||||
|
||||
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] =
|
||||
fishForMessage_internal(max.asScala.dilated, hint, fisher.apply).asJava
|
||||
|
||||
private def fishForMessage_internal(max: FiniteDuration, hint: String, fisher: M ⇒ FishingOutcome): List[M] = {
|
||||
@tailrec def loop(timeout: FiniteDuration, seen: List[M]): List[M] = {
|
||||
val start = System.nanoTime()
|
||||
val maybeMsg = receiveOne_internal(timeout)
|
||||
|
|
@ -243,10 +293,19 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
}
|
||||
}
|
||||
|
||||
loop(max.dilated, Nil)
|
||||
loop(max, Nil)
|
||||
}
|
||||
|
||||
override def expectTerminated[U](actorRef: ActorRef[U], max: FiniteDuration): Unit = {
|
||||
override def expectTerminated[U](actorRef: ActorRef[U], max: FiniteDuration): Unit =
|
||||
expectTerminated_internal(actorRef, max.dilated)
|
||||
|
||||
override def expectTerminated[U](actorRef: ActorRef[U]): Unit =
|
||||
expectTerminated_internal(actorRef, remainingOrDefault)
|
||||
|
||||
override def expectTerminated[U](actorRef: ActorRef[U], max: JDuration): Unit =
|
||||
expectTerminated_internal(actorRef, max.asScala.dilated)
|
||||
|
||||
private def expectTerminated_internal[U](actorRef: ActorRef[U], max: FiniteDuration): Unit = {
|
||||
testActor.asInstanceOf[ActorRef[AnyRef]] ! WatchActor(actorRef)
|
||||
val message =
|
||||
if (max == Duration.Zero) {
|
||||
|
|
@ -260,15 +319,26 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
assert(message.ref == actorRef, s"expected [${actorRef.path}] to stop, but saw [${message.ref.path}] stop")
|
||||
}
|
||||
|
||||
override def expectTerminated[U](actorRef: ActorRef[U], max: java.time.Duration): Unit =
|
||||
expectTerminated(actorRef, max.asScala)
|
||||
override def awaitAssert[A](a: ⇒ A, max: FiniteDuration, interval: FiniteDuration): A =
|
||||
awaitAssert_internal(a, max.dilated, interval)
|
||||
|
||||
override def awaitAssert[A](max: java.time.Duration, interval: java.time.Duration, supplier: Supplier[A]): A =
|
||||
awaitAssert(supplier.get(), if (max == java.time.Duration.ZERO) Duration.Undefined else max.asScala, interval.asScala)
|
||||
override def awaitAssert[A](a: ⇒ A, max: FiniteDuration): A =
|
||||
awaitAssert_internal(a, max.dilated, 100.millis)
|
||||
|
||||
override def awaitAssert[A](a: ⇒ A, max: Duration = Duration.Undefined, interval: Duration = 100.millis): A = {
|
||||
val _max = remainingOrDilated(max)
|
||||
val stop = now + _max
|
||||
override def awaitAssert[A](a: ⇒ A): A =
|
||||
awaitAssert_internal(a, remainingOrDefault, 100.millis)
|
||||
|
||||
override def awaitAssert[A](max: JDuration, interval: JDuration, supplier: Supplier[A]): A =
|
||||
awaitAssert_internal(supplier.get(), max.asScala.dilated, interval.asScala)
|
||||
|
||||
def awaitAssert[A](max: JDuration, supplier: Supplier[A]): A =
|
||||
awaitAssert(max, JDuration.ofMillis(100), supplier)
|
||||
|
||||
def awaitAssert[A](supplier: Supplier[A]): A =
|
||||
awaitAssert(getRemainingOrDefault, supplier)
|
||||
|
||||
private def awaitAssert_internal[A](a: ⇒ A, max: FiniteDuration, interval: FiniteDuration): A = {
|
||||
val stop = now + max
|
||||
|
||||
@tailrec
|
||||
def poll(t: Duration): A = {
|
||||
|
|
@ -294,7 +364,7 @@ private[akka] final class TestProbeImpl[M](name: String, system: ActorSystem[_])
|
|||
}
|
||||
}
|
||||
|
||||
poll(_max min interval)
|
||||
poll(max min interval)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,19 +8,14 @@ import java.time.Duration
|
|||
import java.util.function.Supplier
|
||||
import java.util.{ List ⇒ JList }
|
||||
|
||||
import akka.actor.typed.{ ActorRef, ActorSystem }
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.annotation.InternalApi
|
||||
import akka.actor.testkit.typed.FishingOutcome
|
||||
import akka.actor.testkit.typed.TestKitSettings
|
||||
import akka.actor.testkit.typed.internal.TestProbeImpl
|
||||
import akka.actor.testkit.typed.{ FishingOutcome, TestKitSettings }
|
||||
import akka.actor.testkit.typed.scaladsl.TestDuration
|
||||
import akka.util.JavaDurationConverters._
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.ActorSystem
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.util.unused
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
object FishingOutcomes {
|
||||
/**
|
||||
* Consume this message and continue with the next
|
||||
|
|
@ -108,8 +103,8 @@ abstract class TestProbe[M] {
|
|||
* take maximum wait times are available in a version which implicitly uses
|
||||
* the remaining time governed by the innermost enclosing `within` block.
|
||||
*
|
||||
* Note that the timeout is scaled using Duration.dilated, which uses the
|
||||
* configuration entry "akka.actor.testkit.typed.timefactor", while the min Duration is not.
|
||||
* Note that the max timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor",
|
||||
* while the min Duration is not.
|
||||
*
|
||||
* {{{
|
||||
* val ret = within(50 millis) {
|
||||
|
|
@ -118,19 +113,12 @@ abstract class TestProbe[M] {
|
|||
* }
|
||||
* }}}
|
||||
*/
|
||||
def within[T](min: Duration, max: Duration)(f: Supplier[T]): T =
|
||||
within_internal(min.asScala, max.asScala, f.get())
|
||||
def within[T](min: Duration, max: Duration)(f: Supplier[T]): T
|
||||
|
||||
/**
|
||||
* Same as calling `within(0 seconds, max)(f)`.
|
||||
*/
|
||||
def within[T](max: Duration)(f: Supplier[T]): T =
|
||||
within_internal(scala.concurrent.duration.Duration.Zero, max.asScala, f.get())
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi protected def within_internal[T](min: FiniteDuration, max: FiniteDuration, f: ⇒ T): T
|
||||
def within[T](max: Duration)(f: Supplier[T]): T
|
||||
|
||||
/**
|
||||
* Same as `expectMessage(remainingOrDefault, obj)`, but using the
|
||||
|
|
@ -163,65 +151,23 @@ abstract class TestProbe[M] {
|
|||
def expectNoMessage(max: Duration): Unit
|
||||
|
||||
/**
|
||||
* Assert that no message is received. Waits for the default period configured as `akka.actor.testkit.typed.expect-no-message-default`
|
||||
* That value is dilated.
|
||||
* Assert that no message is received. Waits for the default period configured as `akka.actor.testkit.typed.expect-no-message-default`.
|
||||
* That timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def expectNoMessage(): Unit
|
||||
|
||||
/**
|
||||
* Expect the given actor to be stopped or stop within the given timeout or
|
||||
* throw an [[AssertionError]].
|
||||
*/
|
||||
def expectTerminated[U](actorRef: ActorRef[U], max: Duration): Unit
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every `interval` until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the `max` timeout expires the last exception is thrown.
|
||||
*
|
||||
* Note that the timeout is scaled using Duration.dilated, which uses the configuration entry "akka.test.timefactor".
|
||||
*/
|
||||
def awaitAssert[A](max: Duration, interval: Duration, supplier: Supplier[A]): A
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every 100 milliseconds until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the `max` timeout expires the last exception is thrown.
|
||||
*
|
||||
* Note that the timeout is scaled using Duration.dilated, which uses the configuration entry "akka.test.timefactor".
|
||||
*/
|
||||
def awaitAssert[A](max: Duration, supplier: Supplier[A]): A =
|
||||
awaitAssert(max, Duration.ofMillis(100), supplier)
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every 100 milliseconds until it does not throw an exception and return the
|
||||
* result. A max time is taken it from the innermost enclosing `within` block.
|
||||
*/
|
||||
def awaitAssert[A](supplier: Supplier[A]): A =
|
||||
awaitAssert(Duration.ZERO, supplier)
|
||||
|
||||
// FIXME awaitAssert(Procedure): Unit would be nice for java people to not have to return null
|
||||
|
||||
/**
|
||||
* Same as `expectMessageType(clazz, remainingOrDefault)`,but using the
|
||||
* default timeout as deadline.
|
||||
*/
|
||||
def expectMessageClass[T <: M](clazz: Class[T]): T =
|
||||
expectMessageClass_internal(getRemainingOrDefault.asScala, clazz)
|
||||
def expectMessageClass[T <: M](clazz: Class[T]): T
|
||||
|
||||
/**
|
||||
* Wait for a message of type M and return it when it arrives, or fail if the `max` timeout is hit.
|
||||
* The timeout is dilated.
|
||||
*
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def expectMessageClass[T <: M](clazz: Class[T], max: Duration): T =
|
||||
expectMessageClass_internal(max.asScala.dilated, clazz)
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi protected def expectMessageClass_internal[C](max: FiniteDuration, c: Class[C]): C
|
||||
def expectMessageClass[T <: M](clazz: Class[T], max: Duration): T
|
||||
|
||||
/**
|
||||
* Receive one message of type `M` within the default timeout as deadline.
|
||||
|
|
@ -237,17 +183,14 @@ abstract class TestProbe[M] {
|
|||
/**
|
||||
* Same as `receiveMessages(n, remaining)` but using the default timeout as deadline.
|
||||
*/
|
||||
def receiveMessages(n: Int): JList[M] = receiveN_internal(n, getRemainingOrDefault.asScala).asJava
|
||||
def receiveMessages(n: Int): JList[M]
|
||||
|
||||
/**
|
||||
* Receive `n` messages in a row before the given deadline.
|
||||
*
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def receiveMessages(n: Int, max: Duration): JList[M] = receiveN_internal(n, max.asScala.dilated).asJava
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi protected def receiveN_internal(n: Int, max: FiniteDuration): immutable.Seq[M]
|
||||
def receiveMessages(n: Int, max: Duration): JList[M]
|
||||
|
||||
/**
|
||||
* Java API: Allows for flexible matching of multiple messages within a timeout, the fisher function is fed each incoming
|
||||
|
|
@ -262,23 +205,57 @@ abstract class TestProbe[M] {
|
|||
* is decorated with some fishing details and the test is failed (making it convenient to use this method with a
|
||||
* partial function).
|
||||
*
|
||||
* @param max Max total time without the fisher function returning `CompleteFishing` before failing
|
||||
* The timeout is dilated.
|
||||
* @param max Max total time without the fisher function returning `CompleteFishing` before failing.
|
||||
* The timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
* @return The messages accepted in the order they arrived
|
||||
*/
|
||||
def fishForMessage(max: Duration, fisher: java.util.function.Function[M, FishingOutcome]): java.util.List[M] =
|
||||
fishForMessage(max, "", fisher)
|
||||
def fishForMessage(max: Duration, fisher: java.util.function.Function[M, FishingOutcome]): java.util.List[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] =
|
||||
fishForMessage_internal(max.asScala, hint, fisher.apply).asJava
|
||||
def fishForMessage(max: Duration, hint: String, fisher: java.util.function.Function[M, FishingOutcome]): java.util.List[M]
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
* Expect the given actor to be stopped or stop within the given timeout or
|
||||
* throw an [[AssertionError]].
|
||||
*
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
@InternalApi protected def fishForMessage_internal(max: FiniteDuration, hint: String, fisher: M ⇒ FishingOutcome): List[M]
|
||||
def expectTerminated[U](actorRef: ActorRef[U], max: Duration): Unit
|
||||
|
||||
/**
|
||||
* Expect the given actor to be stopped or stop within the default timeout.
|
||||
*/
|
||||
def expectTerminated[U](actorRef: ActorRef[U]): Unit
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every `interval` until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the `max` timeout expires the last exception is thrown.
|
||||
*
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def awaitAssert[A](max: Duration, interval: Duration, supplier: Supplier[A]): A
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every 100 milliseconds until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the `max` timeout expires the last exception is thrown.
|
||||
*
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def awaitAssert[A](max: Duration, supplier: Supplier[A]): A
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every 100 milliseconds until it does not throw an exception and return the
|
||||
* result. A max time is taken it from the innermost enclosing `within` block.
|
||||
*/
|
||||
def awaitAssert[A](supplier: Supplier[A]): A
|
||||
|
||||
// FIXME awaitAssert(Procedure): Unit would be nice for java people to not have to return null
|
||||
|
||||
/**
|
||||
* Stops the [[TestProbe.getRef]], which is useful when testing watch and termination.
|
||||
|
|
|
|||
|
|
@ -4,14 +4,16 @@
|
|||
|
||||
package akka.actor.testkit.typed.scaladsl
|
||||
|
||||
import akka.actor.typed.{ ActorRef, ActorSystem }
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.actor.testkit.typed.internal.TestProbeImpl
|
||||
import akka.actor.testkit.typed.{ FishingOutcome, TestKitSettings }
|
||||
|
||||
import scala.collection.immutable
|
||||
import scala.concurrent.duration._
|
||||
import scala.reflect.ClassTag
|
||||
import scala.collection.immutable
|
||||
|
||||
import akka.actor.testkit.typed.FishingOutcome
|
||||
import akka.actor.testkit.typed.TestKitSettings
|
||||
import akka.actor.testkit.typed.internal.TestProbeImpl
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.ActorSystem
|
||||
import akka.annotation.DoNotInherit
|
||||
|
||||
object FishingOutcomes {
|
||||
/**
|
||||
|
|
@ -84,8 +86,8 @@ object TestProbe {
|
|||
* take maximum wait times are available in a version which implicitly uses
|
||||
* the remaining time governed by the innermost enclosing `within` block.
|
||||
*
|
||||
* Note that the timeout is scaled using Duration.dilated, which uses the
|
||||
* configuration entry "akka.actor.testkit.typed.timefactor", while the min Duration is not.
|
||||
* Note that the max timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor",
|
||||
* while the min Duration is not.
|
||||
*
|
||||
* {{{
|
||||
* val ret = within(50 millis) {
|
||||
|
|
@ -94,15 +96,12 @@ object TestProbe {
|
|||
* }
|
||||
* }}}
|
||||
*/
|
||||
def within[T](min: FiniteDuration, max: FiniteDuration)(f: ⇒ T): T =
|
||||
within_internal(min, max, f)
|
||||
def within[T](min: FiniteDuration, max: FiniteDuration)(f: ⇒ T): T
|
||||
|
||||
/**
|
||||
* Same as calling `within(0 seconds, max)(f)`.
|
||||
*/
|
||||
def within[T](max: FiniteDuration)(f: ⇒ T): T =
|
||||
within_internal(Duration.Zero, max, f)
|
||||
|
||||
protected def within_internal[T](min: FiniteDuration, max: FiniteDuration, f: ⇒ T): T
|
||||
def within[T](max: FiniteDuration)(f: ⇒ T): T
|
||||
|
||||
/**
|
||||
* Same as `expectMessage(remainingOrDefault, obj)`, but using the default timeout as deadline.
|
||||
|
|
@ -134,24 +133,20 @@ object TestProbe {
|
|||
def expectNoMessage(max: FiniteDuration): Unit
|
||||
|
||||
/**
|
||||
* Assert that no message is received. Waits for the default period configured as `akka.actor.testkit.typed.expect-no-message-default`
|
||||
* That value is dilated.
|
||||
* Assert that no message is received. Waits for the default period configured as `akka.actor.testkit.typed.expect-no-message-default`.
|
||||
* That timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def expectNoMessage(): Unit
|
||||
|
||||
/**
|
||||
* Same as `expectMessageType[T](remainingOrDefault)`, but using the default timeout as deadline.
|
||||
*/
|
||||
def expectMessageType[T <: M](implicit t: ClassTag[T]): T =
|
||||
expectMessageClass_internal(remainingOrDefault, t.runtimeClass.asInstanceOf[Class[T]])
|
||||
def expectMessageType[T <: M](implicit t: ClassTag[T]): T
|
||||
|
||||
/**
|
||||
* Expect a message of type T to arrive within `max` or fail. `max` is dilated.
|
||||
*/
|
||||
def expectMessageType[T <: M](max: FiniteDuration)(implicit t: ClassTag[T]): T =
|
||||
expectMessageClass_internal(max.dilated, t.runtimeClass.asInstanceOf[Class[T]])
|
||||
|
||||
protected def expectMessageClass_internal[C](max: FiniteDuration, c: Class[C]): C
|
||||
def expectMessageType[T <: M](max: FiniteDuration)(implicit t: ClassTag[T]): T
|
||||
|
||||
/**
|
||||
* Receive one message of type `M` within the default timeout as deadline.
|
||||
|
|
@ -167,14 +162,14 @@ object TestProbe {
|
|||
/**
|
||||
* Same as `receiveN(n, remaining)` but using the default timeout as deadline.
|
||||
*/
|
||||
def receiveN(n: Int): immutable.Seq[M] = receiveN_internal(n, remainingOrDefault)
|
||||
def receiveN(n: Int): immutable.Seq[M]
|
||||
|
||||
/**
|
||||
* Receive `n` messages in a row before the given deadline.
|
||||
*
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def receiveN(n: Int, max: FiniteDuration): immutable.Seq[M] = receiveN_internal(n, max.dilated)
|
||||
|
||||
protected def receiveN_internal(n: Int, max: FiniteDuration): immutable.Seq[M]
|
||||
def receiveN(n: Int, max: FiniteDuration): immutable.Seq[M]
|
||||
|
||||
/**
|
||||
* Allows for flexible matching of multiple messages within a timeout, the fisher function is fed each incoming
|
||||
|
|
@ -190,20 +185,16 @@ object TestProbe {
|
|||
* is decorated with some fishing details and the test is failed (making it convenient to use this method with a
|
||||
* partial function).
|
||||
*
|
||||
* @param max Max total time without the fisher function returning `CompleteFishing` before failing
|
||||
* The timeout is dilated.
|
||||
* @param max Max total time without the fisher function returning `CompleteFishing` before failing.
|
||||
* The timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
* @return The messages accepted in the order they arrived
|
||||
*/
|
||||
def fishForMessage(max: FiniteDuration, hint: String)(fisher: M ⇒ FishingOutcome): immutable.Seq[M] =
|
||||
fishForMessage_internal(max, hint, fisher)
|
||||
def fishForMessage(max: FiniteDuration, hint: String)(fisher: M ⇒ FishingOutcome): immutable.Seq[M]
|
||||
|
||||
/**
|
||||
* Same as the other `fishForMessage` but with no hint
|
||||
*/
|
||||
def fishForMessage(max: FiniteDuration)(fisher: M ⇒ FishingOutcome): immutable.Seq[M] =
|
||||
fishForMessage(max, "")(fisher)
|
||||
|
||||
protected def fishForMessage_internal(max: FiniteDuration, hint: String, fisher: M ⇒ FishingOutcome): immutable.Seq[M]
|
||||
def fishForMessage(max: FiniteDuration)(fisher: M ⇒ FishingOutcome): immutable.Seq[M]
|
||||
|
||||
/**
|
||||
* Expect the given actor to be stopped or stop within the given timeout or
|
||||
|
|
@ -211,19 +202,36 @@ object TestProbe {
|
|||
*/
|
||||
def expectTerminated[U](actorRef: ActorRef[U], max: FiniteDuration): Unit
|
||||
|
||||
/**
|
||||
* Expect the given actor to be stopped or stop within the default timeout.
|
||||
*/
|
||||
def expectTerminated[U](actorRef: ActorRef[U]): Unit
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every `interval` until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the `max` timeout expires the last exception is thrown.
|
||||
*
|
||||
* If no timeout is given, take it from the innermost enclosing `within`
|
||||
* block.
|
||||
*
|
||||
* Note that the timeout is scaled using Duration.dilated,
|
||||
* which uses the configuration entry "akka.test.timefactor".
|
||||
* Note that the timeout is scaled using the configuration entry "akka.actor.testkit.typed.timefactor".
|
||||
*/
|
||||
def awaitAssert[A](a: ⇒ A, max: Duration = Duration.Undefined, interval: Duration = 100.millis): A
|
||||
def awaitAssert[A](a: ⇒ A, max: FiniteDuration, interval: FiniteDuration): A
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every 100 ms until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the `max` timeout expires the last exception is thrown.
|
||||
*/
|
||||
def awaitAssert[A](a: ⇒ A, max: FiniteDuration): A
|
||||
|
||||
/**
|
||||
* Evaluate the given assert every 100 ms until it does not throw an exception and return the
|
||||
* result.
|
||||
*
|
||||
* If the default timeout expires the last exception is thrown.
|
||||
*/
|
||||
def awaitAssert[A](a: ⇒ A): A
|
||||
|
||||
/**
|
||||
* Stops the [[TestProbe.ref]], which is useful when testing watch and termination.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package object scaladsl {
|
|||
|
||||
/**
|
||||
* Scala API. Scale timeouts (durations) during tests with the configured
|
||||
* 'akka.test.timefactor'.
|
||||
* 'akka.actor.testkit.typed.timefactor'.
|
||||
* Implicit class providing `dilated` method.
|
||||
*
|
||||
* {{{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue