예제 #1
0
        public void ConcatAll_must_work_in_the_happy_case()
        {
            this.AssertAllStagesStopped(() =>
            {
                var s1 = Source.From(new[] { 1, 2 });
                var s2 = Source.From(new int[] {});
                var s3 = Source.From(new[] { 3 });
                var s4 = Source.From(new[] { 4, 5, 6 });
                var s5 = Source.From(new[] { 7, 8, 9, 10 });

                var main = Source.From(new[] { s1, s2, s3, s4, s5 });

                var subscriber = TestSubscriber.CreateManualProbe <int>(this);
                main.ConcatMany(s => s).To(Sink.FromSubscriber(subscriber)).Run(Materializer);
                var subscription = subscriber.ExpectSubscription();
                subscription.Request(10);
                for (var i = 1; i <= 10; i++)
                {
                    subscriber.ExpectNext(i);
                }

                subscription.Request(1);
                subscriber.ExpectComplete();
            }, Materializer);
        }
예제 #2
0
        public void A_Merge_must_pass_along_early_cancellation()
        {
            this.AssertAllStagesStopped(() =>
            {
                var up1  = TestPublisher.CreateManualProbe <int>(this);
                var up2  = TestPublisher.CreateManualProbe <int>(this);
                var down = TestSubscriber.CreateManualProbe <int>(this);

                var src1 = Source.AsSubscriber <int>();
                var src2 = Source.AsSubscriber <int>();

                var t = RunnableGraph.FromGraph(GraphDsl.Create(src1, src2, Tuple.Create, (b, s1, s2) =>
                {
                    var merge = b.Add(new Merge <int>(2));
                    var sink  = Sink.FromSubscriber(down)
                                .MapMaterializedValue <Tuple <ISubscriber <int>, ISubscriber <int> > >(_ => null);

                    b.From(s1.Outlet).To(merge.In(0));
                    b.From(s2.Outlet).To(merge.In(1));
                    b.From(merge.Out).To(sink);
                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var downstream = down.ExpectSubscription();
                downstream.Cancel();
                up1.Subscribe(t.Item1);
                up2.Subscribe(t.Item2);
                var upSub1 = up1.ExpectSubscription();
                upSub1.ExpectCancellation();
                var upSub2 = up2.ExpectSubscription();
                upSub2.ExpectCancellation();
            }, Materializer);
        }
예제 #3
0
        public void ConcatAll_must_on_cancellation_cancel_the_currently_opening_substream_and_the_master_stream()
        {
            this.AssertAllStagesStopped(() =>
            {
                var publisher  = TestPublisher.CreateManualProbe <Source <int, NotUsed> >(this);
                var subscriber = TestSubscriber.CreateManualProbe <int>(this);
                Source.FromPublisher(publisher)
                .ConcatMany(x => x)
                .To(Sink.FromSubscriber(subscriber))
                .Run(Materializer);

                var upstream   = publisher.ExpectSubscription();
                var downstream = subscriber.ExpectSubscription();
                downstream.Request(1000);

                var substreamPublisher = TestPublisher.CreateManualProbe <int>(this, false);
                var substreamFlow      = Source.FromPublisher(substreamPublisher);
                upstream.ExpectRequest();
                upstream.SendNext(substreamFlow);
                var subUpstream = substreamPublisher.ExpectSubscription();

                downstream.Cancel();

                subUpstream.SendOnSubscribe();

                subUpstream.ExpectCancellation();
                upstream.ExpectCancellation();
            }, Materializer);
        }
예제 #4
0
        public void A_Graph_with_materialized_value_must_expose_the_materialized_value_as_source_multiple_times()
        {
            var sub = TestSubscriber.CreateManualProbe <int>(this);
            var f   = RunnableGraph.FromGraph(GraphDsl.Create(FoldSink, (b, fold) =>
            {
                var zip    = b.Add(new ZipWith <int, int, int>((i, i1) => i + i1));
                var source = Source.From(Enumerable.Range(1, 10)).MapMaterializedValue(_ => Task.FromResult(0));
                b.From(source).To(fold);
                b.From(b.MaterializedValue)
                .Via(Flow.Create <Task <int> >().SelectAsync(4, x => x))
                .To(zip.In0);
                b.From(b.MaterializedValue)
                .Via(Flow.Create <Task <int> >().SelectAsync(4, x => x))
                .To(zip.In1);

                b.From(zip.Out).To(Sink.FromSubscriber(sub).MapMaterializedValue(_ => Task.FromResult(0)));
                return(ClosedShape.Instance);
            })).Run(Materializer);

            f.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();
            var r1 = f.Result;

            sub.ExpectSubscription().Request(1);
            var r2 = sub.ExpectNext();

            r1.Should().Be(r2 / 2);
        }
예제 #5
0
        public void A_TakeWithin_must_deliver_elements_within_the_duration_but_not_afterwards()
        {
            var input = 1;
            var p     = TestPublisher.CreateManualProbe <int>(this);
            var c     = TestSubscriber.CreateManualProbe <int>(this);

            Source.FromPublisher(p)
            .TakeWithin(TimeSpan.FromSeconds(1))
            .To(Sink.FromSubscriber(c))
            .Run(Materializer);
            var pSub = p.ExpectSubscription();
            var cSub = c.ExpectSubscription();

            cSub.Request(100);
            var demand1 = (int)pSub.ExpectRequest();

            Enumerable.Range(1, demand1).ForEach(_ => pSub.SendNext(input++));
            var demand2 = (int)pSub.ExpectRequest();

            Enumerable.Range(1, demand2).ForEach(_ => pSub.SendNext(input++));
            var demand3 = (int)pSub.ExpectRequest();
            var sentN   = demand1 + demand2;

            Enumerable.Range(1, sentN).ForEach(n => c.ExpectNext(n));
            Within(TimeSpan.FromSeconds(2), c.ExpectComplete);
            Enumerable.Range(1, demand3).ForEach(_ => pSub.SendNext(input++));
            c.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
        }
예제 #6
0
        public void A_Unzip_must_produce_to_right_downstream_even_though_left_downstream_cancels()
        {
            this.AssertAllStagesStopped(() =>
            {
                var c1 = TestSubscriber.CreateManualProbe <int>(this);
                var c2 = TestSubscriber.CreateManualProbe <string>(this);

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var unzip  = b.Add(new UnZip <int, string>());
                    var source =
                        Source.From(new[]
                    {
                        new KeyValuePair <int, string>(1, "a"),
                        new KeyValuePair <int, string>(2, "b"),
                        new KeyValuePair <int, string>(3, "c")
                    });

                    b.From(source).To(unzip.In);
                    b.From(unzip.Out0).To(Sink.FromSubscriber(c1));
                    b.From(unzip.Out1).To(Sink.FromSubscriber(c2));

                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var sub1 = c1.ExpectSubscription();
                var sub2 = c2.ExpectSubscription();

                sub1.Cancel();
                sub2.Request(3);
                c2.ExpectNext("a", "b", "c");
                c2.ExpectComplete();
            }, Materializer);
        }
예제 #7
0
        public void Zip_must_work_in_the_happy_case()
        {
            this.AssertAllStagesStopped(() =>
            {
                var probe = TestSubscriber.CreateManualProbe <Tuple <int, string> >(this);

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var zip     = b.Add(new Zip <int, string>());
                    var source1 = Source.From(Enumerable.Range(1, 4));
                    var source2 = Source.From(new[] { "A", "B", "C", "D", "E", "F" });

                    b.From(source1).To(zip.In0);
                    b.From(source2).To(zip.In1);
                    b.From(zip.Out).To(Sink.FromSubscriber(probe));

                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var subscription = probe.ExpectSubscription();

                subscription.Request(2);
                probe.ExpectNext(Tuple.Create(1, "A"));
                probe.ExpectNext(Tuple.Create(2, "B"));
                subscription.Request(1);
                probe.ExpectNext(Tuple.Create(3, "C"));
                subscription.Request(1);
                probe.ExpectNext(Tuple.Create(4, "D"));
                probe.ExpectComplete();
            }, Materializer);
        }
예제 #8
0
        public void A_Flow_based_on_an_iterable_must_produce_elements_to_later_subscriber()
        {
            this.AssertAllStagesStopped(() =>
            {
                var p  = CreateSource(3).RunWith(Sink.AsPublisher <int>(true), Materializer);
                var c1 = TestSubscriber.CreateManualProbe <int>(this);
                var c2 = TestSubscriber.CreateManualProbe <int>(this);

                p.Subscribe(c1);
                var sub1 = c1.ExpectSubscription();
                sub1.Request(1);
                c1.ExpectNext(1, TimeSpan.FromSeconds(60));
                c1.ExpectNoMsg(TimeSpan.FromMilliseconds(100));

                p.Subscribe(c2);
                var sub2 = c2.ExpectSubscription();
                sub2.Request(3);
                //element 1 is already gone
                c2.ExpectNext(2)
                .ExpectNext(3)
                .ExpectComplete();

                sub1.Request(3);
                c1.ExpectNext(2)
                .ExpectNext(3)
                .ExpectComplete();
            }, Materializer);
        }
예제 #9
0
        public void Conflate_must_backpressure_subscriber_when_upstream_is_slower()
        {
            var publisher  = TestPublisher.CreateProbe <int>(this);
            var subscriber = TestSubscriber.CreateManualProbe <int>(this);

            Source.FromPublisher(publisher)
            .ConflateWithSeed(i => i, (sum, i) => sum + i)
            .To(Sink.FromSubscriber(subscriber))
            .Run(Materializer);
            var sub = subscriber.ExpectSubscription();

            sub.Request(1);
            publisher.SendNext(1);
            subscriber.ExpectNext(1);

            sub.Request(1);
            subscriber.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
            publisher.SendNext(2);
            subscriber.ExpectNext(2);

            publisher.SendNext(3);
            publisher.SendNext(4);
            // The request can be in race with the above onNext(4) so the result would be either 3 or 7.
            subscriber.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
            sub.Request(1);
            subscriber.ExpectNext(7);

            sub.Request(1);
            subscriber.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
            sub.Cancel();
        }
예제 #10
0
        public void A_Broadcast_must_pass_along_early_cancellation()
        {
            this.AssertAllStagesStopped(() =>
            {
                var c1 = TestSubscriber.CreateManualProbe <int>(this);
                var c2 = TestSubscriber.CreateManualProbe <int>(this);

                var sink = Sink.FromGraph(GraphDsl.Create(b =>
                {
                    var broadcast = b.Add(new Broadcast <int>(2));
                    b.From(broadcast.Out(0)).To(Sink.FromSubscriber(c1));
                    b.From(broadcast.Out(1)).To(Sink.FromSubscriber(c2));
                    return(new SinkShape <int>(broadcast.In));
                }));

                var s = Source.AsSubscriber <int>().To(sink).Run(Materializer);

                var up = TestPublisher.CreateManualProbe <int>(this);

                var downSub1 = c1.ExpectSubscription();
                var downSub2 = c2.ExpectSubscription();
                downSub1.Cancel();
                downSub2.Cancel();

                up.Subscribe(s);
                var upSub = up.ExpectSubscription();
                upSub.ExpectCancellation();
            }, Materializer);
        }
예제 #11
0
        public void A_Broadcast_must_broadcast_to_other_subscriber()
        {
            this.AssertAllStagesStopped(() =>
            {
                var c1 = TestSubscriber.CreateManualProbe <int>(this);
                var c2 = TestSubscriber.CreateManualProbe <int>(this);
                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var broadcast = b.Add(new Broadcast <int>(2));
                    var source    = Source.From(Enumerable.Range(1, 3));
                    b.From(source).To(broadcast.In);
                    b.From(broadcast.Out(0))
                    .Via(Flow.Create <int>().Buffer(16, OverflowStrategy.Backpressure))
                    .To(Sink.FromSubscriber(c1));
                    b.From(broadcast.Out(1))
                    .Via(Flow.Create <int>().Buffer(16, OverflowStrategy.Backpressure))
                    .To(Sink.FromSubscriber(c2));
                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var sub1 = c1.ExpectSubscription();
                var sub2 = c2.ExpectSubscription();

                sub1.Request(1);
                sub2.Request(2);

                c1.ExpectNext(1).ExpectNoMsg(TimeSpan.FromMilliseconds(100));
                c2.ExpectNext(1, 2).ExpectNoMsg(TimeSpan.FromMilliseconds(100));
                sub1.Request(3);
                c1.ExpectNext(2, 3).ExpectComplete();
                sub2.Request(3);
                c2.ExpectNext(3).ExpectComplete();
            }, Materializer);
        }
예제 #12
0
        public void A_Broadcast_must_produce_to_downstream_even_though_other_cancels()
        {
            this.AssertAllStagesStopped(() =>
            {
                var c1 = TestSubscriber.CreateManualProbe <int>(this);
                var c2 = TestSubscriber.CreateManualProbe <int>(this);
                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var broadcast = b.Add(new Broadcast <int>(2));
                    var source    = Source.From(Enumerable.Range(1, 3));
                    b.From(source).To(broadcast.In);
                    b.From(broadcast.Out(0))
                    .Via(Flow.Create <int>().Named("identity-a"))
                    .To(Sink.FromSubscriber(c1));
                    b.From(broadcast.Out(1))
                    .Via(Flow.Create <int>().Named("identity-b"))
                    .To(Sink.FromSubscriber(c2));
                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var sub1 = c1.ExpectSubscription();
                var sub2 = c2.ExpectSubscription();
                sub2.Cancel();
                sub1.Request(3);
                c1.ExpectNext(1, 2, 3);
                c1.ExpectComplete();
            }, Materializer);
        }
예제 #13
0
        public void A_Merge_for_Flow_must_work_in_the_happy_case()
        {
            this.AssertAllStagesStopped(() =>
            {
                // Different input size (4 and 6)
                var source1 = Source.From(Enumerable.Range(0, 4));
                var source2 = Source.From(new List <int>());
                var source3 = Source.From(Enumerable.Range(4, 6));
                var probe   = TestSubscriber.CreateManualProbe <int>(this);

                source1
                .Merge(source2)
                .Merge(source3)
                .Select(i => i * 2)
                .Select(i => i / 2)
                .Select(i => i + 1)
                .RunWith(Sink.FromSubscriber(probe), Materializer);

                var subscription = probe.ExpectSubscription();

                var collected = new List <int>();
                for (var i = 1; i <= 10; i++)
                {
                    subscription.Request(1);
                    collected.Add(probe.ExpectNext());
                }

                collected.ShouldAllBeEquivalentTo(Enumerable.Range(1, 10));
                probe.ExpectComplete();
            }, Materializer);
        }
예제 #14
0
        public void A_Merge_for_Flow_must_pass_along_early_cancellation()
        {
            this.AssertAllStagesStopped(() =>
            {
                var up1  = TestPublisher.CreateManualProbe <int>(this);
                var up2  = TestPublisher.CreateManualProbe <int>(this);
                var down = TestSubscriber.CreateManualProbe <int>(this);

                var t =
                    Source.AsSubscriber <int>()
                    .MergeMaterialized(Source.AsSubscriber <int>(), Tuple.Create)
                    .ToMaterialized(Sink.FromSubscriber(down), Keep.Left)
                    .Run(Materializer);
                var graphSubscriber1 = t.Item1;
                var graphSubscriber2 = t.Item2;

                var downstream = down.ExpectSubscription();
                downstream.Cancel();
                up1.Subscribe(graphSubscriber1);
                up2.Subscribe(graphSubscriber2);

                up1.ExpectSubscription().ExpectCancellation();
                up2.ExpectSubscription().ExpectCancellation();
            }, Materializer);
        }
예제 #15
0
        public void ConcatAll_must_on_OnError_on_master_stream_cancel_the_current_open_substream_and_signal_error()
        {
            this.AssertAllStagesStopped(() =>
            {
                var publisher  = TestPublisher.CreateManualProbe <Source <int, NotUsed> >(this);
                var subscriber = TestSubscriber.CreateManualProbe <int>(this);
                Source.FromPublisher(publisher)
                .ConcatMany(x => x)
                .To(Sink.FromSubscriber(subscriber))
                .Run(Materializer);

                var upstream   = publisher.ExpectSubscription();
                var downstream = subscriber.ExpectSubscription();
                downstream.Request(1000);

                var substreamPublisher = TestPublisher.CreateManualProbe <int>(this);
                var substreamFlow      = Source.FromPublisher(substreamPublisher);
                upstream.ExpectRequest();
                upstream.SendNext(substreamFlow);
                var subUpstream = substreamPublisher.ExpectSubscription();

                upstream.SendError(TestException);
                subscriber.ExpectError().Should().Be(TestException);
                subUpstream.ExpectCancellation();
            }, Materializer);
        }
예제 #16
0
        public void An_Interleave_for_Flow_must_work_when_segmentSize_is_greater_than_stream_elements()
        {
            this.AssertAllStagesStopped(() =>
            {
                var probe = TestSubscriber.CreateManualProbe <int>(this);
                Source.From(Enumerable.Range(0, 3))
                .Interleave(Source.From(Enumerable.Range(3, 13)), 10)
                .RunWith(Sink.FromSubscriber(probe), Materializer);

                probe.ExpectSubscription().Request(25);
                Enumerable.Range(0, 16).ForEach(i => probe.ExpectNext(i));
                probe.ExpectComplete();

                var probe2 = TestSubscriber.CreateManualProbe <int>(this);
                Source.From(Enumerable.Range(1, 20))
                .Interleave(Source.From(Enumerable.Range(21, 5)), 10)
                .RunWith(Sink.FromSubscriber(probe2), Materializer);

                probe2.ExpectSubscription().Request(100);
                Enumerable.Range(1, 10).ForEach(i => probe2.ExpectNext(i));
                Enumerable.Range(21, 5).ForEach(i => probe2.ExpectNext(i));
                Enumerable.Range(11, 10).ForEach(i => probe2.ExpectNext(i));
                probe2.ExpectComplete();
            }, Materializer);
        }
예제 #17
0
        public void A_Unzip_must_work_with_Zip()
        {
            this.AssertAllStagesStopped(() =>
            {
                var c1 = TestSubscriber.CreateManualProbe <Tuple <int, string> >(this);

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var zip    = b.Add(new Zip <int, string>());
                    var unzip  = b.Add(new UnZip <int, string>());
                    var source =
                        Source.From(new[]
                    {
                        new KeyValuePair <int, string>(1, "a"),
                        new KeyValuePair <int, string>(2, "b"),
                        new KeyValuePair <int, string>(3, "c")
                    });

                    b.From(source).To(unzip.In);
                    b.From(unzip.Out0).To(zip.In0);
                    b.From(unzip.Out1).To(zip.In1);
                    b.From(zip.Out).To(Sink.FromSubscriber(c1));

                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var sub1 = c1.ExpectSubscription();
                sub1.Request(5);
                c1.ExpectNext(Tuple.Create(1, "a"));
                c1.ExpectNext(Tuple.Create(2, "b"));
                c1.ExpectNext(Tuple.Create(3, "c"));
                c1.ExpectComplete();
            }, Materializer);
        }
        public void TestPublisher_and_TestSubscriber_should_have_all_events_accessible_from_manual_probes()
        {
            this.AssertAllStagesStopped(() =>
            {
                var upstream   = TestPublisher.CreateManualProbe <int>(this);
                var downstream = TestSubscriber.CreateManualProbe <int>(this);
                Source.FromPublisher(upstream)
                .RunWith(Sink.AsPublisher <int>(false), Materializer)
                .Subscribe(downstream);

                var upstreamSubscription = upstream.ExpectSubscription();
                object evt = downstream.ExpectEvent();
                evt.Should().BeOfType <TestSubscriber.OnSubscribe>();
                var downstreamSubscription = ((TestSubscriber.OnSubscribe)evt).Subscription;

                upstreamSubscription.SendNext(1);
                downstreamSubscription.Request(1);
                evt = upstream.ExpectEvent();
                evt.Should().BeOfType <TestPublisher.RequestMore>();
                ((TestPublisher.RequestMore)evt).NrOfElements.Should().Be(1);
                evt = downstream.ExpectEvent();
                evt.Should().BeOfType <TestSubscriber.OnNext <int> >();
                ((TestSubscriber.OnNext <int>)evt).Element.Should().Be(1);

                upstreamSubscription.SendNext(1);
                downstreamSubscription.Request(1);
                downstream.ExpectNext(1);

                upstreamSubscription.SendComplete();
                evt = downstream.ExpectEvent();
                evt.Should().BeOfType <TestSubscriber.OnComplete>();
            }, Materializer);
        }
예제 #19
0
 public void A_Flow_with_SelectAsync_must_resume_after_task_failure()
 {
     this.AssertAllStagesStopped(() =>
     {
         this.AssertAllStagesStopped(() =>
         {
             var c = TestSubscriber.CreateManualProbe <int>(this);
             Source.From(Enumerable.Range(1, 5))
             .SelectAsync(4, n => Task.Run(() =>
             {
                 if (n == 3)
                 {
                     throw new TestException("err3");
                 }
                 return(n);
             }))
             .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
             .RunWith(Sink.FromSubscriber(c), Materializer);
             var sub = c.ExpectSubscription();
             sub.Request(10);
             new[] { 1, 2, 4, 5 }.ForEach(i => c.ExpectNext(i));
             c.ExpectComplete();
         }, Materializer);
     }, Materializer);
 }
예제 #20
0
        public void A_GroupedWithin_must_drop_empty_groups()
        {
            var p = TestPublisher.CreateManualProbe <int>(this);
            var c = TestSubscriber.CreateManualProbe <IEnumerable <int> >(this);

            Source.FromPublisher(p)
            .GroupedWithin(1000, TimeSpan.FromMilliseconds(500))
            .To(Sink.FromSubscriber(c))
            .Run(Materializer);

            var pSub = p.ExpectSubscription();
            var cSub = c.ExpectSubscription();

            cSub.Request(2);
            pSub.ExpectRequest();
            c.ExpectNoMsg(TimeSpan.FromMilliseconds(600));

            pSub.SendNext(1);
            pSub.SendNext(2);
            c.ExpectNext().ShouldAllBeEquivalentTo(new [] { 1, 2 });
            // nothing more requested
            c.ExpectNoMsg(TimeSpan.FromMilliseconds(1100));
            cSub.Request(3);
            c.ExpectNoMsg(TimeSpan.FromMilliseconds(600));
            pSub.SendComplete();
            c.ExpectComplete();
            c.ExpectNoMsg(TimeSpan.FromMilliseconds(100));
        }