예제 #1
0
        public void ReconnectAfterHttpError()
        {
            HttpStatusCode error1 = HttpStatusCode.BadRequest, error2 = HttpStatusCode.InternalServerError;
            var            message = new MessageEvent("put", "hello", _uri);

            var handler = Handlers.Sequential(
                Handlers.Status((int)error1),
                Handlers.Status((int)error2),
                StartStream().Then(WriteEvent(message)).Then(LeaveStreamOpen())
                );

            WithServerAndEventSource(handler, c => c.InitialRetryDelay(TimeSpan.FromMilliseconds(20)), (server, es) =>
            {
                var eventSink = new EventSink(es, _testLogging);
                _             = Task.Run(es.StartAsync);

                var action1 = eventSink.ExpectAction();
                var ex1     = Assert.IsType <EventSourceServiceUnsuccessfulResponseException>(action1.Exception);
                Assert.Equal((int)error1, ex1.StatusCode);

                eventSink.ExpectActions(EventSink.ClosedAction());

                var action2 = eventSink.ExpectAction();
                var ex2     = Assert.IsType <EventSourceServiceUnsuccessfulResponseException>(action2.Exception);
                Assert.Equal((int)error2, ex2.StatusCode);

                eventSink.ExpectActions(
                    EventSink.ClosedAction(),
                    EventSink.OpenedAction(),
                    EventSink.MessageReceivedAction(message)
                    );
            });
        }
        public void DetectReadTimeout()
        {
            TimeSpan readTimeout = TimeSpan.FromMilliseconds(300);
            TimeSpan timeToWait  = readTimeout + readTimeout;

            var handler = new StubMessageHandler();

            handler.QueueResponse(StubResponse.StartStream(
                                      StreamAction.Write(":comment1\n"),
                                      StreamAction.Write(":comment2\n"),
                                      StreamAction.Write(":comment3\n").AfterDelay(timeToWait))
                                  );
            handler.QueueResponse(StubResponse.StartStream());

            using (var es = StartEventSource(handler, out var eventSink, config => config.ReadTimeout(readTimeout)))
            {
                eventSink.ExpectActions(
                    EventSink.OpenedAction(),
                    EventSink.CommentReceivedAction(":comment1"),
                    EventSink.CommentReceivedAction(":comment2"),
                    EventSink.ErrorAction(new ReadTimeoutException()),
                    EventSink.ClosedAction()
                    );
            }
        }
        public void ReconnectAfterHttpError()
        {
            HttpStatusCode error1 = HttpStatusCode.BadRequest, error2 = HttpStatusCode.InternalServerError;
            var            message = new MessageEvent("put", "hello", _uri);

            var handler = new StubMessageHandler();

            handler.QueueResponse(StubResponse.WithStatus(error1));
            handler.QueueResponse(StubResponse.WithStatus(error2));
            handler.QueueResponse(StubResponse.StartStream(StreamAction.Write(message)));

            using (var es = MakeEventSource(handler, builder => builder.InitialRetryDelay(TimeSpan.FromMilliseconds(20))))
            {
                var eventSink = new EventSink(es, _testLogging);
                _ = Task.Run(es.StartAsync);

                var action1 = eventSink.ExpectAction();
                var ex1     = Assert.IsType <EventSourceServiceUnsuccessfulResponseException>(action1.Exception);
                Assert.Equal((int)error1, ex1.StatusCode);

                eventSink.ExpectActions(EventSink.ClosedAction());

                var action2 = eventSink.ExpectAction();
                var ex2     = Assert.IsType <EventSourceServiceUnsuccessfulResponseException>(action2.Exception);
                Assert.Equal((int)error2, ex2.StatusCode);

                eventSink.ExpectActions(
                    EventSink.ClosedAction(),
                    EventSink.OpenedAction(),
                    EventSink.MessageReceivedAction(message)
                    );
            }
        }
        public void ReadTimeoutIsDetected(bool utf8Mode)
        {
            TimeSpan readTimeout   = TimeSpan.FromMilliseconds(200);
            var      streamHandler = Handlers.StartChunks("text/event-stream")
                                     .Then(Handlers.WriteChunkString("data: event1\n\ndata: e"))
                                     .Then(Handlers.Delay(readTimeout + readTimeout))
                                     .Then(Handlers.WriteChunkString("vent2\n\n"));

            using (var server = HttpServer.Start(streamHandler))
            {
                var config = Configuration.Builder(server.Uri)
                             .LogAdapter(_testLogging)
                             .ReadTimeout(readTimeout)
                             .PreferDataAsUtf8Bytes(utf8Mode)
                             .Build();
                using (var es = new EventSource(config))
                {
                    var sink = new EventSink(es)
                    {
                        Output = _testLogger.Debug
                    };
                    _ = es.StartAsync();
                    sink.ExpectActions(
                        EventSink.OpenedAction(),
                        EventSink.MessageReceivedAction(new MessageEvent(MessageEvent.DefaultName, "event1", server.Uri)),
                        EventSink.ErrorAction(new ReadTimeoutException()),
                        EventSink.ClosedAction()
                        );
                }
            }
        }
        public void CanRestartStream(bool resetBackoff)
        {
            // This test is in EventSourceStreamReadingTest rather than EventSourceReconnectingTest
            // because the important thing here is that the stream reading logic can be interrupted.
            int nAttempts    = 3;
            var initialDelay = TimeSpan.FromMilliseconds(50);

            var anEvent = new MessageEvent("put", "x", _uri);
            var stream  = StubResponse.StartStream(StreamAction.Write(anEvent));
            var handler = new StubMessageHandler();

            for (var i = 0; i <= nAttempts; i++)
            {
                handler.QueueResponse(stream);
            }

            var backoffs = new List <TimeSpan>();

            using (var es = MakeEventSource(handler, builder => builder.InitialRetryDelay(initialDelay)))
            {
                var sink = new EventSink(es, _testLogging);
                es.Closed += (_, ex) =>
                {
                    backoffs.Add(es.BackOffDelay);
                };
                _ = Task.Run(es.StartAsync);

                sink.ExpectActions(
                    EventSink.OpenedAction(),
                    EventSink.MessageReceivedAction(anEvent)
                    );

                for (var i = 0; i < nAttempts; i++)
                {
                    es.Restart(resetBackoff);

                    sink.ExpectActions(
                        EventSink.ClosedAction(),
                        EventSink.OpenedAction(),
                        EventSink.MessageReceivedAction(anEvent)
                        );
                }
            }

            if (resetBackoff)
            {
                Assert.All(backoffs, delay => Assert.InRange(delay, TimeSpan.Zero, initialDelay));
            }
            else
            {
                AssertBackoffsAlwaysIncrease(backoffs, nAttempts);
            }
        }
