2014-09-09 15:22:49 +02:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
|
|
|
|
*/
|
2014-10-27 14:35:41 +01:00
|
|
|
package akka.stream.scaladsl
|
2014-09-09 15:22:49 +02:00
|
|
|
|
2015-01-28 14:19:50 +01:00
|
|
|
import akka.stream.{ ActorFlowMaterializer, ActorFlowMaterializerSettings, Inlet, Outlet }
|
|
|
|
|
|
2014-09-09 15:22:49 +02:00
|
|
|
import scala.concurrent.duration._
|
2014-10-27 14:35:41 +01:00
|
|
|
|
2015-01-28 14:19:50 +01:00
|
|
|
import akka.stream.testkit.{ TwoStreamsSetup, AkkaSpec, StreamTestKit }
|
2015-04-16 20:13:43 +02:00
|
|
|
import akka.stream.testkit.StreamTestKit.assertAllStagesStopped
|
2014-09-09 15:22:49 +02:00
|
|
|
|
|
|
|
|
class GraphMergeSpec extends TwoStreamsSetup {
|
2015-01-28 14:19:50 +01:00
|
|
|
import FlowGraph.Implicits._
|
2014-09-09 15:22:49 +02:00
|
|
|
|
|
|
|
|
override type Outputs = Int
|
2015-01-28 14:19:50 +01:00
|
|
|
|
2015-03-30 14:22:12 +02:00
|
|
|
override def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) {
|
2015-01-28 14:19:50 +01:00
|
|
|
val merge = b add Merge[Outputs](2)
|
|
|
|
|
|
|
|
|
|
override def left: Inlet[Outputs] = merge.in(0)
|
|
|
|
|
override def right: Inlet[Outputs] = merge.in(1)
|
|
|
|
|
override def out: Outlet[Outputs] = merge.out
|
|
|
|
|
|
|
|
|
|
}
|
2014-09-09 15:22:49 +02:00
|
|
|
|
|
|
|
|
"merge" must {
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"work in the happy case" in assertAllStagesStopped {
|
2014-09-09 15:22:49 +02:00
|
|
|
// Different input sizes (4 and 6)
|
2014-11-09 21:09:50 +01:00
|
|
|
val source1 = Source(0 to 3)
|
|
|
|
|
val source2 = Source(4 to 9)
|
|
|
|
|
val source3 = Source(List[Int]())
|
2014-09-09 15:22:49 +02:00
|
|
|
val probe = StreamTestKit.SubscriberProbe[Int]()
|
|
|
|
|
|
2015-01-28 14:19:50 +01:00
|
|
|
FlowGraph.closed() { implicit b ⇒
|
|
|
|
|
val m1 = b.add(Merge[Int](2))
|
|
|
|
|
val m2 = b.add(Merge[Int](2))
|
2014-09-09 15:22:49 +02:00
|
|
|
|
2015-01-28 14:19:50 +01:00
|
|
|
source1 ~> m1.in(0)
|
|
|
|
|
m1.out ~> Flow[Int].map(_ * 2) ~> m2.in(0)
|
|
|
|
|
m2.out ~> Flow[Int].map(_ / 2).map(_ + 1) ~> Sink(probe)
|
|
|
|
|
source2 ~> m1.in(1)
|
|
|
|
|
source3 ~> m2.in(1)
|
2014-09-09 15:22:49 +02:00
|
|
|
|
|
|
|
|
}.run()
|
|
|
|
|
|
|
|
|
|
val subscription = probe.expectSubscription()
|
|
|
|
|
|
|
|
|
|
var collected = Set.empty[Int]
|
|
|
|
|
for (_ ← 1 to 10) {
|
|
|
|
|
subscription.request(1)
|
|
|
|
|
collected += probe.expectNext()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
collected should be(Set(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
|
|
|
|
|
probe.expectComplete()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"work with n-way merge" in {
|
2014-10-17 14:05:50 +02:00
|
|
|
val source1 = Source(List(1))
|
|
|
|
|
val source2 = Source(List(2))
|
|
|
|
|
val source3 = Source(List(3))
|
|
|
|
|
val source4 = Source(List(4))
|
|
|
|
|
val source5 = Source(List(5))
|
2014-11-09 21:09:50 +01:00
|
|
|
val source6 = Source(List[Int]())
|
2014-09-09 15:22:49 +02:00
|
|
|
|
|
|
|
|
val probe = StreamTestKit.SubscriberProbe[Int]()
|
|
|
|
|
|
2015-01-28 14:19:50 +01:00
|
|
|
FlowGraph.closed() { implicit b ⇒
|
|
|
|
|
val merge = b.add(Merge[Int](6))
|
2014-09-09 15:22:49 +02:00
|
|
|
|
2015-01-28 14:19:50 +01:00
|
|
|
source1 ~> merge.in(0)
|
|
|
|
|
source2 ~> merge.in(1)
|
|
|
|
|
source3 ~> merge.in(2)
|
|
|
|
|
source4 ~> merge.in(3)
|
|
|
|
|
source5 ~> merge.in(4)
|
|
|
|
|
source6 ~> merge.in(5)
|
|
|
|
|
merge.out ~> Sink(probe)
|
2014-09-09 15:22:49 +02:00
|
|
|
|
|
|
|
|
}.run()
|
|
|
|
|
|
|
|
|
|
val subscription = probe.expectSubscription()
|
|
|
|
|
|
|
|
|
|
var collected = Set.empty[Int]
|
|
|
|
|
for (_ ← 1 to 5) {
|
|
|
|
|
subscription.request(1)
|
|
|
|
|
collected += probe.expectNext()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
collected should be(Set(1, 2, 3, 4, 5))
|
|
|
|
|
probe.expectComplete()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
commonTests()
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"work with one immediately completed and one nonempty publisher" in assertAllStagesStopped {
|
2014-11-09 21:09:50 +01:00
|
|
|
val subscriber1 = setup(completedPublisher, nonemptyPublisher(1 to 4))
|
2014-09-09 15:22:49 +02:00
|
|
|
val subscription1 = subscriber1.expectSubscription()
|
|
|
|
|
subscription1.request(4)
|
|
|
|
|
subscriber1.expectNext(1)
|
|
|
|
|
subscriber1.expectNext(2)
|
|
|
|
|
subscriber1.expectNext(3)
|
|
|
|
|
subscriber1.expectNext(4)
|
|
|
|
|
subscriber1.expectComplete()
|
|
|
|
|
|
2014-11-09 21:09:50 +01:00
|
|
|
val subscriber2 = setup(nonemptyPublisher(1 to 4), completedPublisher)
|
2014-09-09 15:22:49 +02:00
|
|
|
val subscription2 = subscriber2.expectSubscription()
|
|
|
|
|
subscription2.request(4)
|
|
|
|
|
subscriber2.expectNext(1)
|
|
|
|
|
subscriber2.expectNext(2)
|
|
|
|
|
subscriber2.expectNext(3)
|
|
|
|
|
subscriber2.expectNext(4)
|
|
|
|
|
subscriber2.expectComplete()
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 20:13:43 +02:00
|
|
|
"work with one delayed completed and one nonempty publisher" in assertAllStagesStopped {
|
2014-11-09 21:09:50 +01:00
|
|
|
val subscriber1 = setup(soonToCompletePublisher, nonemptyPublisher(1 to 4))
|
2014-09-09 15:22:49 +02:00
|
|
|
val subscription1 = subscriber1.expectSubscription()
|
|
|
|
|
subscription1.request(4)
|
|
|
|
|
subscriber1.expectNext(1)
|
|
|
|
|
subscriber1.expectNext(2)
|
|
|
|
|
subscriber1.expectNext(3)
|
|
|
|
|
subscriber1.expectNext(4)
|
|
|
|
|
subscriber1.expectComplete()
|
|
|
|
|
|
2014-11-09 21:09:50 +01:00
|
|
|
val subscriber2 = setup(nonemptyPublisher(1 to 4), soonToCompletePublisher)
|
2014-09-09 15:22:49 +02:00
|
|
|
val subscription2 = subscriber2.expectSubscription()
|
|
|
|
|
subscription2.request(4)
|
|
|
|
|
subscriber2.expectNext(1)
|
|
|
|
|
subscriber2.expectNext(2)
|
|
|
|
|
subscriber2.expectNext(3)
|
|
|
|
|
subscriber2.expectNext(4)
|
|
|
|
|
subscriber2.expectComplete()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"work with one immediately failed and one nonempty publisher" in {
|
|
|
|
|
// This is nondeterministic, multiple scenarios can happen
|
|
|
|
|
pending
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"work with one delayed failed and one nonempty publisher" in {
|
|
|
|
|
// This is nondeterministic, multiple scenarios can happen
|
|
|
|
|
pending
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|