Java TestKit expect msg all of broken (#27563)

* Java API compile coverage of the classic testkit
* API coverage of the typed Java testkit (looks good)
* New name for allOf with duration to allow usage from Java #27492
This commit is contained in:
Johan Andrén 2019-08-29 10:42:15 +02:00 committed by Patrik Nordwall
parent 70e2db7b8d
commit acee1b4185
4 changed files with 311 additions and 6 deletions

View file

@ -0,0 +1,100 @@
/*
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
*/
package akka.actor.testkit.typed.javadsl;
import akka.actor.typed.ActorRef;
import akka.actor.typed.Props;
import akka.actor.typed.Scheduler;
import akka.actor.typed.javadsl.Behaviors;
import java.time.Duration;
import java.util.List;
public class ActorTestKitApiTest {
public void compileOnlyTestCase() {
ActorTestKit testKit = null;
TestProbe<String> probe1 = testKit.createTestProbe();
TestProbe<String> probe2 = testKit.createTestProbe("name");
TestProbe<Integer> probe3 = testKit.createTestProbe(Integer.class);
TestProbe<Integer> probe4 = testKit.createTestProbe("name", Integer.class);
Scheduler scheduler = testKit.scheduler();
SerializationTestKit serializationTestKit = testKit.serializationTestKit();
testKit.shutdownTestKit();
testKit.spawn(Behaviors.empty());
testKit.spawn(Behaviors.empty(), "name");
testKit.spawn(Behaviors.empty(), Props.empty());
testKit.spawn(Behaviors.empty(), "name", Props.empty());
ActorRef<String> actorRef = null;
testKit.stop(actorRef);
testKit.stop(actorRef, Duration.ofSeconds(3));
}
public void testProbeCompileOnlyTestCase() {
TestProbe<String> probe = null;
String awaitAssertSupplied1 =
probe.awaitAssert(
() -> {
return "supplied";
});
String awaitAssertSupplied2 =
probe.awaitAssert(
Duration.ofSeconds(3),
() -> {
return "supplied";
});
String awaitAssertSupplied3 =
probe.awaitAssert(
Duration.ofSeconds(3),
Duration.ofMillis(200),
() -> {
return "supplied";
});
String expectMessage1 = probe.expectMessage("message-1");
String expectMessage2 = probe.expectMessage(Duration.ofSeconds(3), "message-2");
String expectMessage3 = probe.expectMessage(Duration.ofSeconds(3), "hint", "message-2");
String receiveMessage1 = probe.receiveMessage();
String receiveMessage2 = probe.receiveMessage(Duration.ofSeconds(3));
probe.expectMessageClass(String.class);
probe.expectMessageClass(String.class, Duration.ofSeconds(3));
List<String> fishedMessages1 =
probe.fishForMessage(
Duration.ofSeconds(3),
(message) -> {
return FishingOutcomes.complete();
});
List<String> fishedMessages2 =
probe.fishForMessage(
Duration.ofSeconds(3),
"hint",
(message) -> {
return FishingOutcomes.complete();
});
probe.expectNoMessage();
probe.expectNoMessage(Duration.ofSeconds(3));
List<String> tenMessages1 = probe.receiveSeveralMessages(10);
List<String> tenMessages2 = probe.receiveSeveralMessages(10, Duration.ofSeconds(3));
ActorRef<String> ref = probe.getRef();
Duration remaining = probe.getRemaining();
Duration remainingOr = probe.getRemainingOr(Duration.ofSeconds(3));
Duration remainingOrDefault = probe.getRemainingOrDefault();
ActorRef<Object> actorRef = null;
probe.expectTerminated(actorRef);
probe.expectTerminated(actorRef, Duration.ofSeconds(3));
}
}

View file

@ -5,3 +5,8 @@ ProblemFilters.exclude[MissingClassProblem]("akka.testkit.CachingPartialFunction
# #22333 Disable Java serialization
ProblemFilters.exclude[MissingClassProblem]("akka.testkit.TestMessageSerializer")
# Some TestKit methods unaccessible from Java
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.testkit.javadsl.TestKit.expectMsgAnyOf")
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.testkit.javadsl.TestKit.expectMsgAllOf")
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.testkit.javadsl.TestKit.expectMsgAnyOf")

View file

@ -13,6 +13,8 @@ import akka.util.JavaDurationConverters._
import scala.annotation.varargs
import akka.util.ccompat.JavaConverters._
import com.github.ghik.silencer.silent
import scala.concurrent.duration._
/**
@ -516,6 +518,7 @@ class TestKit(system: ActorSystem) {
* Use this variant to implement more complicated or conditional
* processing.
*/
@deprecated("Use the overloaded one which accepts java.time.Duration instead.", since = "2.6.0")
def expectMsgPF[T](max: Duration, hint: String, f: JFunction[Any, T]): T = {
tp.expectMsgPF(max, hint)(new CachingPartialFunction[Any, T] {
@throws(classOf[Exception])
@ -531,6 +534,7 @@ class TestKit(system: ActorSystem) {
* Use this variant to implement more complicated or conditional
* processing.
*/
@silent("deprecated")
def expectMsgPF[T](max: java.time.Duration, hint: String, f: JFunction[Any, T]): T = expectMsgPF(max.asScala, hint, f)
/**
@ -558,7 +562,7 @@ class TestKit(system: ActorSystem) {
* Same as `expectMsgAnyOf(remainingOrDefault, obj...)`, but correctly treating the timeFactor.
*/
@varargs
def expectMsgAnyOf[T](objs: T*): T = tp.expectMsgAnyOf(objs: _*)
def expectMsgAnyOf[T](first: T, objs: T*): T = tp.expectMsgAnyOf((first +: objs): _*)
/**
* Receive one message from the test actor and assert that it equals one of
@ -575,7 +579,8 @@ class TestKit(system: ActorSystem) {
* the given objects. Wait time is bounded by the given duration, with an
* AssertionFailure being thrown in case of timeout.
*/
def expectMsgAnyOf[T](max: java.time.Duration, objs: T*): T = tp.expectMsgAnyOf(max.asScala, objs: _*)
@varargs
def expectMsgAnyOfWithin[T](max: java.time.Duration, objs: T*): T = tp.expectMsgAnyOf(max.asScala, objs: _*)
/**
* Same as `expectMsgAllOf(remainingOrDefault, obj...)`, but correctly treating the timeFactor.
@ -602,12 +607,13 @@ class TestKit(system: ActorSystem) {
* which the objects are received is not fixed. Wait time is bounded by the
* given duration, with an AssertionFailure being thrown in case of timeout.
*/
def expectMsgAllOf[T](max: java.time.Duration, objs: T*): JList[T] = tp.expectMsgAllOf(max.asScala, objs: _*).asJava
@varargs
def expectMsgAllOfWithin[T](max: java.time.Duration, objs: T*): JList[T] =
tp.expectMsgAllOf(max.asScala, objs: _*).asJava
/**
* Same as `expectMsgAnyClassOf(remainingOrDefault, obj...)`, but correctly treating the timeFactor.
*/
@varargs
def expectMsgAnyClassOf[T](objs: Class[_]*): T = tp.expectMsgAnyClassOf(objs: _*).asInstanceOf[T]
@ -675,6 +681,7 @@ class TestKit(system: ActorSystem) {
* @param target the actor ref expected to be Terminated
* @return the received Terminated message
*/
@deprecated("Use the overloaded one which accepts java.time.Duration instead.", since = "2.6.0")
def expectTerminated(max: Duration, target: ActorRef): Terminated = tp.expectTerminated(target, max)
/**
@ -706,16 +713,29 @@ class TestKit(system: ActorSystem) {
* @return the last received message, i.e. the first one for which the
* partial function returned true
*/
def fishForMessage(max: Duration, hint: String, f: JFunction[Any, Boolean]): Any = {
@deprecated("Use the overloaded one which accepts java.time.Duration instead.", since = "2.6.0")
def fishForMessage(max: Duration, hint: String, f: JFunction[Any, Boolean]): Any =
tp.fishForMessage(max, hint)(new CachingPartialFunction[Any, Boolean] {
@throws(classOf[Exception])
override def `match`(x: Any): Boolean = f.apply(x)
})
}
/**
* Hybrid of expectMsgPF and receiveWhile: receive messages while the
* partial function matches and returns false. Use it to ignore certain
* messages while waiting for a specific message.
*
* @return the last received message, i.e. the first one for which the
* partial function returned true
*/
@silent("deprecated")
def fishForMessage(max: java.time.Duration, hint: String, f: JFunction[Any, Boolean]): Any =
fishForMessage(max.asScala, hint, f)
/**
* Same as `fishForMessage`, but gets a different partial function and returns properly typed message.
*/
@deprecated("Use the overloaded one which accepts java.time.Duration instead.", since = "2.6.0")
def fishForSpecificMessage[T](max: Duration, hint: String, f: JFunction[Any, T]): T = {
tp.fishForSpecificMessage(max, hint)(new CachingPartialFunction[Any, T] {
@throws(classOf[Exception])
@ -723,6 +743,13 @@ class TestKit(system: ActorSystem) {
})
}
/**
* Same as `fishForMessage`, but gets a different partial function and returns properly typed message.
*/
@silent("deprecated")
def fishForSpecificMessage[T](max: java.time.Duration, hint: String, f: JFunction[Any, T]): T =
fishForSpecificMessage(max.asScala, hint, f)
/**
* Same as `receiveN(n, remaining)` but correctly taking into account
* Duration.timeFactor.

View file

@ -0,0 +1,173 @@
/*
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
*/
package akka.testkit.javadsl;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.SupervisorStrategy;
import akka.testkit.TestActor;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
public class TestKitApiTest {
public void compileOnlyTestCase() {
TestKit testKit = null;
ActorRef actorRef = null;
TestActor.AutoPilot autoPilot = null;
// just coverage of calling all testkit methods, actual impl is tested elsewhere
testKit.awaitAssert(
() -> {
return null;
});
testKit.awaitAssert(
Duration.ofSeconds(3),
() -> {
return null;
});
testKit.awaitAssert(
Duration.ofSeconds(3),
Duration.ofMillis(200),
() -> {
return null;
});
testKit.awaitCond(
() -> {
return true;
});
testKit.awaitCond(
Duration.ofSeconds(3),
() -> {
return true;
});
testKit.awaitCond(
Duration.ofSeconds(3),
Duration.ofMillis(200),
() -> {
return true;
});
testKit.awaitCond(
Duration.ofSeconds(3),
Duration.ofMillis(200),
"details",
() -> {
return true;
});
testKit.childActorOf(Props.empty());
testKit.childActorOf(Props.empty(), "name");
testKit.childActorOf(Props.empty(), SupervisorStrategy.defaultStrategy());
testKit.childActorOf(Props.empty(), "name", SupervisorStrategy.defaultStrategy());
testKit.dilated(Duration.ofSeconds(3));
testKit.expectMsg("message");
testKit.expectMsg(Duration.ofSeconds(3), "message");
testKit.expectMsg(Duration.ofSeconds(3), "message", "hint");
testKit.expectMsgClass(String.class);
testKit.expectMsgClass(Duration.ofSeconds(3), String.class);
testKit.expectMsgEquals("message");
testKit.expectMsgEquals(Duration.ofSeconds(3), "message");
// FIXME why are these called PF when they take a total function, how are they supposed to be
// used? #27562
testKit.expectMsgPF(
Duration.ofSeconds(3),
"hint",
(value) -> {
return null;
});
testKit.expectMsgPF(
"hint",
(value) -> {
return null;
});
testKit.expectNoMessage();
testKit.expectNoMessage(Duration.ofSeconds(3));
testKit.expectTerminated(actorRef);
testKit.expectTerminated(Duration.ofSeconds(3), actorRef);
// FIXME how is this supposed to be used, scaladoc talks about a partial function but it accepts
// a total function #27562
Object fishResult1 =
testKit.fishForMessage(
Duration.ofSeconds(3),
"hint",
(message) -> {
return "fishResult1";
});
// FIXME how is this supposed to be used, scaladoc talks about a partial function but it accepts
// a total function #27562
String result =
testKit.fishForSpecificMessage(
Duration.ofSeconds(3),
"hint",
(message) -> {
return "fishResult2";
});
List<Object> tenMessages = testKit.receiveN(10);
List<Object> tenMoreMessages = testKit.receiveN(10, Duration.ofSeconds(3));
Object oneMoreMessage = testKit.receiveOne(Duration.ofSeconds(3));
// FIXME how is this supposed to be used, scaladoc talks about a partial function but it accepts
// a total function #27562
List<Object> receiveWhileResults1 =
testKit.receiveWhile(
Duration.ofSeconds(3),
(message) -> {
return message;
});
// FIXME how is this supposed to be used, scaladoc talks about a partial function but it accepts
// a total function #27562
List<Object> receiveWhileResults2 =
testKit.receiveWhile(
Duration.ofSeconds(3),
Duration.ofSeconds(1),
10,
(message) -> {
return "result";
});
// FIXME how is this supposed to be used, scaladoc talks about a partial function but it accepts
// a total function #27562
testKit.ignoreMsg(
(message) -> {
return message;
});
testKit.ignoreNoMsg();
testKit.expectMsgAllOf("one", "two");
testKit.expectMsgAllOfWithin(Duration.ofSeconds(3), "one", "two");
testKit.expectMsgAnyOf("one", "two");
testKit.expectMsgAnyOfWithin(Duration.ofSeconds(3), "one", "two");
testKit.expectMsgAnyClassOf(String.class, Integer.class);
testKit.expectMsgAnyClassOf(Duration.ofSeconds(3), String.class, Integer.class);
ActorRef lastSender = testKit.getLastSender();
ActorSystem system = testKit.getSystem();
Duration remaining = testKit.getRemaining();
Duration remainingOrDefault = testKit.getRemainingOrDefault();
Duration dilated = testKit.dilated(Duration.ofSeconds(3));
ActorRef testActor = testKit.getTestActor();
boolean msgAvailable = testKit.msgAvailable();
testKit.forward(actorRef);
testKit.send(actorRef, "message");
testKit.watch(actorRef);
testKit.unwatch(actorRef);
testKit.setAutoPilot(autoPilot);
}
}