public async Task RetryAfterTimestamp() { var clock = new MockClock(); var timestamp = clock.UtcNow.AddSeconds(4).ToString("r"); var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.ServiceUnavailable, ApplyHeaders = (headers, contentHeaders) => { headers.RetryAfter = RetryConditionHeaderValue.Parse(timestamp); }, Response = "{}", }; var waiter = new MockWaiter(); var httpClient = CreateHttpClient(handler, RetryOptions.Default, waiter, clock); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode); Assert.Equal(5, handler.Calls); Assert.Equal(4, waiter.WaitTimes.Count); foreach (var timespan in waiter.WaitTimes) { // Due to the date format used in HTTP headers, the milliseconds precision gets // lost. Therefore the actual delay is going to be a value between 3 and 4 seconds. Assert.True(timespan.TotalSeconds > 3.0 && timespan.TotalSeconds <= 4.0); } }
public async Task BackOffFactorZero() { var handler = new MockMessageHandler() { Exception = new Exception("transport error"), }; var waiter = new MockWaiter(); var options = RetryOptions.Default; options.BackOffFactor = 0; var httpClient = CreateHttpClient(handler, options, waiter); var ex = await Assert.ThrowsAsync <Exception>( async() => await httpClient.SendAsync(CreateRequest())); Assert.Equal("transport error", ex.Message); Assert.Equal(5, handler.Calls); var expected = new List <TimeSpan>() { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero, }; Assert.Equal(expected, waiter.WaitTimes); }
public async Task RetryAfterSeconds() { var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.ServiceUnavailable, ApplyHeaders = (headers, contentHeaders) => { headers.RetryAfter = RetryConditionHeaderValue.Parse("3"); }, Response = "{}", }; var waiter = new MockWaiter(); var httpClient = CreateHttpClient(handler, RetryOptions.Default, waiter); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode); Assert.Equal(5, handler.Calls); var expected = new List <TimeSpan>() { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3), }; Assert.Equal(expected, waiter.WaitTimes); }
public async Task RetryOnHttp500WhenRequested() { var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.InternalServerError, Response = "{}", }; var waiter = new MockWaiter(); var options = RetryOptions.Default; options.HandleUnsuccessfulResponseFunc = (resp) => resp.StatusCode == HttpStatusCode.InternalServerError; var httpClient = CreateHttpClient(handler, options, waiter); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); Assert.Equal(5, handler.Calls); var expected = new List <TimeSpan>() { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), }; Assert.Equal(expected, waiter.WaitTimes); }
public async Task NoRetryOnHttp500ByDefault() { var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.InternalServerError, Response = "{}", }; var waiter = new MockWaiter(); var httpClient = CreateHttpClient(handler, RetryOptions.Default, waiter); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); Assert.Equal(1, handler.Calls); }
public async Task RetryOnUnsuccessfulResponseDisabled() { var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.ServiceUnavailable, Response = "{}", }; var waiter = new MockWaiter(); var options = RetryOptions.Default; options.HandleUnsuccessfulResponseFunc = null; var httpClient = CreateHttpClient(handler, options, waiter); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode); Assert.Equal(1, handler.Calls); }
public async Task RetryOnExceptionDisabled() { var handler = new MockMessageHandler() { Exception = new Exception("transport error"), }; var waiter = new MockWaiter(); var options = RetryOptions.Default; options.HandleExceptionFunc = null; var httpClient = CreateHttpClient(handler, options, waiter); var ex = await Assert.ThrowsAsync <Exception>( async() => await httpClient.SendAsync(CreateRequest())); Assert.Equal("transport error", ex.Message); Assert.Equal(1, handler.Calls); }
public async Task RetryAfterTooLarge() { var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.ServiceUnavailable, ApplyHeaders = (headers, contentHeaders) => { headers.RetryAfter = RetryConditionHeaderValue.Parse("300"); }, Response = "{}", }; var waiter = new MockWaiter(); var httpClient = CreateHttpClient(handler, RetryOptions.Default, waiter); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode); Assert.Equal(1, handler.Calls); }
public async Task RetryOnHttp503() { var handler = new MockMessageHandler() { StatusCode = HttpStatusCode.ServiceUnavailable, Response = "{}", }; var waiter = new MockWaiter(); var httpClient = CreateHttpClient(handler, RetryOptions.Default, waiter); var response = await httpClient.SendAsync(CreateRequest()); Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode); Assert.Equal(5, handler.Calls); var expected = new List <TimeSpan>() { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), }; Assert.Equal(expected, waiter.WaitTimes); }
public async Task RetryOnException() { var handler = new MockMessageHandler() { Exception = new Exception("transport error"), }; var waiter = new MockWaiter(); var httpClient = CreateHttpClient(handler, RetryOptions.Default, waiter); var ex = await Assert.ThrowsAsync <Exception>( async() => await httpClient.SendAsync(CreateRequest())); Assert.Equal("transport error", ex.Message); Assert.Equal(5, handler.Calls); var expected = new List <TimeSpan>() { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), }; Assert.Equal(expected, waiter.WaitTimes); }