From e59394628c5f9ef942b56f7edfa1a6b4d7ade665 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 9 Apr 2013 14:48:17 +0200 Subject: [PATCH] #3206 - Adding expectTerminated to TestKit --- .../src/test/scala/akka/TestUtils.scala | 2 +- .../scala/akka/actor/ActorLookupSpec.scala | 4 ++-- .../actor/LocalActorRefProviderSpec.scala | 2 +- .../test/scala/akka/io/TcpListenerSpec.scala | 2 +- .../test/scala/akka/routing/RoutingSpec.scala | 10 +++------ .../akka/cluster/ClusterDeathWatchSpec.scala | 3 +-- .../pattern/ClusterSingletonManagerSpec.scala | 2 +- .../contrib/mailbox/PeekMailboxSpec.scala | 2 +- .../code/docs/testkit/TestkitDocSpec.scala | 2 +- .../test/scala/akka/remote/RemotingSpec.scala | 2 +- .../main/java/akka/testkit/JavaTestKit.java | 21 +++++++++++++++++++ .../src/main/scala/akka/testkit/TestKit.scala | 11 ++++++++++ .../scala/akka/testkit/JavaTestKitSpec.scala | 18 ++++++++++++++-- 13 files changed, 61 insertions(+), 20 deletions(-) diff --git a/akka-actor-tests/src/test/scala/akka/TestUtils.scala b/akka-actor-tests/src/test/scala/akka/TestUtils.scala index ed19d33367..eb79aeb4ef 100644 --- a/akka-actor-tests/src/test/scala/akka/TestUtils.scala +++ b/akka-actor-tests/src/test/scala/akka/TestUtils.scala @@ -29,7 +29,7 @@ object TestUtils { def verifyActorTermination(actor: ActorRef)(implicit system: ActorSystem): Unit = { val watcher = TestProbe() watcher.watch(actor) - assert(watcher.expectMsgType[Terminated].actor == actor) + watcher.expectTerminated(actor) } } diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala index a8b42b15a3..0955d47271 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorLookupSpec.scala @@ -81,7 +81,7 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout { val a1 = system.actorOf(p, name) watch(a1) a1 ! PoisonPill - expectMsgType[Terminated].actor must be === a1 + expectTerminated(a1) // not equal because it's terminated system.actorFor(a1.path.toString) must not be (a1) @@ -94,7 +94,7 @@ class ActorLookupSpec extends AkkaSpec with DefaultTimeout { watch(a2) a2 ! PoisonPill - expectMsgType[Terminated].actor must be === a2 + expectTerminated(a2) } "find actors by looking up their root-anchored relative path" in { diff --git a/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala index dae82a5c5f..1712460aa5 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala @@ -69,7 +69,7 @@ class LocalActorRefProviderSpec extends AkkaSpec(LocalActorRefProviderSpec.confi val childProps1 = child.asInstanceOf[LocalActorRef].underlying.props childProps1 must be(Props.empty) system stop a - expectMsgType[Terminated] + expectTerminated(a) val childProps2 = child.asInstanceOf[LocalActorRef].underlying.props childProps2 must not be theSameInstanceAs(childProps1) childProps2 must be theSameInstanceAs ActorCell.terminatedProps diff --git a/akka-actor-tests/src/test/scala/akka/io/TcpListenerSpec.scala b/akka-actor-tests/src/test/scala/akka/io/TcpListenerSpec.scala index 30103b7344..2504d48d7f 100644 --- a/akka-actor-tests/src/test/scala/akka/io/TcpListenerSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/io/TcpListenerSpec.scala @@ -69,7 +69,7 @@ class TcpListenerSpec extends AkkaSpec("akka.io.tcp.batch-accept-limit = 2") { unbindCommander.send(listener, Unbind) 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 { diff --git a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala index cd134623ea..9747251806 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala @@ -82,9 +82,7 @@ class RoutingSpec extends AkkaSpec(RoutingSpec.config) with DefaultTimeout with watch(router) watch(c2) system.stop(c2) - expectMsgPF() { - case t @ Terminated(`c2`) if t.existenceConfirmed == true ⇒ t - } + expectTerminated(c2).existenceConfirmed must be === true // it might take a while until the Router has actually processed the Terminated message awaitCond { router ! "" @@ -95,9 +93,7 @@ class RoutingSpec extends AkkaSpec(RoutingSpec.config) with DefaultTimeout with res == Seq(c1, c1) } system.stop(c1) - expectMsgPF() { - case t @ Terminated(`router`) if t.existenceConfirmed == true ⇒ t - } + expectTerminated(router).existenceConfirmed must be === true } "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) watch(router) system.stop(router) - expectMsgType[Terminated] + expectTerminated(router) } "use configured nr-of-instances when router is specified" in { diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/ClusterDeathWatchSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/ClusterDeathWatchSpec.scala index 38bc59729f..b4d3430de0 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/ClusterDeathWatchSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/ClusterDeathWatchSpec.scala @@ -151,8 +151,7 @@ abstract class ClusterDeathWatchSpec // removed awaitAssert(clusterView.unreachableMembers.map(_.address) must not contain (address(first))) - val t = expectMsgType[Terminated] - t.actor must be(hello) + expectTerminated(hello) enterBarrier("first-unavailable") diff --git a/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterSingletonManagerSpec.scala b/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterSingletonManagerSpec.scala index b29e796d94..fc4d7d9bfc 100644 --- a/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterSingletonManagerSpec.scala +++ b/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterSingletonManagerSpec.scala @@ -353,7 +353,7 @@ class ClusterSingletonManagerSpec extends MultiNodeSpec(ClusterSingletonManagerS case ActorIdentity("singleton", None) ⇒ // already terminated case ActorIdentity("singleton", Some(singleton)) ⇒ watch(singleton) - expectMsgType[Terminated].actor must be(singleton) + expectTerminated(singleton) } } diff --git a/akka-contrib/src/test/scala/akka/contrib/mailbox/PeekMailboxSpec.scala b/akka-contrib/src/test/scala/akka/contrib/mailbox/PeekMailboxSpec.scala index 8a68d64eac..e5f6fa9274 100644 --- a/akka-contrib/src/test/scala/akka/contrib/mailbox/PeekMailboxSpec.scala +++ b/akka-contrib/src/test/scala/akka/contrib/mailbox/PeekMailboxSpec.scala @@ -84,7 +84,7 @@ class PeekMailboxSpec extends AkkaSpec(""" } expectMsg("DIE") expectMsgType[DeadLetter].message must be("DIE") - expectMsgType[Terminated].actor must be(a) + expectTerminated(a) } } diff --git a/akka-docs/rst/scala/code/docs/testkit/TestkitDocSpec.scala b/akka-docs/rst/scala/code/docs/testkit/TestkitDocSpec.scala index d74f3f6f9d..7e9b0794a7 100644 --- a/akka-docs/rst/scala/code/docs/testkit/TestkitDocSpec.scala +++ b/akka-docs/rst/scala/code/docs/testkit/TestkitDocSpec.scala @@ -215,7 +215,7 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { val probe = TestProbe() probe watch target target ! PoisonPill - probe.expectMsgType[Terminated].actor must be(target) + probe.expectTerminated(target) //#test-probe-watch } diff --git a/akka-remote/src/test/scala/akka/remote/RemotingSpec.scala b/akka-remote/src/test/scala/akka/remote/RemotingSpec.scala index fa16d0ceef..d3667f3158 100644 --- a/akka-remote/src/test/scala/akka/remote/RemotingSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemotingSpec.scala @@ -347,7 +347,7 @@ class RemotingSpec extends AkkaSpec(RemotingSpec.cfg) with ImplicitSender with D watch(child) child ! PoisonPill expectMsg("postStop") - expectMsgType[Terminated].actor must be === child + expectTerminated(child) l ! ((Props[Echo1], "child")) val child2 = expectMsgType[ActorRef] child2 ! 45 diff --git a/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java b/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java index cd45e4f3eb..8d63c89f67 100644 --- a/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java +++ b/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java @@ -3,6 +3,8 @@ */ package akka.testkit; +import akka.actor.Terminated; +import akka.japi.Option; import scala.runtime.AbstractFunction0; import akka.actor.ActorRef; import akka.actor.ActorSystem; @@ -456,10 +458,29 @@ public class JavaTestKit { 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 expectTerminated(remaining(), target), + * but correctly treating the timeFactor. + * Don't forget to 'watch' it first! + */ + public Terminated expectTerminated(ActorRef target) { + return expectTerminated(Duration.Undefined(), target); + } + /** * Same as receiveN(n, remaining()), but correctly treating the * timeFactor. */ + public Object[] receiveN(int n) { return (Object[]) p.receiveN(n).toArray(Util.classTag(Object.class)); } diff --git a/akka-testkit/src/main/scala/akka/testkit/TestKit.scala b/akka-testkit/src/main/scala/akka/testkit/TestKit.scala index e6c1967ea4..869d0d146f 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestKit.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestKit.scala @@ -342,6 +342,17 @@ trait TestKitBase { 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 * partial function matches and returns false. Use it to ignore certain diff --git a/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala b/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala index 9feeffb2f4..3b57e12c53 100644 --- a/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala +++ b/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala @@ -19,7 +19,7 @@ class JavaTestKitSpec extends AkkaSpec with DefaultTimeout { new JavaTestKit(system) { val sent = List(1, 2, 3, 4, 5) 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) } } @@ -28,11 +28,25 @@ class JavaTestKitSpec extends AkkaSpec with DefaultTimeout { new JavaTestKit(system) { val sent = List(1, 2, 3) for (m ← sent) { getRef() ! m } - val received = receiveN(sent.size); + val received = receiveN(sent.size) 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 + } + } + } }