Skip to content

Commit

Permalink
Merge pull request #97 from Jericho/release/v0.14.0
Browse files Browse the repository at this point in the history
Release/v0.14.0
  • Loading branch information
Jericho authored Nov 29, 2016
2 parents 4ea8eb0 + 671e444 commit 38185c3
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 231 deletions.
40 changes: 20 additions & 20 deletions Source/StrongGrid.UnitTests/ClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,25 +133,25 @@ public void GetAsync_HTTP429_retry_success()
.With(request => request.Content == null)
.Respond("application/json", "{'name' : 'This is a test'}");

// Fake delay for testing purposes
var mockDelayer = new Mock<IAsyncDelayer>(MockBehavior.Strict);
mockDelayer
.Setup(d => d.CalculateDelay(It.IsAny<HttpResponseHeaders>()))
.Returns(TimeSpan.FromMilliseconds(1))
// Retry strategy
var mockRetryStrategy = new Mock<IRetryStrategy>(MockBehavior.Strict);
mockRetryStrategy
.Setup(rs => rs.ShouldRetry(It.IsAny<int>(), It.IsAny<HttpResponseMessage>()))
.Returns<int, HttpResponseMessage>((attempts, response) => response.StatusCode == (HttpStatusCode)429)
.Verifiable();
mockDelayer
.Setup(d => d.Delay(It.Is<TimeSpan>(t => t.Milliseconds == 1)))
.Returns(Task.FromResult(0))
mockRetryStrategy
.Setup(rs => rs.GetNextDelay(It.IsAny<int>(), It.IsAny<HttpResponseMessage>()))
.Returns(TimeSpan.Zero)
.Verifiable();

var httpClient = new HttpClient(mockHttp);
var client = new Client(apiKey: API_KEY, httpClient: httpClient, asyncDelayer: mockDelayer.Object);
var client = new Client(apiKey: API_KEY, httpClient: httpClient, retryStrategy: mockRetryStrategy.Object);

// Act
var result = client.GetAsync("myendpoint", CancellationToken.None).Result;

// Assert
mockDelayer.VerifyAll();
mockRetryStrategy.VerifyAll();
mockHttp.VerifyNoOutstandingExpectation();
mockHttp.VerifyNoOutstandingRequest();
result.IsSuccessStatusCode.ShouldBeTrue();
Expand All @@ -174,25 +174,25 @@ public void GetAsync_HTTP429_retry_failure()
.With(request => request.Content == null)
.Respond((HttpStatusCode)429);

// Fake delay for testing purposes
var mockDelayer = new Mock<IAsyncDelayer>(MockBehavior.Strict);
mockDelayer
.Setup(d => d.CalculateDelay(It.IsAny<HttpResponseHeaders>()))
.Returns(TimeSpan.FromMilliseconds(1))
// Retry strategy
var mockRetryStrategy = new Mock<IRetryStrategy>(MockBehavior.Strict);
mockRetryStrategy
.Setup(rs => rs.ShouldRetry(It.IsAny<int>(), It.IsAny<HttpResponseMessage>()))
.Returns<int, HttpResponseMessage>((attempts, response) => attempts < 3)
.Verifiable();
mockDelayer
.Setup(d => d.Delay(It.Is<TimeSpan>(t => t.Milliseconds == 1)))
.Returns(Task.FromResult(0))
mockRetryStrategy
.Setup(rs => rs.GetNextDelay(It.IsAny<int>(), It.IsAny<HttpResponseMessage>()))
.Returns(TimeSpan.Zero)
.Verifiable();

var httpClient = new HttpClient(mockHttp);
var client = new Client(apiKey: API_KEY, httpClient: httpClient, asyncDelayer: mockDelayer.Object);
var client = new Client(apiKey: API_KEY, httpClient: httpClient, retryStrategy: mockRetryStrategy.Object);

// Act
var result = client.GetAsync("myendpoint", CancellationToken.None).Result;

