diff --git a/akka-docs/src/main/paradox/project/migration-guide-2.5.x-2.6.x.md b/akka-docs/src/main/paradox/project/migration-guide-2.5.x-2.6.x.md index 04fc42e81a..f9b70efe9c 100644 --- a/akka-docs/src/main/paradox/project/migration-guide-2.5.x-2.6.x.md +++ b/akka-docs/src/main/paradox/project/migration-guide-2.5.x-2.6.x.md @@ -63,6 +63,9 @@ Use @apidoc[AbstractPersistentActorWithAtLeastOnceDelivery] instead. * `LoggingReceive.create(Receive, ActorContext)` use `AbstractActor.Receive` instead. * `ActorMaterialzierSettings.withAutoFusing` disabling fusing is no longer possible. +### JavaTestKit removed + +The `JavaTestKit` has been deprecated since `2.5.0`. Use `akka.testkit.javadsl.TestKit` instead. ## Deprecated features diff --git a/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java b/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java deleted file mode 100644 index f5d792e944..0000000000 --- a/akka-testkit/src/main/java/akka/testkit/JavaTestKit.java +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright (C) 2009-2019 Lightbend Inc. - */ - -package akka.testkit; - -import akka.actor.Terminated; -import scala.runtime.AbstractFunction0; -import akka.actor.ActorRef; -import akka.actor.ActorSystem; -import akka.actor.Props; -import akka.actor.SupervisorStrategy; -import akka.event.Logging; -import akka.event.Logging.LogEvent; -import akka.japi.JavaPartialFunction; -import akka.japi.Util; -import scala.concurrent.duration.Duration; -import scala.concurrent.duration.FiniteDuration; - -import java.util.concurrent.TimeUnit; - -/** - * Java API: Test kit for testing actors. Inheriting from this class enables reception of replies - * from actors, which are queued by an internal actor and can be examined using the - * expectMsg... methods. Assertions and bounds concerning timing are available in the form of - * Within blocks. - * - *

Beware of two points: - * - *

- * - *

