2014-09-02 18:13:36 +02:00
|
|
|
/**
|
2017-01-04 17:37:10 +01:00
|
|
|
* Copyright (C) 2014-2017 Lightbend Inc. <http://www.lightbend.com>
|
2014-09-02 18:13:36 +02:00
|
|
|
*/
|
2014-10-27 14:35:41 +01:00
|
|
|
package akka.stream.scaladsl
|
2014-09-02 18:13:36 +02:00
|
|
|
|
2016-01-20 10:00:37 +02:00
|
|
|
import akka.Done
|
2014-09-02 18:13:36 +02:00
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
import scala.util.{ Failure, Success }
|
2014-10-27 14:35:41 +01:00
|
|
|
import scala.util.control.NoStackTrace
|
2015-06-23 18:28:53 +02:00
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.stream.ActorMaterializerSettings
|
2015-04-24 11:45:03 +03:00
|
|
|
import akka.stream.testkit._
|
|
|
|
|
import akka.stream.testkit.Utils._
|
2014-10-27 14:35:41 +01:00
|
|
|
import akka.testkit.TestProbe
|
2014-09-02 18:13:36 +02:00
|
|
|
|
2016-07-28 16:43:08 +08:00
|
|
|
class FlowOnCompleteSpec extends StreamSpec with ScriptedTest {
|
2014-09-02 18:13:36 +02:00
|
|
|
|
2015-06-23 18:28:53 +02:00
|
|
|
val settings = ActorMaterializerSettings(system)
|
2014-09-02 18:13:36 +02:00
|
|
|
.withInputBuffer(initialSize = 2, maxSize = 16)
|
|
|
|
|
|
2015-06-23 18:28:53 +02:00
|
|
|
implicit val materializer = ActorMaterializer(settings)
|
2014-09-02 18:13:36 +02:00
|
|
|
|
|
|
|
|
"A Flow with onComplete" must {
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"invoke callback on normal completion" in assertAllStagesStopped {
|
2014-09-02 18:13:36 +02:00
|
|
|
val onCompleteProbe = TestProbe()
|
2015-04-24 11:45:03 +03:00
|
|
|
val p = TestPublisher.manualProbe[Int]()
|
2015-12-17 11:48:30 +02:00
|
|
|
Source.fromPublisher(p).to(Sink.onComplete[Int](onCompleteProbe.ref ! _)).run()
|
2014-09-02 18:13:36 +02:00
|
|
|
val proc = p.expectSubscription
|
|
|
|
|
proc.expectRequest()
|
|
|
|
|
proc.sendNext(42)
|
|
|
|
|
onCompleteProbe.expectNoMsg(100.millis)
|
|
|
|
|
proc.sendComplete()
|
2016-01-20 10:00:37 +02:00
|
|
|
onCompleteProbe.expectMsg(Success(Done))
|
2014-09-02 18:13:36 +02:00
|
|
|
}
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"yield the first error" in assertAllStagesStopped {
|
2014-09-02 18:13:36 +02:00
|
|
|
val onCompleteProbe = TestProbe()
|
2015-04-24 11:45:03 +03:00
|
|
|
val p = TestPublisher.manualProbe[Int]()
|
2015-12-17 11:48:30 +02:00
|
|
|
Source.fromPublisher(p).to(Sink.onComplete[Int](onCompleteProbe.ref ! _)).run()
|
2014-09-02 18:13:36 +02:00
|
|
|
val proc = p.expectSubscription
|
|
|
|
|
proc.expectRequest()
|
|
|
|
|
val ex = new RuntimeException("ex") with NoStackTrace
|
|
|
|
|
proc.sendError(ex)
|
|
|
|
|
onCompleteProbe.expectMsg(Failure(ex))
|
|
|
|
|
onCompleteProbe.expectNoMsg(100.millis)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"invoke callback for an empty stream" in assertAllStagesStopped {
|
2014-09-02 18:13:36 +02:00
|
|
|
val onCompleteProbe = TestProbe()
|
2015-04-24 11:45:03 +03:00
|
|
|
val p = TestPublisher.manualProbe[Int]()
|
2015-12-17 11:48:30 +02:00
|
|
|
Source.fromPublisher(p).to(Sink.onComplete[Int](onCompleteProbe.ref ! _)).run()
|
2014-09-02 18:13:36 +02:00
|
|
|
val proc = p.expectSubscription
|
|
|
|
|
proc.expectRequest()
|
|
|
|
|
proc.sendComplete()
|
2016-01-20 10:00:37 +02:00
|
|
|
onCompleteProbe.expectMsg(Success(Done))
|
2014-09-02 18:13:36 +02:00
|
|
|
onCompleteProbe.expectNoMsg(100.millis)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"invoke callback after transform and foreach steps " in assertAllStagesStopped {
|
2014-09-02 18:13:36 +02:00
|
|
|
val onCompleteProbe = TestProbe()
|
2015-04-24 11:45:03 +03:00
|
|
|
val p = TestPublisher.manualProbe[Int]()
|
2014-09-02 18:13:36 +02:00
|
|
|
import system.dispatcher // for the Future.onComplete
|
2014-10-17 14:05:50 +02:00
|
|
|
val foreachSink = Sink.foreach[Int] {
|
2014-09-02 18:13:36 +02:00
|
|
|
x ⇒ onCompleteProbe.ref ! ("foreach-" + x)
|
|
|
|
|
}
|
2015-12-17 11:48:30 +02:00
|
|
|
val future = Source.fromPublisher(p).map { x ⇒
|
2014-09-02 18:13:36 +02:00
|
|
|
onCompleteProbe.ref ! ("map-" + x)
|
|
|
|
|
x
|
2014-10-17 14:05:50 +02:00
|
|
|
}.runWith(foreachSink)
|
2014-10-02 13:34:27 +02:00
|
|
|
future onComplete { onCompleteProbe.ref ! _ }
|
2014-09-02 18:13:36 +02:00
|
|
|
val proc = p.expectSubscription
|
|
|
|
|
proc.expectRequest()
|
|
|
|
|
proc.sendNext(42)
|
|
|
|
|
proc.sendComplete()
|
|
|
|
|
onCompleteProbe.expectMsg("map-42")
|
|
|
|
|
onCompleteProbe.expectMsg("foreach-42")
|
2016-01-20 10:00:37 +02:00
|
|
|
onCompleteProbe.expectMsg(Success(Done))
|
2014-09-02 18:13:36 +02:00
|
|
|
}
|
|
|
|
|
|
2017-04-28 11:11:50 +02:00
|
|
|
"yield error on abrupt termination" in {
|
|
|
|
|
val mat = ActorMaterializer()
|
|
|
|
|
val onCompleteProbe = TestProbe()
|
|
|
|
|
val p = TestPublisher.manualProbe[Int]()
|
|
|
|
|
Source.fromPublisher(p).to(Sink.onComplete[Int](onCompleteProbe.ref ! _)).run()(mat)
|
|
|
|
|
val proc = p.expectSubscription()
|
|
|
|
|
proc.expectRequest()
|
|
|
|
|
mat.shutdown()
|
|
|
|
|
|
|
|
|
|
onCompleteProbe.expectMsgType[Failure[_]]
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-02 18:13:36 +02:00
|
|
|
}
|
|
|
|
|
|
2014-12-16 15:07:41 +01:00
|
|
|
}
|