// Assert
mockDelayer.VerifyAll();
mockRetryStrategy.VerifyAll();
mockHttp.VerifyNoOutstandingExpectation();
mockHttp.VerifyNoOutstandingRequest();
result.IsSuccessStatusCode.ShouldBeFalse();
Expand Down
89 changes: 0 additions & 89 deletions Source/StrongGrid.UnitTests/Utilities/AsyncDelayerTests.cs

This file was deleted.

177 changes: 177 additions & 0 deletions Source/StrongGrid.UnitTests/Utilities/SendGridRetryStrategyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using Moq;
using Shouldly;
using StrongGrid.Utilities;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Xunit;

namespace StrongGrid.UnitTests
{
public class SendGridRetryStrategyTests
{
[Fact]
public void ShouldRetry_returns_false_when_attempts_equal_max()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = (HttpResponseMessage)null;

// Act
var result = sendGridRetryStrategy.ShouldRetry(maxAttempts, response);

// Assert
result.ShouldBeFalse();
}

[Fact]
public void ShouldRetry_returns_false_when_attempts_exceed_max()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = (HttpResponseMessage)null;

// Act
var result = sendGridRetryStrategy.ShouldRetry(maxAttempts + 1, response);

// Assert
result.ShouldBeFalse();
}

[Fact]
public void ShouldRetry_returns_false_when_previous_response_is_null()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = (HttpResponseMessage)null;

// Act
var result = sendGridRetryStrategy.ShouldRetry(1, response);

// Assert
result.ShouldBeFalse();
}

[Fact]
public void ShouldRetry_returns_true_when_statuscode_429()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = new HttpResponseMessage((HttpStatusCode)429);

// Act
var result = sendGridRetryStrategy.ShouldRetry(1, response);

// Assert
result.ShouldBeTrue();
}

[Fact]
public void ShouldRetry_returns_false_when_statuscode_not_429()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = new HttpResponseMessage(HttpStatusCode.BadGateway);

// Act
var result = sendGridRetryStrategy.ShouldRetry(1, response);

// Assert
result.ShouldBeFalse();
}

[Fact]
public void GetNextDelay_with_null_HttpHeaders()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = (HttpResponseMessage)null;

// Act
var result = sendGridRetryStrategy.GetNextDelay(1, response);

// Assert
result.ShouldBe(TimeSpan.FromSeconds(1));
}

[Fact]
public void CalculateDelay_without_XRateLimitReset()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = new HttpResponseMessage((HttpStatusCode)428);

// Act
var result = sendGridRetryStrategy.GetNextDelay(1, response);

// Assert
result.ShouldBe(TimeSpan.FromSeconds(1));
}

[Fact]
public void CalculateDelay_with_too_small_XRateLimitReset()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = new HttpResponseMessage((HttpStatusCode)428);
response.Headers.Add("X-RateLimit-Reset", "-1");

// Act
var result = sendGridRetryStrategy.GetNextDelay(1, response);

// Assert
result.ShouldBe(TimeSpan.FromSeconds(1));
}

[Fact]
public void CalculateDelay_with_reasonable_XRateLimitReset()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = new HttpResponseMessage((HttpStatusCode)428);
response.Headers.Add("X-RateLimit-Reset", mockSystemClock.Object.UtcNow.AddSeconds(3).ToUnixTime().ToString());

// Act
var result = sendGridRetryStrategy.GetNextDelay(1, response);

// Assert
result.ShouldBe(TimeSpan.FromSeconds(3));
}

[Fact]
public void CalculateDelay_with_too_large_XRateLimitReset()
{
// Arrange
var maxAttempts = 5;
var mockSystemClock = new MockSystemClock(2016, 11, 11, 13, 14, 0, 0);
var sendGridRetryStrategy = new SendGridRetryStrategy(maxAttempts, mockSystemClock.Object);
var response = new HttpResponseMessage((HttpStatusCode)428);
response.Headers.Add("X-RateLimit-Reset", mockSystemClock.Object.UtcNow.AddHours(1).ToUnixTime().ToString());

// Act
var result = sendGridRetryStrategy.GetNextDelay(1, response);

// Assert
result.ShouldBe(TimeSpan.FromSeconds(5));
}
}
}
Loading

0 comments on commit 38185c3

Please sign in to comment.