예제 #6
0
        public void CanRestartStream(bool resetBackoff)
        {
            // This test is in EventSourceStreamReadingTest rather than EventSourceReconnectingTest
            // because the important thing here is that the stream reading logic can be interrupted.
            int nAttempts    = 3;
            var initialDelay = TimeSpan.FromMilliseconds(50);

            var anEvent = new MessageEvent("put", "x", _uri);
            var handler = Handlers.Sequential(
                Enumerable.Range(0, nAttempts + 1).Select(_ =>
                                                          StartStream().Then(WriteEvent(anEvent)).Then(LeaveStreamOpen())
                                                          ).ToArray());

            var backoffs = new List <TimeSpan>();

            using (var server = HttpServer.Start(handler))
            {
                using (var es = MakeEventSource(server.Uri, config => config.InitialRetryDelay(initialDelay)))
                {
                    var sink = new EventSink(es, _testLogging);
                    es.Closed += (_, ex) =>
                    {
                        backoffs.Add(es.BackOffDelay);
                    };
                    _ = Task.Run(es.StartAsync);

                    sink.ExpectActions(
                        EventSink.OpenedAction(),
                        EventSink.MessageReceivedAction(anEvent)
                        );

                    for (var i = 0; i < nAttempts; i++)
                    {
                        es.Restart(resetBackoff);

                        sink.ExpectActions(
                            EventSink.ClosedAction(),
                            EventSink.OpenedAction(),
                            EventSink.MessageReceivedAction(anEvent)
                            );
                    }
                }
            }

            if (resetBackoff)
            {
                Assert.All(backoffs, delay => Assert.InRange(delay, TimeSpan.Zero, initialDelay));
            }
            else
            {
                AssertBackoffsAlwaysIncrease(backoffs, nAttempts);
            }
        }
예제 #7
0
        public void DetectReadTimeout()
        {
            TimeSpan readTimeout = TimeSpan.FromMilliseconds(300);
            TimeSpan timeToWait  = readTimeout + readTimeout;

            var handler = StartStream()
                          .Then(Handlers.WriteChunkString(":comment1\n"))
                          .Then(Handlers.WriteChunkString(":comment2\n"))
                          .Then(Handlers.Delay(timeToWait))
                          .Then(Handlers.WriteChunkString(":comment3\n"));

            WithServerAndStartedEventSource(handler, config => config.ReadTimeout(readTimeout), (_, eventSink) =>
            {
                eventSink.ExpectActions(
                    EventSink.OpenedAction(),
                    EventSink.CommentReceivedAction(":comment1"),
                    EventSink.CommentReceivedAction(":comment2"),
                    EventSink.ErrorAction(new ReadTimeoutException()),
                    EventSink.ClosedAction()
                    );
            });
        }
        public void ReadTimeoutIsDetected(bool utf8Mode)
        {
            TimeSpan readTimeout = TimeSpan.FromMilliseconds(200);

            IEnumerable <string> DoChunks()
            {
                yield return("");

                yield return("data: event1\n\ndata: e");

                Thread.Sleep(readTimeout + readTimeout);
                yield return("vent2\n\n");
            }

            using (var server = StartWebServerOnAvailablePort(out var uri, RespondWithChunks("text/event-stream", DoChunks)))
            {
                var config = Configuration.Builder(uri)
                             .LogAdapter(_testLogging)
                             .ReadTimeout(readTimeout)
                             .PreferDataAsUtf8Bytes(utf8Mode)
                             .Build();
                using (var es = new EventSource(config))
                {
                    var sink = new EventSink(es)
                    {
                        Output = _testLogger.Debug
                    };
                    _ = es.StartAsync();
                    sink.ExpectActions(
                        EventSink.OpenedAction(),
                        EventSink.MessageReceivedAction(new MessageEvent(MessageEvent.DefaultName, "event1", uri)),
                        EventSink.ErrorAction(new ReadTimeoutException()),
                        EventSink.ClosedAction()
                        );
                }
            }
        }