Spotify.NET/SpotifyAPI.Web.Tests/RetryHandlers/SimpleRetryHandlerTest.cs

194 lines
6.1 KiB
C#
Raw Normal View History

2020-05-12 16:53:17 +01:00
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
2020-05-12 16:53:17 +01:00
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using SpotifyAPI.Web.Http;
namespace SpotifyAPI.Web
{
[TestFixture]
public class SimpleRetryHandlerTest
{
[Test]
public void HandleRetry_WorksWithLowerCaseHeader()
{
var setup = new Setup();
setup.Response.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.TooManyRequests);
setup.Response.SetupGet(r => r.Headers).Returns(new Dictionary<string, string> {
{ "retry-after", "50" }
});
var retryCalled = 0;
setup.Retry = (IRequest request, CancellationToken ct) =>
{
retryCalled++;
return Task.FromResult(setup.Response.Object);
};
var handler = new SimpleRetryHandler(setup.Sleep.Object)
{
TooManyRequestsConsumesARetry = true,
RetryTimes = 1
};
Assert.DoesNotThrowAsync(async () =>
{
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
});
Assert.AreEqual(1, retryCalled);
}
2020-05-12 16:53:17 +01:00
[Test]
public async Task HandleRetry_TooManyRequestsWithNoSuccess()
{
2020-05-12 18:57:29 +01:00
var setup = new Setup();
setup.Response.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.TooManyRequests);
setup.Response.SetupGet(r => r.Headers).Returns(new Dictionary<string, string> {
2020-05-12 16:53:17 +01:00
{ "Retry-After", "50" }
});
var retryCalled = 0;
setup.Retry = (IRequest request, CancellationToken ct) =>
2020-05-12 16:53:17 +01:00
{
retryCalled++;
2020-05-12 18:57:29 +01:00
return Task.FromResult(setup.Response.Object);
};
2020-05-12 16:53:17 +01:00
2020-05-12 18:57:29 +01:00
var handler = new SimpleRetryHandler(setup.Sleep.Object)
2020-05-12 16:53:17 +01:00
{
TooManyRequestsConsumesARetry = true,
RetryTimes = 2
};
2020-05-12 18:57:29 +01:00
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
2020-05-12 16:53:17 +01:00
Assert.AreEqual(2, retryCalled);
2020-05-12 18:57:29 +01:00
Assert.AreEqual(setup.Response.Object, response);
2020-06-03 22:57:28 +01:00
setup.Sleep.Verify(s => s(TimeSpan.FromSeconds(50)), Times.Exactly(2));
2020-05-12 16:53:17 +01:00
}
[Test]
public async Task HandleRetry_TooManyRetriesWithSuccess()
{
2020-05-12 18:57:29 +01:00
var setup = new Setup();
setup.Response.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.TooManyRequests);
setup.Response.SetupGet(r => r.Headers).Returns(new Dictionary<string, string> {
2020-05-12 16:53:17 +01:00
{ "Retry-After", "50" }
});
2020-05-12 18:57:29 +01:00
2020-05-12 16:53:17 +01:00
var successResponse = new Mock<IResponse>();
successResponse.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.OK);
var retryCalled = 0;
setup.Retry = (request, ct) =>
2020-05-12 16:53:17 +01:00
{
retryCalled++;
return Task.FromResult(successResponse.Object);
2020-05-12 18:57:29 +01:00
};
2020-05-12 16:53:17 +01:00
2020-05-12 18:57:29 +01:00
var handler = new SimpleRetryHandler(setup.Sleep.Object)
2020-05-12 16:53:17 +01:00
{
TooManyRequestsConsumesARetry = true,
RetryTimes = 10
};
2020-05-12 18:57:29 +01:00
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
2020-05-12 16:53:17 +01:00
Assert.AreEqual(1, retryCalled);
Assert.AreEqual(successResponse.Object, response);
2020-06-03 22:57:28 +01:00
setup.Sleep.Verify(s => s(TimeSpan.FromSeconds(50)), Times.Once);
2020-05-12 16:53:17 +01:00
}
[Test]
public async Task HandleRetry_TooManyRetriesWithSuccessNoConsume()
{
2020-05-12 18:57:29 +01:00
var setup = new Setup();
setup.Response.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.TooManyRequests);
setup.Response.SetupGet(r => r.Headers).Returns(new Dictionary<string, string> {
2020-05-12 16:53:17 +01:00
{ "Retry-After", "50" }
});
var successResponse = new Mock<IResponse>();
successResponse.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.OK);
var retryCalled = 0;
setup.Retry = (IRequest request, CancellationToken ct) =>
2020-05-12 16:53:17 +01:00
{
retryCalled++;
return Task.FromResult(successResponse.Object);
2020-05-12 18:57:29 +01:00
};
2020-05-12 16:53:17 +01:00
2020-05-12 18:57:29 +01:00
var handler = new SimpleRetryHandler(setup.Sleep.Object)
2020-05-12 16:53:17 +01:00
{
TooManyRequestsConsumesARetry = false,
RetryTimes = 0
};
2020-05-12 18:57:29 +01:00
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
2020-05-12 16:53:17 +01:00
Assert.AreEqual(1, retryCalled);
Assert.AreEqual(successResponse.Object, response);
2020-06-03 22:57:28 +01:00
setup.Sleep.Verify(s => s(TimeSpan.FromSeconds(50)), Times.Once);
2020-05-12 16:53:17 +01:00
}
[Test]
public async Task HandleRetry_ServerErrors()
{
2020-05-12 18:57:29 +01:00
var setup = new Setup();
setup.Response.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.BadGateway);
2020-05-12 16:53:17 +01:00
var retryCalled = 0;
setup.Retry = (request, ct) =>
2020-05-12 16:53:17 +01:00
{
retryCalled++;
2020-05-12 18:57:29 +01:00
return Task.FromResult(setup.Response.Object);
};
2020-05-12 16:53:17 +01:00
2020-05-12 18:57:29 +01:00
var handler = new SimpleRetryHandler(setup.Sleep.Object)
2020-05-12 16:53:17 +01:00
{
TooManyRequestsConsumesARetry = true,
RetryTimes = 10,
2020-06-03 18:12:12 +01:00
RetryAfter = TimeSpan.FromMilliseconds(50)
2020-05-12 16:53:17 +01:00
};
2020-05-12 18:57:29 +01:00
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
2020-05-12 16:53:17 +01:00
Assert.AreEqual(10, retryCalled);
2020-05-12 18:57:29 +01:00
Assert.AreEqual(setup.Response.Object, response);
2020-06-03 18:12:12 +01:00
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(10));
2020-05-12 16:53:17 +01:00
}
[Test]
public async Task HandleRetry_DirectSuccess()
{
2020-05-12 18:57:29 +01:00
var setup = new Setup();
setup.Response.SetupGet(r => r.StatusCode).Returns(HttpStatusCode.OK);
2020-05-12 16:53:17 +01:00
var retryCalled = 0;
setup.Retry = (request, ct) =>
2020-05-12 16:53:17 +01:00
{
retryCalled++;
2020-05-12 18:57:29 +01:00
return Task.FromResult(setup.Response.Object);
};
2020-05-12 16:53:17 +01:00
2020-05-12 18:57:29 +01:00
var handler = new SimpleRetryHandler(setup.Sleep.Object)
2020-05-12 16:53:17 +01:00
{
TooManyRequestsConsumesARetry = true,
RetryTimes = 10,
2020-06-03 18:12:12 +01:00
RetryAfter = TimeSpan.FromMilliseconds(50)
2020-05-12 16:53:17 +01:00
};
2020-05-12 18:57:29 +01:00
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
2020-05-12 16:53:17 +01:00
Assert.AreEqual(0, retryCalled);
2020-05-12 18:57:29 +01:00
Assert.AreEqual(setup.Response.Object, response);
2020-06-03 18:12:12 +01:00
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(0));
2020-05-12 18:57:29 +01:00
}
private class Setup
{
2020-06-03 18:12:12 +01:00
public Mock<Func<TimeSpan, Task>> Sleep { get; set; } = new Mock<Func<TimeSpan, Task>>();
2020-05-12 18:57:29 +01:00
public Mock<IResponse> Response { get; set; } = new Mock<IResponse>();
public Mock<IRequest> Request { get; set; } = new Mock<IRequest>();
2020-06-03 16:44:13 +01:00
public IRetryHandler.RetryFunc Retry { get; set; }
2020-05-12 16:53:17 +01:00
}
}
}