- * - * @deprecated Use {@link akka.testkit.javadsl.TestKit} instead, since 2.5.0 - */ -@Deprecated -public class JavaTestKit { - /** - * Shut down an actor system and wait for termination. On failure debug output will be logged - * about the remaining actors in the system. - * - *

If verifySystemShutdown is true, then an exception will be thrown on failure. - */ - public static void shutdownActorSystem( - ActorSystem actorSystem, Duration duration, Boolean verifySystemShutdown) { - boolean vss = verifySystemShutdown != null ? verifySystemShutdown : false; - Duration dur = duration != null ? duration : FiniteDuration.create(10, TimeUnit.SECONDS); - TestKit.shutdownActorSystem(actorSystem, dur, vss); - } - - public static void shutdownActorSystem(ActorSystem actorSystem) { - shutdownActorSystem(actorSystem, null, null); - } - - public static void shutdownActorSystem(ActorSystem actorSystem, Duration duration) { - shutdownActorSystem(actorSystem, duration, null); - } - - public static void shutdownActorSystem(ActorSystem actorSystem, Boolean verifySystemShutdown) { - shutdownActorSystem(actorSystem, null, verifySystemShutdown); - } - - private final TestProbe p; - - public JavaTestKit(ActorSystem system) { - p = new TestProbe(system); - } - - /** - * ActorRef of the test actor. Access is provided to enable e.g. registration as message target. - */ - public ActorRef getTestActor() { - return p.testActor(); - } - - /** Shorthand to get the testActor. */ - public ActorRef getRef() { - return getTestActor(); - } - - public ActorSystem getSystem() { - return p.system(); - } - - public static FiniteDuration duration(String s) { - final Duration ret = Duration.apply(s); - if (ret instanceof FiniteDuration) return (FiniteDuration) ret; - else - throw new IllegalArgumentException( - "duration() is only for finite durations, use Duration.Inf() and friends"); - } - - public Duration dilated(Duration d) { - return d.mul(TestKitExtension.get(getSystem()).TestTimeFactor()); - } - - /** Query queue status. */ - public boolean msgAvailable() { - return p.msgAvailable(); - } - - public ActorRef getLastSender() { - return p.lastMessage().sender(); - } - - public void send(ActorRef actor, Object msg) { - actor.tell(msg, p.ref()); - } - - public void forward(ActorRef actor) { - actor.tell(p.lastMessage().msg(), p.lastMessage().sender()); - } - - public void reply(Object msg) { - p.lastMessage().sender().tell(msg, p.ref()); - } - - public FiniteDuration getRemainingTime() { - return p.remaining(); - } - - public FiniteDuration getRemainingTimeOr(FiniteDuration def) { - return p.remainingOr(def); - } - - /** Have the testActor watch someone (i.e. getContext().getWatch(...) ). */ - public ActorRef watch(ActorRef ref) { - return p.watch(ref); - } - - /** Have the testActor stop watching someone (i.e. getContext.unwatch(...)). */ - public ActorRef unwatch(ActorRef ref) { - return p.unwatch(ref); - } - - /** Ignore all messages in the test actor for which the given function returns true. */ - public abstract class IgnoreMsg { - protected abstract boolean ignore(Object msg); - - public IgnoreMsg() { - p.ignoreMsg( - new JavaPartialFunction() { - public Boolean apply(Object in, boolean isCheck) { - return ignore(in); - } - }); - } - } - - /** Stop ignoring messages in the test actor. */ - public void ignoreNoMsg() { - p.ignoreNoMsg(); - } - - /** - * Install an AutoPilot to drive the testActor: the AutoPilot will be run for each received - * message and can be used to send or forward messages, etc. Each invocation must return the - * AutoPilot for the next round. - */ - public void setAutoPilot(TestActor.AutoPilot pilot) { - p.setAutoPilot(pilot); - } - - /** - * Obtain time remaining for execution of the innermost enclosing Within block or - * missing that it returns the properly dilated default for this case from settings (key - * "akka.test.single-expect-default"). - */ - public FiniteDuration remaining() { - return p.remaining(); - } - - /** - * Obtain time remaining for execution of the innermost enclosing Within block or - * missing that it returns the given duration. - */ - public FiniteDuration remainingOr(FiniteDuration duration) { - return p.remainingOr(duration); - } - - /** - * Obtain time remaining for execution of the innermost enclosing Within block or - * missing that it returns the properly dilated default for this case from settings (key - * "akka.test.single-expect-default"). - */ - public FiniteDuration remainingOrDefault() { - return p.remainingOrDefault(); - } - - /** - * Execute code block while bounding its execution time between min and max - * . Within blocks may be nested. All methods in this trait which 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 dilated, which uses the configuration - * entry "akka.test.timefactor", while the min Duration is not. - * - *

- * - *

-   * 
-   * // the run() method needs to finish within 3 seconds
-   * new Within(duration("3 seconds")) {
-   *   protected void run() {
-   *     // ...
-   *   }
-   * }
-   * 
-   * 
- */ - public abstract class Within { - protected abstract void run(); - - public Within(FiniteDuration max) { - p.within( - max, - new AbstractFunction0() { - @Override - public Object apply() { - run(); - return null; - } - }); - } - - public Within(FiniteDuration min, FiniteDuration max) { - p.within( - min, - max, - new AbstractFunction0() { - @Override - public Object apply() { - run(); - return null; - } - }); - } - } - - /** - * Await until the given condition evaluates to true or the timeout expires, - * whichever comes first. - * - *

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". - */ - public abstract class AwaitCond { - protected abstract boolean cond(); - - public AwaitCond() { - this(Duration.Undefined(), p.awaitCond$default$3()); - } - - public AwaitCond(Duration max) { - this(max, p.awaitCond$default$3()); - } - - public AwaitCond(Duration max, Duration interval) { - p.awaitCond( - new AbstractFunction0() { - @Override - public Object apply() { - return cond(); - } - }, - max, - interval, - p.awaitCond$default$4()); - } - - public AwaitCond(Duration max, Duration interval, String message) { - p.awaitCond( - new AbstractFunction0() { - @Override - public Object apply() { - return cond(); - } - }, - max, - interval, - message); - } - } - - /** - * Await until the given assert does not throw an exception or the timeout expires, whichever - * comes first. If the 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". - */ - public abstract class AwaitAssert { - protected abstract void check(); - - public AwaitAssert() { - this(Duration.Undefined(), p.awaitAssert$default$3()); - } - - public AwaitAssert(Duration max) { - this(max, p.awaitAssert$default$3()); - } - - public AwaitAssert(Duration max, Duration interval) { - p.awaitAssert( - new AbstractFunction0() { - @Override - public Object apply() { - check(); - return null; - } - }, - max, - interval); - } - } - - /** - * Receive one message from the test actor and assert that the given matching function accepts it. - * Wait time is bounded by the given duration, with an AssertionFailure being thrown in case of - * timeout. - * - *

The received object as transformed by the matching function can be retrieved with the - * get method. - * - *

Use this variant to implement more complicated or conditional processing. - * - *

- * - *

-   * 
-   * final String out = new ExpectMsg<String>("match hint") {
-   *   protected String match(Object in) {
-   *     if (in instanceof Integer)
-   *       return "match";
-   *     else
-   *       throw noMatch();
-   *   }
-   * }.get(); // this extracts the received message
-   * 
-   * 
- */ - public abstract class ExpectMsg { - private final T result; - - public ExpectMsg(String hint) { - this(Duration.Undefined(), hint); - } - - public ExpectMsg(Duration max, String hint) { - final Object received = p.receiveOne(max); - try { - result = match(received); - } catch (JavaPartialFunction.NoMatchException ex) { - throw new AssertionError("while expecting '" + hint + "' received unexpected: " + received); - } - } - - protected abstract T match(Object msg); - - protected RuntimeException noMatch() { - throw JavaPartialFunction.noMatch(); - } - - public T get() { - return result; - } - } - - /** - * Same as expectMsgEquals(remainingOrDefault(), obj), but correctly treating the - * timeFactor. - */ - public T expectMsgEquals(T msg) { - return p.expectMsg(msg); - } - - /** - * Receive one message from the test actor and assert that it equals the given object. Wait time - * is bounded by the given duration, with an AssertionFailure being thrown in case of timeout. - * - * @return the received object - */ - public T expectMsgEquals(FiniteDuration max, T msg) { - return p.expectMsg(max, msg); - } - - /** - * Same as expectMsgClass(remainingOrDefault(), clazz), but correctly treating the - * timeFactor. - */ - public T expectMsgClass(Class clazz) { - return p.expectMsgClass(clazz); - } - - /** - * Receive one message from the test actor and assert that it conforms to the given class. Wait - * time is bounded by the given duration, with an AssertionFailure being thrown in case of - * timeout. - * - * @return the received object - */ - public T expectMsgClass(FiniteDuration max, Class clazz) { - return p.expectMsgClass(max, clazz); - } - - /** - * Same as expectMsgAnyOf(remainingOrDefault(), obj...), but correctly treating the - * timeFactor. - */ - public Object expectMsgAnyOf(Object... msgs) { - return p.expectMsgAnyOf(Util.immutableSeq(msgs)); - } - - /** - * Receive one message from the test actor and assert that it equals one of the given objects. - * Wait time is bounded by the given duration, with an AssertionFailure being thrown in case of - * timeout. - * - * @return the received object - */ - public Object expectMsgAnyOf(FiniteDuration max, Object... msgs) { - return p.expectMsgAnyOf(max, Util.immutableSeq(msgs)); - } - - /** - * Same as expectMsgAllOf(remainingOrDefault(), obj...), but correctly treating the - * timeFactor. - */ - public Object[] expectMsgAllOf(Object... msgs) { - return (Object[]) - p.expectMsgAllOf(Util.immutableSeq(msgs)).toArray(Util.classTag(Object.class)); - } - - /** - * Receive a number of messages from the test actor matching the given number of objects and - * assert that for each given object one is received which equals it and vice versa. This - * construct is useful when the order in 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. - */ - public Object[] expectMsgAllOf(FiniteDuration max, Object... msgs) { - return (Object[]) - p.expectMsgAllOf(max, Util.immutableSeq(msgs)).toArray(Util.classTag(Object.class)); - } - - /** - * Same as expectMsgAnyClassOf(remainingOrDefault(), obj...), but correctly treating - * the timeFactor. - */ - @SuppressWarnings("unchecked") - public T expectMsgAnyClassOf(Class... classes) { - final Object result = p.expectMsgAnyClassOf(Util.immutableSeq(classes)); - return (T) result; - } - - /** - * Receive one message from the test actor and assert that it conforms to one of the given - * classes. Wait time is bounded by the given duration, with an AssertionFailure being thrown in - * case of timeout. - * - * @return the received object - */ - public Object expectMsgAnyClassOf(FiniteDuration max, Class... classes) { - return p.expectMsgAnyClassOf(max, Util.immutableSeq(classes)); - } - - /** - * Same as expectNoMsg(remainingOrDefault()), but correctly treating the timeFactor. - */ - public void expectNoMsg() { - p.expectNoMsg(); - } - - /** Assert that no message is received for the specified time. */ - public void expectNoMsg(FiniteDuration 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 expectTerminated(remainingOrDefault(), 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)); - } - - /** Receive N messages in a row before the given deadline. */ - public Object[] receiveN(int n, FiniteDuration max) { - return (Object[]) p.receiveN(n, max).toArray(Util.classTag(Object.class)); - } - - /** - * Receive one message from the internal queue of the TestActor. If the given duration is zero, - * the queue is polled (non-blocking). - * - *

This method does NOT automatically scale its Duration parameter! - */ - public Object receiveOne(Duration max) { - return p.receiveOne(max); - } - - /** - * Receive a series of messages until one does not match the given match function or - * the idle timeout is met (disabled by default) or the overall maximum duration is elapsed. - * Returns the sequence of messages. - * - *

Note that it is not an error to hit the max duration in this case. - * - *

One possible use of this method is for testing whether messages of certain characteristics - * are generated at a certain rate. - */ - public abstract class ReceiveWhile { - protected abstract T match(Object msg) throws Exception; - - private Object results; - - public ReceiveWhile(Class clazz) { - this(clazz, Duration.Undefined()); - } - - public ReceiveWhile(Class clazz, Duration max) { - this(clazz, max, Duration.Inf(), Integer.MAX_VALUE); - } - - public ReceiveWhile(Class clazz, Duration max, int messages) { - this(clazz, max, Duration.Inf(), messages); - } - - @SuppressWarnings("all") - public ReceiveWhile(Class clazz, Duration max, Duration idle, int messages) { - results = - p.receiveWhile( - max, - idle, - messages, - new CachingPartialFunction() { - public T match(Object msg) throws Exception { - return ReceiveWhile.this.match(msg); - } - }) - .toArray(Util.classTag(clazz)); - } - - protected RuntimeException noMatch() { - throw JavaPartialFunction.noMatch(); - } - - @SuppressWarnings("unchecked") - public T[] get() { - return (T[]) results; - } - } - - /** - * Facilities for selectively filtering out expected events from logging so that you can keep your - * test run’s console output clean and do not miss real error messages. - * - *

If the occurrences is set to Integer.MAX_VALUE, no tracking is - * done. - */ - public abstract class EventFilter { - protected abstract T run(); - - private final Class clazz; - - private String source = null; - private String message = null; - private boolean pattern = false; - private boolean complete = false; - private int occurrences = Integer.MAX_VALUE; - private Class exceptionType = null; - - @SuppressWarnings("unchecked") - public EventFilter(Class clazz) { - if (Throwable.class.isAssignableFrom(clazz)) { - this.clazz = Logging.Error.class; - exceptionType = (Class) clazz; - } else if (Logging.LogEvent.class.isAssignableFrom(clazz)) { - this.clazz = (Class) clazz; - } else - throw new IllegalArgumentException("supplied class must either be LogEvent or Throwable"); - } - - public T exec() { - akka.testkit.EventFilter filter; - if (clazz == Logging.Error.class) { - if (exceptionType == null) exceptionType = Logging.noCause().getClass(); - filter = new ErrorFilter(exceptionType, source, message, pattern, complete, occurrences); - } else if (clazz == Logging.Warning.class) { - filter = new WarningFilter(source, message, pattern, complete, occurrences); - } else if (clazz == Logging.Info.class) { - filter = new InfoFilter(source, message, pattern, complete, occurrences); - } else if (clazz == Logging.Debug.class) { - filter = new DebugFilter(source, message, pattern, complete, occurrences); - } else throw new IllegalArgumentException("unknown LogLevel " + clazz); - return filter.intercept( - new AbstractFunction0() { - @Override - public T apply() { - return run(); - } - }, - p.system()); - } - - public EventFilter message(String msg) { - message = msg; - pattern = false; - complete = true; - return this; - } - - public EventFilter startsWith(String msg) { - message = msg; - pattern = false; - complete = false; - return this; - } - - public EventFilter matches(String regex) { - message = regex; - pattern = true; - return this; - } - - public EventFilter from(String source) { - this.source = source; - return this; - } - - public EventFilter occurrences(int number) { - occurrences = number; - return this; - } - } - - /** - * Shut down an actor system and wait for termination. On failure debug output will be logged - * about the remaining actors in the system. - * - *

If verifySystemShutdown is true, then an exception will be thrown on failure. - */ - public void shutdown(ActorSystem actorSystem, Duration duration, Boolean verifySystemShutdown) { - boolean vss = verifySystemShutdown != null ? verifySystemShutdown : false; - Duration dur = - duration != null - ? duration - : dilated(FiniteDuration.create(5, TimeUnit.SECONDS)) - .min(FiniteDuration.create(10, TimeUnit.SECONDS)); - JavaTestKit.shutdownActorSystem(actorSystem, dur, vss); - } - - public void shutdown(ActorSystem actorSystem) { - shutdown(actorSystem, null, null); - } - - public void shutdown(ActorSystem actorSystem, Duration duration) { - shutdown(actorSystem, duration, null); - } - - public void shutdown(ActorSystem actorSystem, Boolean verifySystemShutdown) { - shutdown(actorSystem, null, verifySystemShutdown); - } - - /** - * Spawns an actor as a child of this test actor, and returns the child's ActorRef. - * - * @param props Props to create the child actor - * @param name Actor name for the child actor - * @param supervisorStrategy Strategy should decide what to do with failures in the actor. - */ - public ActorRef childActorOf(Props props, String name, SupervisorStrategy supervisorStrategy) { - return p.childActorOf(props, name, supervisorStrategy); - } - - /** - * Spawns an actor as a child of this test actor, and returns the child's ActorRef. The actor will - * have an auto-generated name. - * - * @param props Props to create the child actor - * @param supervisorStrategy Strategy should decide what to do with failures in the actor. - */ - public ActorRef childActorOf(Props props, SupervisorStrategy supervisorStrategy) { - return p.childActorOf(props, supervisorStrategy); - } - - /** - * Spawns an actor as a child of this test actor, and returns the child's ActorRef. The actor will - * be supervised using {@link SupervisorStrategy.stoppingStrategy}. - * - * @param props Props to create the child actor - * @param name Actor name for the child actor - */ - public ActorRef childActorOf(Props props, String name) { - return p.childActorOf(props, name); - } - - /** - * Spawns an actor as a child of this test actor, and returns the child's ActorRef. The actor will - * have an auto-generated name and will be supervised using {@link - * SupervisorStrategy.stoppingStrategy}. - * - * @param props Props to create the child actor - */ - public ActorRef childActorOf(Props props) { - return p.childActorOf(props); - } -} diff --git a/akka-testkit/src/main/mima-filters/2.5.x.backwards.excludes b/akka-testkit/src/main/mima-filters/2.5.x.backwards.excludes new file mode 100644 index 0000000000..ec7da197d5 --- /dev/null +++ b/akka-testkit/src/main/mima-filters/2.5.x.backwards.excludes @@ -0,0 +1,4 @@ +# Remove JavaTestKit https://github.com/akka/akka/issues/26189 +ProblemFilters.exclude[MissingClassProblem]("akka.testkit.JavaTestKit") +ProblemFilters.exclude[MissingClassProblem]("akka.testkit.JavaTestKit$*") +ProblemFilters.exclude[MissingClassProblem]("akka.testkit.CachingPartialFunction") diff --git a/akka-testkit/src/main/scala/akka/testkit/TestKit.scala b/akka-testkit/src/main/scala/akka/testkit/TestKit.scala index db8986eb58..dd72e447ec 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestKit.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestKit.scala @@ -1028,33 +1028,3 @@ trait ImplicitSender { this: TestKitBase => trait DefaultTimeout { this: TestKitBase => implicit val timeout: Timeout = testKitSettings.DefaultTimeout } - -/** - * INTERNAL API - * - * This is a specialized variant of PartialFunction which is only - * applicable if you know that `isDefinedAt(x)` is always called before - * `apply(x)`—with the same `x` of course. - * - * `match(x)` will be called for `isDefinedAt(x)` only, and its semantics - * are the same as for [[akka.japi.JavaPartialFunction]] (apart from the - * missing because unneeded boolean argument). - * - * This class is used internal to JavaTestKit and should not be extended - * by client code directly. - */ -@deprecated(message = "The only usage is in JavaTestKit which is deprecated.", since = "2.5.0") -private[testkit] abstract class CachingPartialFunction[A, B <: AnyRef] - extends scala.runtime.AbstractPartialFunction[A, B] { - import akka.japi.JavaPartialFunction._ - - @throws(classOf[Exception]) - def `match`(x: A): B - - var cache: B = _ - final def isDefinedAt(x: A): Boolean = - try { - cache = `match`(x); true - } catch { case NoMatch => cache = null.asInstanceOf[B]; false } - final override def apply(x: A): B = cache -} diff --git a/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala b/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala deleted file mode 100644 index 428fb61410..0000000000 --- a/akka-testkit/src/test/scala/akka/testkit/JavaTestKitSpec.scala +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2018-2019 Lightbend Inc. - */ - -package akka.testkit - -import language.postfixOps -import akka.actor._ -import com.github.ghik.silencer.silent - -import scala.concurrent.duration._ - -@silent -class JavaTestKitSpec extends AkkaSpec with DefaultTimeout { - - "JavaTestKit" must { - - "be able to receiveN messages" in { - new JavaTestKit(system) { - val sent = List(1, 2, 3, 4, 5) - for (m <- sent) { getRef() ! m } - val received = receiveN(sent.size, 5 seconds) - sent.toSet should be(received.toSet) - } - } - - "be able to receiveN messages with default duration" in { - new JavaTestKit(system) { - val sent = List(1, 2, 3) - for (m <- sent) { getRef() ! m } - val received = receiveN(sent.size) - sent.toSet should be(received.toSet) - } - } - - "be able to expectTerminated" in { - new JavaTestKit(system) { - val actor = system.actorOf(Props(new Actor { def receive = { case _ => } })) - - watch(actor) - system.stop(actor) - expectTerminated(actor).existenceConfirmed should ===(true) - - watch(actor) - expectTerminated(5 seconds, actor).actor should ===(actor) - } - } - - } - -}