Пример #1
0
        public void SendAsync_BackOffExceptionHandler_Throw_Max2Minutes()
        {
            // create exponential back-off without delta interval, so expected seconds are exactly 1, 2, 4, 8, etc.
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero));

            SubtestSendAsync_BackOffExceptionHandler(true, initializer);
        }
Пример #2
0
        private void InitializeExponentialBackOff(ConfigurableHttpClient client, IFcmClientSettings settings)
        {
            // The Maximum Number of Retries is limited to 3 per default for a ConfigurableHttpClient. This is
            // somewhat weird, because the ExponentialBackOff Algorithm is initialized with 10 Retries per default.
            //
            // Somehow the NumTries seems to be the limiting factor here, so it basically overrides anything you
            // are going to write in the Exponential Backoff Handler.
            client.MessageHandler.NumTries = settings.ExponentialBackOffSettings.MaxNumberOfRetries;

            // Create the Default BackOff Algorithm:
            var backoff = new ExponentialBackOff(settings.ExponentialBackOffSettings.DeltaBackOff, settings.ExponentialBackOffSettings.MaxNumberOfRetries);

            // Create the Initializer. Make sure to set the Maximum Timespan between two Requests. It
            // is 16 Seconds per Default:
            var backoffInitializer = new BackOffHandler.Initializer(backoff)
            {
                MaxTimeSpan = settings.ExponentialBackOffSettings.MaxTimeSpan
            };

            // Now create the Handler:
            var initializer = new ExponentialBackOffInitializer(ExponentialBackOffPolicy.UnsuccessfulResponse503, () => new BackOffHandler(backoffInitializer));

            // And finally append the BackOff Handler, which reacts to 503 Requests:
            initializer.Initialize(client);
        }
Пример #3
0
        public void SendAsync_BackOffUnsuccessfulResponseHandler_Cancel()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero));

            SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer, 2);
            SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer, 6);
        }
Пример #4
0
        public void SendAsync_BackOffUnsuccessfulResponseHandler_ServiceUnavailable_Max10Hours()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero))
            {
                MaxTimeSpan = TimeSpan.FromHours(10)
            };

            SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer);
        }
Пример #5
0
        public void SendAsync_BackOffExceptionHandler_Throw_Max1Hour()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero))
            {
                MaxTimeSpan = TimeSpan.FromHours(1)
            };

            SubtestSendAsync_BackOffExceptionHandler(true, initializer);
        }
Пример #6
0
        public void SendAsync_BackOffExceptionHandler_Throw_Max200Milliseconds()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero))
            {
                MaxTimeSpan = TimeSpan.FromMilliseconds(200)
            };

            SubtestSendAsync_BackOffExceptionHandler(true, initializer);
        }
        /// <summary>Subtest that back-off handler works as expected when exception is or isn't thrown.</summary>
        private void SubtestSendAsync_BackOffExceptionHandler(bool throwException,
                                                              BackOffHandler.Initializer initializer, Exception exceptionToThrow = null)
        {
            var handler = new ExceptionMessageHandler {
                ThrowException = throwException
            };

            if (exceptionToThrow != null)
            {
                handler.Exception = exceptionToThrow;
            }

            var configurableHanlder = new ConfigurableMessageHandler(handler);
            var boHandler           = new MockBackOffHandler(initializer);

            configurableHanlder.AddExceptionHandler(boHandler);

            int boHandleCount = 0;

            // if an exception should be thrown and the handler can handle it then calculate the handle count by the
            // lg(MaxTimeSpan)
            if (throwException && initializer.HandleExceptionFunc(exceptionToThrow))
            {
                boHandleCount = Math.Min((int)Math.Floor(Math.Log(boHandler.MaxTimeSpan.TotalSeconds, 2)) + 1,
                                         configurableHanlder.NumTries - 1);
                boHandleCount = boHandleCount >= 0 ? boHandleCount : 0;
            }

            using (var client = new HttpClient(configurableHanlder))
            {
                var request = new HttpRequestMessage(HttpMethod.Get, "https://test-exception-handler");
                try
                {
                    HttpResponseMessage response = client.SendAsync(request).Result;
                    Assert.False(throwException);
                }
                catch (AggregateException ae)
                {
                    Assert.True(throwException);
                    // Don't compare exception messages because for TaskCanceledException the message
                    // on Mono is different if there is a task associated with the exception.
                    Assert.AreEqual(handler.Exception.GetType(), ae.InnerException.GetType());
                }

                Assert.That(boHandler.Waits.Count, Is.EqualTo(boHandleCount));
                // check the exponential behavior - wait 1, 2, 4, 8, ... seconds.
                if (throwException)
                {
                    for (int i = 0; i < boHandler.Waits.Count; ++i)
                    {
                        Assert.That(boHandler.Waits[i].TotalSeconds, Is.EqualTo((int)Math.Pow(2, i)));
                    }
                }
                Assert.That(handler.Calls, Is.EqualTo(boHandleCount + 1));
            }
        }
