#3206 - Adding expectTerminated to TestKit

This commit is contained in:
Viktor Klang 2013-04-09 14:48:17 +02:00
parent abc4652bc0
commit e59394628c
13 changed files with 61 additions and 20 deletions

View file

@ -29,7 +29,7 @@ object TestUtils {
def verifyActorTermination(actor: ActorRef)(implicit system: ActorSystem): Unit = { def verifyActorTermination(actor: ActorRef)(implicit system: ActorSystem): Unit = {
val watcher = TestProbe() val watcher = TestProbe()
watcher.watch(actor) watcher.watch(actor)
assert(watcher.expectMsgType[Terminated].actor == actor) watcher.expectTerminated(actor)
} }
} }

View file

@ -81,7 +81,7 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
val a1 = system.actorOf(p, name) val a1 = system.actorOf(p, name)
watch(a1) watch(a1)
a1 ! PoisonPill a1 ! PoisonPill
expectMsgType[Terminated].actor must be === a1 expectTerminated(a1)
// not equal because it's terminated // not equal because it's terminated
system.actorFor(a1.path.toString) must not be (a1) system.actorFor(a1.path.toString) must not be (a1)
@ -94,7 +94,7 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout {
watch(a2) watch(a2)
a2 ! PoisonPill a2 ! PoisonPill
expectMsgType[Terminated].actor must be === a2 expectTerminated(a2)
} }
"find actors by looking up their root-anchored relative path" in { "find actors by looking up their root-anchored relative path" in {

View file

@ -69,7 +69,7 @@ class LocalActorRefProviderSpec extends AkkaSpec(LocalActorRefProviderSpec.confi
val childProps1 = child.asInstanceOf[LocalActorRef].underlying.props val childProps1 = child.asInstanceOf[LocalActorRef].underlying.props
childProps1 must be(Props.empty) childProps1 must be(Props.empty)
system stop a system stop a
expectMsgType[Terminated] expectTerminated(a)
val childProps2 = child.asInstanceOf[LocalActorRef].underlying.props val childProps2 = child.asInstanceOf[LocalActorRef].underlying.props
childProps2 must not be theSameInstanceAs(childProps1) childProps2 must not be theSameInstanceAs(childProps1)
childProps2 must be theSameInstanceAs ActorCell.terminatedProps childProps2 must be theSameInstanceAs ActorCell.terminatedProps

View file

@ -69,7 +69,7 @@ class TcpListenerSpec extends AkkaSpec("akka.io.tcp.batch-accept-limit = 2") {
unbindCommander.send(listener, Unbind) unbindCommander.send(listener, Unbind)
unbindCommander.expectMsg(Unbound) unbindCommander.expectMsg(Unbound)
parent.expectMsgType[Terminated].actor must be(listener) parent.expectTerminated(listener)
} }
"drop an incoming connection if it cannot be registered with a selector" in new TestSetup { "drop an incoming connection if it cannot be registered with a selector" in new TestSetup {

View file

@ -82,9 +82,7 @@ class RoutingSpec extends AkkaSpec(RoutingSpec.config) with DefaultTimeout with
watch(router) watch(router)
watch(c2) watch(c2)
system.stop(c2) system.stop(c2)
expectMsgPF() { expectTerminated(c2).existenceConfirmed must be === true
case t @ Terminated(`c2`) if t.existenceConfirmed == true t
}
// it might take a while until the Router has actually processed the Terminated message // it might take a while until the Router has actually processed the Terminated message
awaitCond { awaitCond {
router ! "" router ! ""
@ -95,9 +93,7 @@ class RoutingSpec extends AkkaSpec(RoutingSpec.config) with DefaultTimeout with
res == Seq(c1, c1) res == Seq(c1, c1)
} }
system.stop(c1) system.stop(c1)
expectMsgPF() { expectTerminated(router).existenceConfirmed must be === true
case t @ Terminated(`router`) if t.existenceConfirmed == true t
}
} }
"not terminate when resizer is used" in { "not terminate when resizer is used" in {
@ -152,7 +148,7 @@ class RoutingSpec extends AkkaSpec(RoutingSpec.config) with DefaultTimeout with
expectMsgType[RouterRoutees].routees.size must be(3) expectMsgType[RouterRoutees].routees.size must be(3)
watch(router) watch(router)
system.stop(router) system.stop(router)
expectMsgType[Terminated] expectTerminated(router)
} }
"use configured nr-of-instances when router is specified" in { "use configured nr-of-instances when router is specified" in {

View file

@ -151,8 +151,7 @@ abstract class ClusterDeathWatchSpec
// removed // removed
awaitAssert(clusterView.unreachableMembers.map(_.address) must not contain (address(first))) awaitAssert(clusterView.unreachableMembers.map(_.address) must not contain (address(first)))
val t = expectMsgType[Terminated] expectTerminated(hello)
t.actor must be(hello)
enterBarrier("first-unavailable") enterBarrier("first-unavailable")

View file

@ -353,7 +353,7 @@ class ClusterSingletonManagerSpec extends MultiNodeSpec(ClusterSingletonManagerS
case ActorIdentity("singleton", None) // already terminated case ActorIdentity("singleton", None) // already terminated
case ActorIdentity("singleton", Some(singleton)) case ActorIdentity("singleton", Some(singleton))
watch(singleton) watch(singleton)
expectMsgType[Terminated].actor must be(singleton) expectTerminated(singleton)
} }
} }

View file

@ -84,7 +84,7 @@ class PeekMailboxSpec extends AkkaSpec("""
} }
expectMsg("DIE") expectMsg("DIE")
expectMsgType[DeadLetter].message must be("DIE") expectMsgType[DeadLetter].message must be("DIE")
expectMsgType[Terminated].actor must be(a) expectTerminated(a)
} }
} }

View file

@ -215,7 +215,7 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
val probe = TestProbe() val probe = TestProbe()
probe watch target probe watch target
target ! PoisonPill target ! PoisonPill
probe.expectMsgType[Terminated].actor must be(target) probe.expectTerminated(target)
//#test-probe-watch //#test-probe-watch
} }

View file

@ -347,7 +347,7 @@ class RemotingSpec extends AkkaSpec(RemotingSpec.cfg) with ImplicitSender with D
watch(child) watch(child)
child ! PoisonPill child ! PoisonPill
expectMsg("postStop") expectMsg("postStop")
expectMsgType[Terminated].actor must be === child expectTerminated(child)
l ! ((Props[Echo1], "child")) l ! ((Props[Echo1], "child"))
val child2 = expectMsgType[ActorRef] val child2 = expectMsgType[ActorRef]
child2 ! 45 child2 ! 45

View file

@ -3,6 +3,8 @@
*/ */
package akka.testkit; package akka.testkit;
import akka.actor.Terminated;
import akka.japi.Option;
import scala.runtime.AbstractFunction0; import scala.runtime.AbstractFunction0;
import akka.actor.ActorRef; import akka.actor.ActorRef;
import akka.actor.ActorSystem; import akka.actor.ActorSystem;
@ -456,10 +458,29 @@ public class JavaTestKit {
p.expectNoMsg(max); p.expectNoMsg(max);
} }
/**
* Assert that the given ActorRef is Terminated within the specified time.
* Don't forget to 'watch' it first!
*/
public Terminated expectTerminated(Duration max, ActorRef target) {
return p.expectTerminated(target, max);
}
/**
* Same as <code>expectTerminated(remaining(), target)</code>,
* but correctly treating the timeFactor.
* Don't forget to 'watch' it first!
*/
public Terminated expectTerminated(ActorRef target) {
return expectTerminated(Duration.Undefined(), target);
}
/** /**
* Same as <code>receiveN(n, remaining())</code>, but correctly treating the * Same as <code>receiveN(n, remaining())</code>, but correctly treating the
* timeFactor. * timeFactor.
*/ */
public Object[] receiveN(int n) { public Object[] receiveN(int n) {
return (Object[]) p.receiveN(n).toArray(Util.classTag(Object.class)); return (Object[]) p.receiveN(n).toArray(Util.classTag(Object.class));
} }

View file

@ -342,6 +342,17 @@ trait TestKitBase {
f(o) f(o)
} }
/**
* Receive one message from the test actor and assert that it is the Terminated message of the given ActorRef.
* Wait time is bounded by the given duration, with an AssertionFailure being thrown in case of timeout.
*
* @return the received Terminated message
*/
def expectTerminated(target: ActorRef, max: Duration = Duration.Undefined): Terminated =
expectMsgPF(max, "Terminated " + target) {
case t @ Terminated(`target`) t
}
/** /**
* Hybrid of expectMsgPF and receiveWhile: receive messages while the * Hybrid of expectMsgPF and receiveWhile: receive messages while the
* partial function matches and returns false. Use it to ignore certain * partial function matches and returns false. Use it to ignore certain

View file

@ -19,7 +19,7 @@ class JavaTestKitSpec extends AkkaSpec with DefaultTimeout {
new JavaTestKit(system) { new JavaTestKit(system) {
val sent = List(1, 2, 3, 4, 5) val sent = List(1, 2, 3, 4, 5)
for (m sent) { getRef() ! m } for (m sent) { getRef() ! m }
val received = receiveN(sent.size, 5 seconds); val received = receiveN(sent.size, 5 seconds)
sent.toSet must be(received.toSet) sent.toSet must be(received.toSet)
} }
} }
@ -28,11 +28,25 @@ class JavaTestKitSpec extends AkkaSpec with DefaultTimeout {
new JavaTestKit(system) { new JavaTestKit(system) {
val sent = List(1, 2, 3) val sent = List(1, 2, 3)
for (m sent) { getRef() ! m } for (m sent) { getRef() ! m }
val received = receiveN(sent.size); val received = receiveN(sent.size)
sent.toSet must be(received.toSet) sent.toSet must be(received.toSet)
} }
} }
"be able to expectTerminated" in {
new JavaTestKit(system) {
val actor = system.actorOf(Props(new Actor { def receive = { case _ } }))
system stop actor
watch(actor)
expectTerminated(actor).existenceConfirmed must be === true
watch(actor)
expectTerminated(5 seconds, actor).actor must be === actor
}
}
} }
} }