Пример #8
0
        public void SendAsync_BackOffExceptionHandler_DifferentHandler()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero));

            initializer.HandleExceptionFunc = e => (e is InvalidCastException);
            SubtestSendAsync_BackOffExceptionHandler(true, initializer, new InvalidCastException());

            initializer.HandleExceptionFunc = e => !(e is InvalidCastException);
            SubtestSendAsync_BackOffExceptionHandler(true, initializer, new InvalidCastException());
        }
        public void SendAsync_BackOffUnsuccessfulResponseHandler_Cancel()
        {
            // test back-off with maximum 30 minutes per single request
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero))
            {
                MaxTimeSpan = TimeSpan.FromMinutes(30)
            };

            SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer, 2);
            SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer, 6);
        }
Пример #10
0
        private static CreateHttpClientArgs CreateDefaultHttpClientArgs(IFcmClientSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings", "Settings are needed to create the Default HttpClientArgs");
            }

            var args = new CreateHttpClientArgs();

            // Create the Default BackOff Algorithm:
            var backoff = new ExponentialBackOff(settings.ExponentialBackOffSettings.DeltaBackOff, settings.ExponentialBackOffSettings.MaxNumberOfRetries);

            // Create the Initializer. Make sure to set the Maximum Timespan between two Requests. It is 16 Seconds per Default:
            var backoffInitializer = new BackOffHandler.Initializer(backoff)
            {
                MaxTimeSpan = settings.ExponentialBackOffSettings.MaxTimeSpan
            };

            args.Initializers.Add(new ExponentialBackOffInitializer(ExponentialBackOffPolicy.UnsuccessfulResponse503, () => new BackOffHandler(backoffInitializer)));

            return(args);
        }
Пример #11
0
        /// <summary>
        /// Subtest that back-off handler works as expected when a successful or abnormal response is returned.
        /// For testing the back-off handler in case of a canceled request, set the <code>cancelRequestNum</code>
        /// parameter to the index of the request you want to cancel.
        /// </summary>
        private void SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode statusCode,
                                                                         BackOffHandler.Initializer initializer, int cancelRequestNum = 0)
        {
            var handler = new UnsuccessfulResponseMessageHandler {
                ResponseStatusCode = statusCode
            };

            CancellationToken cancellationToken = CancellationToken.None;
            bool cancel = cancelRequestNum > 0;

            if (cancel)
            {
                CancellationTokenSource tcs = new CancellationTokenSource();
                handler.CancellationTokenSource = tcs;
                handler.CancelRequestNum        = cancelRequestNum;
                cancellationToken = tcs.Token;
            }

            var configurableHanlder = new ConfigurableMessageHandler(handler);
            var boHandler           = new MockBackOffHandler(initializer);

            configurableHanlder.UnsuccessfulResponseHandlers.Add(boHandler);

            int boHandleCount = 0;

            if (initializer.HandleUnsuccessfulResponseFunc != null &&
                initializer.HandleUnsuccessfulResponseFunc(new HttpResponseMessage {
                StatusCode = statusCode
            }))
            {
                boHandleCount = Math.Min((int)Math.Floor(Math.Log(boHandler.MaxTimeSpan.TotalSeconds, 2)) + 1,
                                         configurableHanlder.NumTries - 1);
                boHandleCount = boHandleCount >= 0 ? boHandleCount : 0;
                if (cancel)
                {
                    boHandleCount = Math.Min(boHandleCount, cancelRequestNum);
                }
            }

            using (var client = new HttpClient(configurableHanlder))
            {
                var request = new HttpRequestMessage(HttpMethod.Get, "https://test-exception-handler");
                try
                {
                    HttpResponseMessage response = client.SendAsync(request, cancellationToken).Result;
                    Assert.False(cancel);
                }
                catch (AggregateException ae)
                {
                    // a canceled request should throw an exception
                    Assert.IsInstanceOf <TaskCanceledException>(ae.InnerException);
                    Assert.True(cancel);
                }

                Assert.That(boHandler.Waits.Count, Is.EqualTo(boHandleCount));

                // check the exponential behavior - wait 1, 2, 4, 8, ... seconds.
                for (int i = 0; i < boHandler.Waits.Count; ++i)
                {
                    Assert.That(boHandler.Waits[i].TotalSeconds, Is.EqualTo((int)Math.Pow(2, i)));
                }

                // if the request was canceled the number of calls to the message handler is equal to the number of
                // calls to back-off handler
                Assert.That(handler.Calls, Is.EqualTo(boHandleCount + (cancel ? 0 : 1)));
            }
        }
Пример #12
0
        public void SendAsync_BackOffUnsuccessfulResponseHandler_OK()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero));

            SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.OK, initializer);
        }
Пример #13
0
        public void SendAsync_BackOffExceptionHandler_DontThrow()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero));

            SubtestSendAsync_BackOffExceptionHandler(false, initializer);
        }
Пример #14
0
        public void SendAsync_BackOffExceptionHandler_ThrowCanceledException()
        {
            var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero));

            SubtestSendAsync_BackOffExceptionHandler(true, initializer, new TaskCanceledException());
        }
Пример #15
0
 /// <summary> Constructs a new back-off handler by the given initializer. </summary>
 public MockBackOffHandler(BackOffHandler.Initializer initializer)
     : base(initializer)
 {
     Waits = new List <TimeSpan>();
 }