mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 23:08:16 +08:00
Rename all ReRoute to Route to move closer to YARP +semver: breaking
This commit is contained in:
@ -1,119 +1,119 @@
|
||||
using Xunit;
|
||||
|
||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||
|
||||
namespace Ocelot.UnitTests.Authentication
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Authentication.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||
|
||||
namespace Ocelot.UnitTests.Authentication
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Authentication.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
public class AuthenticationMiddlewareTests
|
||||
{
|
||||
private AuthenticationMiddleware _middleware;
|
||||
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public AuthenticationMiddlewareTests()
|
||||
{
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_factory.Setup(x => x.CreateLogger<AuthenticationMiddleware>()).Returns(_logger.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_next_middleware_if_route_is_not_authenticated()
|
||||
{
|
||||
this.Given(x => GivenTheDownStreamRouteIs(
|
||||
new DownstreamReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build()))
|
||||
.And(x => GivenTheTestServerPipelineIsConfigured())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_next_middleware_if_route_is_using_options_method()
|
||||
{
|
||||
this.Given(x => GivenTheDownStreamRouteIs(
|
||||
new DownstreamReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Options" })
|
||||
.WithIsAuthenticated(true)
|
||||
.Build()))
|
||||
.And(x => GivenTheRequestIsUsingOptionsMethod())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_next = (context) =>
|
||||
{
|
||||
byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
|
||||
var stream = new MemoryStream(byteArray);
|
||||
_httpContext.Response.Body = stream;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
_middleware = new AuthenticationMiddleware(_next, _factory.Object);
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheTestServerPipelineIsConfigured()
|
||||
{
|
||||
_next = (context) =>
|
||||
{
|
||||
byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
|
||||
var stream = new MemoryStream(byteArray);
|
||||
_httpContext.Response.Body = stream;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
||||
private void GivenTheRequestIsUsingOptionsMethod()
|
||||
{
|
||||
_httpContext.Request.Method = "OPTIONS";
|
||||
}
|
||||
|
||||
private void ThenTheUserIsAuthenticated()
|
||||
{
|
||||
var content = _httpContext.Response.Body.AsString();
|
||||
content.ShouldBe("The user is authenticated");
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamReRoute downstreamRoute)
|
||||
public class AuthenticationMiddlewareTests
|
||||
{
|
||||
private AuthenticationMiddleware _middleware;
|
||||
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public AuthenticationMiddlewareTests()
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StreamExtensions
|
||||
{
|
||||
public static string AsString(this Stream stream)
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
string text = reader.ReadToEnd();
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_factory.Setup(x => x.CreateLogger<AuthenticationMiddleware>()).Returns(_logger.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_next_middleware_if_route_is_not_authenticated()
|
||||
{
|
||||
this.Given(x => GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build()))
|
||||
.And(x => GivenTheTestServerPipelineIsConfigured())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_next_middleware_if_route_is_using_options_method()
|
||||
{
|
||||
this.Given(x => GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Options" })
|
||||
.WithIsAuthenticated(true)
|
||||
.Build()))
|
||||
.And(x => GivenTheRequestIsUsingOptionsMethod())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_next = (context) =>
|
||||
{
|
||||
byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
|
||||
var stream = new MemoryStream(byteArray);
|
||||
_httpContext.Response.Body = stream;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
_middleware = new AuthenticationMiddleware(_next, _factory.Object);
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheTestServerPipelineIsConfigured()
|
||||
{
|
||||
_next = (context) =>
|
||||
{
|
||||
byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
|
||||
var stream = new MemoryStream(byteArray);
|
||||
_httpContext.Response.Body = stream;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
||||
private void GivenTheRequestIsUsingOptionsMethod()
|
||||
{
|
||||
_httpContext.Request.Method = "OPTIONS";
|
||||
}
|
||||
|
||||
private void ThenTheUserIsAuthenticated()
|
||||
{
|
||||
var content = _httpContext.Response.Body.AsString();
|
||||
content.ShouldBe("The user is authenticated");
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StreamExtensions
|
||||
{
|
||||
public static string AsString(this Stream stream)
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
string text = reader.ReadToEnd();
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace Ocelot.UnitTests.Authorization
|
||||
public void should_call_authorisation_service()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new List<PlaceholderNameAndValue>(),
|
||||
new DownstreamReRouteBuilder()
|
||||
new DownstreamRouteBuilder()
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().Build())
|
||||
.WithIsAuthorised(true)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -60,10 +60,10 @@ namespace Ocelot.UnitTests.Authorization
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(List<PlaceholderNameAndValue> templatePlaceholderNameAndValues, DownstreamReRoute downstreamReRoute)
|
||||
private void GivenTheDownStreamRouteIs(List<PlaceholderNameAndValue> templatePlaceholderNameAndValues, DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(templatePlaceholderNameAndValues);
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamReRoute);
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAuthServiceReturns(Response<bool> expected)
|
||||
|
@ -1,144 +1,144 @@
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
public class OutputCacheMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IOcelotCache<CachedResponse>> _cache;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private OutputCacheMiddleware _middleware;
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ICacheKeyGenerator _cacheKeyGenerator;
|
||||
private CachedResponse _response;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public OutputCacheMiddlewareTests()
|
||||
{
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_cache = new Mock<IOcelotCache<CachedResponse>>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_cacheKeyGenerator = new CacheKeyGenerator();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
_httpContext.Items.UpsertDownstreamRequest(new Ocelot.Request.Middleware.DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_returned_cached_item_when_it_is_in_cache()
|
||||
{
|
||||
var headers = new Dictionary<string, IEnumerable<string>>
|
||||
{
|
||||
{ "test", new List<string> { "test" } }
|
||||
};
|
||||
|
||||
var contentHeaders = new Dictionary<string, IEnumerable<string>>
|
||||
{
|
||||
{ "content-type", new List<string> { "application/json" } }
|
||||
};
|
||||
|
||||
var cachedResponse = new CachedResponse(HttpStatusCode.OK, headers, "", contentHeaders, "some reason");
|
||||
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_returned_cached_item_when_it_is_in_cache_expires_header()
|
||||
{
|
||||
var contentHeaders = new Dictionary<string, IEnumerable<string>>
|
||||
{
|
||||
{ "Expires", new List<string> { "-1" } }
|
||||
};
|
||||
|
||||
var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", contentHeaders, "some reason");
|
||||
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_continue_with_pipeline_and_cache_response()
|
||||
{
|
||||
this.Given(x => x.GivenResponseIsNotCached(new HttpResponseMessage()))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cache.Object, _cacheKeyGenerator);
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenThereIsACachedResponse(CachedResponse response)
|
||||
{
|
||||
_response = response;
|
||||
_cache
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(_response);
|
||||
}
|
||||
|
||||
private void GivenResponseIsNotCached(HttpResponseMessage responseMessage)
|
||||
public class OutputCacheMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IOcelotCache<CachedResponse>> _cache;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private OutputCacheMiddleware _middleware;
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ICacheKeyGenerator _cacheKeyGenerator;
|
||||
private CachedResponse _response;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public OutputCacheMiddlewareTests()
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamResponse(new DownstreamResponse(responseMessage));
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRouteIs()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithIsCached(true)
|
||||
.WithCacheOptions(new CacheOptions(100, "kanken"))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_cache = new Mock<IOcelotCache<CachedResponse>>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_cacheKeyGenerator = new CacheKeyGenerator();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
_httpContext.Items.UpsertDownstreamRequest(new Ocelot.Request.Middleware.DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_returned_cached_item_when_it_is_in_cache()
|
||||
{
|
||||
var headers = new Dictionary<string, IEnumerable<string>>
|
||||
{
|
||||
{ "test", new List<string> { "test" } }
|
||||
};
|
||||
|
||||
var contentHeaders = new Dictionary<string, IEnumerable<string>>
|
||||
{
|
||||
{ "content-type", new List<string> { "application/json" } }
|
||||
};
|
||||
|
||||
var cachedResponse = new CachedResponse(HttpStatusCode.OK, headers, "", contentHeaders, "some reason");
|
||||
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_returned_cached_item_when_it_is_in_cache_expires_header()
|
||||
{
|
||||
var contentHeaders = new Dictionary<string, IEnumerable<string>>
|
||||
{
|
||||
{ "Expires", new List<string> { "-1" } }
|
||||
};
|
||||
|
||||
var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", contentHeaders, "some reason");
|
||||
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_continue_with_pipeline_and_cache_response()
|
||||
{
|
||||
this.Given(x => x.GivenResponseIsNotCached(new HttpResponseMessage()))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cache.Object, _cacheKeyGenerator);
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenThereIsACachedResponse(CachedResponse response)
|
||||
{
|
||||
_response = response;
|
||||
_cache
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(_response);
|
||||
}
|
||||
|
||||
private void GivenResponseIsNotCached(HttpResponseMessage responseMessage)
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamResponse(new DownstreamResponse(responseMessage));
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRouteIs()
|
||||
{
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithIsCached(true)
|
||||
.WithCacheOptions(new CacheOptions(100, "kanken"))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<PlaceholderNameAndValue>(), route);
|
||||
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
}
|
||||
|
||||
private void ThenTheCacheGetIsCalledCorrectly()
|
||||
{
|
||||
_cache
|
||||
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheCacheAddIsCalledCorrectly()
|
||||
{
|
||||
_cache
|
||||
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void ThenTheCacheGetIsCalledCorrectly()
|
||||
{
|
||||
_cache
|
||||
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheCacheAddIsCalledCorrectly()
|
||||
{
|
||||
_cache
|
||||
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,18 +10,18 @@ namespace Ocelot.UnitTests.Cache
|
||||
public class RegionCreatorTests
|
||||
{
|
||||
private string _result;
|
||||
private FileReRoute _reRoute;
|
||||
private FileRoute _route;
|
||||
|
||||
[Fact]
|
||||
public void should_create_region()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
UpstreamPathTemplate = "/testdummy"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoute(reRoute))
|
||||
this.Given(_ => GivenTheRoute(route))
|
||||
.When(_ => WhenICreateTheRegion())
|
||||
.Then(_ => ThenTheRegionIs("Gettestdummy"))
|
||||
.BDDfy();
|
||||
@ -30,7 +30,7 @@ namespace Ocelot.UnitTests.Cache
|
||||
[Fact]
|
||||
public void should_use_region()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
@ -38,21 +38,21 @@ namespace Ocelot.UnitTests.Cache
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoute(reRoute))
|
||||
this.Given(_ => GivenTheRoute(route))
|
||||
.When(_ => WhenICreateTheRegion())
|
||||
.Then(_ => ThenTheRegionIs("region"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(FileReRoute reRoute)
|
||||
}
|
||||
|
||||
private void GivenTheRoute(FileRoute route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenICreateTheRegion()
|
||||
{
|
||||
{
|
||||
RegionCreator regionCreator = new RegionCreator();
|
||||
_result = regionCreator.Create(_reRoute);
|
||||
_result = regionCreator.Create(_route);
|
||||
}
|
||||
|
||||
private void ThenTheRegionIs(string expected)
|
||||
@ -60,4 +60,4 @@ namespace Ocelot.UnitTests.Cache
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@
|
||||
using Ocelot.Cache.CacheManager;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
@ -42,7 +42,7 @@
|
||||
x.WithDictionaryHandle();
|
||||
});
|
||||
_cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
|
||||
_cacheKeyGenerator = new CacheKeyGenerator();
|
||||
_cacheKeyGenerator = new CacheKeyGenerator();
|
||||
_httpContext.Items.UpsertDownstreamRequest(new Ocelot.Request.Middleware.DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
|
||||
_next = context => Task.CompletedTask;
|
||||
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager, _cacheKeyGenerator);
|
||||
@ -85,13 +85,13 @@
|
||||
|
||||
private void GivenTheDownstreamRouteIs()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithIsCached(true)
|
||||
.WithCacheOptions(new CacheOptions(100, "kanken"))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(reRoute);
|
||||
.Build();
|
||||
|
||||
_httpContext.Items.UpsertDownstreamRoute(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,91 +1,91 @@
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.UnitTests.Claims
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Claims;
|
||||
using Ocelot.Claims.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.UnitTests.Claims
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Claims;
|
||||
using Ocelot.Claims.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClaimsToClaimsMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IAddClaimsToRequest> _addHeaders;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private readonly ClaimsToClaimsMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
|
||||
public ClaimsToClaimsMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_addHeaders = new Mock<IAddClaimsToRequest>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToClaimsMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
_middleware = new ClaimsToClaimsMiddleware(_next, _loggerFactory.Object, _addHeaders.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_claims_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToClaims(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("sub", "UserType", "|", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddClaimsToRequestReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheClaimsToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClaimsToClaimsMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IAddClaimsToRequest> _addHeaders;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private readonly ClaimsToClaimsMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
|
||||
public ClaimsToClaimsMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_addHeaders = new Mock<IAddClaimsToRequest>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToClaimsMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
_middleware = new ClaimsToClaimsMiddleware(_next, _loggerFactory.Object, _addHeaders.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_claims_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToClaims(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("sub", "UserType", "|", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddClaimsToRequestReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheClaimsToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
}
|
||||
|
||||
private void GivenTheAddClaimsToRequestReturns()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheClaimsToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeaders
|
||||
.Verify(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void GivenTheAddClaimsToRequestReturns()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheClaimsToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeaders
|
||||
.Verify(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,164 +1,164 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using TestStack.BDDfy;
|
||||
using Values;
|
||||
using Xunit;
|
||||
|
||||
public class AggregatesCreatorTests
|
||||
{
|
||||
private readonly AggregatesCreator _creator;
|
||||
private readonly Mock<IUpstreamTemplatePatternCreator> _utpCreator;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private List<ReRoute> _reRoutes;
|
||||
private List<ReRoute> _result;
|
||||
private UpstreamPathTemplate _aggregate1Utp;
|
||||
private UpstreamPathTemplate _aggregate2Utp;
|
||||
|
||||
public AggregatesCreatorTests()
|
||||
{
|
||||
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
|
||||
_creator = new AggregatesCreator(_utpCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_aggregates()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
ReRouteKeys = new List<string>{"key1"}
|
||||
}
|
||||
}
|
||||
};
|
||||
var reRoutes = new List<ReRoute>();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenThe(reRoutes))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => TheUtpCreatorIsNotCalled())
|
||||
.And(_ => ThenTheResultIsNotNull())
|
||||
.And(_ => ThenTheResultIsEmpty())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_aggregates()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
ReRouteKeys = new List<string>{"key1", "key2"},
|
||||
UpstreamHost = "hosty",
|
||||
UpstreamPathTemplate = "templatey",
|
||||
Aggregator = "aggregatory",
|
||||
ReRouteIsCaseSensitive = true
|
||||
},
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
ReRouteKeys = new List<string>{"key3", "key4"},
|
||||
UpstreamHost = "hosty",
|
||||
UpstreamPathTemplate = "templatey",
|
||||
Aggregator = "aggregatory",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var reRoutes = new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key1").Build()).Build(),
|
||||
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key2").Build()).Build(),
|
||||
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key3").Build()).Build(),
|
||||
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key4").Build()).Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenThe(reRoutes))
|
||||
.And(_ => GivenTheUtpCreatorReturns())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheUtpCreatorIsCalledCorrectly())
|
||||
.And(_ => ThenTheAggregatesAreCreated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheAggregatesAreCreated()
|
||||
{
|
||||
_result.ShouldNotBeNull();
|
||||
_result.Count.ShouldBe(2);
|
||||
|
||||
_result[0].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
|
||||
_result[0].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[0].UpstreamHost);
|
||||
_result[0].UpstreamTemplatePattern.ShouldBe(_aggregate1Utp);
|
||||
_result[0].Aggregator.ShouldBe(_fileConfiguration.Aggregates[0].Aggregator);
|
||||
_result[0].DownstreamReRoute.ShouldContain(x => x == _reRoutes[0].DownstreamReRoute[0]);
|
||||
_result[0].DownstreamReRoute.ShouldContain(x => x == _reRoutes[1].DownstreamReRoute[0]);
|
||||
|
||||
_result[1].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
|
||||
_result[1].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[1].UpstreamHost);
|
||||
_result[1].UpstreamTemplatePattern.ShouldBe(_aggregate2Utp);
|
||||
_result[1].Aggregator.ShouldBe(_fileConfiguration.Aggregates[1].Aggregator);
|
||||
_result[1].DownstreamReRoute.ShouldContain(x => x == _reRoutes[2].DownstreamReRoute[0]);
|
||||
_result[1].DownstreamReRoute.ShouldContain(x => x == _reRoutes[3].DownstreamReRoute[0]);
|
||||
}
|
||||
|
||||
private void ThenTheUtpCreatorIsCalledCorrectly()
|
||||
{
|
||||
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[0]), Times.Once);
|
||||
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[1]), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheUtpCreatorReturns()
|
||||
{
|
||||
_aggregate1Utp = new UpstreamPathTemplateBuilder().Build();
|
||||
_aggregate2Utp = new UpstreamPathTemplateBuilder().Build();
|
||||
|
||||
_utpCreator.SetupSequence(x => x.Create(It.IsAny<IReRoute>()))
|
||||
.Returns(_aggregate1Utp)
|
||||
.Returns(_aggregate2Utp);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsEmpty()
|
||||
{
|
||||
_result.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsNotNull()
|
||||
{
|
||||
_result.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void TheUtpCreatorIsNotCalled()
|
||||
{
|
||||
_utpCreator.Verify(x => x.Create(It.IsAny<FileAggregateReRoute>()), Times.Never);
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void GivenThe(List<ReRoute> reRoutes)
|
||||
{
|
||||
_reRoutes = reRoutes;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileConfiguration, _reRoutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using TestStack.BDDfy;
|
||||
using Values;
|
||||
using Xunit;
|
||||
|
||||
public class AggregatesCreatorTests
|
||||
{
|
||||
private readonly AggregatesCreator _creator;
|
||||
private readonly Mock<IUpstreamTemplatePatternCreator> _utpCreator;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private List<Route> _routes;
|
||||
private List<Route> _result;
|
||||
private UpstreamPathTemplate _aggregate1Utp;
|
||||
private UpstreamPathTemplate _aggregate2Utp;
|
||||
|
||||
public AggregatesCreatorTests()
|
||||
{
|
||||
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
|
||||
_creator = new AggregatesCreator(_utpCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_aggregates()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
Aggregates = new List<FileAggregateRoute>
|
||||
{
|
||||
new FileAggregateRoute
|
||||
{
|
||||
RouteKeys = new List<string>{"key1"}
|
||||
}
|
||||
}
|
||||
};
|
||||
var routes = new List<Route>();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenThe(routes))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => TheUtpCreatorIsNotCalled())
|
||||
.And(_ => ThenTheResultIsNotNull())
|
||||
.And(_ => ThenTheResultIsEmpty())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_aggregates()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
Aggregates = new List<FileAggregateRoute>
|
||||
{
|
||||
new FileAggregateRoute
|
||||
{
|
||||
RouteKeys = new List<string>{"key1", "key2"},
|
||||
UpstreamHost = "hosty",
|
||||
UpstreamPathTemplate = "templatey",
|
||||
Aggregator = "aggregatory",
|
||||
RouteIsCaseSensitive = true
|
||||
},
|
||||
new FileAggregateRoute
|
||||
{
|
||||
RouteKeys = new List<string>{"key3", "key4"},
|
||||
UpstreamHost = "hosty",
|
||||
UpstreamPathTemplate = "templatey",
|
||||
Aggregator = "aggregatory",
|
||||
RouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var routes = new List<Route>
|
||||
{
|
||||
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key1").Build()).Build(),
|
||||
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key2").Build()).Build(),
|
||||
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key3").Build()).Build(),
|
||||
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key4").Build()).Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenThe(routes))
|
||||
.And(_ => GivenTheUtpCreatorReturns())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheUtpCreatorIsCalledCorrectly())
|
||||
.And(_ => ThenTheAggregatesAreCreated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheAggregatesAreCreated()
|
||||
{
|
||||
_result.ShouldNotBeNull();
|
||||
_result.Count.ShouldBe(2);
|
||||
|
||||
_result[0].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
|
||||
_result[0].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[0].UpstreamHost);
|
||||
_result[0].UpstreamTemplatePattern.ShouldBe(_aggregate1Utp);
|
||||
_result[0].Aggregator.ShouldBe(_fileConfiguration.Aggregates[0].Aggregator);
|
||||
_result[0].DownstreamRoute.ShouldContain(x => x == _routes[0].DownstreamRoute[0]);
|
||||
_result[0].DownstreamRoute.ShouldContain(x => x == _routes[1].DownstreamRoute[0]);
|
||||
|
||||
_result[1].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
|
||||
_result[1].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[1].UpstreamHost);
|
||||
_result[1].UpstreamTemplatePattern.ShouldBe(_aggregate2Utp);
|
||||
_result[1].Aggregator.ShouldBe(_fileConfiguration.Aggregates[1].Aggregator);
|
||||
_result[1].DownstreamRoute.ShouldContain(x => x == _routes[2].DownstreamRoute[0]);
|
||||
_result[1].DownstreamRoute.ShouldContain(x => x == _routes[3].DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void ThenTheUtpCreatorIsCalledCorrectly()
|
||||
{
|
||||
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[0]), Times.Once);
|
||||
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[1]), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheUtpCreatorReturns()
|
||||
{
|
||||
_aggregate1Utp = new UpstreamPathTemplateBuilder().Build();
|
||||
_aggregate2Utp = new UpstreamPathTemplateBuilder().Build();
|
||||
|
||||
_utpCreator.SetupSequence(x => x.Create(It.IsAny<IRoute>()))
|
||||
.Returns(_aggregate1Utp)
|
||||
.Returns(_aggregate2Utp);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsEmpty()
|
||||
{
|
||||
_result.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsNotNull()
|
||||
{
|
||||
_result.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void TheUtpCreatorIsNotCalled()
|
||||
{
|
||||
_utpCreator.Verify(x => x.Create(It.IsAny<FileAggregateRoute>()), Times.Never);
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void GivenThe(List<Route> routes)
|
||||
{
|
||||
_routes = routes;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileConfiguration, _routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +1,62 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class AuthenticationOptionsCreatorTests
|
||||
{
|
||||
private readonly AuthenticationOptionsCreator _authOptionsCreator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private AuthenticationOptions _result;
|
||||
|
||||
public AuthenticationOptionsCreatorTests()
|
||||
{
|
||||
_authOptionsCreator = new AuthenticationOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_auth_options()
|
||||
{
|
||||
var fileReRoute = new FileReRoute()
|
||||
{
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string> { "cheese" },
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new AuthenticationOptionsBuilder()
|
||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||
.WithAuthenticationProviderKey("Test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
||||
.Then(x => x.ThenTheFollowingConfigIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheAuthenticationOptions()
|
||||
{
|
||||
_result = _authOptionsCreator.Create(_fileReRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingConfigIsReturned(AuthenticationOptions expected)
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class AuthenticationOptionsCreatorTests
|
||||
{
|
||||
private readonly AuthenticationOptionsCreator _authOptionsCreator;
|
||||
private FileRoute _fileRoute;
|
||||
private AuthenticationOptions _result;
|
||||
|
||||
public AuthenticationOptionsCreatorTests()
|
||||
{
|
||||
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||
_result.AuthenticationProviderKey.ShouldBe(expected.AuthenticationProviderKey);
|
||||
}
|
||||
}
|
||||
_authOptionsCreator = new AuthenticationOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_auth_options()
|
||||
{
|
||||
var fileRoute = new FileRoute()
|
||||
{
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string> { "cheese" },
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new AuthenticationOptionsBuilder()
|
||||
.WithAllowedScopes(fileRoute.AuthenticationOptions?.AllowedScopes)
|
||||
.WithAuthenticationProviderKey("Test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(fileRoute))
|
||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
||||
.Then(x => x.ThenTheFollowingConfigIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileRoute fileRoute)
|
||||
{
|
||||
_fileRoute = fileRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheAuthenticationOptions()
|
||||
{
|
||||
_result = _authOptionsCreator.Create(_fileRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingConfigIsReturned(AuthenticationOptions expected)
|
||||
{
|
||||
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||
_result.AuthenticationProviderKey.ShouldBe(expected.AuthenticationProviderKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,126 +1,126 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ConfigurationCreatorTests
|
||||
{
|
||||
private ConfigurationCreator _creator;
|
||||
private InternalConfiguration _result;
|
||||
private readonly Mock<IServiceProviderConfigurationCreator> _spcCreator;
|
||||
private readonly Mock<IQoSOptionsCreator> _qosCreator;
|
||||
private readonly Mock<IHttpHandlerOptionsCreator> _hhoCreator;
|
||||
private readonly Mock<ILoadBalancerOptionsCreator> _lboCreator;
|
||||
private readonly Mock<IVersionCreator> _vCreator;
|
||||
private FileConfiguration _fileConfig;
|
||||
private List<ReRoute> _reRoutes;
|
||||
private ServiceProviderConfiguration _spc;
|
||||
private LoadBalancerOptions _lbo;
|
||||
private QoSOptions _qoso;
|
||||
private HttpHandlerOptions _hho;
|
||||
private AdministrationPath _adminPath;
|
||||
private readonly ServiceCollection _serviceCollection;
|
||||
|
||||
public ConfigurationCreatorTests()
|
||||
{
|
||||
_vCreator = new Mock<IVersionCreator>();
|
||||
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
|
||||
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
|
||||
_qosCreator = new Mock<IQoSOptionsCreator>();
|
||||
_spcCreator = new Mock<IServiceProviderConfigurationCreator>();
|
||||
_serviceCollection = new ServiceCollection();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_configuration_with_no_admin_path()
|
||||
{
|
||||
this.Given(_ => GivenTheDependenciesAreSetUp())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
|
||||
.And(_ => ThenThePropertiesAreSetCorrectly())
|
||||
.And(_ => ThenTheAdminPathIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_configuration_with_admin_path()
|
||||
{
|
||||
this.Given(_ => GivenTheDependenciesAreSetUp())
|
||||
.And(_ => GivenTheAdminPath())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
|
||||
.And(_ => ThenThePropertiesAreSetCorrectly())
|
||||
.And(_ => ThenTheAdminPathIsSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheAdminPathIsNull()
|
||||
{
|
||||
_result.AdministrationPath.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenThePropertiesAreSetCorrectly()
|
||||
{
|
||||
_result.ShouldNotBeNull();
|
||||
_result.ServiceProviderConfiguration.ShouldBe(_spc);
|
||||
_result.LoadBalancerOptions.ShouldBe(_lbo);
|
||||
_result.QoSOptions.ShouldBe(_qoso);
|
||||
_result.HttpHandlerOptions.ShouldBe(_hho);
|
||||
_result.ReRoutes.ShouldBe(_reRoutes);
|
||||
_result.RequestId.ShouldBe(_fileConfig.GlobalConfiguration.RequestIdKey);
|
||||
_result.DownstreamScheme.ShouldBe(_fileConfig.GlobalConfiguration.DownstreamScheme);
|
||||
}
|
||||
|
||||
private void ThenTheAdminPathIsSet()
|
||||
{
|
||||
_result.AdministrationPath.ShouldBe("wooty");
|
||||
}
|
||||
|
||||
private void ThenTheDepdenciesAreCalledCorrectly()
|
||||
{
|
||||
_spcCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration), Times.Once);
|
||||
_lboCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.LoadBalancerOptions), Times.Once);
|
||||
_qosCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.QoSOptions), Times.Once);
|
||||
_hhoCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.HttpHandlerOptions), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheAdminPath()
|
||||
{
|
||||
_adminPath = new AdministrationPath("wooty");
|
||||
_serviceCollection.AddSingleton<IAdministrationPath>(_adminPath);
|
||||
}
|
||||
|
||||
private void GivenTheDependenciesAreSetUp()
|
||||
{
|
||||
_fileConfig = new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = new FileGlobalConfiguration()
|
||||
};
|
||||
_reRoutes = new List<ReRoute>();
|
||||
_spc = new ServiceProviderConfiguration("", "", "", 1, "", "", 1);
|
||||
_lbo = new LoadBalancerOptionsBuilder().Build();
|
||||
_qoso = new QoSOptions(1, 1, 1, "");
|
||||
_hho = new HttpHandlerOptionsBuilder().Build();
|
||||
|
||||
_spcCreator.Setup(x => x.Create(It.IsAny<FileGlobalConfiguration>())).Returns(_spc);
|
||||
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
|
||||
_qosCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>())).Returns(_qoso);
|
||||
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
var serviceProvider = _serviceCollection.BuildServiceProvider();
|
||||
_creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object, _vCreator.Object);
|
||||
_result = _creator.Create(_fileConfig, _reRoutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ConfigurationCreatorTests
|
||||
{
|
||||
private ConfigurationCreator _creator;
|
||||
private InternalConfiguration _result;
|
||||
private readonly Mock<IServiceProviderConfigurationCreator> _spcCreator;
|
||||
private readonly Mock<IQoSOptionsCreator> _qosCreator;
|
||||
private readonly Mock<IHttpHandlerOptionsCreator> _hhoCreator;
|
||||
private readonly Mock<ILoadBalancerOptionsCreator> _lboCreator;
|
||||
private readonly Mock<IVersionCreator> _vCreator;
|
||||
private FileConfiguration _fileConfig;
|
||||
private List<Route> _routes;
|
||||
private ServiceProviderConfiguration _spc;
|
||||
private LoadBalancerOptions _lbo;
|
||||
private QoSOptions _qoso;
|
||||
private HttpHandlerOptions _hho;
|
||||
private AdministrationPath _adminPath;
|
||||
private readonly ServiceCollection _serviceCollection;
|
||||
|
||||
public ConfigurationCreatorTests()
|
||||
{
|
||||
_vCreator = new Mock<IVersionCreator>();
|
||||
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
|
||||
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
|
||||
_qosCreator = new Mock<IQoSOptionsCreator>();
|
||||
_spcCreator = new Mock<IServiceProviderConfigurationCreator>();
|
||||
_serviceCollection = new ServiceCollection();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_configuration_with_no_admin_path()
|
||||
{
|
||||
this.Given(_ => GivenTheDependenciesAreSetUp())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
|
||||
.And(_ => ThenThePropertiesAreSetCorrectly())
|
||||
.And(_ => ThenTheAdminPathIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_configuration_with_admin_path()
|
||||
{
|
||||
this.Given(_ => GivenTheDependenciesAreSetUp())
|
||||
.And(_ => GivenTheAdminPath())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
|
||||
.And(_ => ThenThePropertiesAreSetCorrectly())
|
||||
.And(_ => ThenTheAdminPathIsSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheAdminPathIsNull()
|
||||
{
|
||||
_result.AdministrationPath.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenThePropertiesAreSetCorrectly()
|
||||
{
|
||||
_result.ShouldNotBeNull();
|
||||
_result.ServiceProviderConfiguration.ShouldBe(_spc);
|
||||
_result.LoadBalancerOptions.ShouldBe(_lbo);
|
||||
_result.QoSOptions.ShouldBe(_qoso);
|
||||
_result.HttpHandlerOptions.ShouldBe(_hho);
|
||||
_result.Routes.ShouldBe(_routes);
|
||||
_result.RequestId.ShouldBe(_fileConfig.GlobalConfiguration.RequestIdKey);
|
||||
_result.DownstreamScheme.ShouldBe(_fileConfig.GlobalConfiguration.DownstreamScheme);
|
||||
}
|
||||
|
||||
private void ThenTheAdminPathIsSet()
|
||||
{
|
||||
_result.AdministrationPath.ShouldBe("wooty");
|
||||
}
|
||||
|
||||
private void ThenTheDepdenciesAreCalledCorrectly()
|
||||
{
|
||||
_spcCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration), Times.Once);
|
||||
_lboCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.LoadBalancerOptions), Times.Once);
|
||||
_qosCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.QoSOptions), Times.Once);
|
||||
_hhoCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.HttpHandlerOptions), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheAdminPath()
|
||||
{
|
||||
_adminPath = new AdministrationPath("wooty");
|
||||
_serviceCollection.AddSingleton<IAdministrationPath>(_adminPath);
|
||||
}
|
||||
|
||||
private void GivenTheDependenciesAreSetUp()
|
||||
{
|
||||
_fileConfig = new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = new FileGlobalConfiguration()
|
||||
};
|
||||
_routes = new List<Route>();
|
||||
_spc = new ServiceProviderConfiguration("", "", "", 1, "", "", 1);
|
||||
_lbo = new LoadBalancerOptionsBuilder().Build();
|
||||
_qoso = new QoSOptions(1, 1, 1, "");
|
||||
_hho = new HttpHandlerOptionsBuilder().Build();
|
||||
|
||||
_spcCreator.Setup(x => x.Create(It.IsAny<FileGlobalConfiguration>())).Returns(_spc);
|
||||
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
|
||||
_qosCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>())).Returns(_qoso);
|
||||
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
var serviceProvider = _serviceCollection.BuildServiceProvider();
|
||||
_creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object, _vCreator.Object);
|
||||
_result = _creator.Create(_fileConfig, _routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,302 +1,302 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Ocelot.Configuration.ChangeTracking;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DiskFileConfigurationRepositoryTests : IDisposable
|
||||
{
|
||||
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
|
||||
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
|
||||
private IFileConfigurationRepository _repo;
|
||||
private string _environmentSpecificPath;
|
||||
private string _ocelotJsonPath;
|
||||
private FileConfiguration _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
|
||||
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
|
||||
// cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
|
||||
// these are not really unit tests but whatever...
|
||||
private string _environmentName = "DEV.DEV";
|
||||
|
||||
private static SemaphoreSlim _semaphore;
|
||||
|
||||
public DiskFileConfigurationRepositoryTests()
|
||||
{
|
||||
_semaphore = new SemaphoreSlim(1, 1);
|
||||
_semaphore.Wait();
|
||||
_hostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
|
||||
_changeTokenSource.Setup(m => m.Activate());
|
||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenIGetTheReRoutes())
|
||||
.Then(_ => ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenIGetTheReRoutes())
|
||||
.Then(_ => ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||
.And(x => AndTheChangeTokenIsActivated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenTheEnvironmentNameIsUnavailable())
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_environment_file_configuration_and_ocelot_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.And(_ => GivenTheUserAddedOcelotJson())
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||
.Then(_ => ThenTheOcelotJsonIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheUserAddedOcelotJson()
|
||||
{
|
||||
_ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
|
||||
|
||||
if (File.Exists(_ocelotJsonPath))
|
||||
{
|
||||
File.Delete(_ocelotJsonPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
|
||||
}
|
||||
|
||||
private void GivenTheEnvironmentNameIsUnavailable()
|
||||
{
|
||||
_environmentName = null;
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
|
||||
}
|
||||
|
||||
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void WhenISetTheConfiguration()
|
||||
{
|
||||
_repo.Set(_fileConfiguration);
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for (var i = 0; i < _result.ReRoutes.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
|
||||
{
|
||||
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
|
||||
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
|
||||
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
|
||||
{
|
||||
var resultText = File.ReadAllText(_ocelotJsonPath);
|
||||
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||
resultText.ShouldBe(expectedText);
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||
|
||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||
|
||||
if (File.Exists(_environmentSpecificPath))
|
||||
{
|
||||
File.Delete(_environmentSpecificPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
|
||||
{
|
||||
var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||
|
||||
var resultText = File.ReadAllText(path);
|
||||
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||
resultText.ShouldBe(expectedText);
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRoutes()
|
||||
{
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(FileConfiguration expecteds)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for (var i = 0; i < _result.ReRoutes.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
|
||||
{
|
||||
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
|
||||
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
|
||||
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void AndTheChangeTokenIsActivated()
|
||||
{
|
||||
_changeTokenSource.Verify(m => m.Activate(), Times.Once);
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForSet()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "123.12.12.12",
|
||||
Port = 80,
|
||||
},
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/asdfs/test/{test}",
|
||||
},
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForGet()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 80,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/test/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Ocelot.Configuration.ChangeTracking;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DiskFileConfigurationRepositoryTests : IDisposable
|
||||
{
|
||||
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
|
||||
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
|
||||
private IFileConfigurationRepository _repo;
|
||||
private string _environmentSpecificPath;
|
||||
private string _ocelotJsonPath;
|
||||
private FileConfiguration _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
|
||||
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
|
||||
// cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
|
||||
// these are not really unit tests but whatever...
|
||||
private string _environmentName = "DEV.DEV";
|
||||
|
||||
private static SemaphoreSlim _semaphore;
|
||||
|
||||
public DiskFileConfigurationRepositoryTests()
|
||||
{
|
||||
_semaphore = new SemaphoreSlim(1, 1);
|
||||
_semaphore.Wait();
|
||||
_hostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
|
||||
_changeTokenSource.Setup(m => m.Activate());
|
||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenIGetTheRoutes())
|
||||
.Then(_ => ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenIGetTheRoutes())
|
||||
.Then(_ => ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||
.And(x => AndTheChangeTokenIsActivated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenTheEnvironmentNameIsUnavailable())
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_environment_file_configuration_and_ocelot_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.And(_ => GivenTheUserAddedOcelotJson())
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||
.Then(_ => ThenTheOcelotJsonIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheUserAddedOcelotJson()
|
||||
{
|
||||
_ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
|
||||
|
||||
if (File.Exists(_ocelotJsonPath))
|
||||
{
|
||||
File.Delete(_ocelotJsonPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
|
||||
}
|
||||
|
||||
private void GivenTheEnvironmentNameIsUnavailable()
|
||||
{
|
||||
_environmentName = null;
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
|
||||
}
|
||||
|
||||
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void WhenISetTheConfiguration()
|
||||
{
|
||||
_repo.Set(_fileConfiguration);
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for (var i = 0; i < _result.Routes.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < _result.Routes[i].DownstreamHostAndPorts.Count; j++)
|
||||
{
|
||||
var result = _result.Routes[i].DownstreamHostAndPorts[j];
|
||||
var expected = expecteds.Routes[i].DownstreamHostAndPorts[j];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
|
||||
_result.Routes[i].DownstreamPathTemplate.ShouldBe(expecteds.Routes[i].DownstreamPathTemplate);
|
||||
_result.Routes[i].DownstreamScheme.ShouldBe(expecteds.Routes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
|
||||
{
|
||||
var resultText = File.ReadAllText(_ocelotJsonPath);
|
||||
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||
resultText.ShouldBe(expectedText);
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||
|
||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||
|
||||
if (File.Exists(_environmentSpecificPath))
|
||||
{
|
||||
File.Delete(_environmentSpecificPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
|
||||
{
|
||||
var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||
|
||||
var resultText = File.ReadAllText(path);
|
||||
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||
resultText.ShouldBe(expectedText);
|
||||
}
|
||||
|
||||
private void WhenIGetTheRoutes()
|
||||
{
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(FileConfiguration expecteds)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for (var i = 0; i < _result.Routes.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < _result.Routes[i].DownstreamHostAndPorts.Count; j++)
|
||||
{
|
||||
var result = _result.Routes[i].DownstreamHostAndPorts[j];
|
||||
var expected = expecteds.Routes[i].DownstreamHostAndPorts[j];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
|
||||
_result.Routes[i].DownstreamPathTemplate.ShouldBe(expecteds.Routes[i].DownstreamPathTemplate);
|
||||
_result.Routes[i].DownstreamScheme.ShouldBe(expecteds.Routes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void AndTheChangeTokenIsActivated()
|
||||
{
|
||||
_changeTokenSource.Verify(m => m.Activate(), Times.Once);
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForSet()
|
||||
{
|
||||
var routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "123.12.12.12",
|
||||
Port = 80,
|
||||
},
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/asdfs/test/{test}",
|
||||
},
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
Routes = routes
|
||||
};
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForGet()
|
||||
{
|
||||
var routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 80,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/test/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
Routes = routes
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,121 +1,121 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class DownstreamAddressesCreatorTests
|
||||
{
|
||||
public DownstreamAddressesCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private List<DownstreamHostAndPort> _result;
|
||||
|
||||
public DownstreamAddressesCreatorTests()
|
||||
{
|
||||
_creator = new DownstreamAddressesCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_do_nothing()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_addresses_from_old_downstream_path_and_port()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test",
|
||||
Port = 80
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
new DownstreamHostAndPort("test", 80),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_addresses_from_downstream_host_and_ports()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test",
|
||||
Port = 80
|
||||
},
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "west",
|
||||
Port = 443
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
new DownstreamHostAndPort("test", 80),
|
||||
new DownstreamHostAndPort("west", 443)
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamAddressesCreatorTests
|
||||
{
|
||||
public DownstreamAddressesCreator _creator;
|
||||
private FileRoute _route;
|
||||
private List<DownstreamHostAndPort> _result;
|
||||
|
||||
public DownstreamAddressesCreatorTests()
|
||||
{
|
||||
_creator = new DownstreamAddressesCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_do_nothing()
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void TheThenFollowingIsReturned(List<DownstreamHostAndPort> expecteds)
|
||||
{
|
||||
_result.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
for (int i = 0; i < _result.Count; i++)
|
||||
{
|
||||
var result = _result[i];
|
||||
var expected = expecteds[i];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingRoute(route))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_addresses_from_old_downstream_path_and_port()
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test",
|
||||
Port = 80
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
new DownstreamHostAndPort("test", 80),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingRoute(route))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_addresses_from_downstream_host_and_ports()
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test",
|
||||
Port = 80
|
||||
},
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "west",
|
||||
Port = 443
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
new DownstreamHostAndPort("test", 80),
|
||||
new DownstreamHostAndPort("west", 443)
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingRoute(route))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingRoute(FileRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_route);
|
||||
}
|
||||
|
||||
private void TheThenFollowingIsReturned(List<DownstreamHostAndPort> expecteds)
|
||||
{
|
||||
_result.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
for (int i = 0; i < _result.Count; i++)
|
||||
{
|
||||
var result = _result[i];
|
||||
var expected = expecteds[i];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,148 +1,148 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using System;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DynamicsCreatorTests
|
||||
{
|
||||
private readonly DynamicsCreator _creator;
|
||||
private readonly Mock<IRateLimitOptionsCreator> _rloCreator;
|
||||
private readonly Mock<IVersionCreator> _versionCreator;
|
||||
private List<ReRoute> _result;
|
||||
private FileConfiguration _fileConfig;
|
||||
private RateLimitOptions _rlo1;
|
||||
private RateLimitOptions _rlo2;
|
||||
private Version _version;
|
||||
|
||||
public DynamicsCreatorTests()
|
||||
{
|
||||
_versionCreator = new Mock<IVersionCreator>();
|
||||
_rloCreator = new Mock<IRateLimitOptionsCreator>();
|
||||
_creator = new DynamicsCreator(_rloCreator.Object, _versionCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_nothing()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenNothingIsReturned())
|
||||
.And(_ => ThenTheRloCreatorIsNotCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_re_routes()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
DynamicReRoutes = new List<FileDynamicReRoute>
|
||||
{
|
||||
new FileDynamicReRoute
|
||||
{
|
||||
ServiceName = "1",
|
||||
RateLimitRule = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = false
|
||||
},
|
||||
DownstreamHttpVersion = "1.1"
|
||||
},
|
||||
new FileDynamicReRoute
|
||||
{
|
||||
ServiceName = "2",
|
||||
RateLimitRule = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
},
|
||||
DownstreamHttpVersion = "2.0"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenTheRloCreatorReturns())
|
||||
.And(_ => GivenTheVersionCreatorReturns())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheReRoutesAreReturned())
|
||||
.And(_ => ThenTheRloCreatorIsCalledCorrectly())
|
||||
.And(_ => ThenTheVersionCreatorIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheRloCreatorIsCalledCorrectly()
|
||||
{
|
||||
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[0].RateLimitRule,
|
||||
_fileConfig.GlobalConfiguration), Times.Once);
|
||||
|
||||
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[1].RateLimitRule,
|
||||
_fileConfig.GlobalConfiguration), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheVersionCreatorIsCalledCorrectly()
|
||||
{
|
||||
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[0].DownstreamHttpVersion), Times.Once);
|
||||
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[1].DownstreamHttpVersion), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheReRoutesAreReturned()
|
||||
{
|
||||
_result.Count.ShouldBe(2);
|
||||
_result[0].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeFalse();
|
||||
_result[0].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo1);
|
||||
_result[0].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_version);
|
||||
_result[0].DownstreamReRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicReRoutes[0].ServiceName);
|
||||
|
||||
_result[1].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
|
||||
_result[1].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo2);
|
||||
_result[1].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_version);
|
||||
_result[1].DownstreamReRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicReRoutes[1].ServiceName);
|
||||
}
|
||||
|
||||
private void GivenTheVersionCreatorReturns()
|
||||
{
|
||||
_version = new Version("1.1");
|
||||
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_version);
|
||||
}
|
||||
|
||||
private void GivenTheRloCreatorReturns()
|
||||
{
|
||||
_rlo1 = new RateLimitOptionsBuilder().Build();
|
||||
_rlo2 = new RateLimitOptionsBuilder().WithEnableRateLimiting(true).Build();
|
||||
|
||||
_rloCreator
|
||||
.SetupSequence(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()))
|
||||
.Returns(_rlo1)
|
||||
.Returns(_rlo2);
|
||||
}
|
||||
|
||||
private void ThenTheRloCreatorIsNotCalled()
|
||||
{
|
||||
_rloCreator.Verify(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()), Times.Never);
|
||||
}
|
||||
|
||||
private void ThenNothingIsReturned()
|
||||
{
|
||||
_result.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileConfig);
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfig)
|
||||
{
|
||||
_fileConfig = fileConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using System;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DynamicsCreatorTests
|
||||
{
|
||||
private readonly DynamicsCreator _creator;
|
||||
private readonly Mock<IRateLimitOptionsCreator> _rloCreator;
|
||||
private readonly Mock<IVersionCreator> _versionCreator;
|
||||
private List<Route> _result;
|
||||
private FileConfiguration _fileConfig;
|
||||
private RateLimitOptions _rlo1;
|
||||
private RateLimitOptions _rlo2;
|
||||
private Version _version;
|
||||
|
||||
public DynamicsCreatorTests()
|
||||
{
|
||||
_versionCreator = new Mock<IVersionCreator>();
|
||||
_rloCreator = new Mock<IRateLimitOptionsCreator>();
|
||||
_creator = new DynamicsCreator(_rloCreator.Object, _versionCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_nothing()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenNothingIsReturned())
|
||||
.And(_ => ThenTheRloCreatorIsNotCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_re_routes()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
DynamicRoutes = new List<FileDynamicRoute>
|
||||
{
|
||||
new FileDynamicRoute
|
||||
{
|
||||
ServiceName = "1",
|
||||
RateLimitRule = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = false
|
||||
},
|
||||
DownstreamHttpVersion = "1.1"
|
||||
},
|
||||
new FileDynamicRoute
|
||||
{
|
||||
ServiceName = "2",
|
||||
RateLimitRule = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
},
|
||||
DownstreamHttpVersion = "2.0"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenTheRloCreatorReturns())
|
||||
.And(_ => GivenTheVersionCreatorReturns())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheRoutesAreReturned())
|
||||
.And(_ => ThenTheRloCreatorIsCalledCorrectly())
|
||||
.And(_ => ThenTheVersionCreatorIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheRloCreatorIsCalledCorrectly()
|
||||
{
|
||||
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[0].RateLimitRule,
|
||||
_fileConfig.GlobalConfiguration), Times.Once);
|
||||
|
||||
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[1].RateLimitRule,
|
||||
_fileConfig.GlobalConfiguration), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheVersionCreatorIsCalledCorrectly()
|
||||
{
|
||||
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[0].DownstreamHttpVersion), Times.Once);
|
||||
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[1].DownstreamHttpVersion), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheRoutesAreReturned()
|
||||
{
|
||||
_result.Count.ShouldBe(2);
|
||||
_result[0].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeFalse();
|
||||
_result[0].DownstreamRoute[0].RateLimitOptions.ShouldBe(_rlo1);
|
||||
_result[0].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_version);
|
||||
_result[0].DownstreamRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicRoutes[0].ServiceName);
|
||||
|
||||
_result[1].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
|
||||
_result[1].DownstreamRoute[0].RateLimitOptions.ShouldBe(_rlo2);
|
||||
_result[1].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_version);
|
||||
_result[1].DownstreamRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicRoutes[1].ServiceName);
|
||||
}
|
||||
|
||||
private void GivenTheVersionCreatorReturns()
|
||||
{
|
||||
_version = new Version("1.1");
|
||||
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_version);
|
||||
}
|
||||
|
||||
private void GivenTheRloCreatorReturns()
|
||||
{
|
||||
_rlo1 = new RateLimitOptionsBuilder().Build();
|
||||
_rlo2 = new RateLimitOptionsBuilder().WithEnableRateLimiting(true).Build();
|
||||
|
||||
_rloCreator
|
||||
.SetupSequence(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()))
|
||||
.Returns(_rlo1)
|
||||
.Returns(_rlo2);
|
||||
}
|
||||
|
||||
private void ThenTheRloCreatorIsNotCalled()
|
||||
{
|
||||
_rloCreator.Verify(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()), Times.Never);
|
||||
}
|
||||
|
||||
private void ThenNothingIsReturned()
|
||||
{
|
||||
_result.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileConfig);
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfig)
|
||||
{
|
||||
_fileConfig = fileConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,205 +1,205 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.Responder;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using static Ocelot.Infrastructure.Wait;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationPollerTests : IDisposable
|
||||
{
|
||||
private readonly FileConfigurationPoller _poller;
|
||||
private Mock<IOcelotLoggerFactory> _factory;
|
||||
private readonly Mock<IFileConfigurationRepository> _repo;
|
||||
private readonly FileConfiguration _fileConfig;
|
||||
private Mock<IFileConfigurationPollerOptions> _config;
|
||||
private readonly Mock<IInternalConfigurationRepository> _internalConfigRepo;
|
||||
private readonly Mock<IInternalConfigurationCreator> _internalConfigCreator;
|
||||
private IInternalConfiguration _internalConfig;
|
||||
|
||||
public FileConfigurationPollerTests()
|
||||
{
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_factory.Setup(x => x.CreateLogger<FileConfigurationPoller>()).Returns(logger.Object);
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_fileConfig = new FileConfiguration();
|
||||
_config = new Mock<IFileConfigurationPollerOptions>();
|
||||
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(_fileConfig));
|
||||
_config.Setup(x => x.Delay).Returns(100);
|
||||
_internalConfigRepo = new Mock<IInternalConfigurationRepository>();
|
||||
_internalConfigCreator = new Mock<IInternalConfigurationCreator>();
|
||||
_internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig));
|
||||
_poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_start()
|
||||
{
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_setter_when_gets_new_config()
|
||||
{
|
||||
var newConfig = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => WhenTheConfigIsChanged(newConfig, 0))
|
||||
.Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_poll_if_already_polling()
|
||||
{
|
||||
var newConfig = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => WhenTheConfigIsChanged(newConfig, 10))
|
||||
.Then(x => ThenTheSetterIsCalled(newConfig, 1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_do_nothing_if_call_to_provider_fails()
|
||||
{
|
||||
var newConfig = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => WhenProviderErrors())
|
||||
.Then(x => ThenTheSetterIsCalled(newConfig, 0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_dispose_cleanly_without_starting()
|
||||
{
|
||||
this.When(x => WhenPollerIsDisposed())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenPollerHasStarted()
|
||||
{
|
||||
_poller.StartAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
private void WhenProviderErrors()
|
||||
{
|
||||
_repo
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(new ErrorResponse<FileConfiguration>(new AnyError()));
|
||||
}
|
||||
|
||||
private void WhenTheConfigIsChanged(FileConfiguration newConfig, int delay)
|
||||
{
|
||||
_repo
|
||||
.Setup(x => x.Get())
|
||||
.Callback(() => Thread.Sleep(delay))
|
||||
.ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
|
||||
}
|
||||
|
||||
private void WhenPollerIsDisposed()
|
||||
{
|
||||
_poller.Dispose();
|
||||
}
|
||||
|
||||
private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times)
|
||||
{
|
||||
var result = WaitFor(4000).Until(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.Exactly(times));
|
||||
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.Exactly(times));
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
result.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheSetterIsCalledAtLeast(FileConfiguration fileConfig, int times)
|
||||
{
|
||||
var result = WaitFor(4000).Until(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.AtLeast(times));
|
||||
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.AtLeast(times));
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
result.ShouldBeTrue();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_poller.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.Responder;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using static Ocelot.Infrastructure.Wait;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationPollerTests : IDisposable
|
||||
{
|
||||
private readonly FileConfigurationPoller _poller;
|
||||
private Mock<IOcelotLoggerFactory> _factory;
|
||||
private readonly Mock<IFileConfigurationRepository> _repo;
|
||||
private readonly FileConfiguration _fileConfig;
|
||||
private Mock<IFileConfigurationPollerOptions> _config;
|
||||
private readonly Mock<IInternalConfigurationRepository> _internalConfigRepo;
|
||||
private readonly Mock<IInternalConfigurationCreator> _internalConfigCreator;
|
||||
private IInternalConfiguration _internalConfig;
|
||||
|
||||
public FileConfigurationPollerTests()
|
||||
{
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_factory.Setup(x => x.CreateLogger<FileConfigurationPoller>()).Returns(logger.Object);
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_fileConfig = new FileConfiguration();
|
||||
_config = new Mock<IFileConfigurationPollerOptions>();
|
||||
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(_fileConfig));
|
||||
_config.Setup(x => x.Delay).Returns(100);
|
||||
_internalConfigRepo = new Mock<IInternalConfigurationRepository>();
|
||||
_internalConfigCreator = new Mock<IInternalConfigurationCreator>();
|
||||
_internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig));
|
||||
_poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_start()
|
||||
{
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_setter_when_gets_new_config()
|
||||
{
|
||||
var newConfig = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => WhenTheConfigIsChanged(newConfig, 0))
|
||||
.Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_poll_if_already_polling()
|
||||
{
|
||||
var newConfig = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => WhenTheConfigIsChanged(newConfig, 10))
|
||||
.Then(x => ThenTheSetterIsCalled(newConfig, 1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_do_nothing_if_call_to_provider_fails()
|
||||
{
|
||||
var newConfig = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenPollerHasStarted())
|
||||
.Given(x => WhenProviderErrors())
|
||||
.Then(x => ThenTheSetterIsCalled(newConfig, 0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_dispose_cleanly_without_starting()
|
||||
{
|
||||
this.When(x => WhenPollerIsDisposed())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenPollerHasStarted()
|
||||
{
|
||||
_poller.StartAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
private void WhenProviderErrors()
|
||||
{
|
||||
_repo
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(new ErrorResponse<FileConfiguration>(new AnyError()));
|
||||
}
|
||||
|
||||
private void WhenTheConfigIsChanged(FileConfiguration newConfig, int delay)
|
||||
{
|
||||
_repo
|
||||
.Setup(x => x.Get())
|
||||
.Callback(() => Thread.Sleep(delay))
|
||||
.ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
|
||||
}
|
||||
|
||||
private void WhenPollerIsDisposed()
|
||||
{
|
||||
_poller.Dispose();
|
||||
}
|
||||
|
||||
private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times)
|
||||
{
|
||||
var result = WaitFor(4000).Until(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.Exactly(times));
|
||||
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.Exactly(times));
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
result.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheSetterIsCalledAtLeast(FileConfiguration fileConfig, int times)
|
||||
{
|
||||
var result = WaitFor(4000).Until(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.AtLeast(times));
|
||||
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.AtLeast(times));
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
result.ShouldBeTrue();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_poller.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
var config = new InternalConfiguration(new List<Route>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||
|
@ -1,127 +1,127 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.Responder;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class FileInternalConfigurationCreatorTests
|
||||
{
|
||||
private readonly Mock<IConfigurationValidator> _validator;
|
||||
private readonly Mock<IReRoutesCreator> _reRoutesCreator;
|
||||
private readonly Mock<IAggregatesCreator> _aggregatesCreator;
|
||||
private readonly Mock<IDynamicsCreator> _dynamicsCreator;
|
||||
private readonly Mock<IConfigurationCreator> _configCreator;
|
||||
private Response<IInternalConfiguration> _config;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private readonly FileInternalConfigurationCreator _creator;
|
||||
private Response<IInternalConfiguration> _result;
|
||||
private List<ReRoute> _reRoutes;
|
||||
private List<ReRoute> _aggregates;
|
||||
private List<ReRoute> _dynamics;
|
||||
private InternalConfiguration _internalConfig;
|
||||
|
||||
public FileInternalConfigurationCreatorTests()
|
||||
{
|
||||
_validator = new Mock<IConfigurationValidator>();
|
||||
_reRoutesCreator = new Mock<IReRoutesCreator>();
|
||||
_aggregatesCreator = new Mock<IAggregatesCreator>();
|
||||
_dynamicsCreator = new Mock<IDynamicsCreator>();
|
||||
_configCreator = new Mock<IConfigurationCreator>();
|
||||
|
||||
_creator = new FileInternalConfigurationCreator(_validator.Object, _reRoutesCreator.Object, _aggregatesCreator.Object, _dynamicsCreator.Object, _configCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_validation_error()
|
||||
{
|
||||
var fileConfiguration = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfiguration))
|
||||
.And(_ => GivenTheValidationFails())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_internal_configuration()
|
||||
{
|
||||
var fileConfiguration = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfiguration))
|
||||
.And(_ => GivenTheValidationSucceeds())
|
||||
.And(_ => GivenTheDependenciesAreSetUp())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheDependenciesAreCalledCorrectly()
|
||||
{
|
||||
_reRoutesCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
|
||||
_aggregatesCreator.Verify(x => x.Create(_fileConfiguration, _reRoutes), Times.Once);
|
||||
_dynamicsCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
|
||||
|
||||
var mergedReRoutes = _reRoutes
|
||||
.Union(_aggregates)
|
||||
.Union(_dynamics)
|
||||
.ToList();
|
||||
|
||||
_configCreator.Verify(x => x.Create(_fileConfiguration, It.Is<List<ReRoute>>(y => y.Count == mergedReRoutes.Count)), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDependenciesAreSetUp()
|
||||
{
|
||||
_reRoutes = new List<ReRoute> { new ReRouteBuilder().Build() };
|
||||
_aggregates = new List<ReRoute> { new ReRouteBuilder().Build() };
|
||||
_dynamics = new List<ReRoute> { new ReRouteBuilder().Build() };
|
||||
_internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null, null);
|
||||
|
||||
_reRoutesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_reRoutes);
|
||||
_aggregatesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<ReRoute>>())).Returns(_aggregates);
|
||||
_dynamicsCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_dynamics);
|
||||
_configCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<ReRoute>>())).Returns(_internalConfig);
|
||||
}
|
||||
|
||||
private void GivenTheValidationSucceeds()
|
||||
{
|
||||
var ok = new ConfigurationValidationResult(false);
|
||||
var response = new OkResponse<ConfigurationValidationResult>(ok);
|
||||
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private async Task WhenICreate()
|
||||
{
|
||||
_result = await _creator.Create(_fileConfiguration);
|
||||
}
|
||||
|
||||
private void GivenTheValidationFails()
|
||||
{
|
||||
var error = new ConfigurationValidationResult(true, new List<Error> { new AnyError() });
|
||||
var response = new OkResponse<ConfigurationValidationResult>(error);
|
||||
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.Responder;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class FileInternalConfigurationCreatorTests
|
||||
{
|
||||
private readonly Mock<IConfigurationValidator> _validator;
|
||||
private readonly Mock<IRoutesCreator> _routesCreator;
|
||||
private readonly Mock<IAggregatesCreator> _aggregatesCreator;
|
||||
private readonly Mock<IDynamicsCreator> _dynamicsCreator;
|
||||
private readonly Mock<IConfigurationCreator> _configCreator;
|
||||
private Response<IInternalConfiguration> _config;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private readonly FileInternalConfigurationCreator _creator;
|
||||
private Response<IInternalConfiguration> _result;
|
||||
private List<Route> _routes;
|
||||
private List<Route> _aggregates;
|
||||
private List<Route> _dynamics;
|
||||
private InternalConfiguration _internalConfig;
|
||||
|
||||
public FileInternalConfigurationCreatorTests()
|
||||
{
|
||||
_validator = new Mock<IConfigurationValidator>();
|
||||
_routesCreator = new Mock<IRoutesCreator>();
|
||||
_aggregatesCreator = new Mock<IAggregatesCreator>();
|
||||
_dynamicsCreator = new Mock<IDynamicsCreator>();
|
||||
_configCreator = new Mock<IConfigurationCreator>();
|
||||
|
||||
_creator = new FileInternalConfigurationCreator(_validator.Object, _routesCreator.Object, _aggregatesCreator.Object, _dynamicsCreator.Object, _configCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_validation_error()
|
||||
{
|
||||
var fileConfiguration = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfiguration))
|
||||
.And(_ => GivenTheValidationFails())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_internal_configuration()
|
||||
{
|
||||
var fileConfiguration = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfiguration))
|
||||
.And(_ => GivenTheValidationSucceeds())
|
||||
.And(_ => GivenTheDependenciesAreSetUp())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheDependenciesAreCalledCorrectly()
|
||||
{
|
||||
_routesCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
|
||||
_aggregatesCreator.Verify(x => x.Create(_fileConfiguration, _routes), Times.Once);
|
||||
_dynamicsCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
|
||||
|
||||
var mergedRoutes = _routes
|
||||
.Union(_aggregates)
|
||||
.Union(_dynamics)
|
||||
.ToList();
|
||||
|
||||
_configCreator.Verify(x => x.Create(_fileConfiguration, It.Is<List<Route>>(y => y.Count == mergedRoutes.Count)), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDependenciesAreSetUp()
|
||||
{
|
||||
_routes = new List<Route> { new RouteBuilder().Build() };
|
||||
_aggregates = new List<Route> { new RouteBuilder().Build() };
|
||||
_dynamics = new List<Route> { new RouteBuilder().Build() };
|
||||
_internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null, null);
|
||||
|
||||
_routesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_routes);
|
||||
_aggregatesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<Route>>())).Returns(_aggregates);
|
||||
_dynamicsCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_dynamics);
|
||||
_configCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<Route>>())).Returns(_internalConfig);
|
||||
}
|
||||
|
||||
private void GivenTheValidationSucceeds()
|
||||
{
|
||||
var ok = new ConfigurationValidationResult(false);
|
||||
var response = new OkResponse<ConfigurationValidationResult>(ok);
|
||||
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private async Task WhenICreate()
|
||||
{
|
||||
_result = await _creator.Create(_fileConfiguration);
|
||||
}
|
||||
|
||||
private void GivenTheValidationFails()
|
||||
{
|
||||
var error = new ConfigurationValidationResult(true, new List<Error> { new AnyError() });
|
||||
var response = new OkResponse<ConfigurationValidationResult>(error);
|
||||
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
public class HeaderFindAndReplaceCreatorTests
|
||||
{
|
||||
private HeaderFindAndReplaceCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private FileRoute _route;
|
||||
private HeaderTransformations _result;
|
||||
private Mock<IPlaceholders> _placeholders;
|
||||
private Mock<IOcelotLoggerFactory> _factory;
|
||||
@ -34,13 +34,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_create()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
UpstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Test", "Test, Chicken"},
|
||||
{"Moop", "o, a"}
|
||||
},
|
||||
},
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Pop", "West, East"},
|
||||
@ -60,7 +60,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
new HeaderFindAndReplace("Bop", "e", "r", 0)
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingUpstreamIsReturned(upstream))
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
@ -71,19 +71,19 @@ namespace Ocelot.UnitTests.Configuration
|
||||
public void should_create_with_add_headers_to_request()
|
||||
{
|
||||
const string key = "X-Forwarded-For";
|
||||
const string value = "{RemoteIpAddress}";
|
||||
const string value = "{RemoteIpAddress}";
|
||||
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
UpstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{key, value},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var expected = new AddHeader(key, value);
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingAddHeaderToUpstreamIsReturned(expected))
|
||||
.BDDfy();
|
||||
@ -92,8 +92,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_use_base_url_placeholder()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Location", "http://www.bbc.co.uk/, {BaseUrl}"},
|
||||
@ -105,7 +105,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/", "http://ocelot.com/", 0),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
@ -115,7 +115,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_log_errors_and_not_add_headers()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
@ -131,7 +131,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheBaseUrlErrors())
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(expected))
|
||||
@ -149,8 +149,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_use_base_url_partial_placeholder()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Location", "http://www.bbc.co.uk/pay, {BaseUrl}pay"},
|
||||
@ -162,7 +162,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/pay", "http://ocelot.com/pay", 0),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
@ -172,8 +172,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_add_trace_id_header()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Trace-Id", "{TraceId}"},
|
||||
@ -182,7 +182,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
var expected = new AddHeader("Trace-Id", "{TraceId}");
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingAddHeaderToDownstreamIsReturned(expected))
|
||||
@ -192,7 +192,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_add_downstream_header_as_is_when_no_replacement_is_given()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
@ -202,7 +202,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
var expected = new AddHeader("X-Custom-Header", "Value");
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.And(x => WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingAddHeaderToDownstreamIsReturned(expected))
|
||||
.BDDfy();
|
||||
@ -211,7 +211,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_add_upstream_header_as_is_when_no_replacement_is_given()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
UpstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
@ -221,7 +221,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
var expected = new AddHeader("X-Custom-Header", "Value");
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
this.Given(x => GivenTheRoute(route))
|
||||
.And(x => WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingAddHeaderToUpstreamIsReturned(expected))
|
||||
.BDDfy();
|
||||
@ -241,8 +241,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
_result.AddHeadersToDownstream[0].Key.ShouldBe(addHeader.Key);
|
||||
_result.AddHeadersToDownstream[0].Value.ShouldBe(addHeader.Value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ThenTheFollowingAddHeaderToUpstreamIsReturned(AddHeader addHeader)
|
||||
{
|
||||
_result.AddHeadersToUpstream[0].Key.ShouldBe(addHeader.Key);
|
||||
@ -251,8 +251,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
private void ThenTheFollowingDownstreamIsReturned(List<HeaderFindAndReplace> downstream)
|
||||
{
|
||||
_result.Downstream.Count.ShouldBe(downstream.Count);
|
||||
|
||||
_result.Downstream.Count.ShouldBe(downstream.Count);
|
||||
|
||||
for (int i = 0; i < _result.Downstream.Count; i++)
|
||||
{
|
||||
var result = _result.Downstream[i];
|
||||
@ -261,23 +261,23 @@ namespace Ocelot.UnitTests.Configuration
|
||||
result.Index.ShouldBe(expected.Index);
|
||||
result.Key.ShouldBe(expected.Key);
|
||||
result.Replace.ShouldBe(expected.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(FileReRoute reRoute)
|
||||
private void GivenTheRoute(FileRoute route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
_result = _creator.Create(_route);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingUpstreamIsReturned(List<HeaderFindAndReplace> expecteds)
|
||||
{
|
||||
_result.Upstream.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
_result.Upstream.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
for (int i = 0; i < _result.Upstream.Count; i++)
|
||||
{
|
||||
var result = _result.Upstream[i];
|
||||
@ -289,4 +289,4 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,239 +1,239 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Logging;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class HttpHandlerOptionsCreatorTests
|
||||
{
|
||||
private IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private HttpHandlerOptions _httpHandlerOptions;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IServiceCollection _serviceCollection;
|
||||
|
||||
public HttpHandlerOptionsCreatorTests()
|
||||
{
|
||||
_serviceCollection = new ServiceCollection();
|
||||
_serviceProvider = _serviceCollection.BuildServiceProvider();
|
||||
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_use_tracing_if_fake_tracer_registered()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
UseTracing = true
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_tracing_if_real_tracer_registered()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
UseTracing = true
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.And(x => GivenARealTracer())
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_useCookie_false_and_allowAutoRedirect_true_as_default()
|
||||
{
|
||||
var fileReRoute = new FileReRoute();
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_specified_useCookie_and_allowAutoRedirect()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
AllowAutoRedirect = false,
|
||||
UseCookieContainer = false,
|
||||
UseTracing = false
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_useproxy_true_as_default()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions()
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_specified_useproxy()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
UseProxy = false
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_specified_MaxConnectionsPerServer()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
MaxConnectionsPerServer = 10
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
MaxConnectionsPerServer = -1
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range_when_zero()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
MaxConnectionsPerServer = 0
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileReRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateHttpHandlerOptions()
|
||||
{
|
||||
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileReRoute.HttpHandlerOptions);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingOptionsReturned(HttpHandlerOptions expected)
|
||||
{
|
||||
_httpHandlerOptions.ShouldNotBeNull();
|
||||
_httpHandlerOptions.AllowAutoRedirect.ShouldBe(expected.AllowAutoRedirect);
|
||||
_httpHandlerOptions.UseCookieContainer.ShouldBe(expected.UseCookieContainer);
|
||||
_httpHandlerOptions.UseTracing.ShouldBe(expected.UseTracing);
|
||||
_httpHandlerOptions.UseProxy.ShouldBe(expected.UseProxy);
|
||||
_httpHandlerOptions.MaxConnectionsPerServer.ShouldBe(expected.MaxConnectionsPerServer);
|
||||
}
|
||||
|
||||
private void GivenARealTracer()
|
||||
{
|
||||
var tracer = new FakeTracer();
|
||||
_serviceCollection.AddSingleton<ITracer, FakeTracer>();
|
||||
_serviceProvider = _serviceCollection.BuildServiceProvider();
|
||||
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
|
||||
}
|
||||
|
||||
private class FakeTracer : ITracer
|
||||
{
|
||||
public void Event(HttpContext httpContext, string @event)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken, Action<string> addTraceIdToRepo,
|
||||
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> baseSendAsync)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Logging;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class HttpHandlerOptionsCreatorTests
|
||||
{
|
||||
private IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
|
||||
private FileRoute _fileRoute;
|
||||
private HttpHandlerOptions _httpHandlerOptions;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IServiceCollection _serviceCollection;
|
||||
|
||||
public HttpHandlerOptionsCreatorTests()
|
||||
{
|
||||
_serviceCollection = new ServiceCollection();
|
||||
_serviceProvider = _serviceCollection.BuildServiceProvider();
|
||||
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_use_tracing_if_fake_tracer_registered()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
UseTracing = true
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_tracing_if_real_tracer_registered()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
UseTracing = true
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.And(x => GivenARealTracer())
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_useCookie_false_and_allowAutoRedirect_true_as_default()
|
||||
{
|
||||
var fileRoute = new FileRoute();
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_specified_useCookie_and_allowAutoRedirect()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
AllowAutoRedirect = false,
|
||||
UseCookieContainer = false,
|
||||
UseTracing = false
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_useproxy_true_as_default()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions()
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_specified_useproxy()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
UseProxy = false
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_with_specified_MaxConnectionsPerServer()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
MaxConnectionsPerServer = 10
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
MaxConnectionsPerServer = -1
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range_when_zero()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
HttpHandlerOptions = new FileHttpHandlerOptions
|
||||
{
|
||||
MaxConnectionsPerServer = 0
|
||||
}
|
||||
};
|
||||
|
||||
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
|
||||
|
||||
this.Given(x => GivenTheFollowing(fileRoute))
|
||||
.When(x => WhenICreateHttpHandlerOptions())
|
||||
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileRoute fileRoute)
|
||||
{
|
||||
_fileRoute = fileRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateHttpHandlerOptions()
|
||||
{
|
||||
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileRoute.HttpHandlerOptions);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingOptionsReturned(HttpHandlerOptions expected)
|
||||
{
|
||||
_httpHandlerOptions.ShouldNotBeNull();
|
||||
_httpHandlerOptions.AllowAutoRedirect.ShouldBe(expected.AllowAutoRedirect);
|
||||
_httpHandlerOptions.UseCookieContainer.ShouldBe(expected.UseCookieContainer);
|
||||
_httpHandlerOptions.UseTracing.ShouldBe(expected.UseTracing);
|
||||
_httpHandlerOptions.UseProxy.ShouldBe(expected.UseProxy);
|
||||
_httpHandlerOptions.MaxConnectionsPerServer.ShouldBe(expected.MaxConnectionsPerServer);
|
||||
}
|
||||
|
||||
private void GivenARealTracer()
|
||||
{
|
||||
var tracer = new FakeTracer();
|
||||
_serviceCollection.AddSingleton<ITracer, FakeTracer>();
|
||||
_serviceProvider = _serviceCollection.BuildServiceProvider();
|
||||
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
|
||||
}
|
||||
|
||||
private class FakeTracer : ITracer
|
||||
{
|
||||
public void Event(HttpContext httpContext, string @event)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken, Action<string> addTraceIdToRepo,
|
||||
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> baseSendAsync)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
private void ThenTheConfigurationIsReturned()
|
||||
{
|
||||
_getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
|
||||
_getResult.Data.Routes[0].DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
|
||||
}
|
||||
|
||||
private void WhenIGetTheConfiguration()
|
||||
@ -92,19 +92,19 @@ namespace Ocelot.UnitTests.Configuration
|
||||
AdministrationPath = administrationPath;
|
||||
}
|
||||
|
||||
public List<ReRoute> ReRoutes
|
||||
public List<Route> Routes
|
||||
{
|
||||
get
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate(_downstreamTemplatePath)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
return new List<ReRoute>
|
||||
return new List<Route>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.Build()
|
||||
};
|
||||
|
@ -11,22 +11,22 @@ namespace Ocelot.UnitTests.Configuration
|
||||
public class QoSOptionsCreatorTests
|
||||
{
|
||||
private QoSOptionsCreator _creator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileRoute _fileRoute;
|
||||
private QoSOptions _result;
|
||||
|
||||
public QoSOptionsCreatorTests()
|
||||
{
|
||||
_creator = new QoSOptionsCreator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_qos_options()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
DurationOfBreak = 1,
|
||||
TimeoutValue = 1
|
||||
}
|
||||
@ -37,20 +37,20 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.WithTimeoutValue(1)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
this.Given(x => x.GivenTheFollowingRoute(route))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
private void GivenTheFollowingRoute(FileRoute fileRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
_fileRoute = fileRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute.QoSOptions);
|
||||
_result = _creator.Create(_fileRoute.QoSOptions);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(QoSOptions expected)
|
||||
@ -60,4 +60,4 @@ namespace Ocelot.UnitTests.Configuration
|
||||
_result.TimeoutValue.ShouldBe(expected.TimeoutValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,106 +1,106 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RateLimitOptionsCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private bool _enabled;
|
||||
private RateLimitOptionsCreator _creator;
|
||||
private RateLimitOptions _result;
|
||||
|
||||
public RateLimitOptionsCreatorTests()
|
||||
{
|
||||
_creator = new RateLimitOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_rate_limit_options()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
ClientWhitelist = new List<string>(),
|
||||
Period = "Period",
|
||||
Limit = 1,
|
||||
PeriodTimespan = 1,
|
||||
EnableRateLimiting = true
|
||||
}
|
||||
};
|
||||
var fileGlobalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitOptions
|
||||
{
|
||||
ClientIdHeader = "ClientIdHeader",
|
||||
DisableRateLimitHeaders = true,
|
||||
QuotaExceededMessage = "QuotaExceededMessage",
|
||||
RateLimitCounterPrefix = "RateLimitCounterPrefix",
|
||||
HttpStatusCode = 200
|
||||
}
|
||||
};
|
||||
var expected = new RateLimitOptionsBuilder()
|
||||
.WithClientIdHeader("ClientIdHeader")
|
||||
.WithClientWhiteList(() => fileReRoute.RateLimitOptions.ClientWhitelist)
|
||||
.WithDisableRateLimitHeaders(true)
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithHttpStatusCode(200)
|
||||
.WithQuotaExceededMessage("QuotaExceededMessage")
|
||||
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
||||
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||
fileReRoute.RateLimitOptions.PeriodTimespan,
|
||||
fileReRoute.RateLimitOptions.Limit))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
|
||||
.And(x => x.GivenRateLimitingIsEnabled())
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||
{
|
||||
_fileGlobalConfig = fileGlobalConfig;
|
||||
}
|
||||
|
||||
private void GivenRateLimitingIsEnabled()
|
||||
{
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute.RateLimitOptions, _fileGlobalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
|
||||
{
|
||||
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
|
||||
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
|
||||
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
|
||||
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
||||
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
||||
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
||||
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RateLimitOptionsCreatorTests
|
||||
{
|
||||
private FileRoute _fileRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private bool _enabled;
|
||||
private RateLimitOptionsCreator _creator;
|
||||
private RateLimitOptions _result;
|
||||
|
||||
public RateLimitOptionsCreatorTests()
|
||||
{
|
||||
_creator = new RateLimitOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_rate_limit_options()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
ClientWhitelist = new List<string>(),
|
||||
Period = "Period",
|
||||
Limit = 1,
|
||||
PeriodTimespan = 1,
|
||||
EnableRateLimiting = true
|
||||
}
|
||||
};
|
||||
var fileGlobalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitOptions
|
||||
{
|
||||
ClientIdHeader = "ClientIdHeader",
|
||||
DisableRateLimitHeaders = true,
|
||||
QuotaExceededMessage = "QuotaExceededMessage",
|
||||
RateLimitCounterPrefix = "RateLimitCounterPrefix",
|
||||
HttpStatusCode = 200
|
||||
}
|
||||
};
|
||||
var expected = new RateLimitOptionsBuilder()
|
||||
.WithClientIdHeader("ClientIdHeader")
|
||||
.WithClientWhiteList(() => fileRoute.RateLimitOptions.ClientWhitelist)
|
||||
.WithDisableRateLimitHeaders(true)
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithHttpStatusCode(200)
|
||||
.WithQuotaExceededMessage("QuotaExceededMessage")
|
||||
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
||||
.WithRateLimitRule(new RateLimitRule(fileRoute.RateLimitOptions.Period,
|
||||
fileRoute.RateLimitOptions.PeriodTimespan,
|
||||
fileRoute.RateLimitOptions.Limit))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
|
||||
.And(x => x.GivenRateLimitingIsEnabled())
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileRoute(FileRoute fileRoute)
|
||||
{
|
||||
_fileRoute = fileRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||
{
|
||||
_fileGlobalConfig = fileGlobalConfig;
|
||||
}
|
||||
|
||||
private void GivenRateLimitingIsEnabled()
|
||||
{
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileRoute.RateLimitOptions, _fileGlobalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
|
||||
{
|
||||
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
|
||||
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
|
||||
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
|
||||
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
||||
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
||||
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
||||
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RequestIdKeyCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileRoute _fileRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private string _result;
|
||||
private RequestIdKeyCreator _creator;
|
||||
@ -21,13 +21,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_use_global_configuration()
|
||||
{
|
||||
var reRoute = new FileReRoute();
|
||||
var route = new FileRoute();
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
this.Given(x => x.GivenTheFollowingRoute(route))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
@ -37,13 +37,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_use_re_route_specific()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
var globalConfig = new FileGlobalConfiguration();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
this.Given(x => x.GivenTheFollowingRoute(route))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
@ -53,25 +53,25 @@ namespace Ocelot.UnitTests.Configuration
|
||||
[Fact]
|
||||
public void should_use_re_route_over_global_specific()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
var route = new FileRoute
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
};
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "test"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
this.Given(x => x.GivenTheFollowingRoute(route))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
private void GivenTheFollowingRoute(FileRoute fileRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
_fileRoute = fileRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration globalConfig)
|
||||
@ -81,7 +81,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute, _fileGlobalConfig);
|
||||
_result = _creator.Create(_fileRoute, _fileGlobalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(string expected)
|
||||
@ -89,4 +89,4 @@ namespace Ocelot.UnitTests.Configuration
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,84 +1,84 @@
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ReRouteKeyCreatorTests
|
||||
{
|
||||
private ReRouteKeyCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private string _result;
|
||||
|
||||
public ReRouteKeyCreatorTests()
|
||||
{
|
||||
_creator = new ReRouteKeyCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_sticky_session_key()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
LoadBalancerOptions = new FileLoadBalancerOptions
|
||||
{
|
||||
Key = "testy",
|
||||
Type = nameof(CookieStickySessions)
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(reRoute))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheResultIs($"{nameof(CookieStickySessions)}:{reRoute.LoadBalancerOptions.Key}"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_re_route_key()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/product",
|
||||
UpstreamHttpMethod = new List<string> { "GET", "POST", "PUT" },
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 123
|
||||
},
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 123
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(reRoute))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheResultIs($"{reRoute.UpstreamPathTemplate}|{string.Join(",", reRoute.UpstreamHttpMethod)}|{string.Join(",", reRoute.DownstreamHostAndPorts.Select(x => $"{x.Host}:{x.Port}"))}"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThe(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RouteKeyCreatorTests
|
||||
{
|
||||
private RouteKeyCreator _creator;
|
||||
private FileRoute _route;
|
||||
private string _result;
|
||||
|
||||
public RouteKeyCreatorTests()
|
||||
{
|
||||
_creator = new RouteKeyCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_sticky_session_key()
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
LoadBalancerOptions = new FileLoadBalancerOptions
|
||||
{
|
||||
Key = "testy",
|
||||
Type = nameof(CookieStickySessions)
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(route))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheResultIs($"{nameof(CookieStickySessions)}:{route.LoadBalancerOptions.Key}"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_re_route_key()
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/product",
|
||||
UpstreamHttpMethod = new List<string> { "GET", "POST", "PUT" },
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 123
|
||||
},
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 123
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(route))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheResultIs($"{route.UpstreamPathTemplate}|{string.Join(",", route.UpstreamHttpMethod)}|{string.Join(",", route.DownstreamHostAndPorts.Select(x => $"{x.Host}:{x.Port}"))}"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThe(FileRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_route);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,80 +1,80 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ReRouteOptionsCreatorTests
|
||||
{
|
||||
private readonly ReRouteOptionsCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private ReRouteOptions _result;
|
||||
|
||||
public ReRouteOptionsCreatorTests()
|
||||
{
|
||||
_creator = new ReRouteOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_re_route_options()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
},
|
||||
AuthenticationOptions = new FileAuthenticationOptions()
|
||||
{
|
||||
AuthenticationProviderKey = "Test"
|
||||
},
|
||||
RouteClaimsRequirement = new Dictionary<string, string>()
|
||||
{
|
||||
{"",""}
|
||||
},
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
TtlSeconds = 1
|
||||
},
|
||||
ServiceName = "west"
|
||||
};
|
||||
|
||||
var expected = new ReRouteOptionsBuilder()
|
||||
.WithIsAuthenticated(true)
|
||||
.WithIsAuthorised(true)
|
||||
.WithIsCached(true)
|
||||
.WithRateLimiting(true)
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(reRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(ReRouteOptions expected)
|
||||
{
|
||||
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
|
||||
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
|
||||
_result.IsCached.ShouldBe(expected.IsCached);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.UseServiceDiscovery.ShouldBe(expected.UseServiceDiscovery);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RouteOptionsCreatorTests
|
||||
{
|
||||
private readonly RouteOptionsCreator _creator;
|
||||
private FileRoute _route;
|
||||
private RouteOptions _result;
|
||||
|
||||
public RouteOptionsCreatorTests()
|
||||
{
|
||||
_creator = new RouteOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_re_route_options()
|
||||
{
|
||||
var route = new FileRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
},
|
||||
AuthenticationOptions = new FileAuthenticationOptions()
|
||||
{
|
||||
AuthenticationProviderKey = "Test"
|
||||
},
|
||||
RouteClaimsRequirement = new Dictionary<string, string>()
|
||||
{
|
||||
{"",""}
|
||||
},
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
TtlSeconds = 1
|
||||
},
|
||||
ServiceName = "west"
|
||||
};
|
||||
|
||||
var expected = new RouteOptionsBuilder()
|
||||
.WithIsAuthenticated(true)
|
||||
.WithIsAuthorised(true)
|
||||
.WithIsCached(true)
|
||||
.WithRateLimiting(true)
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(route))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_route);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(RouteOptions expected)
|
||||
{
|
||||
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
|
||||
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
|
||||
_result.IsCached.ShouldBe(expected.IsCached);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.UseServiceDiscovery.ShouldBe(expected.UseServiceDiscovery);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,283 +1,283 @@
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using System;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ReRoutesCreatorTests
|
||||
{
|
||||
private ReRoutesCreator _creator;
|
||||
private Mock<IClaimsToThingCreator> _cthCreator;
|
||||
private Mock<IAuthenticationOptionsCreator> _aoCreator;
|
||||
private Mock<IUpstreamTemplatePatternCreator> _utpCreator;
|
||||
private Mock<IRequestIdKeyCreator> _ridkCreator;
|
||||
private Mock<IQoSOptionsCreator> _qosoCreator;
|
||||
private Mock<IReRouteOptionsCreator> _rroCreator;
|
||||
private Mock<IRateLimitOptionsCreator> _rloCreator;
|
||||
private Mock<IRegionCreator> _rCreator;
|
||||
private Mock<IHttpHandlerOptionsCreator> _hhoCreator;
|
||||
private Mock<IHeaderFindAndReplaceCreator> _hfarCreator;
|
||||
private Mock<IDownstreamAddressesCreator> _daCreator;
|
||||
private Mock<ILoadBalancerOptionsCreator> _lboCreator;
|
||||
private Mock<IReRouteKeyCreator> _rrkCreator;
|
||||
private Mock<ISecurityOptionsCreator> _soCreator;
|
||||
private Mock<IVersionCreator> _versionCreator;
|
||||
private FileConfiguration _fileConfig;
|
||||
private ReRouteOptions _rro;
|
||||
private string _requestId;
|
||||
private string _rrk;
|
||||
private UpstreamPathTemplate _upt;
|
||||
private AuthenticationOptions _ao;
|
||||
private List<ClaimToThing> _ctt;
|
||||
private QoSOptions _qoso;
|
||||
private RateLimitOptions _rlo;
|
||||
private string _region;
|
||||
private HttpHandlerOptions _hho;
|
||||
private HeaderTransformations _ht;
|
||||
private List<DownstreamHostAndPort> _dhp;
|
||||
private LoadBalancerOptions _lbo;
|
||||
private List<ReRoute> _result;
|
||||
private SecurityOptions _securityOptions;
|
||||
private Version _expectedVersion;
|
||||
|
||||
public ReRoutesCreatorTests()
|
||||
{
|
||||
_cthCreator = new Mock<IClaimsToThingCreator>();
|
||||
_aoCreator = new Mock<IAuthenticationOptionsCreator>();
|
||||
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
|
||||
_ridkCreator = new Mock<IRequestIdKeyCreator>();
|
||||
_qosoCreator = new Mock<IQoSOptionsCreator>();
|
||||
_rroCreator = new Mock<IReRouteOptionsCreator>();
|
||||
_rloCreator = new Mock<IRateLimitOptionsCreator>();
|
||||
_rCreator = new Mock<IRegionCreator>();
|
||||
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
|
||||
_hfarCreator = new Mock<IHeaderFindAndReplaceCreator>();
|
||||
_daCreator = new Mock<IDownstreamAddressesCreator>();
|
||||
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
|
||||
_rrkCreator = new Mock<IReRouteKeyCreator>();
|
||||
_soCreator = new Mock<ISecurityOptionsCreator>();
|
||||
_versionCreator = new Mock<IVersionCreator>();
|
||||
|
||||
_creator = new ReRoutesCreator(
|
||||
_cthCreator.Object,
|
||||
_aoCreator.Object,
|
||||
_utpCreator.Object,
|
||||
_ridkCreator.Object,
|
||||
_qosoCreator.Object,
|
||||
_rroCreator.Object,
|
||||
_rloCreator.Object,
|
||||
_rCreator.Object,
|
||||
_hhoCreator.Object,
|
||||
_hfarCreator.Object,
|
||||
_daCreator.Object,
|
||||
_lboCreator.Object,
|
||||
_rrkCreator.Object,
|
||||
_soCreator.Object,
|
||||
_versionCreator.Object
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_nothing()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenNoReRoutesAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_re_routes()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
ServiceName = "dave",
|
||||
DangerousAcceptAnyServerCertificateValidator = true,
|
||||
AddClaimsToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "a","b" }
|
||||
},
|
||||
AddHeadersToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "c","d" }
|
||||
},
|
||||
AddQueriesToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "e","f" }
|
||||
},
|
||||
UpstreamHttpMethod = new List<string> { "GET", "POST" }
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
ServiceName = "wave",
|
||||
DangerousAcceptAnyServerCertificateValidator = false,
|
||||
AddClaimsToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "g","h" }
|
||||
},
|
||||
AddHeadersToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "i","j" }
|
||||
},
|
||||
AddQueriesToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "k","l" }
|
||||
},
|
||||
UpstreamHttpMethod = new List<string> { "PUT", "DELETE" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenTheDependenciesAreSetUpCorrectly())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
|
||||
.And(_ => ThenTheReRoutesAreCreated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheDependenciesAreCalledCorrectly()
|
||||
{
|
||||
ThenTheDepsAreCalledFor(_fileConfig.ReRoutes[0], _fileConfig.GlobalConfiguration);
|
||||
ThenTheDepsAreCalledFor(_fileConfig.ReRoutes[1], _fileConfig.GlobalConfiguration);
|
||||
}
|
||||
|
||||
private void GivenTheDependenciesAreSetUpCorrectly()
|
||||
{
|
||||
_expectedVersion = new Version("1.1");
|
||||
_rro = new ReRouteOptions(false, false, false, false, false);
|
||||
_requestId = "testy";
|
||||
_rrk = "besty";
|
||||
_upt = new UpstreamPathTemplateBuilder().Build();
|
||||
_ao = new AuthenticationOptionsBuilder().Build();
|
||||
_ctt = new List<ClaimToThing>();
|
||||
_qoso = new QoSOptionsBuilder().Build();
|
||||
_rlo = new RateLimitOptionsBuilder().Build();
|
||||
_region = "vesty";
|
||||
_hho = new HttpHandlerOptionsBuilder().Build();
|
||||
_ht = new HeaderTransformations(new List<HeaderFindAndReplace>(), new List<HeaderFindAndReplace>(), new List<AddHeader>(), new List<AddHeader>());
|
||||
_dhp = new List<DownstreamHostAndPort>();
|
||||
_lbo = new LoadBalancerOptionsBuilder().Build();
|
||||
|
||||
_rroCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_rro);
|
||||
_ridkCreator.Setup(x => x.Create(It.IsAny<FileReRoute>(), It.IsAny<FileGlobalConfiguration>())).Returns(_requestId);
|
||||
_rrkCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_rrk);
|
||||
_utpCreator.Setup(x => x.Create(It.IsAny<IReRoute>())).Returns(_upt);
|
||||
_aoCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_ao);
|
||||
_cthCreator.Setup(x => x.Create(It.IsAny<Dictionary<string, string>>())).Returns(_ctt);
|
||||
_qosoCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>())).Returns(_qoso);
|
||||
_rloCreator.Setup(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>())).Returns(_rlo);
|
||||
_rCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_region);
|
||||
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
|
||||
_hfarCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_ht);
|
||||
_daCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_dhp);
|
||||
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
|
||||
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_expectedVersion);
|
||||
}
|
||||
|
||||
private void ThenTheReRoutesAreCreated()
|
||||
{
|
||||
_result.Count.ShouldBe(2);
|
||||
|
||||
ThenTheReRouteIsSet(_fileConfig.ReRoutes[0], 0);
|
||||
ThenTheReRouteIsSet(_fileConfig.ReRoutes[1], 1);
|
||||
}
|
||||
|
||||
private void ThenNoReRoutesAreReturned()
|
||||
{
|
||||
_result.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfig)
|
||||
{
|
||||
_fileConfig = fileConfig;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileConfig);
|
||||
}
|
||||
|
||||
private void ThenTheReRouteIsSet(FileReRoute expected, int reRouteIndex)
|
||||
{
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_expectedVersion);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].IsAuthenticated.ShouldBe(_rro.IsAuthenticated);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].IsAuthorised.ShouldBe(_rro.IsAuthorised);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].IsCached.ShouldBe(_rro.IsCached);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBe(_rro.EnableRateLimiting);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].RequestIdKey.ShouldBe(_requestId);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].LoadBalancerKey.ShouldBe(_rrk);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].UpstreamPathTemplate.ShouldBe(_upt);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].AuthenticationOptions.ShouldBe(_ao);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].ClaimsToHeaders.ShouldBe(_ctt);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].ClaimsToQueries.ShouldBe(_ctt);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].ClaimsToClaims.ShouldBe(_ctt);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].QosOptions.ShouldBe(_qoso);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].CacheOptions.Region.ShouldBe(_region);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].CacheOptions.TtlSeconds.ShouldBe(expected.FileCacheOptions.TtlSeconds);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].HttpHandlerOptions.ShouldBe(_hho);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].UpstreamHeadersFindAndReplace.ShouldBe(_ht.Upstream);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DownstreamHeadersFindAndReplace.ShouldBe(_ht.Downstream);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].AddHeadersToUpstream.ShouldBe(_ht.AddHeadersToUpstream);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].AddHeadersToDownstream.ShouldBe(_ht.AddHeadersToDownstream);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DownstreamAddresses.ShouldBe(_dhp);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].LoadBalancerOptions.ShouldBe(_lbo);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].UseServiceDiscovery.ShouldBe(_rro.UseServiceDiscovery);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DangerousAcceptAnyServerCertificateValidator.ShouldBe(expected.DangerousAcceptAnyServerCertificateValidator);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DelegatingHandlers.ShouldBe(expected.DelegatingHandlers);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].ServiceName.ShouldBe(expected.ServiceName);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DownstreamScheme.ShouldBe(expected.DownstreamScheme);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].RouteClaimsRequirement.ShouldBe(expected.RouteClaimsRequirement);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate);
|
||||
_result[reRouteIndex].DownstreamReRoute[0].Key.ShouldBe(expected.Key);
|
||||
_result[reRouteIndex].UpstreamHttpMethod
|
||||
.Select(x => x.Method)
|
||||
.ToList()
|
||||
.ShouldContain(x => x == expected.UpstreamHttpMethod[0]);
|
||||
_result[reRouteIndex].UpstreamHttpMethod
|
||||
.Select(x => x.Method)
|
||||
.ToList()
|
||||
.ShouldContain(x => x == expected.UpstreamHttpMethod[1]);
|
||||
_result[reRouteIndex].UpstreamHost.ShouldBe(expected.UpstreamHost);
|
||||
_result[reRouteIndex].DownstreamReRoute.Count.ShouldBe(1);
|
||||
_result[reRouteIndex].UpstreamTemplatePattern.ShouldBe(_upt);
|
||||
}
|
||||
|
||||
private void ThenTheDepsAreCalledFor(FileReRoute fileReRoute, FileGlobalConfiguration globalConfig)
|
||||
{
|
||||
_rroCreator.Verify(x => x.Create(fileReRoute), Times.Once);
|
||||
_ridkCreator.Verify(x => x.Create(fileReRoute, globalConfig), Times.Once);
|
||||
_rrkCreator.Verify(x => x.Create(fileReRoute), Times.Once);
|
||||
_utpCreator.Verify(x => x.Create(fileReRoute), Times.Exactly(2));
|
||||
_aoCreator.Verify(x => x.Create(fileReRoute), Times.Once);
|
||||
_cthCreator.Verify(x => x.Create(fileReRoute.AddHeadersToRequest), Times.Once);
|
||||
_cthCreator.Verify(x => x.Create(fileReRoute.AddClaimsToRequest), Times.Once);
|
||||
_cthCreator.Verify(x => x.Create(fileReRoute.AddQueriesToRequest), Times.Once);
|
||||
_qosoCreator.Verify(x => x.Create(fileReRoute.QoSOptions, fileReRoute.UpstreamPathTemplate, fileReRoute.UpstreamHttpMethod));
|
||||
_rloCreator.Verify(x => x.Create(fileReRoute.RateLimitOptions, globalConfig), Times.Once);
|
||||
_rCreator.Verify(x => x.Create(fileReRoute), Times.Once);
|
||||
_hhoCreator.Verify(x => x.Create(fileReRoute.HttpHandlerOptions), Times.Once);
|
||||
_hfarCreator.Verify(x => x.Create(fileReRoute), Times.Once);
|
||||
_daCreator.Verify(x => x.Create(fileReRoute), Times.Once);
|
||||
_lboCreator.Verify(x => x.Create(fileReRoute.LoadBalancerOptions), Times.Once);
|
||||
_soCreator.Verify(x => x.Create(fileReRoute.SecurityOptions), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using System;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RoutesCreatorTests
|
||||
{
|
||||
private RoutesCreator _creator;
|
||||
private Mock<IClaimsToThingCreator> _cthCreator;
|
||||
private Mock<IAuthenticationOptionsCreator> _aoCreator;
|
||||
private Mock<IUpstreamTemplatePatternCreator> _utpCreator;
|
||||
private Mock<IRequestIdKeyCreator> _ridkCreator;
|
||||
private Mock<IQoSOptionsCreator> _qosoCreator;
|
||||
private Mock<IRouteOptionsCreator> _rroCreator;
|
||||
private Mock<IRateLimitOptionsCreator> _rloCreator;
|
||||
private Mock<IRegionCreator> _rCreator;
|
||||
private Mock<IHttpHandlerOptionsCreator> _hhoCreator;
|
||||
private Mock<IHeaderFindAndReplaceCreator> _hfarCreator;
|
||||
private Mock<IDownstreamAddressesCreator> _daCreator;
|
||||
private Mock<ILoadBalancerOptionsCreator> _lboCreator;
|
||||
private Mock<IRouteKeyCreator> _rrkCreator;
|
||||
private Mock<ISecurityOptionsCreator> _soCreator;
|
||||
private Mock<IVersionCreator> _versionCreator;
|
||||
private FileConfiguration _fileConfig;
|
||||
private RouteOptions _rro;
|
||||
private string _requestId;
|
||||
private string _rrk;
|
||||
private UpstreamPathTemplate _upt;
|
||||
private AuthenticationOptions _ao;
|
||||
private List<ClaimToThing> _ctt;
|
||||
private QoSOptions _qoso;
|
||||
private RateLimitOptions _rlo;
|
||||
private string _region;
|
||||
private HttpHandlerOptions _hho;
|
||||
private HeaderTransformations _ht;
|
||||
private List<DownstreamHostAndPort> _dhp;
|
||||
private LoadBalancerOptions _lbo;
|
||||
private List<Route> _result;
|
||||
private SecurityOptions _securityOptions;
|
||||
private Version _expectedVersion;
|
||||
|
||||
public RoutesCreatorTests()
|
||||
{
|
||||
_cthCreator = new Mock<IClaimsToThingCreator>();
|
||||
_aoCreator = new Mock<IAuthenticationOptionsCreator>();
|
||||
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
|
||||
_ridkCreator = new Mock<IRequestIdKeyCreator>();
|
||||
_qosoCreator = new Mock<IQoSOptionsCreator>();
|
||||
_rroCreator = new Mock<IRouteOptionsCreator>();
|
||||
_rloCreator = new Mock<IRateLimitOptionsCreator>();
|
||||
_rCreator = new Mock<IRegionCreator>();
|
||||
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
|
||||
_hfarCreator = new Mock<IHeaderFindAndReplaceCreator>();
|
||||
_daCreator = new Mock<IDownstreamAddressesCreator>();
|
||||
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
|
||||
_rrkCreator = new Mock<IRouteKeyCreator>();
|
||||
_soCreator = new Mock<ISecurityOptionsCreator>();
|
||||
_versionCreator = new Mock<IVersionCreator>();
|
||||
|
||||
_creator = new RoutesCreator(
|
||||
_cthCreator.Object,
|
||||
_aoCreator.Object,
|
||||
_utpCreator.Object,
|
||||
_ridkCreator.Object,
|
||||
_qosoCreator.Object,
|
||||
_rroCreator.Object,
|
||||
_rloCreator.Object,
|
||||
_rCreator.Object,
|
||||
_hhoCreator.Object,
|
||||
_hfarCreator.Object,
|
||||
_daCreator.Object,
|
||||
_lboCreator.Object,
|
||||
_rrkCreator.Object,
|
||||
_soCreator.Object,
|
||||
_versionCreator.Object
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_nothing()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenNoRoutesAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_re_routes()
|
||||
{
|
||||
var fileConfig = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
ServiceName = "dave",
|
||||
DangerousAcceptAnyServerCertificateValidator = true,
|
||||
AddClaimsToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "a","b" }
|
||||
},
|
||||
AddHeadersToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "c","d" }
|
||||
},
|
||||
AddQueriesToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "e","f" }
|
||||
},
|
||||
UpstreamHttpMethod = new List<string> { "GET", "POST" }
|
||||
},
|
||||
new FileRoute
|
||||
{
|
||||
ServiceName = "wave",
|
||||
DangerousAcceptAnyServerCertificateValidator = false,
|
||||
AddClaimsToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "g","h" }
|
||||
},
|
||||
AddHeadersToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "i","j" }
|
||||
},
|
||||
AddQueriesToRequest = new Dictionary<string, string>
|
||||
{
|
||||
{ "k","l" }
|
||||
},
|
||||
UpstreamHttpMethod = new List<string> { "PUT", "DELETE" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileConfig))
|
||||
.And(_ => GivenTheDependenciesAreSetUpCorrectly())
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
|
||||
.And(_ => ThenTheRoutesAreCreated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheDependenciesAreCalledCorrectly()
|
||||
{
|
||||
ThenTheDepsAreCalledFor(_fileConfig.Routes[0], _fileConfig.GlobalConfiguration);
|
||||
ThenTheDepsAreCalledFor(_fileConfig.Routes[1], _fileConfig.GlobalConfiguration);
|
||||
}
|
||||
|
||||
private void GivenTheDependenciesAreSetUpCorrectly()
|
||||
{
|
||||
_expectedVersion = new Version("1.1");
|
||||
_rro = new RouteOptions(false, false, false, false, false);
|
||||
_requestId = "testy";
|
||||
_rrk = "besty";
|
||||
_upt = new UpstreamPathTemplateBuilder().Build();
|
||||
_ao = new AuthenticationOptionsBuilder().Build();
|
||||
_ctt = new List<ClaimToThing>();
|
||||
_qoso = new QoSOptionsBuilder().Build();
|
||||
_rlo = new RateLimitOptionsBuilder().Build();
|
||||
_region = "vesty";
|
||||
_hho = new HttpHandlerOptionsBuilder().Build();
|
||||
_ht = new HeaderTransformations(new List<HeaderFindAndReplace>(), new List<HeaderFindAndReplace>(), new List<AddHeader>(), new List<AddHeader>());
|
||||
_dhp = new List<DownstreamHostAndPort>();
|
||||
_lbo = new LoadBalancerOptionsBuilder().Build();
|
||||
|
||||
_rroCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_rro);
|
||||
_ridkCreator.Setup(x => x.Create(It.IsAny<FileRoute>(), It.IsAny<FileGlobalConfiguration>())).Returns(_requestId);
|
||||
_rrkCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_rrk);
|
||||
_utpCreator.Setup(x => x.Create(It.IsAny<IRoute>())).Returns(_upt);
|
||||
_aoCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_ao);
|
||||
_cthCreator.Setup(x => x.Create(It.IsAny<Dictionary<string, string>>())).Returns(_ctt);
|
||||
_qosoCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>())).Returns(_qoso);
|
||||
_rloCreator.Setup(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>())).Returns(_rlo);
|
||||
_rCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_region);
|
||||
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
|
||||
_hfarCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_ht);
|
||||
_daCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_dhp);
|
||||
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
|
||||
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_expectedVersion);
|
||||
}
|
||||
|
||||
private void ThenTheRoutesAreCreated()
|
||||
{
|
||||
_result.Count.ShouldBe(2);
|
||||
|
||||
ThenTheRouteIsSet(_fileConfig.Routes[0], 0);
|
||||
ThenTheRouteIsSet(_fileConfig.Routes[1], 1);
|
||||
}
|
||||
|
||||
private void ThenNoRoutesAreReturned()
|
||||
{
|
||||
_result.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
private void GivenThe(FileConfiguration fileConfig)
|
||||
{
|
||||
_fileConfig = fileConfig;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileConfig);
|
||||
}
|
||||
|
||||
private void ThenTheRouteIsSet(FileRoute expected, int routeIndex)
|
||||
{
|
||||
_result[routeIndex].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_expectedVersion);
|
||||
_result[routeIndex].DownstreamRoute[0].IsAuthenticated.ShouldBe(_rro.IsAuthenticated);
|
||||
_result[routeIndex].DownstreamRoute[0].IsAuthorised.ShouldBe(_rro.IsAuthorised);
|
||||
_result[routeIndex].DownstreamRoute[0].IsCached.ShouldBe(_rro.IsCached);
|
||||
_result[routeIndex].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBe(_rro.EnableRateLimiting);
|
||||
_result[routeIndex].DownstreamRoute[0].RequestIdKey.ShouldBe(_requestId);
|
||||
_result[routeIndex].DownstreamRoute[0].LoadBalancerKey.ShouldBe(_rrk);
|
||||
_result[routeIndex].DownstreamRoute[0].UpstreamPathTemplate.ShouldBe(_upt);
|
||||
_result[routeIndex].DownstreamRoute[0].AuthenticationOptions.ShouldBe(_ao);
|
||||
_result[routeIndex].DownstreamRoute[0].ClaimsToHeaders.ShouldBe(_ctt);
|
||||
_result[routeIndex].DownstreamRoute[0].ClaimsToQueries.ShouldBe(_ctt);
|
||||
_result[routeIndex].DownstreamRoute[0].ClaimsToClaims.ShouldBe(_ctt);
|
||||
_result[routeIndex].DownstreamRoute[0].QosOptions.ShouldBe(_qoso);
|
||||
_result[routeIndex].DownstreamRoute[0].RateLimitOptions.ShouldBe(_rlo);
|
||||
_result[routeIndex].DownstreamRoute[0].CacheOptions.Region.ShouldBe(_region);
|
||||
_result[routeIndex].DownstreamRoute[0].CacheOptions.TtlSeconds.ShouldBe(expected.FileCacheOptions.TtlSeconds);
|
||||
_result[routeIndex].DownstreamRoute[0].HttpHandlerOptions.ShouldBe(_hho);
|
||||
_result[routeIndex].DownstreamRoute[0].UpstreamHeadersFindAndReplace.ShouldBe(_ht.Upstream);
|
||||
_result[routeIndex].DownstreamRoute[0].DownstreamHeadersFindAndReplace.ShouldBe(_ht.Downstream);
|
||||
_result[routeIndex].DownstreamRoute[0].AddHeadersToUpstream.ShouldBe(_ht.AddHeadersToUpstream);
|
||||
_result[routeIndex].DownstreamRoute[0].AddHeadersToDownstream.ShouldBe(_ht.AddHeadersToDownstream);
|
||||
_result[routeIndex].DownstreamRoute[0].DownstreamAddresses.ShouldBe(_dhp);
|
||||
_result[routeIndex].DownstreamRoute[0].LoadBalancerOptions.ShouldBe(_lbo);
|
||||
_result[routeIndex].DownstreamRoute[0].UseServiceDiscovery.ShouldBe(_rro.UseServiceDiscovery);
|
||||
_result[routeIndex].DownstreamRoute[0].DangerousAcceptAnyServerCertificateValidator.ShouldBe(expected.DangerousAcceptAnyServerCertificateValidator);
|
||||
_result[routeIndex].DownstreamRoute[0].DelegatingHandlers.ShouldBe(expected.DelegatingHandlers);
|
||||
_result[routeIndex].DownstreamRoute[0].ServiceName.ShouldBe(expected.ServiceName);
|
||||
_result[routeIndex].DownstreamRoute[0].DownstreamScheme.ShouldBe(expected.DownstreamScheme);
|
||||
_result[routeIndex].DownstreamRoute[0].RouteClaimsRequirement.ShouldBe(expected.RouteClaimsRequirement);
|
||||
_result[routeIndex].DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate);
|
||||
_result[routeIndex].DownstreamRoute[0].Key.ShouldBe(expected.Key);
|
||||
_result[routeIndex].UpstreamHttpMethod
|
||||
.Select(x => x.Method)
|
||||
.ToList()
|
||||
.ShouldContain(x => x == expected.UpstreamHttpMethod[0]);
|
||||
_result[routeIndex].UpstreamHttpMethod
|
||||
.Select(x => x.Method)
|
||||
.ToList()
|
||||
.ShouldContain(x => x == expected.UpstreamHttpMethod[1]);
|
||||
_result[routeIndex].UpstreamHost.ShouldBe(expected.UpstreamHost);
|
||||
_result[routeIndex].DownstreamRoute.Count.ShouldBe(1);
|
||||
_result[routeIndex].UpstreamTemplatePattern.ShouldBe(_upt);
|
||||
}
|
||||
|
||||
private void ThenTheDepsAreCalledFor(FileRoute fileRoute, FileGlobalConfiguration globalConfig)
|
||||
{
|
||||
_rroCreator.Verify(x => x.Create(fileRoute), Times.Once);
|
||||
_ridkCreator.Verify(x => x.Create(fileRoute, globalConfig), Times.Once);
|
||||
_rrkCreator.Verify(x => x.Create(fileRoute), Times.Once);
|
||||
_utpCreator.Verify(x => x.Create(fileRoute), Times.Exactly(2));
|
||||
_aoCreator.Verify(x => x.Create(fileRoute), Times.Once);
|
||||
_cthCreator.Verify(x => x.Create(fileRoute.AddHeadersToRequest), Times.Once);
|
||||
_cthCreator.Verify(x => x.Create(fileRoute.AddClaimsToRequest), Times.Once);
|
||||
_cthCreator.Verify(x => x.Create(fileRoute.AddQueriesToRequest), Times.Once);
|
||||
_qosoCreator.Verify(x => x.Create(fileRoute.QoSOptions, fileRoute.UpstreamPathTemplate, fileRoute.UpstreamHttpMethod));
|
||||
_rloCreator.Verify(x => x.Create(fileRoute.RateLimitOptions, globalConfig), Times.Once);
|
||||
_rCreator.Verify(x => x.Create(fileRoute), Times.Once);
|
||||
_hhoCreator.Verify(x => x.Create(fileRoute.HttpHandlerOptions), Times.Once);
|
||||
_hfarCreator.Verify(x => x.Create(fileRoute), Times.Once);
|
||||
_daCreator.Verify(x => x.Create(fileRoute), Times.Once);
|
||||
_lboCreator.Verify(x => x.Create(fileRoute.LoadBalancerOptions), Times.Once);
|
||||
_soCreator.Verify(x => x.Create(fileRoute.SecurityOptions), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,68 +1,68 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class SecurityOptionsCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private SecurityOptions _result;
|
||||
private ISecurityOptionsCreator _creator;
|
||||
|
||||
public SecurityOptionsCreatorTests()
|
||||
{
|
||||
_creator = new SecurityOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_security_config()
|
||||
{
|
||||
var ipAllowedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
|
||||
var ipBlockedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
SecurityOptions = new FileSecurityOptions()
|
||||
{
|
||||
IPAllowedList = ipAllowedList,
|
||||
IPBlockedList = ipBlockedList
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new SecurityOptions(ipAllowedList, ipBlockedList);
|
||||
|
||||
this.Given(x => x.GivenThe(fileReRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheResultIs(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThe(FileReRoute reRoute)
|
||||
{
|
||||
_fileReRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute.SecurityOptions);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(SecurityOptions expected)
|
||||
{
|
||||
for (int i = 0; i < expected.IPAllowedList.Count; i++)
|
||||
{
|
||||
_result.IPAllowedList[i].ShouldBe(expected.IPAllowedList[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < expected.IPBlockedList.Count; i++)
|
||||
{
|
||||
_result.IPBlockedList[i].ShouldBe(expected.IPBlockedList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class SecurityOptionsCreatorTests
|
||||
{
|
||||
private FileRoute _fileRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private SecurityOptions _result;
|
||||
private ISecurityOptionsCreator _creator;
|
||||
|
||||
public SecurityOptionsCreatorTests()
|
||||
{
|
||||
_creator = new SecurityOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_security_config()
|
||||
{
|
||||
var ipAllowedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
|
||||
var ipBlockedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
SecurityOptions = new FileSecurityOptions()
|
||||
{
|
||||
IPAllowedList = ipAllowedList,
|
||||
IPBlockedList = ipBlockedList
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new SecurityOptions(ipAllowedList, ipBlockedList);
|
||||
|
||||
this.Given(x => x.GivenThe(fileRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheResultIs(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThe(FileRoute route)
|
||||
{
|
||||
_fileRoute = route;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileRoute.SecurityOptions);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(SecurityOptions expected)
|
||||
{
|
||||
for (int i = 0; i < expected.IPAllowedList.Count; i++)
|
||||
{
|
||||
_result.IPAllowedList[i].ShouldBe(expected.IPAllowedList[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < expected.IPBlockedList.Count; i++)
|
||||
{
|
||||
_result.IPBlockedList[i].ShouldBe(expected.IPBlockedList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,260 +1,260 @@
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class UpstreamTemplatePatternCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private readonly UpstreamTemplatePatternCreator _creator;
|
||||
private UpstreamPathTemplate _result;
|
||||
|
||||
public UpstreamTemplatePatternCreatorTests()
|
||||
{
|
||||
_creator = new UpstreamTemplatePatternCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_up_to_next_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/v{apiVersion}/cards",
|
||||
Priority = 0
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/v[^/]+/cards$"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_re_route_priority()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/orders/{catchAll}",
|
||||
Priority = 0
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/.+$"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_zero_priority()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{catchAll}",
|
||||
Priority = 1
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
ReRouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/",
|
||||
ReRouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/[^/]+(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{url}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/[^/]+/products/variants/[^/]+(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_query_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+&productId=.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheTemplatePattern()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(string expected)
|
||||
{
|
||||
_result.Template.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenThePriorityIs(int v)
|
||||
{
|
||||
_result.Priority.ShouldBe(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class UpstreamTemplatePatternCreatorTests
|
||||
{
|
||||
private FileRoute _fileRoute;
|
||||
private readonly UpstreamTemplatePatternCreator _creator;
|
||||
private UpstreamPathTemplate _result;
|
||||
|
||||
public UpstreamTemplatePatternCreatorTests()
|
||||
{
|
||||
_creator = new UpstreamTemplatePatternCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_up_to_next_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/v{apiVersion}/cards",
|
||||
Priority = 0
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/v[^/]+/cards$"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_re_route_priority()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/orders/{catchAll}",
|
||||
Priority = 0
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/.+$"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_zero_priority()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{catchAll}",
|
||||
Priority = 1
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
RouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/",
|
||||
RouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
RouteIsCaseSensitive = true
|
||||
};
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
RouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
|
||||
RouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
|
||||
RouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/[^/]+(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{url}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
|
||||
RouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/[^/]+/products/variants/[^/]+(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_query_string()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+&productId=.+$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileRoute(FileRoute fileRoute)
|
||||
{
|
||||
_fileRoute = fileRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheTemplatePattern()
|
||||
{
|
||||
_result = _creator.Create(_fileRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(string expected)
|
||||
{
|
||||
_result.Template.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenThePriorityIs(int v)
|
||||
{
|
||||
_result.Priority.ShouldBe(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,103 +1,103 @@
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Ocelot.Requester;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration.Validation
|
||||
{
|
||||
public class FileQoSOptionsFluentValidatorTests
|
||||
{
|
||||
private FileQoSOptionsFluentValidator _validator;
|
||||
private ServiceCollection _services;
|
||||
private ValidationResult _result;
|
||||
private FileQoSOptions _qosOptions;
|
||||
|
||||
public FileQoSOptionsFluentValidatorTests()
|
||||
{
|
||||
_services = new ServiceCollection();
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_validator = new FileQoSOptionsFluentValidator(provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_as_nothing_set()
|
||||
{
|
||||
this.Given(_ => GivenThe(new FileQoSOptions()))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_as_qos_delegate_set()
|
||||
{
|
||||
var qosOptions = new FileQoSOptions
|
||||
{
|
||||
TimeoutValue = 1,
|
||||
ExceptionsAllowedBeforeBreaking = 1
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(qosOptions))
|
||||
.And(_ => GivenAQosDelegate())
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_invalid_as_no_qos_delegate()
|
||||
{
|
||||
var qosOptions = new FileQoSOptions
|
||||
{
|
||||
TimeoutValue = 1,
|
||||
ExceptionsAllowedBeforeBreaking = 1
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(qosOptions))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInValid())
|
||||
.And(_ => ThenTheErrorIs())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheErrorIs()
|
||||
{
|
||||
_result.Errors[0].ErrorMessage.ShouldBe("Unable to start Ocelot because either a ReRoute or GlobalConfiguration are using QoSOptions but no QosDelegatingHandlerDelegate has been registered in dependency injection container. Are you missing a package like Ocelot.Provider.Polly and services.AddPolly()?");
|
||||
}
|
||||
|
||||
private void ThenTheResultIsInValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void GivenAQosDelegate()
|
||||
{
|
||||
QosDelegatingHandlerDelegate fake = (a, b) =>
|
||||
{
|
||||
return null;
|
||||
};
|
||||
_services.AddSingleton<QosDelegatingHandlerDelegate>(fake);
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_validator = new FileQoSOptionsFluentValidator(provider);
|
||||
}
|
||||
|
||||
private void GivenThe(FileQoSOptions qosOptions)
|
||||
{
|
||||
_qosOptions = qosOptions;
|
||||
}
|
||||
|
||||
private void WhenIValidate()
|
||||
{
|
||||
_result = _validator.Validate(_qosOptions);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Ocelot.Requester;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration.Validation
|
||||
{
|
||||
public class FileQoSOptionsFluentValidatorTests
|
||||
{
|
||||
private FileQoSOptionsFluentValidator _validator;
|
||||
private ServiceCollection _services;
|
||||
private ValidationResult _result;
|
||||
private FileQoSOptions _qosOptions;
|
||||
|
||||
public FileQoSOptionsFluentValidatorTests()
|
||||
{
|
||||
_services = new ServiceCollection();
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_validator = new FileQoSOptionsFluentValidator(provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_as_nothing_set()
|
||||
{
|
||||
this.Given(_ => GivenThe(new FileQoSOptions()))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_as_qos_delegate_set()
|
||||
{
|
||||
var qosOptions = new FileQoSOptions
|
||||
{
|
||||
TimeoutValue = 1,
|
||||
ExceptionsAllowedBeforeBreaking = 1
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(qosOptions))
|
||||
.And(_ => GivenAQosDelegate())
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_invalid_as_no_qos_delegate()
|
||||
{
|
||||
var qosOptions = new FileQoSOptions
|
||||
{
|
||||
TimeoutValue = 1,
|
||||
ExceptionsAllowedBeforeBreaking = 1
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(qosOptions))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInValid())
|
||||
.And(_ => ThenTheErrorIs())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheErrorIs()
|
||||
{
|
||||
_result.Errors[0].ErrorMessage.ShouldBe("Unable to start Ocelot because either a Route or GlobalConfiguration are using QoSOptions but no QosDelegatingHandlerDelegate has been registered in dependency injection container. Are you missing a package like Ocelot.Provider.Polly and services.AddPolly()?");
|
||||
}
|
||||
|
||||
private void ThenTheResultIsInValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void GivenAQosDelegate()
|
||||
{
|
||||
QosDelegatingHandlerDelegate fake = (a, b) =>
|
||||
{
|
||||
return null;
|
||||
};
|
||||
_services.AddSingleton<QosDelegatingHandlerDelegate>(fake);
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_validator = new FileQoSOptionsFluentValidator(provider);
|
||||
}
|
||||
|
||||
private void GivenThe(FileQoSOptions qosOptions)
|
||||
{
|
||||
_qosOptions = qosOptions;
|
||||
}
|
||||
|
||||
private void WhenIValidate()
|
||||
{
|
||||
_result = _validator.Validate(_qosOptions);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,77 @@
|
||||
using FluentValidation.Results;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration.Validation
|
||||
{
|
||||
public class HostAndPortValidatorTests
|
||||
{
|
||||
private HostAndPortValidator _validator;
|
||||
private ValidationResult _result;
|
||||
private FileHostAndPort _hostAndPort;
|
||||
|
||||
public HostAndPortValidatorTests()
|
||||
{
|
||||
_validator = new HostAndPortValidator();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
public void should_be_invalid_because_host_empty(string host)
|
||||
{
|
||||
var fileHostAndPort = new FileHostAndPort
|
||||
{
|
||||
Host = host
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileHostAndPort))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInValid())
|
||||
.And(_ => ThenTheErorrIs())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_because_host_set()
|
||||
{
|
||||
var fileHostAndPort = new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileHostAndPort))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThe(FileHostAndPort hostAndPort)
|
||||
{
|
||||
_hostAndPort = hostAndPort;
|
||||
}
|
||||
|
||||
private void WhenIValidate()
|
||||
{
|
||||
_result = _validator.Validate(_hostAndPort);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheErorrIs()
|
||||
{
|
||||
_result.Errors[0].ErrorMessage.ShouldBe("When not using service discovery Host must be set on DownstreamHostAndPorts if you are not using ReRoute.Host or Ocelot cannot find your service!");
|
||||
}
|
||||
|
||||
private void ThenTheResultIsInValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
using FluentValidation.Results;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration.Validation
|
||||
{
|
||||
public class HostAndPortValidatorTests
|
||||
{
|
||||
private HostAndPortValidator _validator;
|
||||
private ValidationResult _result;
|
||||
private FileHostAndPort _hostAndPort;
|
||||
|
||||
public HostAndPortValidatorTests()
|
||||
{
|
||||
_validator = new HostAndPortValidator();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
public void should_be_invalid_because_host_empty(string host)
|
||||
{
|
||||
var fileHostAndPort = new FileHostAndPort
|
||||
{
|
||||
Host = host
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileHostAndPort))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInValid())
|
||||
.And(_ => ThenTheErorrIs())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_because_host_set()
|
||||
{
|
||||
var fileHostAndPort = new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileHostAndPort))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThe(FileHostAndPort hostAndPort)
|
||||
{
|
||||
_hostAndPort = hostAndPort;
|
||||
}
|
||||
|
||||
private void WhenIValidate()
|
||||
{
|
||||
_result = _validator.Validate(_hostAndPort);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheErorrIs()
|
||||
{
|
||||
_result.Errors[0].ErrorMessage.ShouldBe("When not using service discovery Host must be set on DownstreamHostAndPorts if you are not using Route.Host or Ocelot cannot find your service!");
|
||||
}
|
||||
|
||||
private void ThenTheResultIsInValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,433 +1,433 @@
|
||||
namespace Ocelot.UnitTests.Configuration.Validation
|
||||
{
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Ocelot.Requester;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ReRouteFluentValidatorTests
|
||||
{
|
||||
private readonly ReRouteFluentValidator _validator;
|
||||
private readonly Mock<IAuthenticationSchemeProvider> _authProvider;
|
||||
private QosDelegatingHandlerDelegate _qosDelegatingHandler;
|
||||
private Mock<IServiceProvider> _serviceProvider;
|
||||
private FileReRoute _reRoute;
|
||||
private ValidationResult _result;
|
||||
|
||||
public ReRouteFluentValidatorTests()
|
||||
{
|
||||
_authProvider = new Mock<IAuthenticationSchemeProvider>();
|
||||
_serviceProvider = new Mock<IServiceProvider>();
|
||||
// Todo - replace with mocks
|
||||
_validator = new ReRouteFluentValidator(_authProvider.Object, new HostAndPortValidator(), new FileQoSOptionsFluentValidator(_serviceProvider.Object));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void downstream_path_template_should_not_be_empty()
|
||||
{
|
||||
var fileReRoute = new FileReRoute();
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Downstream Path Template cannot be empty"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void upstream_path_template_should_not_be_empty()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Upstream Path Template cannot be empty"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void downstream_path_template_should_start_with_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Downstream Path Template test doesnt start with forward slash"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void downstream_path_template_should_not_contain_double_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "//test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Downstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://test")]
|
||||
[InlineData("http://test")]
|
||||
[InlineData("/test/http://")]
|
||||
[InlineData("/test/https://")]
|
||||
public void downstream_path_template_should_not_contain_scheme(string downstreamPathTemplate)
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = downstreamPathTemplate
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains($"Downstream Path Template {downstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void upstream_path_template_should_start_with_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Upstream Path Template test doesnt start with forward slash"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void upstream_path_template_should_not_contain_double_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "//test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Upstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://test")]
|
||||
[InlineData("http://test")]
|
||||
[InlineData("/test/http://")]
|
||||
[InlineData("/test/https://")]
|
||||
public void upstream_path_template_should_not_contain_scheme(string upstreamPathTemplate)
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = upstreamPathTemplate
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains($"Upstream Path Template {upstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_enable_rate_limiting_true_and_period_is_empty()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("RateLimitOptions.Period is empty"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_enable_rate_limiting_true_and_period_has_value()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true,
|
||||
Period = "test"
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("RateLimitOptions.Period does not contain integer then s (second), m (minute), h (hour), d (day) e.g. 1m for 1 minute period"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_specified_authentication_provider_isnt_registered()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "JwtLads"
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains($"Authentication Options AuthenticationProviderKey:JwtLads,AllowedScopes:[] is unsupported authentication provider"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_not_using_service_discovery_and_no_host_and_ports()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("When not using service discovery DownstreamHostAndPorts must be set and not empty or Ocelot cannot find your service!"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_if_using_service_discovery_and_no_host_and_ports()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
ServiceName = "Lads"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_re_route_using_host_and_port_and_paths()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_if_specified_authentication_provider_is_registered()
|
||||
{
|
||||
const string key = "JwtLads";
|
||||
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = key
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.And(_ => GivenAnAuthProvider(key))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("1.0")]
|
||||
[InlineData("1.1")]
|
||||
[InlineData("2.0")]
|
||||
[InlineData("1,0")]
|
||||
[InlineData("1,1")]
|
||||
[InlineData("2,0")]
|
||||
[InlineData("1")]
|
||||
[InlineData("2")]
|
||||
[InlineData("")]
|
||||
[InlineData(null)]
|
||||
public void should_be_valid_re_route_using_downstream_http_version(string version)
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000,
|
||||
},
|
||||
},
|
||||
DownstreamHttpVersion = version,
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("retg1.1")]
|
||||
[InlineData("re2.0")]
|
||||
[InlineData("1,0a")]
|
||||
[InlineData("a1,1")]
|
||||
[InlineData("12,0")]
|
||||
[InlineData("asdf")]
|
||||
public void should_be_invalid_re_route_using_downstream_http_version(string version)
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000,
|
||||
},
|
||||
},
|
||||
DownstreamHttpVersion = version,
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileReRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("'Downstream Http Version' is not in the correct format."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAnAuthProvider(string key)
|
||||
{
|
||||
var schemes = new List<AuthenticationScheme>
|
||||
{
|
||||
new AuthenticationScheme(key, key, typeof(FakeAutheHandler))
|
||||
};
|
||||
|
||||
_authProvider
|
||||
.Setup(x => x.GetAllSchemesAsync())
|
||||
.ReturnsAsync(schemes);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void GivenThe(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIValidate()
|
||||
{
|
||||
_result = _validator.Validate(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsInvalid()
|
||||
{
|
||||
_result.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenTheErrorsContains(string expected)
|
||||
{
|
||||
_result.Errors.ShouldContain(x => x.ErrorMessage == expected);
|
||||
}
|
||||
|
||||
private class FakeAutheHandler : IAuthenticationHandler
|
||||
{
|
||||
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<AuthenticateResult> AuthenticateAsync()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task ChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task ForbidAsync(AuthenticationProperties properties)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Configuration.Validation
|
||||
{
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Validator;
|
||||
using Ocelot.Requester;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RouteFluentValidatorTests
|
||||
{
|
||||
private readonly RouteFluentValidator _validator;
|
||||
private readonly Mock<IAuthenticationSchemeProvider> _authProvider;
|
||||
private QosDelegatingHandlerDelegate _qosDelegatingHandler;
|
||||
private Mock<IServiceProvider> _serviceProvider;
|
||||
private FileRoute _route;
|
||||
private ValidationResult _result;
|
||||
|
||||
public RouteFluentValidatorTests()
|
||||
{
|
||||
_authProvider = new Mock<IAuthenticationSchemeProvider>();
|
||||
_serviceProvider = new Mock<IServiceProvider>();
|
||||
// Todo - replace with mocks
|
||||
_validator = new RouteFluentValidator(_authProvider.Object, new HostAndPortValidator(), new FileQoSOptionsFluentValidator(_serviceProvider.Object));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void downstream_path_template_should_not_be_empty()
|
||||
{
|
||||
var fileRoute = new FileRoute();
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Downstream Path Template cannot be empty"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void upstream_path_template_should_not_be_empty()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Upstream Path Template cannot be empty"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void downstream_path_template_should_start_with_forward_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Downstream Path Template test doesnt start with forward slash"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void downstream_path_template_should_not_contain_double_forward_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "//test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Downstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://test")]
|
||||
[InlineData("http://test")]
|
||||
[InlineData("/test/http://")]
|
||||
[InlineData("/test/https://")]
|
||||
public void downstream_path_template_should_not_contain_scheme(string downstreamPathTemplate)
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = downstreamPathTemplate
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains($"Downstream Path Template {downstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void upstream_path_template_should_start_with_forward_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Upstream Path Template test doesnt start with forward slash"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void upstream_path_template_should_not_contain_double_forward_slash()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "//test"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("Upstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://test")]
|
||||
[InlineData("http://test")]
|
||||
[InlineData("/test/http://")]
|
||||
[InlineData("/test/https://")]
|
||||
public void upstream_path_template_should_not_contain_scheme(string upstreamPathTemplate)
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = upstreamPathTemplate
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains($"Upstream Path Template {upstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_enable_rate_limiting_true_and_period_is_empty()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("RateLimitOptions.Period is empty"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_enable_rate_limiting_true_and_period_has_value()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true,
|
||||
Period = "test"
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("RateLimitOptions.Period does not contain integer then s (second), m (minute), h (hour), d (day) e.g. 1m for 1 minute period"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_specified_authentication_provider_isnt_registered()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "JwtLads"
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains($"Authentication Options AuthenticationProviderKey:JwtLads,AllowedScopes:[] is unsupported authentication provider"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_be_valid_if_not_using_service_discovery_and_no_host_and_ports()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("When not using service discovery DownstreamHostAndPorts must be set and not empty or Ocelot cannot find your service!"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_if_using_service_discovery_and_no_host_and_ports()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
ServiceName = "Lads"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_re_route_using_host_and_port_and_paths()
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_valid_if_specified_authentication_provider_is_registered()
|
||||
{
|
||||
const string key = "JwtLads";
|
||||
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = key
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.And(_ => GivenAnAuthProvider(key))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("1.0")]
|
||||
[InlineData("1.1")]
|
||||
[InlineData("2.0")]
|
||||
[InlineData("1,0")]
|
||||
[InlineData("1,1")]
|
||||
[InlineData("2,0")]
|
||||
[InlineData("1")]
|
||||
[InlineData("2")]
|
||||
[InlineData("")]
|
||||
[InlineData(null)]
|
||||
public void should_be_valid_re_route_using_downstream_http_version(string version)
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000,
|
||||
},
|
||||
},
|
||||
DownstreamHttpVersion = version,
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("retg1.1")]
|
||||
[InlineData("re2.0")]
|
||||
[InlineData("1,0a")]
|
||||
[InlineData("a1,1")]
|
||||
[InlineData("12,0")]
|
||||
[InlineData("asdf")]
|
||||
public void should_be_invalid_re_route_using_downstream_http_version(string version)
|
||||
{
|
||||
var fileRoute = new FileRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/test",
|
||||
UpstreamPathTemplate = "/test",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 5000,
|
||||
},
|
||||
},
|
||||
DownstreamHttpVersion = version,
|
||||
};
|
||||
|
||||
this.Given(_ => GivenThe(fileRoute))
|
||||
.When(_ => WhenIValidate())
|
||||
.Then(_ => ThenTheResultIsInvalid())
|
||||
.And(_ => ThenTheErrorsContains("'Downstream Http Version' is not in the correct format."))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAnAuthProvider(string key)
|
||||
{
|
||||
var schemes = new List<AuthenticationScheme>
|
||||
{
|
||||
new AuthenticationScheme(key, key, typeof(FakeAutheHandler))
|
||||
};
|
||||
|
||||
_authProvider
|
||||
.Setup(x => x.GetAllSchemesAsync())
|
||||
.ReturnsAsync(schemes);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsValid()
|
||||
{
|
||||
_result.IsValid.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void GivenThe(FileRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIValidate()
|
||||
{
|
||||
_result = _validator.Validate(_route);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsInvalid()
|
||||
{
|
||||
_result.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenTheErrorsContains(string expected)
|
||||
{
|
||||
_result.Errors.ShouldContain(x => x.ErrorMessage == expected);
|
||||
}
|
||||
|
||||
private class FakeAutheHandler : IAuthenticationHandler
|
||||
{
|
||||
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<AuthenticateResult> AuthenticateAsync()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task ChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Task ForbidAsync(AuthenticationProperties properties)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,260 +1,260 @@
|
||||
namespace Ocelot.UnitTests.Consul
|
||||
{
|
||||
using global::Consul;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Logging;
|
||||
using Provider.Consul;
|
||||
using Responses;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ConsulFileConfigurationRepositoryTests
|
||||
{
|
||||
private ConsulFileConfigurationRepository _repo;
|
||||
private Mock<IOptions<FileConfiguration>> _options;
|
||||
private Mock<IOcelotCache<FileConfiguration>> _cache;
|
||||
private Mock<IConsulClientFactory> _factory;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IConsulClient> _client;
|
||||
private Mock<IKVEndpoint> _kvEndpoint;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private Response _setResult;
|
||||
private Response<FileConfiguration> _getResult;
|
||||
|
||||
public ConsulFileConfigurationRepositoryTests()
|
||||
{
|
||||
_cache = new Mock<IOcelotCache<FileConfiguration>>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
_options = new Mock<IOptions<FileConfiguration>>();
|
||||
_factory = new Mock<IConsulClientFactory>();
|
||||
_client = new Mock<IConsulClient>();
|
||||
_kvEndpoint = new Mock<IKVEndpoint>();
|
||||
|
||||
_client
|
||||
.Setup(x => x.KV)
|
||||
.Returns(_kvEndpoint.Object);
|
||||
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
||||
.Returns(_client.Object);
|
||||
|
||||
_options
|
||||
.SetupGet(x => x.Value)
|
||||
.Returns(() => _fileConfiguration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_config()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenWritingToConsulSucceeds())
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_config()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenFetchFromConsulSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_null_config()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.Given(_ => GivenFetchFromConsulReturnsNull())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_config_from_cache()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenFetchFromCacheSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_config_key()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenTheConfigKeyComesFromFileConfig("Tom"))
|
||||
.And(_ => GivenFetchFromConsulSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.And(_ => ThenTheConfigKeyIs("Tom"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_default_config_key()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenFetchFromConsulSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.And(_ => ThenTheConfigKeyIs("InternalConfiguration"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheConfigKeyIs(string expected)
|
||||
{
|
||||
_kvEndpoint
|
||||
.Verify(x => x.Get(expected, It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfigKeyComesFromFileConfig(string key)
|
||||
{
|
||||
_fileConfiguration.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = key;
|
||||
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsNull()
|
||||
{
|
||||
_getResult.Data.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIs(FileConfiguration config)
|
||||
{
|
||||
var expected = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
var result = JsonConvert.SerializeObject(_getResult.Data, Formatting.Indented);
|
||||
result.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private async Task WhenIGetTheConfiguration()
|
||||
{
|
||||
_getResult = await _repo.Get();
|
||||
}
|
||||
|
||||
private void GivenWritingToConsulSucceeds()
|
||||
{
|
||||
var response = new WriteResult<bool>();
|
||||
response.Response = true;
|
||||
|
||||
_kvEndpoint
|
||||
.Setup(x => x.Put(It.IsAny<KVPair>(), It.IsAny<CancellationToken>())).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void GivenFetchFromCacheSucceeds()
|
||||
{
|
||||
_cache.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>())).Returns(_fileConfiguration);
|
||||
}
|
||||
|
||||
private void GivenFetchFromConsulReturnsNull()
|
||||
{
|
||||
QueryResult<KVPair> result = new QueryResult<KVPair>();
|
||||
|
||||
_kvEndpoint
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(result);
|
||||
}
|
||||
|
||||
private void GivenFetchFromConsulSucceeds()
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_fileConfiguration, Formatting.Indented);
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(json);
|
||||
|
||||
var kvp = new KVPair("OcelotConfiguration");
|
||||
kvp.Value = bytes;
|
||||
|
||||
var query = new QueryResult<KVPair>();
|
||||
query.Response = kvp;
|
||||
|
||||
_kvEndpoint
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(query);
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsStoredAs(FileConfiguration config)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(json);
|
||||
|
||||
_kvEndpoint
|
||||
.Verify(x => x.Put(It.Is<KVPair>(k => k.Value.SequenceEqual(bytes)), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
private async Task WhenISetTheConfiguration()
|
||||
{
|
||||
_setResult = await _repo.Set(_fileConfiguration);
|
||||
}
|
||||
|
||||
private void GivenIHaveAConfiguration(FileConfiguration config)
|
||||
{
|
||||
_fileConfiguration = config;
|
||||
|
||||
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfiguration()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "123.12.12.12",
|
||||
Port = 80,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/asdfs/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Consul
|
||||
{
|
||||
using global::Consul;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Logging;
|
||||
using Provider.Consul;
|
||||
using Responses;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ConsulFileConfigurationRepositoryTests
|
||||
{
|
||||
private ConsulFileConfigurationRepository _repo;
|
||||
private Mock<IOptions<FileConfiguration>> _options;
|
||||
private Mock<IOcelotCache<FileConfiguration>> _cache;
|
||||
private Mock<IConsulClientFactory> _factory;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IConsulClient> _client;
|
||||
private Mock<IKVEndpoint> _kvEndpoint;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private Response _setResult;
|
||||
private Response<FileConfiguration> _getResult;
|
||||
|
||||
public ConsulFileConfigurationRepositoryTests()
|
||||
{
|
||||
_cache = new Mock<IOcelotCache<FileConfiguration>>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
_options = new Mock<IOptions<FileConfiguration>>();
|
||||
_factory = new Mock<IConsulClientFactory>();
|
||||
_client = new Mock<IConsulClient>();
|
||||
_kvEndpoint = new Mock<IKVEndpoint>();
|
||||
|
||||
_client
|
||||
.Setup(x => x.KV)
|
||||
.Returns(_kvEndpoint.Object);
|
||||
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
||||
.Returns(_client.Object);
|
||||
|
||||
_options
|
||||
.SetupGet(x => x.Value)
|
||||
.Returns(() => _fileConfiguration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_config()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenWritingToConsulSucceeds())
|
||||
.When(_ => WhenISetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_config()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenFetchFromConsulSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_null_config()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.Given(_ => GivenFetchFromConsulReturnsNull())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_config_from_cache()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenFetchFromCacheSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.Then(_ => ThenTheConfigurationIs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_config_key()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenTheConfigKeyComesFromFileConfig("Tom"))
|
||||
.And(_ => GivenFetchFromConsulSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.And(_ => ThenTheConfigKeyIs("Tom"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_default_config_key()
|
||||
{
|
||||
var config = FakeFileConfiguration();
|
||||
|
||||
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||
.And(_ => GivenFetchFromConsulSucceeds())
|
||||
.When(_ => WhenIGetTheConfiguration())
|
||||
.And(_ => ThenTheConfigKeyIs("InternalConfiguration"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheConfigKeyIs(string expected)
|
||||
{
|
||||
_kvEndpoint
|
||||
.Verify(x => x.Get(expected, It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfigKeyComesFromFileConfig(string key)
|
||||
{
|
||||
_fileConfiguration.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = key;
|
||||
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsNull()
|
||||
{
|
||||
_getResult.Data.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIs(FileConfiguration config)
|
||||
{
|
||||
var expected = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
var result = JsonConvert.SerializeObject(_getResult.Data, Formatting.Indented);
|
||||
result.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private async Task WhenIGetTheConfiguration()
|
||||
{
|
||||
_getResult = await _repo.Get();
|
||||
}
|
||||
|
||||
private void GivenWritingToConsulSucceeds()
|
||||
{
|
||||
var response = new WriteResult<bool>();
|
||||
response.Response = true;
|
||||
|
||||
_kvEndpoint
|
||||
.Setup(x => x.Put(It.IsAny<KVPair>(), It.IsAny<CancellationToken>())).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void GivenFetchFromCacheSucceeds()
|
||||
{
|
||||
_cache.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>())).Returns(_fileConfiguration);
|
||||
}
|
||||
|
||||
private void GivenFetchFromConsulReturnsNull()
|
||||
{
|
||||
QueryResult<KVPair> result = new QueryResult<KVPair>();
|
||||
|
||||
_kvEndpoint
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(result);
|
||||
}
|
||||
|
||||
private void GivenFetchFromConsulSucceeds()
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_fileConfiguration, Formatting.Indented);
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(json);
|
||||
|
||||
var kvp = new KVPair("OcelotConfiguration");
|
||||
kvp.Value = bytes;
|
||||
|
||||
var query = new QueryResult<KVPair>();
|
||||
query.Response = kvp;
|
||||
|
||||
_kvEndpoint
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(query);
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsStoredAs(FileConfiguration config)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(json);
|
||||
|
||||
_kvEndpoint
|
||||
.Verify(x => x.Put(It.Is<KVPair>(k => k.Value.SequenceEqual(bytes)), It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
private async Task WhenISetTheConfiguration()
|
||||
{
|
||||
_setResult = await _repo.Set(_fileConfiguration);
|
||||
}
|
||||
|
||||
private void GivenIHaveAConfiguration(FileConfiguration config)
|
||||
{
|
||||
_fileConfiguration = config;
|
||||
|
||||
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfiguration()
|
||||
{
|
||||
var routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "123.12.12.12",
|
||||
Port = 80,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/asdfs/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
Routes = routes
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
using Ocelot.Configuration.Builder;
|
||||
|
||||
namespace Ocelot.UnitTests.Consul
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Logging;
|
||||
using Provider.Consul;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
public class ProviderFactoryTests
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public ProviderFactoryTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
loggerFactory.Setup(x => x.CreateLogger<Consul>()).Returns(logger.Object);
|
||||
loggerFactory.Setup(x => x.CreateLogger<PollConsul>()).Returns(logger.Object);
|
||||
var consulFactory = new Mock<IConsulClientFactory>();
|
||||
services.AddSingleton<IConsulClientFactory>(consulFactory.Object);
|
||||
services.AddSingleton<IOcelotLoggerFactory>(loggerFactory.Object);
|
||||
_provider = services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ConsulServiceDiscoveryProvider()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("")
|
||||
.Build();
|
||||
|
||||
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", "", 1, "", "", 1), reRoute);
|
||||
provider.ShouldBeOfType<Consul>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_PollingConsulServiceDiscoveryProvider()
|
||||
{
|
||||
var stopsPollerFromPolling = 10000;
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("")
|
||||
.Build();
|
||||
|
||||
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "http", "", 1, "", "", stopsPollerFromPolling), reRoute);
|
||||
var pollProvider = provider as PollConsul;
|
||||
pollProvider.ShouldNotBeNull();
|
||||
pollProvider.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration.Builder;
|
||||
|
||||
namespace Ocelot.UnitTests.Consul
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Logging;
|
||||
using Provider.Consul;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
public class ProviderFactoryTests
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public ProviderFactoryTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
loggerFactory.Setup(x => x.CreateLogger<Consul>()).Returns(logger.Object);
|
||||
loggerFactory.Setup(x => x.CreateLogger<PollConsul>()).Returns(logger.Object);
|
||||
var consulFactory = new Mock<IConsulClientFactory>();
|
||||
services.AddSingleton<IConsulClientFactory>(consulFactory.Object);
|
||||
services.AddSingleton<IOcelotLoggerFactory>(loggerFactory.Object);
|
||||
_provider = services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ConsulServiceDiscoveryProvider()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("")
|
||||
.Build();
|
||||
|
||||
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", "", 1, "", "", 1), route);
|
||||
provider.ShouldBeOfType<Consul>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_PollingConsulServiceDiscoveryProvider()
|
||||
{
|
||||
var stopsPollerFromPolling = 10000;
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("")
|
||||
.Build();
|
||||
|
||||
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "http", "", 1, "", "", stopsPollerFromPolling), route);
|
||||
var pollProvider = provider as PollConsul;
|
||||
pollProvider.ShouldNotBeNull();
|
||||
pollProvider.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,334 +1,334 @@
|
||||
namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ConfigurationBuilderExtensionsTests
|
||||
{
|
||||
private IConfigurationRoot _configuration;
|
||||
private string _result;
|
||||
private IConfigurationRoot _configRoot;
|
||||
private FileConfiguration _globalConfig;
|
||||
private FileConfiguration _reRouteA;
|
||||
private FileConfiguration _reRouteB;
|
||||
private FileConfiguration _aggregate;
|
||||
private FileConfiguration _envSpecific;
|
||||
private Mock<IWebHostEnvironment> _hostingEnvironment;
|
||||
|
||||
public ConfigurationBuilderExtensionsTests()
|
||||
{
|
||||
_hostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
// Clean up config files before each test
|
||||
var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");
|
||||
|
||||
foreach (var config in subConfigFiles)
|
||||
{
|
||||
config.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_base_url_to_config()
|
||||
{
|
||||
this.Given(_ => GivenTheBaseUrl("test"))
|
||||
.When(_ => WhenIGet("BaseUrl"))
|
||||
.Then(_ => ThenTheResultIs("test"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_merge_files()
|
||||
{
|
||||
this.Given(_ => GivenMultipleConfigurationFiles("", false))
|
||||
.And(_ => GivenTheEnvironmentIs(null))
|
||||
.When(_ => WhenIAddOcelotConfiguration())
|
||||
.Then(_ => ThenTheConfigsAreMerged())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_merge_files_except_env()
|
||||
{
|
||||
this.Given(_ => GivenMultipleConfigurationFiles("", true))
|
||||
.And(_ => GivenTheEnvironmentIs("Env"))
|
||||
.When(_ => WhenIAddOcelotConfiguration())
|
||||
.Then(_ => ThenTheConfigsAreMerged())
|
||||
.And(_ => NotContainsEnvSpecificConfig())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_merge_files_in_specific_folder()
|
||||
{
|
||||
string configFolder = "ConfigFiles";
|
||||
this.Given(_ => GivenMultipleConfigurationFiles(configFolder, false))
|
||||
.When(_ => WhenIAddOcelotConfigurationWithSpecificFolder(configFolder))
|
||||
.Then(_ => ThenTheConfigsAreMerged())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenMultipleConfigurationFiles(string folder, bool addEnvSpecificConfig)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(folder))
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
|
||||
_globalConfig = new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
BaseUrl = "BaseUrl",
|
||||
RateLimitOptions = new FileRateLimitOptions
|
||||
{
|
||||
HttpStatusCode = 500,
|
||||
ClientIdHeader = "ClientIdHeader",
|
||||
DisableRateLimitHeaders = true,
|
||||
QuotaExceededMessage = "QuotaExceededMessage",
|
||||
RateLimitCounterPrefix = "RateLimitCounterPrefix"
|
||||
},
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Host = "Host",
|
||||
Port = 80,
|
||||
Type = "Type"
|
||||
},
|
||||
RequestIdKey = "RequestIdKey"
|
||||
}
|
||||
};
|
||||
|
||||
_reRouteA = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamScheme",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplate",
|
||||
Key = "Key",
|
||||
UpstreamHost = "UpstreamHost",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethod"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "Host",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_reRouteB = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamSchemeB",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplateB",
|
||||
Key = "KeyB",
|
||||
UpstreamHost = "UpstreamHostB",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethodB"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "HostB",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamSchemeBB",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplateBB",
|
||||
Key = "KeyBB",
|
||||
UpstreamHost = "UpstreamHostBB",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethodBB"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "HostBB",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_aggregate = new FileConfiguration
|
||||
{
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"KeyB",
|
||||
"KeyBB"
|
||||
},
|
||||
UpstreamPathTemplate = "UpstreamPathTemplate",
|
||||
},
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"KeyB",
|
||||
"KeyBB"
|
||||
},
|
||||
UpstreamPathTemplate = "UpstreamPathTemplate",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_envSpecific = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamSchemeSpec",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplateSpec",
|
||||
Key = "KeySpec",
|
||||
UpstreamHost = "UpstreamHostSpec",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethodSpec"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "HostSpec",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
string globalFilename = Path.Combine(folder, "ocelot.global.json");
|
||||
string reroutesAFilename = Path.Combine(folder, "ocelot.reRoutesA.json");
|
||||
string reroutesBFilename = Path.Combine(folder, "ocelot.reRoutesB.json");
|
||||
string aggregatesFilename = Path.Combine(folder, "ocelot.aggregates.json");
|
||||
|
||||
File.WriteAllText(globalFilename, JsonConvert.SerializeObject(_globalConfig));
|
||||
File.WriteAllText(reroutesAFilename, JsonConvert.SerializeObject(_reRouteA));
|
||||
File.WriteAllText(reroutesBFilename, JsonConvert.SerializeObject(_reRouteB));
|
||||
File.WriteAllText(aggregatesFilename, JsonConvert.SerializeObject(_aggregate));
|
||||
|
||||
if (addEnvSpecificConfig)
|
||||
{
|
||||
string envSpecificFilename = Path.Combine(folder, "ocelot.Env.json");
|
||||
File.WriteAllText(envSpecificFilename, JsonConvert.SerializeObject(_envSpecific));
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheEnvironmentIs(string env)
|
||||
{
|
||||
_hostingEnvironment.SetupGet(x => x.EnvironmentName).Returns(env);
|
||||
}
|
||||
|
||||
private void WhenIAddOcelotConfiguration()
|
||||
{
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder();
|
||||
|
||||
builder.AddOcelot(_hostingEnvironment.Object);
|
||||
|
||||
_configRoot = builder.Build();
|
||||
}
|
||||
|
||||
private void WhenIAddOcelotConfigurationWithSpecificFolder(string folder)
|
||||
{
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder();
|
||||
builder.AddOcelot(folder, _hostingEnvironment.Object);
|
||||
_configRoot = builder.Build();
|
||||
}
|
||||
|
||||
private void ThenTheConfigsAreMerged()
|
||||
{
|
||||
var fc = (FileConfiguration)_configRoot.Get(typeof(FileConfiguration));
|
||||
|
||||
fc.GlobalConfiguration.BaseUrl.ShouldBe(_globalConfig.GlobalConfiguration.BaseUrl);
|
||||
fc.GlobalConfiguration.RateLimitOptions.ClientIdHeader.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.ClientIdHeader);
|
||||
fc.GlobalConfiguration.RateLimitOptions.DisableRateLimitHeaders.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.DisableRateLimitHeaders);
|
||||
fc.GlobalConfiguration.RateLimitOptions.HttpStatusCode.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.HttpStatusCode);
|
||||
fc.GlobalConfiguration.RateLimitOptions.QuotaExceededMessage.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.QuotaExceededMessage);
|
||||
fc.GlobalConfiguration.RateLimitOptions.RateLimitCounterPrefix.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.RateLimitCounterPrefix);
|
||||
fc.GlobalConfiguration.RequestIdKey.ShouldBe(_globalConfig.GlobalConfiguration.RequestIdKey);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Type.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Type);
|
||||
|
||||
fc.ReRoutes.Count.ShouldBe(_reRouteA.ReRoutes.Count + _reRouteB.ReRoutes.Count);
|
||||
|
||||
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteA.ReRoutes[0].DownstreamPathTemplate);
|
||||
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteB.ReRoutes[0].DownstreamPathTemplate);
|
||||
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteB.ReRoutes[1].DownstreamPathTemplate);
|
||||
|
||||
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteA.ReRoutes[0].DownstreamScheme);
|
||||
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteB.ReRoutes[0].DownstreamScheme);
|
||||
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteB.ReRoutes[1].DownstreamScheme);
|
||||
|
||||
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteA.ReRoutes[0].Key);
|
||||
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteB.ReRoutes[0].Key);
|
||||
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteB.ReRoutes[1].Key);
|
||||
|
||||
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteA.ReRoutes[0].UpstreamHost);
|
||||
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteB.ReRoutes[0].UpstreamHost);
|
||||
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteB.ReRoutes[1].UpstreamHost);
|
||||
|
||||
fc.Aggregates.Count.ShouldBe(_aggregate.Aggregates.Count);
|
||||
}
|
||||
|
||||
private void NotContainsEnvSpecificConfig()
|
||||
{
|
||||
var fc = (FileConfiguration)_configRoot.Get(typeof(FileConfiguration));
|
||||
fc.ReRoutes.ShouldNotContain(x => x.DownstreamScheme == _envSpecific.ReRoutes[0].DownstreamScheme);
|
||||
fc.ReRoutes.ShouldNotContain(x => x.DownstreamPathTemplate == _envSpecific.ReRoutes[0].DownstreamPathTemplate);
|
||||
fc.ReRoutes.ShouldNotContain(x => x.Key == _envSpecific.ReRoutes[0].Key);
|
||||
}
|
||||
|
||||
private void GivenTheBaseUrl(string baseUrl)
|
||||
{
|
||||
#pragma warning disable CS0618
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddOcelotBaseUrl(baseUrl);
|
||||
#pragma warning restore CS0618
|
||||
_configuration = builder.Build();
|
||||
}
|
||||
|
||||
private void WhenIGet(string key)
|
||||
{
|
||||
_result = _configuration.GetValue(key, "");
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ConfigurationBuilderExtensionsTests
|
||||
{
|
||||
private IConfigurationRoot _configuration;
|
||||
private string _result;
|
||||
private IConfigurationRoot _configRoot;
|
||||
private FileConfiguration _globalConfig;
|
||||
private FileConfiguration _routeA;
|
||||
private FileConfiguration _routeB;
|
||||
private FileConfiguration _aggregate;
|
||||
private FileConfiguration _envSpecific;
|
||||
private Mock<IWebHostEnvironment> _hostingEnvironment;
|
||||
|
||||
public ConfigurationBuilderExtensionsTests()
|
||||
{
|
||||
_hostingEnvironment = new Mock<IWebHostEnvironment>();
|
||||
// Clean up config files before each test
|
||||
var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");
|
||||
|
||||
foreach (var config in subConfigFiles)
|
||||
{
|
||||
config.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_base_url_to_config()
|
||||
{
|
||||
this.Given(_ => GivenTheBaseUrl("test"))
|
||||
.When(_ => WhenIGet("BaseUrl"))
|
||||
.Then(_ => ThenTheResultIs("test"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_merge_files()
|
||||
{
|
||||
this.Given(_ => GivenMultipleConfigurationFiles("", false))
|
||||
.And(_ => GivenTheEnvironmentIs(null))
|
||||
.When(_ => WhenIAddOcelotConfiguration())
|
||||
.Then(_ => ThenTheConfigsAreMerged())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_merge_files_except_env()
|
||||
{
|
||||
this.Given(_ => GivenMultipleConfigurationFiles("", true))
|
||||
.And(_ => GivenTheEnvironmentIs("Env"))
|
||||
.When(_ => WhenIAddOcelotConfiguration())
|
||||
.Then(_ => ThenTheConfigsAreMerged())
|
||||
.And(_ => NotContainsEnvSpecificConfig())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_merge_files_in_specific_folder()
|
||||
{
|
||||
string configFolder = "ConfigFiles";
|
||||
this.Given(_ => GivenMultipleConfigurationFiles(configFolder, false))
|
||||
.When(_ => WhenIAddOcelotConfigurationWithSpecificFolder(configFolder))
|
||||
.Then(_ => ThenTheConfigsAreMerged())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenMultipleConfigurationFiles(string folder, bool addEnvSpecificConfig)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(folder))
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
|
||||
_globalConfig = new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
BaseUrl = "BaseUrl",
|
||||
RateLimitOptions = new FileRateLimitOptions
|
||||
{
|
||||
HttpStatusCode = 500,
|
||||
ClientIdHeader = "ClientIdHeader",
|
||||
DisableRateLimitHeaders = true,
|
||||
QuotaExceededMessage = "QuotaExceededMessage",
|
||||
RateLimitCounterPrefix = "RateLimitCounterPrefix"
|
||||
},
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Scheme = "https",
|
||||
Host = "Host",
|
||||
Port = 80,
|
||||
Type = "Type"
|
||||
},
|
||||
RequestIdKey = "RequestIdKey"
|
||||
}
|
||||
};
|
||||
|
||||
_routeA = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamScheme",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplate",
|
||||
Key = "Key",
|
||||
UpstreamHost = "UpstreamHost",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethod"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "Host",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_routeB = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamSchemeB",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplateB",
|
||||
Key = "KeyB",
|
||||
UpstreamHost = "UpstreamHostB",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethodB"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "HostB",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
},
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamSchemeBB",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplateBB",
|
||||
Key = "KeyBB",
|
||||
UpstreamHost = "UpstreamHostBB",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethodBB"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "HostBB",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_aggregate = new FileConfiguration
|
||||
{
|
||||
Aggregates = new List<FileAggregateRoute>
|
||||
{
|
||||
new FileAggregateRoute
|
||||
{
|
||||
RouteKeys = new List<string>
|
||||
{
|
||||
"KeyB",
|
||||
"KeyBB"
|
||||
},
|
||||
UpstreamPathTemplate = "UpstreamPathTemplate",
|
||||
},
|
||||
new FileAggregateRoute
|
||||
{
|
||||
RouteKeys = new List<string>
|
||||
{
|
||||
"KeyB",
|
||||
"KeyBB"
|
||||
},
|
||||
UpstreamPathTemplate = "UpstreamPathTemplate",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_envSpecific = new FileConfiguration
|
||||
{
|
||||
Routes = new List<FileRoute>
|
||||
{
|
||||
new FileRoute
|
||||
{
|
||||
DownstreamScheme = "DownstreamSchemeSpec",
|
||||
DownstreamPathTemplate = "DownstreamPathTemplateSpec",
|
||||
Key = "KeySpec",
|
||||
UpstreamHost = "UpstreamHostSpec",
|
||||
UpstreamHttpMethod = new List<string>
|
||||
{
|
||||
"UpstreamHttpMethodSpec"
|
||||
},
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "HostSpec",
|
||||
Port = 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
string globalFilename = Path.Combine(folder, "ocelot.global.json");
|
||||
string routesAFilename = Path.Combine(folder, "ocelot.routesA.json");
|
||||
string routesBFilename = Path.Combine(folder, "ocelot.routesB.json");
|
||||
string aggregatesFilename = Path.Combine(folder, "ocelot.aggregates.json");
|
||||
|
||||
File.WriteAllText(globalFilename, JsonConvert.SerializeObject(_globalConfig));
|
||||
File.WriteAllText(routesAFilename, JsonConvert.SerializeObject(_routeA));
|
||||
File.WriteAllText(routesBFilename, JsonConvert.SerializeObject(_routeB));
|
||||
File.WriteAllText(aggregatesFilename, JsonConvert.SerializeObject(_aggregate));
|
||||
|
||||
if (addEnvSpecificConfig)
|
||||
{
|
||||
string envSpecificFilename = Path.Combine(folder, "ocelot.Env.json");
|
||||
File.WriteAllText(envSpecificFilename, JsonConvert.SerializeObject(_envSpecific));
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheEnvironmentIs(string env)
|
||||
{
|
||||
_hostingEnvironment.SetupGet(x => x.EnvironmentName).Returns(env);
|
||||
}
|
||||
|
||||
private void WhenIAddOcelotConfiguration()
|
||||
{
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder();
|
||||
|
||||
builder.AddOcelot(_hostingEnvironment.Object);
|
||||
|
||||
_configRoot = builder.Build();
|
||||
}
|
||||
|
||||
private void WhenIAddOcelotConfigurationWithSpecificFolder(string folder)
|
||||
{
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder();
|
||||
builder.AddOcelot(folder, _hostingEnvironment.Object);
|
||||
_configRoot = builder.Build();
|
||||
}
|
||||
|
||||
private void ThenTheConfigsAreMerged()
|
||||
{
|
||||
var fc = (FileConfiguration)_configRoot.Get(typeof(FileConfiguration));
|
||||
|
||||
fc.GlobalConfiguration.BaseUrl.ShouldBe(_globalConfig.GlobalConfiguration.BaseUrl);
|
||||
fc.GlobalConfiguration.RateLimitOptions.ClientIdHeader.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.ClientIdHeader);
|
||||
fc.GlobalConfiguration.RateLimitOptions.DisableRateLimitHeaders.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.DisableRateLimitHeaders);
|
||||
fc.GlobalConfiguration.RateLimitOptions.HttpStatusCode.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.HttpStatusCode);
|
||||
fc.GlobalConfiguration.RateLimitOptions.QuotaExceededMessage.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.QuotaExceededMessage);
|
||||
fc.GlobalConfiguration.RateLimitOptions.RateLimitCounterPrefix.ShouldBe(_globalConfig.GlobalConfiguration.RateLimitOptions.RateLimitCounterPrefix);
|
||||
fc.GlobalConfiguration.RequestIdKey.ShouldBe(_globalConfig.GlobalConfiguration.RequestIdKey);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
fc.GlobalConfiguration.ServiceDiscoveryProvider.Type.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Type);
|
||||
|
||||
fc.Routes.Count.ShouldBe(_routeA.Routes.Count + _routeB.Routes.Count);
|
||||
|
||||
fc.Routes.ShouldContain(x => x.DownstreamPathTemplate == _routeA.Routes[0].DownstreamPathTemplate);
|
||||
fc.Routes.ShouldContain(x => x.DownstreamPathTemplate == _routeB.Routes[0].DownstreamPathTemplate);
|
||||
fc.Routes.ShouldContain(x => x.DownstreamPathTemplate == _routeB.Routes[1].DownstreamPathTemplate);
|
||||
|
||||
fc.Routes.ShouldContain(x => x.DownstreamScheme == _routeA.Routes[0].DownstreamScheme);
|
||||
fc.Routes.ShouldContain(x => x.DownstreamScheme == _routeB.Routes[0].DownstreamScheme);
|
||||
fc.Routes.ShouldContain(x => x.DownstreamScheme == _routeB.Routes[1].DownstreamScheme);
|
||||
|
||||
fc.Routes.ShouldContain(x => x.Key == _routeA.Routes[0].Key);
|
||||
fc.Routes.ShouldContain(x => x.Key == _routeB.Routes[0].Key);
|
||||
fc.Routes.ShouldContain(x => x.Key == _routeB.Routes[1].Key);
|
||||
|
||||
fc.Routes.ShouldContain(x => x.UpstreamHost == _routeA.Routes[0].UpstreamHost);
|
||||
fc.Routes.ShouldContain(x => x.UpstreamHost == _routeB.Routes[0].UpstreamHost);
|
||||
fc.Routes.ShouldContain(x => x.UpstreamHost == _routeB.Routes[1].UpstreamHost);
|
||||
|
||||
fc.Aggregates.Count.ShouldBe(_aggregate.Aggregates.Count);
|
||||
}
|
||||
|
||||
private void NotContainsEnvSpecificConfig()
|
||||
{
|
||||
var fc = (FileConfiguration)_configRoot.Get(typeof(FileConfiguration));
|
||||
fc.Routes.ShouldNotContain(x => x.DownstreamScheme == _envSpecific.Routes[0].DownstreamScheme);
|
||||
fc.Routes.ShouldNotContain(x => x.DownstreamPathTemplate == _envSpecific.Routes[0].DownstreamPathTemplate);
|
||||
fc.Routes.ShouldNotContain(x => x.Key == _envSpecific.Routes[0].Key);
|
||||
}
|
||||
|
||||
private void GivenTheBaseUrl(string baseUrl)
|
||||
{
|
||||
#pragma warning disable CS0618
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddOcelotBaseUrl(baseUrl);
|
||||
#pragma warning restore CS0618
|
||||
_configuration = builder.Build();
|
||||
}
|
||||
|
||||
private void WhenIGet(string key)
|
||||
{
|
||||
_result = _configuration.GetValue(key, "");
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,403 +1,403 @@
|
||||
namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Infrastructure;
|
||||
using Ocelot.Multiplexer;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.UnitTests.Requester;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Infrastructure;
|
||||
using Ocelot.Multiplexer;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.UnitTests.Requester;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using static Ocelot.UnitTests.Multiplexing.UserDefinedResponseAggregatorTests;
|
||||
|
||||
public class OcelotBuilderTests
|
||||
{
|
||||
private readonly IServiceCollection _services;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private readonly IConfiguration _configRoot;
|
||||
private IOcelotBuilder _ocelotBuilder;
|
||||
private readonly int _maxRetries;
|
||||
private Exception _ex;
|
||||
|
||||
public OcelotBuilderTests()
|
||||
{
|
||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||
_services = new ServiceCollection();
|
||||
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||
_services.AddSingleton(_configRoot);
|
||||
_maxRetries = 100;
|
||||
}
|
||||
|
||||
private IWebHostEnvironment GetHostingEnvironment()
|
||||
{
|
||||
var environment = new Mock<IWebHostEnvironment>();
|
||||
environment
|
||||
.Setup(e => e.ApplicationName)
|
||||
.Returns(typeof(OcelotBuilderTests).GetTypeInfo().Assembly.GetName().Name);
|
||||
|
||||
return environment.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_specific_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddSpecificTransientDelegatingHandler<FakeDelegatingHandler>())
|
||||
.And(x => AddSpecificTransientDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheSpecificHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_type_specific_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandler)))
|
||||
.And(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandlerTwo)))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheSpecificHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_global_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
|
||||
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheGlobalHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_global_type_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
|
||||
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheGlobalHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_services()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ocelot_builder()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnOcelotBuilderIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_logger_factory()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenIValidateScopes())
|
||||
.When(x => WhenIAccessLoggerFactory())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_without_passing_in_config()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServicesWithoutConfig())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_singleton_defined_aggregators()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddSingletonDefinedAggregator<TestDefinedAggregator>())
|
||||
.When(x => AddSingletonDefinedAggregator<TestDefinedAggregator>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.And(x => ThenTheAggregatorsAreSingleton<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_transient_defined_aggregators()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTransientDefinedAggregator<TestDefinedAggregator>())
|
||||
.When(x => AddTransientDefinedAggregator<TestDefinedAggregator>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.And(x => ThenTheAggregatorsAreTransient<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_default_ctor()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer<FakeCustomLoadBalancer>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_factory_method()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer(() => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_di_factory_method()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer(provider => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_factory_method_with_arguments()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer((reroute, discoveryProvider) => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_iplaceholder()
|
||||
{
|
||||
this.Given(x => x.WhenISetUpOcelotServices())
|
||||
.When(x => AddConfigPlaceholders())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.And(x => ThenTheIPlaceholderInstanceIsReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer((provider, reroute, discoveryProvider) => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void AddSingletonDefinedAggregator<T>()
|
||||
where T : class, IDefinedAggregator
|
||||
{
|
||||
_ocelotBuilder.AddSingletonDefinedAggregator<T>();
|
||||
}
|
||||
|
||||
private void AddTransientDefinedAggregator<T>()
|
||||
where T : class, IDefinedAggregator
|
||||
{
|
||||
_ocelotBuilder.AddTransientDefinedAggregator<T>();
|
||||
}
|
||||
|
||||
private void AddConfigPlaceholders()
|
||||
{
|
||||
_ocelotBuilder.AddConfigPlaceholders();
|
||||
}
|
||||
|
||||
private void ThenTheSpecificHandlersAreTransient()
|
||||
{
|
||||
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||
var first = handlers[0];
|
||||
handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||
var second = handlers[0];
|
||||
first.ShouldNotBe(second);
|
||||
}
|
||||
|
||||
private void ThenTheGlobalHandlersAreTransient()
|
||||
{
|
||||
var handlers = _serviceProvider.GetServices<GlobalDelegatingHandler>().ToList();
|
||||
var first = handlers[0].DelegatingHandler;
|
||||
handlers = _serviceProvider.GetServices<GlobalDelegatingHandler>().ToList();
|
||||
var second = handlers[0].DelegatingHandler;
|
||||
first.ShouldNotBe(second);
|
||||
}
|
||||
|
||||
private void AddTransientGlobalDelegatingHandler<T>()
|
||||
where T : DelegatingHandler
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler<T>(true);
|
||||
}
|
||||
|
||||
private void AddSpecificTransientDelegatingHandler<T>()
|
||||
where T : DelegatingHandler
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler<T>();
|
||||
}
|
||||
|
||||
private void AddTypeTransientGlobalDelegatingHandler(Type type)
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler(type, true);
|
||||
}
|
||||
|
||||
private void AddTypeSpecificTransientDelegatingHandler(Type type)
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler(type);
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsHandlers<TOne, TWo>()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var handlers = _serviceProvider.GetServices<GlobalDelegatingHandler>().ToList();
|
||||
handlers[0].DelegatingHandler.ShouldBeOfType<TOne>();
|
||||
handlers[1].DelegatingHandler.ShouldBeOfType<TWo>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<TOne, TWo>()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||
handlers[0].ShouldBeOfType<TOne>();
|
||||
handlers[1].ShouldBeOfType<TWo>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TOne, TWo>()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var handlers = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
handlers[0].ShouldBeOfType<TOne>();
|
||||
handlers[1].ShouldBeOfType<TWo>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var creators = _serviceProvider.GetServices<ILoadBalancerCreator>().ToList();
|
||||
creators.Count(c => c.GetType() == typeof(NoLoadBalancerCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(RoundRobinCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(CookieStickySessionsCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(LeastConnectionCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(DelegateInvokingLoadBalancerCreator<FakeCustomLoadBalancer>)).ShouldBe(1);
|
||||
}
|
||||
|
||||
private void ThenTheAggregatorsAreTransient<TOne, TWo>()
|
||||
{
|
||||
var aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var first = aggregators[0];
|
||||
aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var second = aggregators[0];
|
||||
first.ShouldNotBe(second);
|
||||
}
|
||||
|
||||
private void ThenTheAggregatorsAreSingleton<TOne, TWo>()
|
||||
{
|
||||
var aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var first = aggregators[0];
|
||||
aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var second = aggregators[0];
|
||||
first.ShouldBe(second);
|
||||
}
|
||||
|
||||
private void ThenAnOcelotBuilderIsReturned()
|
||||
{
|
||||
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
||||
}
|
||||
|
||||
private void ThenTheIPlaceholderInstanceIsReplaced()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var placeholders = _serviceProvider.GetService<IPlaceholders>();
|
||||
placeholders.ShouldBeOfType<ConfigAwarePlaceholders>();
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServices()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot(_configRoot);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServicesWithoutConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIAccessLoggerFactory()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var logger = _serviceProvider.GetService<IFileConfigurationSetter>();
|
||||
logger.ShouldNotBeNull();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIValidateScopes()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenAnExceptionIsntThrown()
|
||||
{
|
||||
_ex.ShouldBeNull();
|
||||
}
|
||||
|
||||
private class FakeCustomLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public Task<Response<ServiceHostAndPort>> Lease(HttpContext httpContext)
|
||||
{
|
||||
// Not relevant for these tests
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Release(ServiceHostAndPort hostAndPort)
|
||||
{
|
||||
// Not relevant for these tests
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public class OcelotBuilderTests
|
||||
{
|
||||
private readonly IServiceCollection _services;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private readonly IConfiguration _configRoot;
|
||||
private IOcelotBuilder _ocelotBuilder;
|
||||
private readonly int _maxRetries;
|
||||
private Exception _ex;
|
||||
|
||||
public OcelotBuilderTests()
|
||||
{
|
||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||
_services = new ServiceCollection();
|
||||
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
|
||||
_services.AddSingleton(_configRoot);
|
||||
_maxRetries = 100;
|
||||
}
|
||||
|
||||
private IWebHostEnvironment GetHostingEnvironment()
|
||||
{
|
||||
var environment = new Mock<IWebHostEnvironment>();
|
||||
environment
|
||||
.Setup(e => e.ApplicationName)
|
||||
.Returns(typeof(OcelotBuilderTests).GetTypeInfo().Assembly.GetName().Name);
|
||||
|
||||
return environment.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_specific_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddSpecificTransientDelegatingHandler<FakeDelegatingHandler>())
|
||||
.And(x => AddSpecificTransientDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheSpecificHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_type_specific_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandler)))
|
||||
.And(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandlerTwo)))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheSpecificHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_global_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
|
||||
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheGlobalHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_global_type_delegating_handlers_transient()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
|
||||
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => ThenTheGlobalHandlersAreTransient())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_services()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ocelot_builder()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnOcelotBuilderIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_logger_factory()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenIValidateScopes())
|
||||
.When(x => WhenIAccessLoggerFactory())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_without_passing_in_config()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServicesWithoutConfig())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_singleton_defined_aggregators()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddSingletonDefinedAggregator<TestDefinedAggregator>())
|
||||
.When(x => AddSingletonDefinedAggregator<TestDefinedAggregator>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.And(x => ThenTheAggregatorsAreSingleton<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_transient_defined_aggregators()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddTransientDefinedAggregator<TestDefinedAggregator>())
|
||||
.When(x => AddTransientDefinedAggregator<TestDefinedAggregator>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.And(x => ThenTheAggregatorsAreTransient<TestDefinedAggregator, TestDefinedAggregator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_default_ctor()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer<FakeCustomLoadBalancer>())
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_factory_method()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer(() => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_di_factory_method()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer(provider => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators_by_factory_method_with_arguments()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer((route, discoveryProvider) => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_iplaceholder()
|
||||
{
|
||||
this.Given(x => x.WhenISetUpOcelotServices())
|
||||
.When(x => AddConfigPlaceholders())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.And(x => ThenTheIPlaceholderInstanceIsReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_custom_load_balancer_creators()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => _ocelotBuilder.AddCustomLoadBalancer((provider, route, discoveryProvider) => new FakeCustomLoadBalancer()))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void AddSingletonDefinedAggregator<T>()
|
||||
where T : class, IDefinedAggregator
|
||||
{
|
||||
_ocelotBuilder.AddSingletonDefinedAggregator<T>();
|
||||
}
|
||||
|
||||
private void AddTransientDefinedAggregator<T>()
|
||||
where T : class, IDefinedAggregator
|
||||
{
|
||||
_ocelotBuilder.AddTransientDefinedAggregator<T>();
|
||||
}
|
||||
|
||||
private void AddConfigPlaceholders()
|
||||
{
|
||||
_ocelotBuilder.AddConfigPlaceholders();
|
||||
}
|
||||
|
||||
private void ThenTheSpecificHandlersAreTransient()
|
||||
{
|
||||
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||
var first = handlers[0];
|
||||
handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||
var second = handlers[0];
|
||||
first.ShouldNotBe(second);
|
||||
}
|
||||
|
||||
private void ThenTheGlobalHandlersAreTransient()
|
||||
{
|
||||
var handlers = _serviceProvider.GetServices<GlobalDelegatingHandler>().ToList();
|
||||
var first = handlers[0].DelegatingHandler;
|
||||
handlers = _serviceProvider.GetServices<GlobalDelegatingHandler>().ToList();
|
||||
var second = handlers[0].DelegatingHandler;
|
||||
first.ShouldNotBe(second);
|
||||
}
|
||||
|
||||
private void AddTransientGlobalDelegatingHandler<T>()
|
||||
where T : DelegatingHandler
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler<T>(true);
|
||||
}
|
||||
|
||||
private void AddSpecificTransientDelegatingHandler<T>()
|
||||
where T : DelegatingHandler
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler<T>();
|
||||
}
|
||||
|
||||
private void AddTypeTransientGlobalDelegatingHandler(Type type)
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler(type, true);
|
||||
}
|
||||
|
||||
private void AddTypeSpecificTransientDelegatingHandler(Type type)
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler(type);
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsHandlers<TOne, TWo>()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var handlers = _serviceProvider.GetServices<GlobalDelegatingHandler>().ToList();
|
||||
handlers[0].DelegatingHandler.ShouldBeOfType<TOne>();
|
||||
handlers[1].DelegatingHandler.ShouldBeOfType<TWo>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<TOne, TWo>()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
|
||||
handlers[0].ShouldBeOfType<TOne>();
|
||||
handlers[1].ShouldBeOfType<TWo>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TOne, TWo>()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var handlers = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
handlers[0].ShouldBeOfType<TOne>();
|
||||
handlers[1].ShouldBeOfType<TWo>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var creators = _serviceProvider.GetServices<ILoadBalancerCreator>().ToList();
|
||||
creators.Count(c => c.GetType() == typeof(NoLoadBalancerCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(RoundRobinCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(CookieStickySessionsCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(LeastConnectionCreator)).ShouldBe(1);
|
||||
creators.Count(c => c.GetType() == typeof(DelegateInvokingLoadBalancerCreator<FakeCustomLoadBalancer>)).ShouldBe(1);
|
||||
}
|
||||
|
||||
private void ThenTheAggregatorsAreTransient<TOne, TWo>()
|
||||
{
|
||||
var aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var first = aggregators[0];
|
||||
aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var second = aggregators[0];
|
||||
first.ShouldNotBe(second);
|
||||
}
|
||||
|
||||
private void ThenTheAggregatorsAreSingleton<TOne, TWo>()
|
||||
{
|
||||
var aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var first = aggregators[0];
|
||||
aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
|
||||
var second = aggregators[0];
|
||||
first.ShouldBe(second);
|
||||
}
|
||||
|
||||
private void ThenAnOcelotBuilderIsReturned()
|
||||
{
|
||||
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
||||
}
|
||||
|
||||
private void ThenTheIPlaceholderInstanceIsReplaced()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var placeholders = _serviceProvider.GetService<IPlaceholders>();
|
||||
placeholders.ShouldBeOfType<ConfigAwarePlaceholders>();
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServices()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot(_configRoot);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServicesWithoutConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIAccessLoggerFactory()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var logger = _serviceProvider.GetService<IFileConfigurationSetter>();
|
||||
logger.ShouldNotBeNull();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIValidateScopes()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenAnExceptionIsntThrown()
|
||||
{
|
||||
_ex.ShouldBeNull();
|
||||
}
|
||||
|
||||
private class FakeCustomLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public Task<Response<ServiceHostAndPort>> Lease(HttpContext httpContext)
|
||||
{
|
||||
// Not relevant for these tests
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Release(ServiceHostAndPort hostAndPort)
|
||||
{
|
||||
// Not relevant for these tests
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,104 +1,104 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
namespace Ocelot.UnitTests.DownstreamPathManipulation
|
||||
{
|
||||
using Ocelot.DownstreamPathManipulation.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.PathManipulation;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
namespace Ocelot.UnitTests.DownstreamPathManipulation
|
||||
{
|
||||
using Ocelot.DownstreamPathManipulation.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.PathManipulation;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
public class ClaimsToDownstreamPathMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IChangeDownstreamPathTemplate> _changePath;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private ClaimsToDownstreamPathMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
|
||||
public ClaimsToDownstreamPathMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToDownstreamPathMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
public class ClaimsToDownstreamPathMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IChangeDownstreamPathTemplate> _changePath;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private ClaimsToDownstreamPathMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
|
||||
public ClaimsToDownstreamPathMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToDownstreamPathMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
_changePath = new Mock<IChangeDownstreamPathTemplate>();
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com")));
|
||||
_middleware = new ClaimsToDownstreamPathMiddleware(_next, _loggerFactory.Object, _changePath.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToDownstreamPath(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0),
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheChangeDownstreamPathReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenChangeDownstreamPathIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheChangeDownstreamPathReturnsOk()
|
||||
{
|
||||
_changePath
|
||||
.Setup(x => x.ChangeDownstreamPath(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<DownstreamPathTemplate>(),
|
||||
It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenChangeDownstreamPathIsCalledCorrectly()
|
||||
{
|
||||
_changePath
|
||||
.Verify(x => x.ChangeDownstreamPath(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
_httpContext.Items.DownstreamReRoute().DownstreamPathTemplate,
|
||||
_httpContext.Items.TemplatePlaceholderNameAndValues()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com")));
|
||||
_middleware = new ClaimsToDownstreamPathMiddleware(_next, _loggerFactory.Object, _changePath.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToDownstreamPath(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0),
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheChangeDownstreamPathReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenChangeDownstreamPathIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheChangeDownstreamPathReturnsOk()
|
||||
{
|
||||
_changePath
|
||||
.Setup(x => x.ChangeDownstreamPath(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<DownstreamPathTemplate>(),
|
||||
It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenChangeDownstreamPathIsCalledCorrectly()
|
||||
{
|
||||
_changePath
|
||||
.Verify(x => x.ChangeDownstreamPath(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
_httpContext.Items.DownstreamRoute().DownstreamPathTemplate,
|
||||
_httpContext.Items.TemplatePlaceholderNameAndValues()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,306 +1,306 @@
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
using System;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Responses;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamRouteCreatorTests
|
||||
{
|
||||
private readonly DownstreamRouteCreator _creator;
|
||||
private readonly QoSOptions _qoSOptions;
|
||||
private readonly HttpHandlerOptions _handlerOptions;
|
||||
private readonly LoadBalancerOptions _loadBalancerOptions;
|
||||
private Response<DownstreamRoute> _result;
|
||||
private string _upstreamHost;
|
||||
private string _upstreamUrlPath;
|
||||
private string _upstreamHttpMethod;
|
||||
private IInternalConfiguration _configuration;
|
||||
private Mock<IQoSOptionsCreator> _qosOptionsCreator;
|
||||
private Response<DownstreamRoute> _resultTwo;
|
||||
private string _upstreamQuery;
|
||||
|
||||
public DownstreamRouteCreatorTests()
|
||||
{
|
||||
_qosOptionsCreator = new Mock<IQoSOptionsCreator>();
|
||||
_qoSOptions = new QoSOptionsBuilder().Build();
|
||||
_handlerOptions = new HttpHandlerOptionsBuilder().Build();
|
||||
_loadBalancerOptions = new LoadBalancerOptionsBuilder().WithType(nameof(NoLoadBalancer)).Build();
|
||||
_qosOptionsCreator
|
||||
.Setup(x => x.Create(It.IsAny<QoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>()))
|
||||
.Returns(_qoSOptions);
|
||||
_creator = new DownstreamRouteCreator(_qosOptionsCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamRouteIsCreated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_rate_limit_options()
|
||||
{
|
||||
var rateLimitOptions = new RateLimitOptionsBuilder()
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithClientIdHeader("test")
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("auth")
|
||||
.WithRateLimitOptions(rateLimitOptions)
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.Build();
|
||||
|
||||
var reRoutes = new List<ReRoute> { reRoute };
|
||||
|
||||
var configuration = new InternalConfiguration(reRoutes, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamRouteIsCreated())
|
||||
.And(_ => WithRateLimitOptions(rateLimitOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_cache_downstream_route()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
|
||||
.When(_ => WhenICreate())
|
||||
.And(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
|
||||
.When(_ => WhenICreateAgain())
|
||||
.Then(_ => ThenTheDownstreamRoutesAreTheSameReference())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_cache_downstream_route()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, "/geoffistheworst/"))
|
||||
.When(_ => WhenICreate())
|
||||
.And(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
|
||||
.When(_ => WhenICreateAgain())
|
||||
.Then(_ => ThenTheDownstreamRoutesAreTheNotSameReference())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_no_path()
|
||||
{
|
||||
var upstreamUrlPath = "/auth/";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamPathIsForwardSlash())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_only_first_segment_no_traling_slash()
|
||||
{
|
||||
var upstreamUrlPath = "/auth";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamPathIsForwardSlash())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_segments_no_traling_slash()
|
||||
{
|
||||
var upstreamUrlPath = "/auth/test";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenThePathDoesNotHaveTrailingSlash())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_and_remove_query_string()
|
||||
{
|
||||
var upstreamUrlPath = "/auth/test?test=1&best=2";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheQueryStringIsRemoved())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_for_sticky_sessions()
|
||||
{
|
||||
var loadBalancerOptions = new LoadBalancerOptionsBuilder().WithType(nameof(CookieStickySessions)).WithKey("boom").WithExpiryInMs(1).Build();
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheStickySessionLoadBalancerIsUsed(loadBalancerOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_qos()
|
||||
{
|
||||
var qoSOptions = new QoSOptionsBuilder()
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithTimeoutValue(1)
|
||||
.Build();
|
||||
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.And(_ => GivenTheQosCreatorReturns(qoSOptions))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheQosOptionsAreSet(qoSOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_handler_options()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheHandlerOptionsAreSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheQosCreatorReturns(QoSOptions options)
|
||||
{
|
||||
_qosOptionsCreator
|
||||
.Setup(x => x.Create(It.IsAny<QoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>()))
|
||||
.Returns(options);
|
||||
}
|
||||
|
||||
private void WithRateLimitOptions(RateLimitOptions expected)
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].RateLimitOptions.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].RateLimitOptions.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRouteIsCreated()
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test");
|
||||
_result.Data.ReRoute.UpstreamHttpMethod[0].ShouldBe(HttpMethod.Get);
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].UseServiceDiscovery.ShouldBeTrue();
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].HttpHandlerOptions.ShouldNotBeNull();
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].QosOptions.ShouldNotBeNull();
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamScheme.ShouldBe("http");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerOptions.Type.ShouldBe(nameof(NoLoadBalancer));
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].HttpHandlerOptions.ShouldBe(_handlerOptions);
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].QosOptions.ShouldBe(_qoSOptions);
|
||||
_result.Data.ReRoute.UpstreamTemplatePattern.ShouldNotBeNull();
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].UpstreamPathTemplate.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamPathIsForwardSlash()
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/|GET");
|
||||
}
|
||||
|
||||
private void ThenThePathDoesNotHaveTrailingSlash()
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
|
||||
}
|
||||
|
||||
private void ThenTheQueryStringIsRemoved()
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
|
||||
}
|
||||
|
||||
private void ThenTheStickySessionLoadBalancerIsUsed(LoadBalancerOptions expected)
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe($"{nameof(CookieStickySessions)}:boom");
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerOptions.Type.ShouldBe(nameof(CookieStickySessions));
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerOptions.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheQosOptionsAreSet(QoSOptions expected)
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].QosOptions.ShouldBe(expected);
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].QosOptions.UseQos.ShouldBeTrue();
|
||||
_qosOptionsCreator
|
||||
.Verify(x => x.Create(expected, _upstreamUrlPath, It.IsAny<List<string>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfiguration(IInternalConfiguration config)
|
||||
{
|
||||
_upstreamHost = "doesnt matter";
|
||||
_upstreamUrlPath = "/auth/test";
|
||||
_upstreamHttpMethod = "GET";
|
||||
_configuration = config;
|
||||
}
|
||||
|
||||
private void GivenTheConfiguration(IInternalConfiguration config, string upstreamUrlPath)
|
||||
{
|
||||
_upstreamHost = "doesnt matter";
|
||||
_upstreamUrlPath = upstreamUrlPath;
|
||||
_upstreamHttpMethod = "GET";
|
||||
_configuration = config;
|
||||
}
|
||||
|
||||
private void ThenTheHandlerOptionsAreSet()
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamReRoute[0].HttpHandlerOptions.ShouldBe(_handlerOptions);
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _configuration, _upstreamHost);
|
||||
}
|
||||
|
||||
private void WhenICreateAgain()
|
||||
{
|
||||
_resultTwo = _creator.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _configuration, _upstreamHost);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRoutesAreTheSameReference()
|
||||
{
|
||||
_result.ShouldBe(_resultTwo);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRoutesAreTheNotSameReference()
|
||||
{
|
||||
_result.ShouldNotBe(_resultTwo);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
using System;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Responses;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamRouteCreatorTests
|
||||
{
|
||||
private readonly DownstreamRouteCreator _creator;
|
||||
private readonly QoSOptions _qoSOptions;
|
||||
private readonly HttpHandlerOptions _handlerOptions;
|
||||
private readonly LoadBalancerOptions _loadBalancerOptions;
|
||||
private Response<Ocelot.DownstreamRouteFinder.DownstreamRouteHolder> _result;
|
||||
private string _upstreamHost;
|
||||
private string _upstreamUrlPath;
|
||||
private string _upstreamHttpMethod;
|
||||
private IInternalConfiguration _configuration;
|
||||
private Mock<IQoSOptionsCreator> _qosOptionsCreator;
|
||||
private Response<Ocelot.DownstreamRouteFinder.DownstreamRouteHolder> _resultTwo;
|
||||
private string _upstreamQuery;
|
||||
|
||||
public DownstreamRouteCreatorTests()
|
||||
{
|
||||
_qosOptionsCreator = new Mock<IQoSOptionsCreator>();
|
||||
_qoSOptions = new QoSOptionsBuilder().Build();
|
||||
_handlerOptions = new HttpHandlerOptionsBuilder().Build();
|
||||
_loadBalancerOptions = new LoadBalancerOptionsBuilder().WithType(nameof(NoLoadBalancer)).Build();
|
||||
_qosOptionsCreator
|
||||
.Setup(x => x.Create(It.IsAny<QoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>()))
|
||||
.Returns(_qoSOptions);
|
||||
_creator = new DownstreamRouteCreator(_qosOptionsCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamRouteIsCreated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_rate_limit_options()
|
||||
{
|
||||
var rateLimitOptions = new RateLimitOptionsBuilder()
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithClientIdHeader("test")
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithServiceName("auth")
|
||||
.WithRateLimitOptions(rateLimitOptions)
|
||||
.Build();
|
||||
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.Build();
|
||||
|
||||
var routes = new List<Route> { route };
|
||||
|
||||
var configuration = new InternalConfiguration(routes, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamRouteIsCreated())
|
||||
.And(_ => WithRateLimitOptions(rateLimitOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_cache_downstream_route()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
|
||||
.When(_ => WhenICreate())
|
||||
.And(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
|
||||
.When(_ => WhenICreateAgain())
|
||||
.Then(_ => ThenTheDownstreamRoutesAreTheSameReference())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_cache_downstream_route()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, "/geoffistheworst/"))
|
||||
.When(_ => WhenICreate())
|
||||
.And(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
|
||||
.When(_ => WhenICreateAgain())
|
||||
.Then(_ => ThenTheDownstreamRoutesAreTheNotSameReference())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_no_path()
|
||||
{
|
||||
var upstreamUrlPath = "/auth/";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamPathIsForwardSlash())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_only_first_segment_no_traling_slash()
|
||||
{
|
||||
var upstreamUrlPath = "/auth";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheDownstreamPathIsForwardSlash())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_segments_no_traling_slash()
|
||||
{
|
||||
var upstreamUrlPath = "/auth/test";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenThePathDoesNotHaveTrailingSlash())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_and_remove_query_string()
|
||||
{
|
||||
var upstreamUrlPath = "/auth/test?test=1&best=2";
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheQueryStringIsRemoved())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_for_sticky_sessions()
|
||||
{
|
||||
var loadBalancerOptions = new LoadBalancerOptionsBuilder().WithType(nameof(CookieStickySessions)).WithKey("boom").WithExpiryInMs(1).Build();
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheStickySessionLoadBalancerIsUsed(loadBalancerOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_qos()
|
||||
{
|
||||
var qoSOptions = new QoSOptionsBuilder()
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithTimeoutValue(1)
|
||||
.Build();
|
||||
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.And(_ => GivenTheQosCreatorReturns(qoSOptions))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheQosOptionsAreSet(qoSOptions))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_route_with_handler_options()
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
|
||||
|
||||
this.Given(_ => GivenTheConfiguration(configuration))
|
||||
.When(_ => WhenICreate())
|
||||
.Then(_ => ThenTheHandlerOptionsAreSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheQosCreatorReturns(QoSOptions options)
|
||||
{
|
||||
_qosOptionsCreator
|
||||
.Setup(x => x.Create(It.IsAny<QoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>()))
|
||||
.Returns(options);
|
||||
}
|
||||
|
||||
private void WithRateLimitOptions(RateLimitOptions expected)
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
|
||||
_result.Data.Route.DownstreamRoute[0].RateLimitOptions.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.Data.Route.DownstreamRoute[0].RateLimitOptions.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRouteIsCreated()
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test");
|
||||
_result.Data.Route.UpstreamHttpMethod[0].ShouldBe(HttpMethod.Get);
|
||||
_result.Data.Route.DownstreamRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
|
||||
_result.Data.Route.DownstreamRoute[0].UseServiceDiscovery.ShouldBeTrue();
|
||||
_result.Data.Route.DownstreamRoute[0].HttpHandlerOptions.ShouldNotBeNull();
|
||||
_result.Data.Route.DownstreamRoute[0].QosOptions.ShouldNotBeNull();
|
||||
_result.Data.Route.DownstreamRoute[0].DownstreamScheme.ShouldBe("http");
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerOptions.Type.ShouldBe(nameof(Ocelot.LoadBalancer.LoadBalancers.NoLoadBalancer));
|
||||
_result.Data.Route.DownstreamRoute[0].HttpHandlerOptions.ShouldBe(_handlerOptions);
|
||||
_result.Data.Route.DownstreamRoute[0].QosOptions.ShouldBe(_qoSOptions);
|
||||
_result.Data.Route.UpstreamTemplatePattern.ShouldNotBeNull();
|
||||
_result.Data.Route.DownstreamRoute[0].UpstreamPathTemplate.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamPathIsForwardSlash()
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe("/");
|
||||
_result.Data.Route.DownstreamRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerKey.ShouldBe("/auth/|GET");
|
||||
}
|
||||
|
||||
private void ThenThePathDoesNotHaveTrailingSlash()
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test");
|
||||
_result.Data.Route.DownstreamRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
|
||||
}
|
||||
|
||||
private void ThenTheQueryStringIsRemoved()
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test");
|
||||
_result.Data.Route.DownstreamRoute[0].ServiceName.ShouldBe("auth");
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
|
||||
}
|
||||
|
||||
private void ThenTheStickySessionLoadBalancerIsUsed(LoadBalancerOptions expected)
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerKey.ShouldBe($"{nameof(Ocelot.LoadBalancer.LoadBalancers.CookieStickySessions)}:boom");
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerOptions.Type.ShouldBe(nameof(Ocelot.LoadBalancer.LoadBalancers.CookieStickySessions));
|
||||
_result.Data.Route.DownstreamRoute[0].LoadBalancerOptions.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheQosOptionsAreSet(QoSOptions expected)
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].QosOptions.ShouldBe(expected);
|
||||
_result.Data.Route.DownstreamRoute[0].QosOptions.UseQos.ShouldBeTrue();
|
||||
_qosOptionsCreator
|
||||
.Verify(x => x.Create(expected, _upstreamUrlPath, It.IsAny<List<string>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfiguration(IInternalConfiguration config)
|
||||
{
|
||||
_upstreamHost = "doesnt matter";
|
||||
_upstreamUrlPath = "/auth/test";
|
||||
_upstreamHttpMethod = "GET";
|
||||
_configuration = config;
|
||||
}
|
||||
|
||||
private void GivenTheConfiguration(IInternalConfiguration config, string upstreamUrlPath)
|
||||
{
|
||||
_upstreamHost = "doesnt matter";
|
||||
_upstreamUrlPath = upstreamUrlPath;
|
||||
_upstreamHttpMethod = "GET";
|
||||
_configuration = config;
|
||||
}
|
||||
|
||||
private void ThenTheHandlerOptionsAreSet()
|
||||
{
|
||||
_result.Data.Route.DownstreamRoute[0].HttpHandlerOptions.ShouldBe(_handlerOptions);
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _configuration, _upstreamHost);
|
||||
}
|
||||
|
||||
private void WhenICreateAgain()
|
||||
{
|
||||
_resultTwo = _creator.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _configuration, _upstreamHost);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRoutesAreTheSameReference()
|
||||
{
|
||||
_result.ShouldBe(_resultTwo);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRoutesAreTheNotSameReference()
|
||||
{
|
||||
_result.ShouldNotBe(_resultTwo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
{
|
||||
private readonly Mock<IDownstreamRouteProvider> _finder;
|
||||
private readonly Mock<IDownstreamRouteProviderFactory> _factory;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private Response<Ocelot.DownstreamRouteFinder.DownstreamRouteHolder> _downstreamRoute;
|
||||
private IInternalConfiguration _config;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
@ -50,16 +50,16 @@
|
||||
{
|
||||
var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(
|
||||
new DownstreamRoute(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => GivenTheFollowingConfig(config))
|
||||
@ -79,9 +79,9 @@
|
||||
_httpContext.Items.SetIInternalConfiguration(config);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
|
||||
private void GivenTheDownStreamRouteFinderReturns(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
_downstreamRoute = new OkResponse<Ocelot.DownstreamRouteFinder.DownstreamRouteHolder>(downstreamRoute);
|
||||
_finder
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IInternalConfiguration>(), It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,164 +1,164 @@
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamRouteProviderFactoryTests
|
||||
{
|
||||
private readonly DownstreamRouteProviderFactory _factory;
|
||||
private IInternalConfiguration _config;
|
||||
private IDownstreamRouteProvider _result;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
public DownstreamRouteProviderFactoryTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
|
||||
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||
services.AddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
||||
services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteFinder>();
|
||||
services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteCreator>();
|
||||
var provider = services.BuildServiceProvider();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteProviderFactory>()).Returns(_logger.Object);
|
||||
_factory = new DownstreamRouteProviderFactory(provider, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder()
|
||||
{
|
||||
var reRoutes = new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder().Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_when_not_dynamic_re_route_and_service_discovery_on()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("test").WithPort(50).WithType("test").Build();
|
||||
var reRoutes = new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder().WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("woot").Build()).Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_as_no_service_discovery_given_no_scheme()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("").WithHost("test").WithPort(50).Build();
|
||||
var reRoutes = new List<ReRoute>();
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_as_no_service_discovery_given_no_host()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("").WithPort(50).Build();
|
||||
var reRoutes = new List<ReRoute>();
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_given_no_service_discovery_port()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("localhost").WithPort(0).Build();
|
||||
var reRoutes = new List<ReRoute>();
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_given_no_service_discovery_type()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("localhost").WithPort(50).WithType("").Build();
|
||||
var reRoutes = new List<ReRoute>();
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_creator()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("test").WithPort(50).WithType("test").Build();
|
||||
var reRoutes = new List<ReRoute>();
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteCreator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_creator_with_dynamic_re_route()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("test").WithPort(50).WithType("test").Build();
|
||||
var reRoutes = new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder().Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteCreator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheResultShouldBe<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_result = _factory.Get(_config);
|
||||
}
|
||||
|
||||
private void GivenTheReRoutes(List<ReRoute> reRoutes)
|
||||
{
|
||||
_config = new InternalConfiguration(reRoutes, "", null, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
}
|
||||
|
||||
private void GivenTheReRoutes(List<ReRoute> reRoutes, ServiceProviderConfiguration config)
|
||||
{
|
||||
_config = new InternalConfiguration(reRoutes, "", config, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamRouteProviderFactoryTests
|
||||
{
|
||||
private readonly DownstreamRouteProviderFactory _factory;
|
||||
private IInternalConfiguration _config;
|
||||
private IDownstreamRouteProvider _result;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
public DownstreamRouteProviderFactoryTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
|
||||
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||
services.AddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
||||
services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteFinder>();
|
||||
services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteCreator>();
|
||||
var provider = services.BuildServiceProvider();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteProviderFactory>()).Returns(_logger.Object);
|
||||
_factory = new DownstreamRouteProviderFactory(provider, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder()
|
||||
{
|
||||
var routes = new List<Route>
|
||||
{
|
||||
new RouteBuilder().Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_when_not_dynamic_re_route_and_service_discovery_on()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("test").WithPort(50).WithType("test").Build();
|
||||
var routes = new List<Route>
|
||||
{
|
||||
new RouteBuilder().WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("woot").Build()).Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_as_no_service_discovery_given_no_scheme()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("").WithHost("test").WithPort(50).Build();
|
||||
var routes = new List<Route>();
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_as_no_service_discovery_given_no_host()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("").WithPort(50).Build();
|
||||
var routes = new List<Route>();
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_given_no_service_discovery_port()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("localhost").WithPort(0).Build();
|
||||
var routes = new List<Route>();
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_finder_given_no_service_discovery_type()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("localhost").WithPort(50).WithType("").Build();
|
||||
var routes = new List<Route>();
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_creator()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("test").WithPort(50).WithType("test").Build();
|
||||
var routes = new List<Route>();
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteCreator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_downstream_route_creator_with_dynamic_re_route()
|
||||
{
|
||||
var spConfig = new ServiceProviderConfigurationBuilder().WithScheme("http").WithHost("test").WithPort(50).WithType("test").Build();
|
||||
var routes = new List<Route>
|
||||
{
|
||||
new RouteBuilder().Build()
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheRoutes(routes, spConfig))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheResultShouldBe<DownstreamRouteCreator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheResultShouldBe<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_result = _factory.Get(_config);
|
||||
}
|
||||
|
||||
private void GivenTheRoutes(List<Route> routes)
|
||||
{
|
||||
_config = new InternalConfiguration(routes, "", null, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
}
|
||||
|
||||
private void GivenTheRoutes(List<Route> routes, ServiceProviderConfiguration config)
|
||||
{
|
||||
_config = new InternalConfiguration(routes, "", config, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,440 +1,440 @@
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
public class DownstreamUrlCreatorMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
|
||||
private OkResponse<DownstreamPath> _downstreamPath;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private DownstreamUrlCreatorMiddleware _middleware;
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly HttpRequestMessage _request;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public DownstreamUrlCreatorMiddlewareTests()
|
||||
{
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<DownstreamUrlCreatorMiddleware>()).Returns(_logger.Object);
|
||||
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
|
||||
public class DownstreamUrlCreatorMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
|
||||
private OkResponse<DownstreamPath> _downstreamPath;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private DownstreamUrlCreatorMiddleware _middleware;
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly HttpRequestMessage _request;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public DownstreamUrlCreatorMiddlewareTests()
|
||||
{
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<DownstreamUrlCreatorMiddleware>()).Returns(_logger.Object);
|
||||
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
|
||||
_request = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
|
||||
_next = context => Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_scheme_and_path()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://my.url:80/api/products/1?q=123"))
|
||||
.And(x => ThenTheQueryStringIs("?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_query_string()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{subscriptionId}", "1"),
|
||||
new PlaceholderNameAndValue("{unitId}", "2")
|
||||
},
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates"))
|
||||
.And(x => ThenTheQueryStringIs(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_query_string_but_leave_non_placeholder_queries()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{subscriptionId}", "1"),
|
||||
new PlaceholderNameAndValue("{unitId}", "2")
|
||||
},
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2&productId=2"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates?productId=2"))
|
||||
.And(x => ThenTheQueryStringIs("?productId=2"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_query_string_exact_match()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates/{unitIdIty}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{subscriptionId}", "1"),
|
||||
new PlaceholderNameAndValue("{unitId}", "2"),
|
||||
new PlaceholderNameAndValue("{unitIdIty}", "3")
|
||||
},
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2?unitIdIty=3"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates/3"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates/3"))
|
||||
.And(x => ThenTheQueryStringIs(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_create_service_fabric_url()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://my.url:80/api/products/1?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url_with_query_string_for_stateless_service()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?Tom=test&laura=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?Tom=test&laura=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url_with_query_string_for_stateful_service()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url_with_version_from_upstream_path_template()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithDownstreamReRoute(
|
||||
new DownstreamReRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("/products").Build())
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build()
|
||||
).Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/products", "Service_1.0/Api"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Service_1.0/Api/products?PartitionKind=test&PartitionKey=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void issue_473_should_not_remove_additional_query_string()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/Authorized/{action}?server={server}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
|
||||
.WithDownstreamScheme("http")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("/uc/Authorized/{server}/{action}").Build())
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{action}", "1"),
|
||||
new PlaceholderNameAndValue("{server}", "2")
|
||||
},
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/uc/Authorized/2/1/refresh?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/Authorized/1?server=2"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:5000/Authorized/1?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d&server=2"))
|
||||
.And(x => ThenTheQueryStringIs("?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d&server=2"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_replace_by_empty_scheme()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamScheme("")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("https://localhost:19081?PartitionKind=test&PartitionKey=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
|
||||
{
|
||||
_next = context => Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_scheme_and_path()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://my.url:80/api/products/1?q=123"))
|
||||
.And(x => ThenTheQueryStringIs("?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_query_string()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{subscriptionId}", "1"),
|
||||
new PlaceholderNameAndValue("{unitId}", "2")
|
||||
},
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates"))
|
||||
.And(x => ThenTheQueryStringIs(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_query_string_but_leave_non_placeholder_queries()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{subscriptionId}", "1"),
|
||||
new PlaceholderNameAndValue("{unitId}", "2")
|
||||
},
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2&productId=2"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates?productId=2"))
|
||||
.And(x => ThenTheQueryStringIs("?productId=2"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_query_string_exact_match()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates/{unitIdIty}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{subscriptionId}", "1"),
|
||||
new PlaceholderNameAndValue("{unitId}", "2"),
|
||||
new PlaceholderNameAndValue("{unitIdIty}", "3")
|
||||
},
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2?unitIdIty=3"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates/3"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates/3"))
|
||||
.And(x => ThenTheQueryStringIs(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_create_service_fabric_url()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://my.url:80/api/products/1?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRouteHolder = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRouteHolder))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url_with_query_string_for_stateless_service()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRouteHolder = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRouteHolder))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?Tom=test&laura=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?Tom=test&laura=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url_with_query_string_for_stateful_service()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRouteHolder = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRouteHolder))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_fabric_url_with_version_from_upstream_path_template()
|
||||
{
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder().WithDownstreamRoute(
|
||||
new DownstreamRouteBuilder()
|
||||
.WithDownstreamScheme("http")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("/products").Build())
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build()
|
||||
).Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/products", "Service_1.0/Api"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Service_1.0/Api/products?PartitionKind=test&PartitionKey=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void issue_473_should_not_remove_additional_query_string()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/Authorized/{action}?server={server}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
|
||||
.WithDownstreamScheme("http")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("/uc/Authorized/{server}/{action}").Build())
|
||||
.Build();
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{action}", "1"),
|
||||
new PlaceholderNameAndValue("{server}", "2")
|
||||
},
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/uc/Authorized/2/1/refresh?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d"))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/Authorized/1?server=2"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:5000/Authorized/1?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d&server=2"))
|
||||
.And(x => ThenTheQueryStringIs("?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d&server=2"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_replace_by_empty_scheme()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamScheme("")
|
||||
.WithServiceName("Ocelot/OcelotApp")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var downstreamRouteHolder = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.Build());
|
||||
|
||||
var config = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.WithHost("localhost")
|
||||
.WithPort(19081)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRouteHolder))
|
||||
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("https://localhost:19081?PartitionKind=test&PartitionKey=1"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
|
||||
{
|
||||
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null, null);
|
||||
_httpContext.Items.SetIInternalConfiguration(configuration);
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware = new DownstreamUrlCreatorMiddleware(_next, _loggerFactory.Object, _downstreamUrlTemplateVariableReplacer.Object);
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
_httpContext.Items.SetIInternalConfiguration(configuration);
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware = new DownstreamUrlCreatorMiddleware(_next, _loggerFactory.Object, _downstreamUrlTemplateVariableReplacer.Object);
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestUriIs(string uri)
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestUriIs(string uri)
|
||||
{
|
||||
_request.RequestUri = new Uri(uri);
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(_request));
|
||||
}
|
||||
|
||||
private void GivenTheUrlReplacerWillReturnSequence(params string[] paths)
|
||||
{
|
||||
var setup = _downstreamUrlTemplateVariableReplacer
|
||||
.SetupSequence(x => x.Replace(It.IsAny<string>(), It.IsAny<List<PlaceholderNameAndValue>>()));
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var response = new OkResponse<DownstreamPath>(new DownstreamPath(path));
|
||||
setup.Returns(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheUrlReplacerWillReturn(string path)
|
||||
{
|
||||
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path));
|
||||
_downstreamUrlTemplateVariableReplacer
|
||||
.Setup(x => x.Replace(It.IsAny<string>(), It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||
.Returns(_downstreamPath);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestUriIs(string expectedUri)
|
||||
{
|
||||
_httpContext.Items.DownstreamRequest().ToHttpRequestMessage().RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
|
||||
private void ThenTheQueryStringIs(string queryString)
|
||||
{
|
||||
_httpContext.Items.DownstreamRequest().Query.ShouldBe(queryString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheUrlReplacerWillReturnSequence(params string[] paths)
|
||||
{
|
||||
var setup = _downstreamUrlTemplateVariableReplacer
|
||||
.SetupSequence(x => x.Replace(It.IsAny<string>(), It.IsAny<List<PlaceholderNameAndValue>>()));
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var response = new OkResponse<DownstreamPath>(new DownstreamPath(path));
|
||||
setup.Returns(response);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheUrlReplacerWillReturn(string path)
|
||||
{
|
||||
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path));
|
||||
_downstreamUrlTemplateVariableReplacer
|
||||
.Setup(x => x.Replace(It.IsAny<string>(), It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||
.Returns(_downstreamPath);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestUriIs(string expectedUri)
|
||||
{
|
||||
_httpContext.Items.DownstreamRequest().ToHttpRequestMessage().RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
|
||||
private void ThenTheQueryStringIs(string queryString)
|
||||
{
|
||||
_httpContext.Items.DownstreamRequest().Query.ShouldBe(queryString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,210 +1,210 @@
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class UpstreamUrlPathTemplateVariableReplacerTests
|
||||
{
|
||||
private DownstreamRoute _downstreamRoute;
|
||||
private Response<DownstreamPath> _result;
|
||||
private readonly IDownstreamPathPlaceholderReplacer _downstreamPathReplacer;
|
||||
|
||||
public UpstreamUrlPathTemplateVariableReplacerTests()
|
||||
{
|
||||
_downstreamPathReplacer = new DownstreamTemplatePathPlaceholderReplacer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables_with_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_no_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_multiple_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/product/products/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable_with_path_after()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_two_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class UpstreamUrlPathTemplateVariableReplacerTests
|
||||
{
|
||||
private DownstreamRouteHolder _downstreamRoute;
|
||||
private Response<DownstreamPath> _result;
|
||||
private readonly IDownstreamPathPlaceholderReplacer _downstreamPathReplacer;
|
||||
|
||||
public UpstreamUrlPathTemplateVariableReplacerTests()
|
||||
{
|
||||
_downstreamPathReplacer = new DownstreamTemplatePathPlaceholderReplacer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_three_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12"),
|
||||
new PlaceholderNameAndValue("{categoryId}", "34")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsAUrlMatch(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = downstreamRoute;
|
||||
}
|
||||
|
||||
private void WhenIReplaceTheTemplateVariables()
|
||||
{
|
||||
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value, _downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamUrlPathIsReturned(string expected)
|
||||
{
|
||||
_result.Data.Value.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables_with_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRouteHolder(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_no_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_multiple_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/product/products/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(templateVariables,
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable_with_path_after()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(templateVariables,
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_two_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(templateVariables,
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_three_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12"),
|
||||
new PlaceholderNameAndValue("{categoryId}", "34")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRouteHolder(templateVariables,
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsAUrlMatch(DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = downstreamRoute;
|
||||
}
|
||||
|
||||
private void WhenIReplaceTheTemplateVariables()
|
||||
{
|
||||
_result = _downstreamPathReplacer.Replace(_downstreamRoute.Route.DownstreamRoute[0].DownstreamPathTemplate.Value, _downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamUrlPathIsReturned(string expected)
|
||||
{
|
||||
_result.Data.Value.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
namespace Ocelot.UnitTests.Eureka
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Provider.Eureka;
|
||||
using Shouldly;
|
||||
using Steeltoe.Common.Discovery;
|
||||
using Xunit;
|
||||
|
||||
public class EurekaProviderFactoryTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_not_get()
|
||||
{
|
||||
var config = new ServiceProviderConfigurationBuilder().Build();
|
||||
var sp = new ServiceCollection().BuildServiceProvider();
|
||||
var provider = EurekaProviderFactory.Get(sp, config, null);
|
||||
provider.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get()
|
||||
{
|
||||
var config = new ServiceProviderConfigurationBuilder().WithType("eureka").Build();
|
||||
var client = new Mock<IDiscoveryClient>();
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IDiscoveryClient>(client.Object);
|
||||
var sp = services.BuildServiceProvider();
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("")
|
||||
.Build();
|
||||
var provider = EurekaProviderFactory.Get(sp, config, reRoute);
|
||||
provider.ShouldBeOfType<Eureka>();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Eureka
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Provider.Eureka;
|
||||
using Shouldly;
|
||||
using Steeltoe.Common.Discovery;
|
||||
using Xunit;
|
||||
|
||||
public class EurekaProviderFactoryTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_not_get()
|
||||
{
|
||||
var config = new ServiceProviderConfigurationBuilder().Build();
|
||||
var sp = new ServiceCollection().BuildServiceProvider();
|
||||
var provider = EurekaProviderFactory.Get(sp, config, null);
|
||||
provider.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get()
|
||||
{
|
||||
var config = new ServiceProviderConfigurationBuilder().WithType("eureka").Build();
|
||||
var client = new Mock<IDiscoveryClient>();
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IDiscoveryClient>(client.Object);
|
||||
var sp = services.BuildServiceProvider();
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("")
|
||||
.Build();
|
||||
var provider = EurekaProviderFactory.Get(sp, config, route);
|
||||
provider.ShouldBeOfType<Eureka>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
public class ClaimsToHeadersMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IAddHeadersToRequest> _addHeaders;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private Response<Ocelot.DownstreamRouteFinder.DownstreamRouteHolder> _downstreamRoute;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private ClaimsToHeadersMiddleware _middleware;
|
||||
@ -44,9 +44,9 @@
|
||||
[Fact]
|
||||
public void should_call_add_headers_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToHeaders(new List<ClaimToThing>
|
||||
{
|
||||
@ -69,13 +69,13 @@
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
private void GivenTheDownStreamRouteIs(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
_downstreamRoute = new OkResponse<Ocelot.DownstreamRouteFinder.DownstreamRouteHolder>(downstreamRoute);
|
||||
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToDownstreamRequestReturnsOk()
|
||||
|
@ -52,7 +52,7 @@ namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
this.Given(x => GivenTheFollowingRequest())
|
||||
.And(x => GivenTheDownstreamRequestIs())
|
||||
.And(x => GivenTheReRouteHasPreFindAndReplaceSetUp())
|
||||
.And(x => GivenTheRouteHasPreFindAndReplaceSetUp())
|
||||
.And(x => GivenTheHttpResponseMessageIs())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly())
|
||||
@ -65,13 +65,13 @@ namespace Ocelot.UnitTests.Headers
|
||||
private void ThenAddHeadersToResponseIsCalledCorrectly()
|
||||
{
|
||||
_addHeadersToResponse
|
||||
.Verify(x => x.Add(_httpContext.Items.DownstreamReRoute().AddHeadersToDownstream, _httpContext.Items.DownstreamResponse()), Times.Once);
|
||||
.Verify(x => x.Add(_httpContext.Items.DownstreamRoute().AddHeadersToDownstream, _httpContext.Items.DownstreamResponse()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenAddHeadersToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeadersToRequest
|
||||
.Verify(x => x.SetHeadersOnDownstreamRequest(_httpContext.Items.DownstreamReRoute().AddHeadersToUpstream, _httpContext), Times.Once);
|
||||
.Verify(x => x.SetHeadersOnDownstreamRequest(_httpContext.Items.DownstreamRoute().AddHeadersToUpstream, _httpContext), Times.Once);
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
@ -89,18 +89,18 @@ namespace Ocelot.UnitTests.Headers
|
||||
_httpContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new HttpResponseMessage()));
|
||||
}
|
||||
|
||||
private void GivenTheReRouteHasPreFindAndReplaceSetUp()
|
||||
private void GivenTheRouteHasPreFindAndReplaceSetUp()
|
||||
{
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs)
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs)
|
||||
.WithDownstreamHeaderFindAndReplace(fAndRs).Build())
|
||||
.Build();
|
||||
|
||||
var dR = new DownstreamRoute(null, reRoute);
|
||||
var dR = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(null, route);
|
||||
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(dR.TemplatePlaceholderNameAndValues);
|
||||
_httpContext.Items.UpsertDownstreamReRoute(dR.ReRoute.DownstreamReRoute[0]);
|
||||
_httpContext.Items.UpsertDownstreamRoute(dR.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly()
|
||||
|
@ -1,74 +1,74 @@
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class CookieStickySessionsCreatorTests
|
||||
{
|
||||
private readonly CookieStickySessionsCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamReRoute _reRoute;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public CookieStickySessionsCreatorTests()
|
||||
{
|
||||
_creator = new CookieStickySessionsCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("myType", "myKey", 1000))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<CookieStickySessions>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("CookieStickySessions"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_reRoute, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class CookieStickySessionsCreatorTests
|
||||
{
|
||||
private readonly CookieStickySessionsCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamRoute _route;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public CookieStickySessionsCreatorTests()
|
||||
{
|
||||
_creator = new CookieStickySessionsCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("myType", "myKey", 1000))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<CookieStickySessions>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("CookieStickySessions"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARoute(DownstreamRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_route, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,16 +19,16 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
public class DelegateInvokingLoadBalancerCreatorTests
|
||||
{
|
||||
private DelegateInvokingLoadBalancerCreator<FakeLoadBalancer> _creator;
|
||||
private Func<DownstreamReRoute, IServiceDiscoveryProvider, ILoadBalancer> _creatorFunc;
|
||||
private Func<DownstreamRoute, IServiceDiscoveryProvider, ILoadBalancer> _creatorFunc;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamReRoute _reRoute;
|
||||
private DownstreamRoute _route;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public DelegateInvokingLoadBalancerCreatorTests()
|
||||
{
|
||||
_creatorFunc = (reRoute, serviceDiscoveryProvider) =>
|
||||
new FakeLoadBalancer(reRoute, serviceDiscoveryProvider);
|
||||
_creatorFunc = (route, serviceDiscoveryProvider) =>
|
||||
new FakeLoadBalancer(route, serviceDiscoveryProvider);
|
||||
_creator = new DelegateInvokingLoadBalancerCreator<FakeLoadBalancer>(_creatorFunc);
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
@ -44,10 +44,10 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_result_of_specified_creator_func()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<FakeLoadBalancer>())
|
||||
.BDDfy();
|
||||
@ -56,10 +56,10 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => x.GivenTheCreatorFuncThrows())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenAnErrorIsReturned())
|
||||
@ -68,7 +68,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
|
||||
private void GivenTheCreatorFuncThrows()
|
||||
{
|
||||
_creatorFunc = (reRoute, serviceDiscoveryProvider) => throw new Exception();
|
||||
_creatorFunc = (route, serviceDiscoveryProvider) => throw new Exception();
|
||||
|
||||
_creator = new DelegateInvokingLoadBalancerCreator<FakeLoadBalancer>(_creatorFunc);
|
||||
}
|
||||
@ -78,14 +78,14 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
_loadBalancer.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
||||
private void GivenARoute(DownstreamRoute route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_reRoute, _serviceProvider.Object);
|
||||
_loadBalancer = _creator.Create(_route, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
@ -106,13 +106,13 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
|
||||
private class FakeLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public FakeLoadBalancer(DownstreamReRoute reRoute, IServiceDiscoveryProvider serviceDiscoveryProvider)
|
||||
public FakeLoadBalancer(DownstreamRoute downstreamRoute, IServiceDiscoveryProvider serviceDiscoveryProvider)
|
||||
{
|
||||
ReRoute = reRoute;
|
||||
DownstreamRoute = downstreamRoute;
|
||||
ServiceDiscoveryProvider = serviceDiscoveryProvider;
|
||||
}
|
||||
|
||||
public DownstreamReRoute ReRoute { get; }
|
||||
public DownstreamRoute DownstreamRoute { get; }
|
||||
public IServiceDiscoveryProvider ServiceDiscoveryProvider { get; }
|
||||
|
||||
public Task<Response<ServiceHostAndPort>> Lease(HttpContext httpContext)
|
||||
|
@ -1,74 +1,74 @@
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class LeastConnectionCreatorTests
|
||||
{
|
||||
private readonly LeastConnectionCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamReRoute _reRoute;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public LeastConnectionCreatorTests()
|
||||
{
|
||||
_creator = new LeastConnectionCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("myService")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("LeastConnection"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_reRoute, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class LeastConnectionCreatorTests
|
||||
{
|
||||
private readonly LeastConnectionCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamRoute _route;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public LeastConnectionCreatorTests()
|
||||
{
|
||||
_creator = new LeastConnectionCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("myService")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("LeastConnection"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARoute(DownstreamRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_route, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
|
||||
public class LoadBalancerFactoryTests
|
||||
{
|
||||
private DownstreamReRoute _reRoute;
|
||||
private DownstreamRoute _route;
|
||||
private readonly LoadBalancerFactory _factory;
|
||||
private Response<ILoadBalancer> _result;
|
||||
private readonly Mock<IServiceDiscoveryProviderFactory> _serviceProviderFactory;
|
||||
@ -46,11 +46,11 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_no_load_balancer_by_default()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
@ -61,12 +61,12 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_matching_load_balancer()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeLoadBalancerTwo", "", 0))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
@ -77,12 +77,12 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_error_response_if_cannot_find_load_balancer_creator()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("DoesntExistLoadBalancer", "", 0))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
@ -94,12 +94,12 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_error_response_if_creator_errors()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("BrokenLoadBalancer", "", 0))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
@ -110,12 +110,12 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_call_service_provider()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeLoadBalancerOne", "", 0))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
@ -126,12 +126,12 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_error_response_when_call_to_service_provider_fails()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeLoadBalancerOne", "", 0))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryFails())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
@ -147,31 +147,31 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
private void GivenTheServiceProviderFactoryReturns()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()))
|
||||
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamRoute>()))
|
||||
.Returns(new OkResponse<IServiceDiscoveryProvider>(_serviceProvider.Object));
|
||||
}
|
||||
|
||||
private void GivenTheServiceProviderFactoryFails()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()))
|
||||
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamRoute>()))
|
||||
.Returns(new ErrorResponse<IServiceDiscoveryProvider>(new CannotFindDataError("For tests")));
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIsCalledCorrectly()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()), Times.Once);
|
||||
.Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamRoute>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
||||
private void GivenARoute(DownstreamRoute route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_result = _factory.Get(_reRoute, _serviceProviderConfig);
|
||||
_result = _factory.Get(_route, _serviceProviderConfig);
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
@ -203,7 +203,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public Response<ILoadBalancer> Create(DownstreamReRoute reRoute, IServiceDiscoveryProvider serviceProvider)
|
||||
public Response<ILoadBalancer> Create(DownstreamRoute route, IServiceDiscoveryProvider serviceProvider)
|
||||
{
|
||||
return new OkResponse<ILoadBalancer>(new T());
|
||||
}
|
||||
@ -219,7 +219,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
Type = typeof(T).Name;
|
||||
}
|
||||
|
||||
public Response<ILoadBalancer> Create(DownstreamReRoute reRoute, IServiceDiscoveryProvider serviceProvider)
|
||||
public Response<ILoadBalancer> Create(DownstreamRoute route, IServiceDiscoveryProvider serviceProvider)
|
||||
{
|
||||
return new ErrorResponse<ILoadBalancer>(new ErrorInvokingLoadBalancerCreator(new Exception()));
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
|
||||
public class LoadBalancerHouseTests
|
||||
{
|
||||
private DownstreamReRoute _reRoute;
|
||||
private DownstreamRoute _route;
|
||||
private ILoadBalancer _loadBalancer;
|
||||
private readonly LoadBalancerHouse _loadBalancerHouse;
|
||||
private Response<ILoadBalancer> _getResult;
|
||||
@ -34,11 +34,11 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_store_load_balancer_on_first_request()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerKey("test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(route, new FakeLoadBalancer()))
|
||||
.Then(x => x.ThenItIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
@ -46,13 +46,13 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_not_store_load_balancer_on_second_request()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeLoadBalancer", "", 0))
|
||||
.WithLoadBalancerKey("test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(route, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(route))
|
||||
.Then(x => x.ThenItIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
@ -60,21 +60,21 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_store_load_balancers_by_key()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeLoadBalancer", "", 0))
|
||||
.WithLoadBalancerKey("test")
|
||||
.Build();
|
||||
|
||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
||||
var routeTwo = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeRoundRobinLoadBalancer", "", 0))
|
||||
.WithLoadBalancerKey("testtwo")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.And(x => x.GivenThereIsALoadBalancer(reRouteTwo, new FakeRoundRobinLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(route, new FakeLoadBalancer()))
|
||||
.And(x => x.GivenThereIsALoadBalancer(routeTwo, new FakeRoundRobinLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(route))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>())
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRouteTwo))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(routeTwo))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeRoundRobinLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
@ -82,39 +82,39 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_return_error_if_exception()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder().Build();
|
||||
var route = new DownstreamRouteBuilder().Build();
|
||||
|
||||
this.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
this.When(x => x.WhenWeGetTheLoadBalancer(route))
|
||||
.Then(x => x.ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_new_load_balancer_if_reroute_load_balancer_has_changed()
|
||||
public void should_get_new_load_balancer_if_route_load_balancer_has_changed()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("FakeLoadBalancer", "", 0))
|
||||
.WithLoadBalancerKey("test")
|
||||
.Build();
|
||||
|
||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
||||
var routeTwo = new DownstreamRouteBuilder()
|
||||
.WithLoadBalancerOptions(new LoadBalancerOptions("LeastConnection", "", 0))
|
||||
.WithLoadBalancerKey("test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(route, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(route))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>())
|
||||
.When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(reRouteTwo))
|
||||
.When(x => x.WhenIGetTheRouteWithTheSameKeyButDifferentLoadBalancer(routeTwo))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(DownstreamReRoute reRoute)
|
||||
private void WhenIGetTheRouteWithTheSameKeyButDifferentLoadBalancer(DownstreamRoute route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).Returns(new OkResponse<ILoadBalancer>(new LeastConnection(null, null)));
|
||||
_getResult = _loadBalancerHouse.Get(_reRoute, _serviceProviderConfig);
|
||||
_route = route;
|
||||
_factory.Setup(x => x.Get(_route, _serviceProviderConfig)).Returns(new OkResponse<ILoadBalancer>(new LeastConnection(null, null)));
|
||||
_getResult = _loadBalancerHouse.Get(_route, _serviceProviderConfig);
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
@ -133,26 +133,26 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
_getResult.IsError.ShouldBe(false);
|
||||
_getResult.ShouldBeOfType<OkResponse<ILoadBalancer>>();
|
||||
_getResult.Data.ShouldBe(_loadBalancer);
|
||||
_factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once);
|
||||
_factory.Verify(x => x.Get(_route, _serviceProviderConfig), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenThereIsALoadBalancer(DownstreamReRoute reRoute, ILoadBalancer loadBalancer)
|
||||
private void GivenThereIsALoadBalancer(DownstreamRoute route, ILoadBalancer loadBalancer)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
_loadBalancer = loadBalancer;
|
||||
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).Returns(new OkResponse<ILoadBalancer>(loadBalancer));
|
||||
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig);
|
||||
_factory.Setup(x => x.Get(_route, _serviceProviderConfig)).Returns(new OkResponse<ILoadBalancer>(loadBalancer));
|
||||
_getResult = _loadBalancerHouse.Get(route, _serviceProviderConfig);
|
||||
}
|
||||
|
||||
private void WhenWeGetTheLoadBalancer(DownstreamReRoute reRoute)
|
||||
private void WhenWeGetTheLoadBalancer(DownstreamRoute route)
|
||||
{
|
||||
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig);
|
||||
_getResult = _loadBalancerHouse.Get(route, _serviceProviderConfig);
|
||||
}
|
||||
|
||||
private void ThenItIsReturned()
|
||||
{
|
||||
_getResult.Data.ShouldBe(_loadBalancer);
|
||||
_factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once);
|
||||
_factory.Verify(x => x.Get(_route, _serviceProviderConfig), Times.Once);
|
||||
}
|
||||
|
||||
private class FakeLoadBalancer : ILoadBalancer
|
||||
|
@ -56,7 +56,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
@ -76,7 +76,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_set_pipeline_error_if_cannot_get_load_balancer()
|
||||
{
|
||||
var downstreamRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
@ -95,7 +95,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_set_pipeline_error_if_cannot_get_least()
|
||||
{
|
||||
var downstreamRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
@ -115,7 +115,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
[Fact]
|
||||
public void should_set_scheme()
|
||||
{
|
||||
var downstreamRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
@ -174,16 +174,16 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
.ReturnsAsync(new OkResponse<ServiceHostAndPort>(_hostAndPort));
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamReRoute downstreamRoute, List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue> placeholder)
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute, List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue> placeholder)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(placeholder);
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute);
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerHouseReturns()
|
||||
{
|
||||
_loadBalancerHouse
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.Returns(new OkResponse<ILoadBalancer>(_loadBalancer.Object));
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
});
|
||||
|
||||
_loadBalancerHouse
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.Returns(_getLoadBalancerHouseError);
|
||||
}
|
||||
|
||||
|
@ -1,73 +1,73 @@
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class NoLoadBalancerCreatorTests
|
||||
{
|
||||
private readonly NoLoadBalancerCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamReRoute _reRoute;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public NoLoadBalancerCreatorTests()
|
||||
{
|
||||
_creator = new NoLoadBalancerCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<NoLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("NoLoadBalancer"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_reRoute, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class NoLoadBalancerCreatorTests
|
||||
{
|
||||
private readonly NoLoadBalancerCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamRoute _route;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public NoLoadBalancerCreatorTests()
|
||||
{
|
||||
_creator = new NoLoadBalancerCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<NoLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("NoLoadBalancer"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARoute(DownstreamRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_route, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,73 +1,73 @@
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RoundRobinCreatorTests
|
||||
{
|
||||
private readonly RoundRobinCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamReRoute _reRoute;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public RoundRobinCreatorTests()
|
||||
{
|
||||
_creator = new RoundRobinCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<RoundRobin>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("RoundRobin"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_reRoute, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RoundRobinCreatorTests
|
||||
{
|
||||
private readonly RoundRobinCreator _creator;
|
||||
private readonly Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private DownstreamRoute _route;
|
||||
private Response<ILoadBalancer> _loadBalancer;
|
||||
private string _typeName;
|
||||
|
||||
public RoundRobinCreatorTests()
|
||||
{
|
||||
_creator = new RoundRobinCreator();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_instance_of_expected_load_balancer_type()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenARoute(route))
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<RoundRobin>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_expected_name()
|
||||
{
|
||||
this.When(x => x.WhenIGetTheLoadBalancerTypeName())
|
||||
.Then(x => x.ThenTheLoadBalancerTypeIs("RoundRobin"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARoute(DownstreamRoute route)
|
||||
{
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_loadBalancer = _creator.Create(_route, _serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancerTypeName()
|
||||
{
|
||||
_typeName = _creator.Type;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
where T : ILoadBalancer
|
||||
{
|
||||
_loadBalancer.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerTypeIs(string type)
|
||||
{
|
||||
_typeName.ShouldBe(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,25 +6,25 @@ using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using static Ocelot.UnitTests.Multiplexing.UserDefinedResponseAggregatorTests;
|
||||
|
||||
using static Ocelot.UnitTests.Multiplexing.UserDefinedResponseAggregatorTests;
|
||||
|
||||
namespace Ocelot.UnitTests.Multiplexing
|
||||
{
|
||||
public class DefinedAggregatorProviderTests
|
||||
{
|
||||
private ServiceLocatorDefinedAggregatorProvider _provider;
|
||||
private Response<IDefinedAggregator> _aggregator;
|
||||
private ReRoute _reRoute;
|
||||
private Route _route;
|
||||
|
||||
[Fact]
|
||||
public void should_find_aggregator()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
var route = new RouteBuilder()
|
||||
.WithAggregator("TestDefinedAggregator")
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenDefinedAggregator())
|
||||
.And(_ => GivenReRoute(reRoute))
|
||||
.And(_ => GivenRoute(route))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheAggregatorIsReturned())
|
||||
.BDDfy();
|
||||
@ -33,12 +33,12 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_not_find_aggregator()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
var route = new RouteBuilder()
|
||||
.WithAggregator("TestDefinedAggregator")
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenNoDefinedAggregator())
|
||||
.And(_ => GivenReRoute(reRoute))
|
||||
.And(_ => GivenRoute(route))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
@ -66,14 +66,14 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
_provider = new ServiceLocatorDefinedAggregatorProvider(services);
|
||||
}
|
||||
|
||||
private void GivenReRoute(ReRoute reRoute)
|
||||
private void GivenRoute(Route route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_aggregator = _provider.Get(_reRoute);
|
||||
_aggregator = _provider.Get(_route);
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace Ocelot.UnitTests.Multiplexing
|
||||
namespace Ocelot.UnitTests.Multiplexing
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
@ -14,68 +14,68 @@
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class MultiplexingMiddlewareTests
|
||||
{
|
||||
private readonly MultiplexingMiddleware _middleware;
|
||||
private DownstreamRoute _downstreamRoute;
|
||||
private int _count;
|
||||
private Mock<IResponseAggregator> _aggregator;
|
||||
private Mock<IResponseAggregatorFactory> _factory;
|
||||
|
||||
public class MultiplexingMiddlewareTests
|
||||
{
|
||||
private readonly MultiplexingMiddleware _middleware;
|
||||
private Ocelot.DownstreamRouteFinder.DownstreamRouteHolder _downstreamRoute;
|
||||
private int _count;
|
||||
private Mock<IResponseAggregator> _aggregator;
|
||||
private Mock<IResponseAggregatorFactory> _factory;
|
||||
private HttpContext _httpContext;
|
||||
private RequestDelegate _next;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
|
||||
public MultiplexingMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_factory = new Mock<IResponseAggregatorFactory>();
|
||||
_aggregator = new Mock<IResponseAggregator>();
|
||||
_factory.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(_aggregator.Object);
|
||||
|
||||
public MultiplexingMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_factory = new Mock<IResponseAggregatorFactory>();
|
||||
_aggregator = new Mock<IResponseAggregator>();
|
||||
_factory.Setup(x => x.Get(It.IsAny<Route>())).Returns(_aggregator.Object);
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<MultiplexingMiddleware>()).Returns(_logger.Object);
|
||||
_loggerFactory.Setup(x => x.CreateLogger<MultiplexingMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.FromResult(_count++);
|
||||
_middleware = new MultiplexingMiddleware(_next, _loggerFactory.Object, _factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_multiplex()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
|
||||
|
||||
this.Given(x => GivenTheFollowing(reRoute))
|
||||
.When(x => WhenIMultiplex())
|
||||
.Then(x => ThePipelineIsCalled(2))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_multiplex()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
|
||||
|
||||
this.Given(x => GivenTheFollowing(reRoute))
|
||||
.When(x => WhenIMultiplex())
|
||||
.Then(x => ThePipelineIsCalled(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(ReRoute reRoute)
|
||||
{
|
||||
_downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
|
||||
_httpContext.Items.UpsertDownstreamRoute(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void WhenIMultiplex()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThePipelineIsCalled(int expected)
|
||||
{
|
||||
_count.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
_middleware = new MultiplexingMiddleware(_next, _loggerFactory.Object, _factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_multiplex()
|
||||
{
|
||||
var route = new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().Build()).WithDownstreamRoute(new DownstreamRouteBuilder().Build()).Build();
|
||||
|
||||
this.Given(x => GivenTheFollowing(route))
|
||||
.When(x => WhenIMultiplex())
|
||||
.Then(x => ThePipelineIsCalled(2))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_multiplex()
|
||||
{
|
||||
var route = new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().Build()).Build();
|
||||
|
||||
this.Given(x => GivenTheFollowing(route))
|
||||
.When(x => WhenIMultiplex())
|
||||
.Then(x => ThePipelineIsCalled(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(Route route)
|
||||
{
|
||||
_downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<PlaceholderNameAndValue>(), route);
|
||||
_httpContext.Items.UpsertDownstreamRoute(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void WhenIMultiplex()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThePipelineIsCalled(int expected)
|
||||
{
|
||||
_count.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
{
|
||||
private readonly InMemoryResponseAggregatorFactory _factory;
|
||||
private Mock<IDefinedAggregatorProvider> _provider;
|
||||
private ReRoute _reRoute;
|
||||
private Route _route;
|
||||
private IResponseAggregator _aggregator;
|
||||
|
||||
public ResponseAggregatorFactoryTests()
|
||||
@ -25,10 +25,10 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_return_simple_json_aggregator()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
var route = new RouteBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenReRoute(reRoute))
|
||||
this.Given(_ => GivenRoute(route))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheAggregatorIs<SimpleJsonResponseAggregator>())
|
||||
.BDDfy();
|
||||
@ -37,24 +37,24 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_return_user_defined_aggregator()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
var route = new RouteBuilder()
|
||||
.WithAggregator("doesntmatter")
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenReRoute(reRoute))
|
||||
this.Given(_ => GivenRoute(route))
|
||||
.When(_ => WhenIGet())
|
||||
.Then(_ => ThenTheAggregatorIs<UserDefinedResponseAggregator>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenReRoute(ReRoute reRoute)
|
||||
private void GivenRoute(Route route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_aggregator = _factory.Get(_reRoute);
|
||||
_aggregator = _factory.Get(_route);
|
||||
}
|
||||
|
||||
private void ThenTheAggregatorIs<T>()
|
||||
|
@ -22,7 +22,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
private readonly SimpleJsonResponseAggregator _aggregator;
|
||||
private List<HttpContext> _downstreamContexts;
|
||||
private HttpContext _upstreamContext;
|
||||
private ReRoute _reRoute;
|
||||
private Route _route;
|
||||
|
||||
public SimpleJsonResponseAggregatorTests()
|
||||
{
|
||||
@ -32,23 +32,23 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_aggregate_n_responses_and_set_response_content_on_upstream_context_withConfig()
|
||||
{
|
||||
var commentsDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Comments").Build();
|
||||
var commentsDownstreamRoute = new DownstreamRouteBuilder().WithKey("Comments").Build();
|
||||
|
||||
var userDetailsDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("UserDetails")
|
||||
var userDetailsDownstreamRoute = new DownstreamRouteBuilder().WithKey("UserDetails")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplate("", 0, false, "/v1/users/{userId}"))
|
||||
.Build();
|
||||
|
||||
var downstreamReRoutes = new List<DownstreamReRoute>
|
||||
var downstreamRoutes = new List<DownstreamRoute>
|
||||
{
|
||||
commentsDownstreamReRoute,
|
||||
userDetailsDownstreamReRoute
|
||||
commentsDownstreamRoute,
|
||||
userDetailsDownstreamRoute
|
||||
};
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoutes(downstreamReRoutes)
|
||||
.WithAggregateReRouteConfig(new List<AggregateReRouteConfig>()
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoutes(downstreamRoutes)
|
||||
.WithAggregateRouteConfig(new List<AggregateRouteConfig>()
|
||||
{
|
||||
new AggregateReRouteConfig(){ReRouteKey = "UserDetails",JsonPath = "$[*].writerId",Parameter = "userId"}
|
||||
new AggregateRouteConfig(){RouteKey = "UserDetails",JsonPath = "$[*].writerId",Parameter = "userId"}
|
||||
})
|
||||
.Build();
|
||||
|
||||
@ -56,19 +56,19 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
|
||||
var commentsDownstreamContext = new DefaultHttpContext();
|
||||
commentsDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent(commentsResponseContent, Encoding.UTF8, "application/json"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
|
||||
commentsDownstreamContext.Items.UpsertDownstreamReRoute(commentsDownstreamReRoute);
|
||||
commentsDownstreamContext.Items.UpsertDownstreamRoute(commentsDownstreamRoute);
|
||||
|
||||
var userDetailsResponseContent = @"[{""id"":1,""firstName"":""abolfazl"",""lastName"":""rajabpour""},{""id"":2,""firstName"":""reza"",""lastName"":""rezaei""}]";
|
||||
var userDetailsDownstreamContext = new DefaultHttpContext();
|
||||
userDetailsDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent(userDetailsResponseContent, Encoding.UTF8, "application/json"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
|
||||
userDetailsDownstreamContext.Items.UpsertDownstreamReRoute(userDetailsDownstreamReRoute);
|
||||
userDetailsDownstreamContext.Items.UpsertDownstreamRoute(userDetailsDownstreamRoute);
|
||||
|
||||
var downstreamContexts = new List<HttpContext> { commentsDownstreamContext, userDetailsDownstreamContext };
|
||||
|
||||
var expected = "{\"Comments\":" + commentsResponseContent + ",\"UserDetails\":" + userDetailsResponseContent + "}";
|
||||
|
||||
this.Given(x => GivenTheUpstreamContext(new DefaultHttpContext()))
|
||||
.And(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheDownstreamContext(downstreamContexts))
|
||||
.When(x => WhenIAggregate())
|
||||
.Then(x => ThenTheContentIs(expected))
|
||||
@ -80,34 +80,34 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_aggregate_n_responses_and_set_response_content_on_upstream_context()
|
||||
{
|
||||
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
|
||||
var billDownstreamRoute = new DownstreamRouteBuilder().WithKey("Bill").Build();
|
||||
|
||||
var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
|
||||
var georgeDownstreamRoute = new DownstreamRouteBuilder().WithKey("George").Build();
|
||||
|
||||
var downstreamReRoutes = new List<DownstreamReRoute>
|
||||
var downstreamRoutes = new List<DownstreamRoute>
|
||||
{
|
||||
billDownstreamReRoute,
|
||||
georgeDownstreamReRoute
|
||||
billDownstreamRoute,
|
||||
georgeDownstreamRoute
|
||||
};
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoutes(downstreamReRoutes)
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoutes(downstreamRoutes)
|
||||
.Build();
|
||||
|
||||
var billDownstreamContext = new DefaultHttpContext();
|
||||
billDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
|
||||
billDownstreamContext.Items.UpsertDownstreamReRoute(billDownstreamReRoute);
|
||||
billDownstreamContext.Items.UpsertDownstreamRoute(billDownstreamRoute);
|
||||
|
||||
var georgeDownstreamContext = new DefaultHttpContext();
|
||||
georgeDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("George says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
|
||||
georgeDownstreamContext.Items.UpsertDownstreamReRoute(georgeDownstreamReRoute);
|
||||
georgeDownstreamContext.Items.UpsertDownstreamRoute(georgeDownstreamRoute);
|
||||
|
||||
var downstreamContexts = new List<HttpContext> { billDownstreamContext, georgeDownstreamContext };
|
||||
|
||||
var expected = "{\"Bill\":Bill says hi,\"George\":George says hi}";
|
||||
|
||||
this.Given(x => GivenTheUpstreamContext(new DefaultHttpContext()))
|
||||
.And(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheDownstreamContext(downstreamContexts))
|
||||
.When(x => WhenIAggregate())
|
||||
.Then(x => ThenTheContentIs(expected))
|
||||
@ -119,27 +119,27 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_return_error_if_any_downstreams_have_errored()
|
||||
{
|
||||
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
|
||||
var billDownstreamRoute = new DownstreamRouteBuilder().WithKey("Bill").Build();
|
||||
|
||||
var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
|
||||
var georgeDownstreamRoute = new DownstreamRouteBuilder().WithKey("George").Build();
|
||||
|
||||
var downstreamReRoutes = new List<DownstreamReRoute>
|
||||
var downstreamRoutes = new List<DownstreamRoute>
|
||||
{
|
||||
billDownstreamReRoute,
|
||||
georgeDownstreamReRoute
|
||||
billDownstreamRoute,
|
||||
georgeDownstreamRoute
|
||||
};
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoutes(downstreamReRoutes)
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoutes(downstreamRoutes)
|
||||
.Build();
|
||||
|
||||
var billDownstreamContext = new DefaultHttpContext();
|
||||
billDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
|
||||
billDownstreamContext.Items.UpsertDownstreamReRoute(billDownstreamReRoute);
|
||||
billDownstreamContext.Items.UpsertDownstreamRoute(billDownstreamRoute);
|
||||
|
||||
var georgeDownstreamContext = new DefaultHttpContext();
|
||||
georgeDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Error"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
|
||||
georgeDownstreamContext.Items.UpsertDownstreamReRoute(georgeDownstreamReRoute);
|
||||
georgeDownstreamContext.Items.UpsertDownstreamRoute(georgeDownstreamRoute);
|
||||
|
||||
georgeDownstreamContext.Items.SetError(new AnyError());
|
||||
|
||||
@ -148,7 +148,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
var expected = "Error";
|
||||
|
||||
this.Given(x => GivenTheUpstreamContext(new DefaultHttpContext()))
|
||||
.And(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheRoute(route))
|
||||
.And(x => GivenTheDownstreamContext(downstreamContexts))
|
||||
.When(x => WhenIAggregate())
|
||||
.Then(x => ThenTheContentIs(expected))
|
||||
@ -167,9 +167,9 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
_upstreamContext.Items.DownstreamResponse().ShouldBe(_downstreamContexts[1].Items.DownstreamResponse());
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(ReRoute reRoute)
|
||||
private void GivenTheRoute(Route route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void GivenTheUpstreamContext(HttpContext upstreamContext)
|
||||
@ -184,7 +184,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
|
||||
private void WhenIAggregate()
|
||||
{
|
||||
_aggregator.Aggregate(_reRoute, _upstreamContext, _downstreamContexts).GetAwaiter().GetResult();
|
||||
_aggregator.Aggregate(_route, _upstreamContext, _downstreamContexts).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheContentIs(string expected)
|
||||
|
@ -21,7 +21,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
{
|
||||
private readonly UserDefinedResponseAggregator _aggregator;
|
||||
private readonly Mock<IDefinedAggregatorProvider> _provider;
|
||||
private ReRoute _reRoute;
|
||||
private Route _route;
|
||||
private List<HttpContext> _contexts;
|
||||
private HttpContext _context;
|
||||
|
||||
@ -34,7 +34,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_call_aggregator()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
var route = new RouteBuilder().Build();
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
@ -51,7 +51,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheProviderReturnsAggregator())
|
||||
.And(_ => GivenReRoute(reRoute))
|
||||
.And(_ => GivenRoute(route))
|
||||
.And(_ => GivenContexts(contexts))
|
||||
.And(_ => GivenContext(context))
|
||||
.When(_ => WhenIAggregate())
|
||||
@ -63,7 +63,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
[Fact]
|
||||
public void should_not_find_aggregator()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
var route = new RouteBuilder().Build();
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheProviderReturnsError())
|
||||
.And(_ => GivenReRoute(reRoute))
|
||||
.And(_ => GivenRoute(route))
|
||||
.And(_ => GivenContexts(contexts))
|
||||
.And(_ => GivenContext(context))
|
||||
.When(_ => WhenIAggregate())
|
||||
@ -97,7 +97,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
|
||||
private void GivenTheProviderReturnsError()
|
||||
{
|
||||
_provider.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(new ErrorResponse<IDefinedAggregator>(new AnyError()));
|
||||
_provider.Setup(x => x.Get(It.IsAny<Route>())).Returns(new ErrorResponse<IDefinedAggregator>(new AnyError()));
|
||||
}
|
||||
|
||||
private async Task ThenTheContentIsCorrect()
|
||||
@ -108,7 +108,7 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
|
||||
private void ThenTheProviderIsCalled()
|
||||
{
|
||||
_provider.Verify(x => x.Get(_reRoute), Times.Once);
|
||||
_provider.Verify(x => x.Get(_route), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenContext(HttpContext context)
|
||||
@ -123,18 +123,18 @@ namespace Ocelot.UnitTests.Multiplexing
|
||||
|
||||
private async Task WhenIAggregate()
|
||||
{
|
||||
await _aggregator.Aggregate(_reRoute, _context, _contexts);
|
||||
await _aggregator.Aggregate(_route, _context, _contexts);
|
||||
}
|
||||
|
||||
private void GivenTheProviderReturnsAggregator()
|
||||
{
|
||||
var aggregator = new TestDefinedAggregator();
|
||||
_provider.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(new OkResponse<IDefinedAggregator>(aggregator));
|
||||
_provider.Setup(x => x.Get(It.IsAny<Route>())).Returns(new OkResponse<IDefinedAggregator>(aggregator));
|
||||
}
|
||||
|
||||
private void GivenReRoute(ReRoute reRoute)
|
||||
private void GivenRoute(Route route)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
public class TestDefinedAggregator : IDefinedAggregator
|
||||
|
@ -1,45 +1,45 @@
|
||||
namespace Ocelot.UnitTests.Polly
|
||||
{
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Provider.Polly;
|
||||
using Shouldly;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
public class OcelotBuilderExtensionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_build()
|
||||
{
|
||||
var loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
var services = new ServiceCollection();
|
||||
var options = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithDurationOfBreak(200)
|
||||
.Build();
|
||||
var reRoute = new DownstreamReRouteBuilder().WithQosOptions(options)
|
||||
.Build();
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.Build();
|
||||
services
|
||||
.AddOcelot(configuration)
|
||||
.AddPolly();
|
||||
var provider = services.BuildServiceProvider();
|
||||
|
||||
var handler = provider.GetService<QosDelegatingHandlerDelegate>();
|
||||
handler.ShouldNotBeNull();
|
||||
|
||||
var delgatingHandler = handler(reRoute, loggerFactory.Object);
|
||||
delgatingHandler.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Polly
|
||||
{
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Provider.Polly;
|
||||
using Shouldly;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
public class OcelotBuilderExtensionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_build()
|
||||
{
|
||||
var loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
var services = new ServiceCollection();
|
||||
var options = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithDurationOfBreak(200)
|
||||
.Build();
|
||||
var route = new DownstreamRouteBuilder().WithQosOptions(options)
|
||||
.Build();
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.Build();
|
||||
services
|
||||
.AddOcelot(configuration)
|
||||
.AddPolly();
|
||||
var provider = services.BuildServiceProvider();
|
||||
|
||||
var handler = provider.GetService<QosDelegatingHandlerDelegate>();
|
||||
handler.ShouldNotBeNull();
|
||||
|
||||
var delgatingHandler = handler(route, loggerFactory.Object);
|
||||
delgatingHandler.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
namespace Ocelot.UnitTests.Polly
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Provider.Polly;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
public class PollyQoSProviderTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_build()
|
||||
{
|
||||
var options = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithDurationOfBreak(200)
|
||||
.Build();
|
||||
var reRoute = new DownstreamReRouteBuilder().WithQosOptions(options)
|
||||
.Build();
|
||||
var factory = new Mock<IOcelotLoggerFactory>();
|
||||
var pollyQoSProvider = new PollyQoSProvider(reRoute, factory.Object);
|
||||
pollyQoSProvider.CircuitBreaker.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Polly
|
||||
{
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Provider.Polly;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
public class PollyQoSProviderTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_build()
|
||||
{
|
||||
var options = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithDurationOfBreak(200)
|
||||
.Build();
|
||||
var route = new DownstreamRouteBuilder().WithQosOptions(options)
|
||||
.Build();
|
||||
var factory = new Mock<IOcelotLoggerFactory>();
|
||||
var pollyQoSProvider = new PollyQoSProvider(route, factory.Object);
|
||||
pollyQoSProvider.CircuitBreaker.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,102 +1,102 @@
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.UnitTests.QueryStrings
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.QueryStrings.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.UnitTests.QueryStrings
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.QueryStrings.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
public class ClaimsToQueryStringMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IAddQueriesToRequest> _addQueries;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private ClaimsToQueryStringMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public ClaimsToQueryStringMiddlewareTests()
|
||||
{
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToQueryStringMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
public class ClaimsToQueryStringMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IAddQueriesToRequest> _addQueries;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private ClaimsToQueryStringMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private HttpContext _httpContext;
|
||||
private Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
public ClaimsToQueryStringMiddlewareTests()
|
||||
{
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToQueryStringMiddleware>()).Returns(_logger.Object);
|
||||
_next = context => Task.CompletedTask;
|
||||
_addQueries = new Mock<IAddQueriesToRequest>();
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com")));
|
||||
_middleware = new ClaimsToQueryStringMiddleware(_next, _loggerFactory.Object, _addQueries.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToQueries(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddQueriesToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToRequestReturnsOk()
|
||||
{
|
||||
_addQueries
|
||||
.Setup(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<DownstreamRequest>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddQueriesToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addQueries
|
||||
.Verify(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
_httpContext.Items.DownstreamRequest()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com")));
|
||||
_middleware = new ClaimsToQueryStringMiddleware(_next, _loggerFactory.Object, _addQueries.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToQueries(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddQueriesToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_middleware.Invoke(_httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToRequestReturnsOk()
|
||||
{
|
||||
_addQueries
|
||||
.Setup(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<DownstreamRequest>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddQueriesToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addQueries
|
||||
.Verify(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
_httpContext.Items.DownstreamRequest()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,23 +50,23 @@ namespace Ocelot.UnitTests.RateLimit
|
||||
{
|
||||
var upstreamTemplate = new UpstreamPathTemplateBuilder().Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithRateLimitOptions(new RateLimitOptions(true, "ClientId", () => new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamPathTemplate(upstreamTemplate)
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
var route = new RouteBuilder()
|
||||
.WithDownstreamRoute(downstreamRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(), reRoute);
|
||||
var downstreamRouteHolder = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(), route);
|
||||
|
||||
this.Given(x => x.WhenICallTheMiddlewareMultipleTimes(2, downstreamRoute))
|
||||
this.Given(x => x.WhenICallTheMiddlewareMultipleTimes(2, downstreamRouteHolder))
|
||||
.Then(x => x.ThenThereIsNoDownstreamResponse())
|
||||
.When(x => x.WhenICallTheMiddlewareMultipleTimes(3, downstreamRoute))
|
||||
.When(x => x.WhenICallTheMiddlewareMultipleTimes(3, downstreamRouteHolder))
|
||||
.Then(x => x.ThenTheResponseIs429())
|
||||
.BDDfy();
|
||||
}
|
||||
@ -74,9 +74,9 @@ namespace Ocelot.UnitTests.RateLimit
|
||||
[Fact]
|
||||
public void should_call_middleware_withWhitelistClient()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new Ocelot.DownstreamRouteFinder.DownstreamRouteHolder(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithRateLimitOptions(
|
||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", () => new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule("1s", 100, 3), 429))
|
||||
@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.RateLimit
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddlewareMultipleTimes(int times, DownstreamRoute downstreamRoute)
|
||||
private void WhenICallTheMiddlewareMultipleTimes(int times, Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
var httpContexts = new List<HttpContext>();
|
||||
|
||||
@ -98,7 +98,7 @@ namespace Ocelot.UnitTests.RateLimit
|
||||
{
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Response.Body = new FakeStream();
|
||||
httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
httpContext.Items.UpsertDownstreamRoute(downstreamRoute);
|
||||
var clientId = "ocelotclient1";
|
||||
@ -116,7 +116,7 @@ namespace Ocelot.UnitTests.RateLimit
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddlewareWithWhiteClient(DownstreamRoute downstreamRoute)
|
||||
private void WhenICallTheMiddlewareWithWhiteClient(Ocelot.DownstreamRouteFinder.DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
var clientId = "ocelotclient2";
|
||||
|
||||
@ -124,7 +124,7 @@ namespace Ocelot.UnitTests.RateLimit
|
||||
{
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Response.Body = new FakeStream();
|
||||
httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
httpContext.Items.UpsertDownstreamRoute(downstreamRoute);
|
||||
var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
|
||||
|
@ -60,7 +60,7 @@
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_downstream_reroute_method_to_downstream_request()
|
||||
public void Should_map_downstream_route_method_to_downstream_request()
|
||||
{
|
||||
this.Given(_ => GivenTheHttpContextContainsARequest())
|
||||
.And(_ => GivenTheMapperWillReturnAMappedRequest())
|
||||
@ -91,7 +91,7 @@
|
||||
|
||||
private void GivenTheHttpContextContainsARequest()
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamReRoute(new DownstreamReRouteBuilder().Build());
|
||||
_httpContext.Items.UpsertDownstreamRoute(new DownstreamRouteBuilder().Build());
|
||||
}
|
||||
|
||||
private void GivenTheMapperWillReturnAMappedRequest()
|
||||
@ -99,7 +99,7 @@
|
||||
_mappedRequest = new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "http://www.bbc.co.uk"));
|
||||
|
||||
_requestMapper
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>()))
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamRoute>()))
|
||||
.ReturnsAsync(_mappedRequest);
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@
|
||||
_mappedRequest = new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(new System.Exception("boooom!")));
|
||||
|
||||
_requestMapper
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>()))
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamRoute>()))
|
||||
.ReturnsAsync(_mappedRequest);
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
private void ThenTheContexRequestIsMappedToADownstreamRequest()
|
||||
{
|
||||
_requestMapper.Verify(rm => rm.Map(_httpContext.Request, _httpContext.Items.DownstreamReRoute()), Times.Once);
|
||||
_requestMapper.Verify(rm => rm.Map(_httpContext.Request, _httpContext.Items.DownstreamRoute()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestIsStored()
|
||||
|
@ -1,484 +1,484 @@
|
||||
namespace Ocelot.UnitTests.Request.Mapper
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Request.Mapper;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RequestMapperTests
|
||||
{
|
||||
private readonly HttpContext _httpContext;
|
||||
private readonly HttpRequest _inputRequest;
|
||||
|
||||
private readonly RequestMapper _requestMapper;
|
||||
|
||||
private Response<HttpRequestMessage> _mappedRequest;
|
||||
|
||||
private List<KeyValuePair<string, StringValues>> _inputHeaders = null;
|
||||
|
||||
private DownstreamReRoute _downstreamReRoute;
|
||||
|
||||
public RequestMapperTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_inputRequest = _httpContext.Request;
|
||||
_requestMapper = new RequestMapper();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https", "my.url:123", "/abc/DEF", "?a=1&b=2", "https://my.url:123/abc/DEF?a=1&b=2")]
|
||||
[InlineData("http", "blah.com", "/d ef", "?abc=123", "http://blah.com/d%20ef?abc=123")] // note! the input is encoded when building the input request
|
||||
[InlineData("http", "myusername:mypassword@abc.co.uk", null, null, "http://myusername:mypassword@abc.co.uk/")]
|
||||
[InlineData("http", "點看.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
[InlineData("http", "xn--c1yn36f.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
public void Should_map_valid_request_uri(string scheme, string host, string path, string queryString, string expectedUri)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasUri(expectedUri))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("ftp", "google.com", "/abc/DEF", "?a=1&b=2")]
|
||||
public void Should_error_on_unsupported_request_uri(string scheme, string host, string path, string queryString)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("WHATEVER")]
|
||||
public void Should_map_method(string method)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod(method))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasMethod(method))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "GET")]
|
||||
[InlineData(null, "GET")]
|
||||
[InlineData("POST", "POST")]
|
||||
public void Should_use_downstream_reroute_method_if_set(string input, string expected)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheDownstreamReRouteMethodIs(input))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasMethod(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_all_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasEachHeader())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoHeaders())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContent("This is my content"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNullContent())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content_type()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoContentType())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content_length()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoContentLength())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content_headers()
|
||||
{
|
||||
byte[] md5bytes = new byte[0];
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
md5bytes = md5.ComputeHash(Encoding.UTF8.GetBytes("some md5"));
|
||||
}
|
||||
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheContentTypeIs("application/json"))
|
||||
.And(_ => GivenTheContentEncodingIs("gzip, compress"))
|
||||
.And(_ => GivenTheContentLanguageIs("english"))
|
||||
.And(_ => GivenTheContentLocationIs("/my-receipts/38"))
|
||||
.And(_ => GivenTheContentRangeIs("bytes 1-2/*"))
|
||||
.And(_ => GivenTheContentDispositionIs("inline"))
|
||||
.And(_ => GivenTheContentMD5Is(md5bytes))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
|
||||
.And(_ => ThenTheMappedRequestHasContentEncodingHeader("gzip", "compress"))
|
||||
.And(_ => ThenTheMappedRequestHasContentLanguageHeader("english"))
|
||||
.And(_ => ThenTheMappedRequestHasContentLocationHeader("/my-receipts/38"))
|
||||
.And(_ => ThenTheMappedRequestHasContentMD5Header(md5bytes))
|
||||
.And(_ => ThenTheMappedRequestHasContentRangeHeader())
|
||||
.And(_ => ThenTheMappedRequestHasContentDispositionHeader("inline"))
|
||||
.And(_ => ThenTheMappedRequestHasContentSize("This is my content".Length))
|
||||
.And(_ => ThenTheContentHeadersAreNotAddedToNonContentHeaders())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_add_content_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheContentTypeIs("application/json"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("POST"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamReRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
|
||||
.And(_ => ThenTheMappedRequestHasContentSize("This is my content".Length))
|
||||
.And(_ => ThenTheOtherContentTypeHeadersAreNotMapped())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamReRouteMethodIs(string input)
|
||||
{
|
||||
_downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownStreamHttpMethod(input)
|
||||
.WithDownstreamHttpVersion(new Version("1.1")).Build();
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamReRoute()
|
||||
{
|
||||
_downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamHttpVersion(new Version("1.1")).Build();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoContentLength()
|
||||
{
|
||||
_inputRequest.ContentLength = null;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoContentType()
|
||||
{
|
||||
_inputRequest.ContentType = null;
|
||||
}
|
||||
|
||||
|
||||
private void ThenTheContentHeadersAreNotAddedToNonContentHeaders()
|
||||
{
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Disposition");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentMD5");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentRange");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentLanguage");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentEncoding");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentLocation");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Length");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Type");
|
||||
}
|
||||
|
||||
private void ThenTheOtherContentTypeHeadersAreNotMapped()
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentDisposition.ShouldBeNull();
|
||||
_mappedRequest.Data.Content.Headers.ContentMD5.ShouldBeNull();
|
||||
_mappedRequest.Data.Content.Headers.ContentRange.ShouldBeNull();
|
||||
_mappedRequest.Data.Content.Headers.ContentLanguage.ShouldBeEmpty();
|
||||
_mappedRequest.Data.Content.Headers.ContentEncoding.ShouldBeEmpty();
|
||||
_mappedRequest.Data.Content.Headers.ContentLocation.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentDispositionHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentDisposition.DispositionType.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentDispositionIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Disposition", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentMD5Header(byte[] expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentMD5.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentMD5Is(byte[] input)
|
||||
{
|
||||
var base64 = Convert.ToBase64String(input);
|
||||
_inputRequest.Headers.Add("Content-MD5", base64);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentRangeHeader()
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentRange.From.ShouldBe(1);
|
||||
_mappedRequest.Data.Content.Headers.ContentRange.To.ShouldBe(2);
|
||||
}
|
||||
|
||||
private void GivenTheContentRangeIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Range", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentLocationHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLocation.OriginalString.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentLocationIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Location", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentLanguageHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLanguage.First().ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentLanguageIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Language", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentEncodingHeader(string expected, string expectedTwo)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentEncoding.ToArray()[0].ShouldBe(expected);
|
||||
_mappedRequest.Data.Content.Headers.ContentEncoding.ToArray()[1].ShouldBe(expectedTwo);
|
||||
}
|
||||
|
||||
private void GivenTheContentEncodingIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Encoding", input);
|
||||
}
|
||||
|
||||
private void GivenTheContentTypeIs(string contentType)
|
||||
{
|
||||
_inputRequest.ContentType = contentType;
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentTypeHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentType.MediaType.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentSize(long expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLength.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasMethod(string method)
|
||||
{
|
||||
_inputRequest.Method = method;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasScheme(string scheme)
|
||||
{
|
||||
_inputRequest.Scheme = scheme;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHost(string host)
|
||||
{
|
||||
_inputRequest.Host = new HostString(host);
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasPath(string path)
|
||||
{
|
||||
if (path != null)
|
||||
{
|
||||
_inputRequest.Path = path;
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasQueryString(string querystring)
|
||||
{
|
||||
if (querystring != null)
|
||||
{
|
||||
_inputRequest.QueryString = new QueryString(querystring);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasAValidUri()
|
||||
{
|
||||
GivenTheInputRequestHasScheme("http");
|
||||
GivenTheInputRequestHasHost("www.google.com");
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHeaders()
|
||||
{
|
||||
_inputHeaders = new List<KeyValuePair<string, StringValues>>()
|
||||
{
|
||||
new KeyValuePair<string, StringValues>("abc", new StringValues(new string[]{"123","456" })),
|
||||
new KeyValuePair<string, StringValues>("def", new StringValues(new string[]{"789","012" })),
|
||||
};
|
||||
|
||||
foreach (var inputHeader in _inputHeaders)
|
||||
{
|
||||
_inputRequest.Headers.Add(inputHeader);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoHeaders()
|
||||
{
|
||||
_inputRequest.Headers.Clear();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasContent(string content)
|
||||
{
|
||||
_inputRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNullContent()
|
||||
{
|
||||
_inputRequest.Body = null;
|
||||
}
|
||||
|
||||
private async Task WhenMapped()
|
||||
{
|
||||
_mappedRequest = await _requestMapper.Map(_inputRequest, _downstreamReRoute);
|
||||
}
|
||||
|
||||
private void ThenNoErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasUri(string expectedUri)
|
||||
{
|
||||
_mappedRequest.Data.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasMethod(string expectedMethod)
|
||||
{
|
||||
_mappedRequest.Data.Method.ToString().ShouldBe(expectedMethod);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasEachHeader()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(_inputHeaders.Count);
|
||||
foreach (var header in _mappedRequest.Data.Headers)
|
||||
{
|
||||
var inputHeader = _inputHeaders.First(h => h.Key == header.Key);
|
||||
inputHeader.ShouldNotBeNull();
|
||||
inputHeader.Value.Count().ShouldBe(header.Value.Count());
|
||||
foreach (var inputHeaderValue in inputHeader.Value)
|
||||
{
|
||||
header.Value.Any(v => v == inputHeaderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoHeaders()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContent(string expectedContent)
|
||||
{
|
||||
_mappedRequest.Data.Content.ReadAsStringAsync().GetAwaiter().GetResult().ShouldBe(expectedContent);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoContent()
|
||||
{
|
||||
_mappedRequest.Data.Content.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestIsNull()
|
||||
{
|
||||
_mappedRequest.Data.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Request.Mapper
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Request.Mapper;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class RequestMapperTests
|
||||
{
|
||||
private readonly HttpContext _httpContext;
|
||||
private readonly HttpRequest _inputRequest;
|
||||
|
||||
private readonly RequestMapper _requestMapper;
|
||||
|
||||
private Response<HttpRequestMessage> _mappedRequest;
|
||||
|
||||
private List<KeyValuePair<string, StringValues>> _inputHeaders = null;
|
||||
|
||||
private DownstreamRoute _downstreamRoute;
|
||||
|
||||
public RequestMapperTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_inputRequest = _httpContext.Request;
|
||||
_requestMapper = new RequestMapper();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https", "my.url:123", "/abc/DEF", "?a=1&b=2", "https://my.url:123/abc/DEF?a=1&b=2")]
|
||||
[InlineData("http", "blah.com", "/d ef", "?abc=123", "http://blah.com/d%20ef?abc=123")] // note! the input is encoded when building the input request
|
||||
[InlineData("http", "myusername:mypassword@abc.co.uk", null, null, "http://myusername:mypassword@abc.co.uk/")]
|
||||
[InlineData("http", "點看.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
[InlineData("http", "xn--c1yn36f.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
public void Should_map_valid_request_uri(string scheme, string host, string path, string queryString, string expectedUri)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasUri(expectedUri))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("ftp", "google.com", "/abc/DEF", "?a=1&b=2")]
|
||||
public void Should_error_on_unsupported_request_uri(string scheme, string host, string path, string queryString)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("WHATEVER")]
|
||||
public void Should_map_method(string method)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod(method))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasMethod(method))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "GET")]
|
||||
[InlineData(null, "GET")]
|
||||
[InlineData("POST", "POST")]
|
||||
public void Should_use_downstream_route_method_if_set(string input, string expected)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheDownstreamRouteMethodIs(input))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasMethod(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_all_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasEachHeader())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoHeaders())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContent("This is my content"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNullContent())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content_type()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoContentType())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content_length()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoContentLength())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content_headers()
|
||||
{
|
||||
byte[] md5bytes = new byte[0];
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
md5bytes = md5.ComputeHash(Encoding.UTF8.GetBytes("some md5"));
|
||||
}
|
||||
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheContentTypeIs("application/json"))
|
||||
.And(_ => GivenTheContentEncodingIs("gzip, compress"))
|
||||
.And(_ => GivenTheContentLanguageIs("english"))
|
||||
.And(_ => GivenTheContentLocationIs("/my-receipts/38"))
|
||||
.And(_ => GivenTheContentRangeIs("bytes 1-2/*"))
|
||||
.And(_ => GivenTheContentDispositionIs("inline"))
|
||||
.And(_ => GivenTheContentMD5Is(md5bytes))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
|
||||
.And(_ => ThenTheMappedRequestHasContentEncodingHeader("gzip", "compress"))
|
||||
.And(_ => ThenTheMappedRequestHasContentLanguageHeader("english"))
|
||||
.And(_ => ThenTheMappedRequestHasContentLocationHeader("/my-receipts/38"))
|
||||
.And(_ => ThenTheMappedRequestHasContentMD5Header(md5bytes))
|
||||
.And(_ => ThenTheMappedRequestHasContentRangeHeader())
|
||||
.And(_ => ThenTheMappedRequestHasContentDispositionHeader("inline"))
|
||||
.And(_ => ThenTheMappedRequestHasContentSize("This is my content".Length))
|
||||
.And(_ => ThenTheContentHeadersAreNotAddedToNonContentHeaders())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_add_content_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheContentTypeIs("application/json"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("POST"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.And(_ => GivenTheDownstreamRoute())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
|
||||
.And(_ => ThenTheMappedRequestHasContentSize("This is my content".Length))
|
||||
.And(_ => ThenTheOtherContentTypeHeadersAreNotMapped())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRouteMethodIs(string input)
|
||||
{
|
||||
_downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownStreamHttpMethod(input)
|
||||
.WithDownstreamHttpVersion(new Version("1.1")).Build();
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRoute()
|
||||
{
|
||||
_downstreamRoute = new DownstreamRouteBuilder()
|
||||
.WithDownstreamHttpVersion(new Version("1.1")).Build();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoContentLength()
|
||||
{
|
||||
_inputRequest.ContentLength = null;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoContentType()
|
||||
{
|
||||
_inputRequest.ContentType = null;
|
||||
}
|
||||
|
||||
|
||||
private void ThenTheContentHeadersAreNotAddedToNonContentHeaders()
|
||||
{
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Disposition");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentMD5");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentRange");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentLanguage");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentEncoding");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-ContentLocation");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Length");
|
||||
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Type");
|
||||
}
|
||||
|
||||
private void ThenTheOtherContentTypeHeadersAreNotMapped()
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentDisposition.ShouldBeNull();
|
||||
_mappedRequest.Data.Content.Headers.ContentMD5.ShouldBeNull();
|
||||
_mappedRequest.Data.Content.Headers.ContentRange.ShouldBeNull();
|
||||
_mappedRequest.Data.Content.Headers.ContentLanguage.ShouldBeEmpty();
|
||||
_mappedRequest.Data.Content.Headers.ContentEncoding.ShouldBeEmpty();
|
||||
_mappedRequest.Data.Content.Headers.ContentLocation.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentDispositionHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentDisposition.DispositionType.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentDispositionIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Disposition", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentMD5Header(byte[] expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentMD5.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentMD5Is(byte[] input)
|
||||
{
|
||||
var base64 = Convert.ToBase64String(input);
|
||||
_inputRequest.Headers.Add("Content-MD5", base64);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentRangeHeader()
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentRange.From.ShouldBe(1);
|
||||
_mappedRequest.Data.Content.Headers.ContentRange.To.ShouldBe(2);
|
||||
}
|
||||
|
||||
private void GivenTheContentRangeIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Range", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentLocationHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLocation.OriginalString.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentLocationIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Location", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentLanguageHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLanguage.First().ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheContentLanguageIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Language", input);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentEncodingHeader(string expected, string expectedTwo)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentEncoding.ToArray()[0].ShouldBe(expected);
|
||||
_mappedRequest.Data.Content.Headers.ContentEncoding.ToArray()[1].ShouldBe(expectedTwo);
|
||||
}
|
||||
|
||||
private void GivenTheContentEncodingIs(string input)
|
||||
{
|
||||
_inputRequest.Headers.Add("Content-Encoding", input);
|
||||
}
|
||||
|
||||
private void GivenTheContentTypeIs(string contentType)
|
||||
{
|
||||
_inputRequest.ContentType = contentType;
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentTypeHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentType.MediaType.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentSize(long expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLength.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasMethod(string method)
|
||||
{
|
||||
_inputRequest.Method = method;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasScheme(string scheme)
|
||||
{
|
||||
_inputRequest.Scheme = scheme;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHost(string host)
|
||||
{
|
||||
_inputRequest.Host = new HostString(host);
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasPath(string path)
|
||||
{
|
||||
if (path != null)
|
||||
{
|
||||
_inputRequest.Path = path;
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasQueryString(string querystring)
|
||||
{
|
||||
if (querystring != null)
|
||||
{
|
||||
_inputRequest.QueryString = new QueryString(querystring);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasAValidUri()
|
||||
{
|
||||
GivenTheInputRequestHasScheme("http");
|
||||
GivenTheInputRequestHasHost("www.google.com");
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHeaders()
|
||||
{
|
||||
_inputHeaders = new List<KeyValuePair<string, StringValues>>()
|
||||
{
|
||||
new KeyValuePair<string, StringValues>("abc", new StringValues(new string[]{"123","456" })),
|
||||
new KeyValuePair<string, StringValues>("def", new StringValues(new string[]{"789","012" })),
|
||||
};
|
||||
|
||||
foreach (var inputHeader in _inputHeaders)
|
||||
{
|
||||
_inputRequest.Headers.Add(inputHeader);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoHeaders()
|
||||
{
|
||||
_inputRequest.Headers.Clear();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasContent(string content)
|
||||
{
|
||||
_inputRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNullContent()
|
||||
{
|
||||
_inputRequest.Body = null;
|
||||
}
|
||||
|
||||
private async Task WhenMapped()
|
||||
{
|
||||
_mappedRequest = await _requestMapper.Map(_inputRequest, _downstreamRoute);
|
||||
}
|
||||
|
||||
private void ThenNoErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasUri(string expectedUri)
|
||||
{
|
||||
_mappedRequest.Data.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasMethod(string expectedMethod)
|
||||
{
|
||||
_mappedRequest.Data.Method.ToString().ShouldBe(expectedMethod);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasEachHeader()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(_inputHeaders.Count);
|
||||
foreach (var header in _mappedRequest.Data.Headers)
|
||||
{
|
||||
var inputHeader = _inputHeaders.First(h => h.Key == header.Key);
|
||||
inputHeader.ShouldNotBeNull();
|
||||
inputHeader.Value.Count().ShouldBe(header.Value.Count());
|
||||
foreach (var inputHeaderValue in inputHeader.Value)
|
||||
{
|
||||
header.Value.Any(v => v == inputHeaderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoHeaders()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContent(string expectedContent)
|
||||
{
|
||||
_mappedRequest.Data.Content.ReadAsStringAsync().GetAwaiter().GetResult().ShouldBe(expectedContent);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoContent()
|
||||
{
|
||||
_mappedRequest.Data.Content.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestIsNull()
|
||||
{
|
||||
_mappedRequest.Data.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,40 +21,40 @@
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ReRouteRequestIdMiddlewareTests
|
||||
public class RequestIdMiddlewareTests
|
||||
{
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private string _value;
|
||||
private string _key;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private readonly ReRouteRequestIdMiddleware _middleware;
|
||||
private readonly RequestIdMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
private readonly Mock<IRequestScopedDataRepository> _repo;
|
||||
private HttpContext _httpContext;
|
||||
public ReRouteRequestIdMiddlewareTests()
|
||||
public RequestIdMiddlewareTests()
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory.Setup(x => x.CreateLogger<ReRouteRequestIdMiddleware>()).Returns(_logger.Object);
|
||||
_loggerFactory.Setup(x => x.CreateLogger<RequestIdMiddleware>()).Returns(_logger.Object);
|
||||
_next = context =>
|
||||
{
|
||||
_httpContext.Response.Headers.Add("LSRequestId", _httpContext.TraceIdentifier);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
_middleware = new ReRouteRequestIdMiddleware(_next, _loggerFactory.Object, _repo.Object);
|
||||
_middleware = new RequestIdMiddleware(_next, _loggerFactory.Object, _repo.Object);
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(_downstreamRequest));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_pass_down_request_id_from_upstream_request()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -75,9 +75,9 @@
|
||||
[Fact]
|
||||
public void should_add_request_id_when_not_on_upstream_request()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -95,9 +95,9 @@
|
||||
[Fact]
|
||||
public void should_add_request_id_scoped_repo_for_logging_later()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -119,9 +119,9 @@
|
||||
[Fact]
|
||||
public void should_update_request_id_scoped_repo_for_logging_later()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -143,9 +143,9 @@
|
||||
[Fact]
|
||||
public void should_not_update_if_global_request_id_is_same_as_re_route_request_id()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
|
||||
var downstreamRoute = new DownstreamRouteHolder(new List<PlaceholderNameAndValue>(),
|
||||
new RouteBuilder()
|
||||
.WithDownstreamRoute(new DownstreamRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -194,11 +194,11 @@
|
||||
_repo.Verify(x => x.Update("RequestId", _value), Times.Never);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRouteHolder downstreamRoute)
|
||||
{
|
||||
_httpContext.Items.UpsertTemplatePlaceholderNameAndValues(downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
|
||||
_httpContext.Items.UpsertDownstreamReRoute(downstreamRoute.ReRoute.DownstreamReRoute[0]);
|
||||
_httpContext.Items.UpsertDownstreamRoute(downstreamRoute.Route.DownstreamRoute[0]);
|
||||
}
|
||||
|
||||
private void GivenTheRequestIdIsAddedToTheRequest(string key, string value)
|
File diff suppressed because it is too large
Load Diff
@ -1,446 +1,446 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class HttpClientBuilderTests : IDisposable
|
||||
{
|
||||
private HttpClientBuilder _builder;
|
||||
private readonly Mock<IDelegatingHandlerHandlerFactory> _factory;
|
||||
private IHttpClient _httpClient;
|
||||
private HttpResponseMessage _response;
|
||||
private HttpContext _context;
|
||||
private readonly Mock<IHttpClientCache> _cacheHandlers;
|
||||
private readonly Mock<IOcelotLogger> _logger;
|
||||
private int _count;
|
||||
private IWebHost _host;
|
||||
private IHttpClient _againHttpClient;
|
||||
private IHttpClient _firstHttpClient;
|
||||
private MemoryHttpClientCache _realCache;
|
||||
|
||||
public HttpClientBuilderTests()
|
||||
{
|
||||
_cacheHandlers = new Mock<IHttpClientCache>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_factory = new Mock<IDelegatingHandlerHandlerFactory>();
|
||||
_builder = new HttpClientBuilder(_factory.Object, _cacheHandlers.Object, _logger.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_http_client()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(reRoute))
|
||||
.When(x => WhenIBuild())
|
||||
.Then(x => ThenTheHttpClientShouldNotBeNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_from_cache()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenARealCache())
|
||||
.And(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(reRoute))
|
||||
.And(x => WhenIBuildTheFirstTime())
|
||||
.And(x => WhenISave())
|
||||
.And(x => WhenIBuildAgain())
|
||||
.And(x => WhenISave())
|
||||
.When(x => WhenIBuildAgain())
|
||||
.Then(x => ThenTheHttpClientIsFromTheCache())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_from_cache_with_different_query_string()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenARealCache())
|
||||
.And(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(reRoute, "http://wwww.someawesomewebsite.com/woot?badman=1"))
|
||||
.And(x => WhenIBuildTheFirstTime())
|
||||
.And(x => WhenISave())
|
||||
.And(x => WhenIBuildAgain())
|
||||
.And(x => GivenARequest(reRoute, "http://wwww.someawesomewebsite.com/woot?badman=2"))
|
||||
.And(x => WhenISave())
|
||||
.When(x => WhenIBuildAgain())
|
||||
.Then(x => ThenTheHttpClientIsFromTheCache())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_get_from_cache_with_different_query_string()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRouteA = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var reRouteB = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenARealCache())
|
||||
.And(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(reRouteA, "http://wwww.someawesomewebsite.com/woot?badman=1"))
|
||||
.And(x => WhenIBuildTheFirstTime())
|
||||
.And(x => WhenISave())
|
||||
.And(x => WhenIBuildAgain())
|
||||
.And(x => GivenARequest(reRouteB, "http://wwww.someawesomewebsite.com/woot?badman=2"))
|
||||
.And(x => WhenISave())
|
||||
.When(x => WhenIBuildAgain())
|
||||
.Then(x => ThenTheHttpClientIsNotFromTheCache())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_log_if_ignoring_ssl_errors()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.WithDangerousAcceptAnyServerCertificateValidator(true)
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(reRoute))
|
||||
.When(x => WhenIBuild())
|
||||
.Then(x => ThenTheHttpClientShouldNotBeNull())
|
||||
.Then(x => ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_delegating_handlers_in_order()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var fakeOne = new FakeDelegatingHandler();
|
||||
var fakeTwo = new FakeDelegatingHandler();
|
||||
|
||||
var handlers = new List<Func<DelegatingHandler>>()
|
||||
{
|
||||
() => fakeOne,
|
||||
() => fakeTwo
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFactoryReturns(handlers))
|
||||
.And(x => GivenARequest(reRoute))
|
||||
.And(x => WhenIBuild())
|
||||
.When(x => WhenICallTheClient())
|
||||
.Then(x => ThenTheFakeAreHandledInOrder(fakeOne, fakeTwo))
|
||||
.And(x => ThenSomethingIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_re_use_cookies_from_container()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenADownstreamService())
|
||||
.And(_ => GivenARequest(reRoute))
|
||||
.And(_ => GivenTheFactoryReturnsNothing())
|
||||
.And(_ => WhenIBuild())
|
||||
.And(_ => WhenICallTheClient("http://localhost:5003"))
|
||||
.And(_ => ThenTheCookieIsSet())
|
||||
.And(_ => GivenTheClientIsCached())
|
||||
.And(_ => WhenIBuild())
|
||||
.When(_ => WhenICallTheClient("http://localhost:5003"))
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("PUT")]
|
||||
[InlineData("DELETE")]
|
||||
[InlineData("PATCH")]
|
||||
public void should_add_verb_to_cache_key(string verb)
|
||||
{
|
||||
var downstreamUrl = "http://localhost:5012/";
|
||||
|
||||
var method = new HttpMethod(verb);
|
||||
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenADownstreamService())
|
||||
.And(_ => GivenARequestWithAUrlAndMethod(reRoute, downstreamUrl, method))
|
||||
.And(_ => GivenTheFactoryReturnsNothing())
|
||||
.And(_ => WhenIBuild())
|
||||
.And(_ => GivenCacheIsCalledWithExpectedKey($"{method.ToString()}:{downstreamUrl}"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARealCache()
|
||||
{
|
||||
_realCache = new MemoryHttpClientCache();
|
||||
_builder = new HttpClientBuilder(_factory.Object, _realCache, _logger.Object);
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientIsFromTheCache()
|
||||
{
|
||||
_againHttpClient.ShouldBe(_firstHttpClient);
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientIsNotFromTheCache()
|
||||
{
|
||||
_againHttpClient.ShouldNotBe(_firstHttpClient);
|
||||
}
|
||||
|
||||
private void WhenISave()
|
||||
{
|
||||
_builder.Save();
|
||||
}
|
||||
|
||||
private void GivenCacheIsCalledWithExpectedKey(string expectedKey)
|
||||
{
|
||||
_cacheHandlers.Verify(x => x.Get(It.IsAny<DownstreamReRoute>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged()
|
||||
{
|
||||
_logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {_context.Items.DownstreamReRoute().UpstreamPathTemplate}, DownstreamPathTemplate: {_context.Items.DownstreamReRoute().DownstreamPathTemplate}"), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheClientIsCached()
|
||||
{
|
||||
_cacheHandlers.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(_httpClient);
|
||||
}
|
||||
|
||||
private void ThenTheCookieIsSet()
|
||||
{
|
||||
_response.Headers.TryGetValues("Set-Cookie", out var test).ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void WhenICallTheClient(string url)
|
||||
{
|
||||
_response = _httpClient
|
||||
.SendAsync(new HttpRequestMessage(HttpMethod.Get, url))
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsOk()
|
||||
{
|
||||
_response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
private void GivenADownstreamService()
|
||||
{
|
||||
_host = new WebHostBuilder()
|
||||
.UseUrls("http://localhost:5003")
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(context =>
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
context.Response.Cookies.Append("test", "0");
|
||||
context.Response.StatusCode = 200;
|
||||
_count++;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (_count == 1)
|
||||
{
|
||||
if (context.Request.Cookies.TryGetValue("test", out var cookieValue) || context.Request.Headers.TryGetValue("Set-Cookie", out var headerValue))
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
context.Response.StatusCode = 500;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
})
|
||||
.Build();
|
||||
|
||||
_host.Start();
|
||||
}
|
||||
|
||||
private void GivenARequest(DownstreamReRoute downstream)
|
||||
{
|
||||
GivenARequest(downstream, "http://localhost:5003");
|
||||
}
|
||||
|
||||
private void GivenARequest(DownstreamReRoute downstream, string downstreamUrl)
|
||||
{
|
||||
GivenARequestWithAUrlAndMethod(downstream, downstreamUrl, HttpMethod.Get);
|
||||
}
|
||||
|
||||
private void GivenARequestWithAUrlAndMethod(DownstreamReRoute downstream, string url, HttpMethod method)
|
||||
{
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class HttpClientBuilderTests : IDisposable
|
||||
{
|
||||
private HttpClientBuilder _builder;
|
||||
private readonly Mock<IDelegatingHandlerHandlerFactory> _factory;
|
||||
private IHttpClient _httpClient;
|
||||
private HttpResponseMessage _response;
|
||||
private HttpContext _context;
|
||||
private readonly Mock<IHttpClientCache> _cacheHandlers;
|
||||
private readonly Mock<IOcelotLogger> _logger;
|
||||
private int _count;
|
||||
private IWebHost _host;
|
||||
private IHttpClient _againHttpClient;
|
||||
private IHttpClient _firstHttpClient;
|
||||
private MemoryHttpClientCache _realCache;
|
||||
|
||||
public HttpClientBuilderTests()
|
||||
{
|
||||
_cacheHandlers = new Mock<IHttpClientCache>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_factory = new Mock<IDelegatingHandlerHandlerFactory>();
|
||||
_builder = new HttpClientBuilder(_factory.Object, _cacheHandlers.Object, _logger.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_http_client()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(route))
|
||||
.When(x => WhenIBuild())
|
||||
.Then(x => ThenTheHttpClientShouldNotBeNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_from_cache()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenARealCache())
|
||||
.And(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(route))
|
||||
.And(x => WhenIBuildTheFirstTime())
|
||||
.And(x => WhenISave())
|
||||
.And(x => WhenIBuildAgain())
|
||||
.And(x => WhenISave())
|
||||
.When(x => WhenIBuildAgain())
|
||||
.Then(x => ThenTheHttpClientIsFromTheCache())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_from_cache_with_different_query_string()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenARealCache())
|
||||
.And(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(route, "http://wwww.someawesomewebsite.com/woot?badman=1"))
|
||||
.And(x => WhenIBuildTheFirstTime())
|
||||
.And(x => WhenISave())
|
||||
.And(x => WhenIBuildAgain())
|
||||
.And(x => GivenARequest(route, "http://wwww.someawesomewebsite.com/woot?badman=2"))
|
||||
.And(x => WhenISave())
|
||||
.When(x => WhenIBuildAgain())
|
||||
.Then(x => ThenTheHttpClientIsFromTheCache())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_get_from_cache_with_different_query_string()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var routeA = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var routeB = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenARealCache())
|
||||
.And(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(routeA, "http://wwww.someawesomewebsite.com/woot?badman=1"))
|
||||
.And(x => WhenIBuildTheFirstTime())
|
||||
.And(x => WhenISave())
|
||||
.And(x => WhenIBuildAgain())
|
||||
.And(x => GivenARequest(routeB, "http://wwww.someawesomewebsite.com/woot?badman=2"))
|
||||
.And(x => WhenISave())
|
||||
.When(x => WhenIBuildAgain())
|
||||
.Then(x => ThenTheHttpClientIsNotFromTheCache())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_log_if_ignoring_ssl_errors()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.WithDangerousAcceptAnyServerCertificateValidator(true)
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFactoryReturns())
|
||||
.And(x => GivenARequest(route))
|
||||
.When(x => WhenIBuild())
|
||||
.Then(x => ThenTheHttpClientShouldNotBeNull())
|
||||
.Then(x => ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_delegating_handlers_in_order()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var fakeOne = new FakeDelegatingHandler();
|
||||
var fakeTwo = new FakeDelegatingHandler();
|
||||
|
||||
var handlers = new List<Func<DelegatingHandler>>()
|
||||
{
|
||||
() => fakeOne,
|
||||
() => fakeTwo
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFactoryReturns(handlers))
|
||||
.And(x => GivenARequest(route))
|
||||
.And(x => WhenIBuild())
|
||||
.When(x => WhenICallTheClient())
|
||||
.Then(x => ThenTheFakeAreHandledInOrder(fakeOne, fakeTwo))
|
||||
.And(x => ThenSomethingIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_re_use_cookies_from_container()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenADownstreamService())
|
||||
.And(_ => GivenARequest(route))
|
||||
.And(_ => GivenTheFactoryReturnsNothing())
|
||||
.And(_ => WhenIBuild())
|
||||
.And(_ => WhenICallTheClient("http://localhost:5003"))
|
||||
.And(_ => ThenTheCookieIsSet())
|
||||
.And(_ => GivenTheClientIsCached())
|
||||
.And(_ => WhenIBuild())
|
||||
.When(_ => WhenICallTheClient("http://localhost:5003"))
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("PUT")]
|
||||
[InlineData("DELETE")]
|
||||
[InlineData("PATCH")]
|
||||
public void should_add_verb_to_cache_key(string verb)
|
||||
{
|
||||
var downstreamUrl = "http://localhost:5012/";
|
||||
|
||||
var method = new HttpMethod(verb);
|
||||
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
this.Given(_ => GivenADownstreamService())
|
||||
.And(_ => GivenARequestWithAUrlAndMethod(route, downstreamUrl, method))
|
||||
.And(_ => GivenTheFactoryReturnsNothing())
|
||||
.And(_ => WhenIBuild())
|
||||
.And(_ => GivenCacheIsCalledWithExpectedKey($"{method.ToString()}:{downstreamUrl}"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARealCache()
|
||||
{
|
||||
_realCache = new MemoryHttpClientCache();
|
||||
_builder = new HttpClientBuilder(_factory.Object, _realCache, _logger.Object);
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientIsFromTheCache()
|
||||
{
|
||||
_againHttpClient.ShouldBe(_firstHttpClient);
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientIsNotFromTheCache()
|
||||
{
|
||||
_againHttpClient.ShouldNotBe(_firstHttpClient);
|
||||
}
|
||||
|
||||
private void WhenISave()
|
||||
{
|
||||
_builder.Save();
|
||||
}
|
||||
|
||||
private void GivenCacheIsCalledWithExpectedKey(string expectedKey)
|
||||
{
|
||||
_cacheHandlers.Verify(x => x.Get(It.IsAny<DownstreamRoute>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged()
|
||||
{
|
||||
_logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamRoute, UpstreamPathTemplate: {_context.Items.DownstreamRoute().UpstreamPathTemplate}, DownstreamPathTemplate: {_context.Items.DownstreamRoute().DownstreamPathTemplate}"), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheClientIsCached()
|
||||
{
|
||||
_cacheHandlers.Setup(x => x.Get(It.IsAny<DownstreamRoute>())).Returns(_httpClient);
|
||||
}
|
||||
|
||||
private void ThenTheCookieIsSet()
|
||||
{
|
||||
_response.Headers.TryGetValues("Set-Cookie", out var test).ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void WhenICallTheClient(string url)
|
||||
{
|
||||
_response = _httpClient
|
||||
.SendAsync(new HttpRequestMessage(HttpMethod.Get, url))
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsOk()
|
||||
{
|
||||
_response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
private void GivenADownstreamService()
|
||||
{
|
||||
_host = new WebHostBuilder()
|
||||
.UseUrls("http://localhost:5003")
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(context =>
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
context.Response.Cookies.Append("test", "0");
|
||||
context.Response.StatusCode = 200;
|
||||
_count++;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (_count == 1)
|
||||
{
|
||||
if (context.Request.Cookies.TryGetValue("test", out var cookieValue) || context.Request.Headers.TryGetValue("Set-Cookie", out var headerValue))
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
context.Response.StatusCode = 500;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
})
|
||||
.Build();
|
||||
|
||||
_host.Start();
|
||||
}
|
||||
|
||||
private void GivenARequest(DownstreamRoute downstream)
|
||||
{
|
||||
GivenARequest(downstream, "http://localhost:5003");
|
||||
}
|
||||
|
||||
private void GivenARequest(DownstreamRoute downstream, string downstreamUrl)
|
||||
{
|
||||
GivenARequestWithAUrlAndMethod(downstream, downstreamUrl, HttpMethod.Get);
|
||||
}
|
||||
|
||||
private void GivenARequestWithAUrlAndMethod(DownstreamRoute downstream, string url, HttpMethod method)
|
||||
{
|
||||
_context = new DefaultHttpContext();
|
||||
_context.Items.UpsertDownstreamReRoute(downstream);
|
||||
_context.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri(url), Method = method }));
|
||||
}
|
||||
|
||||
private void ThenSomethingIsReturned()
|
||||
{
|
||||
_response.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void WhenICallTheClient()
|
||||
{
|
||||
_response = _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://test.com")).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheFakeAreHandledInOrder(FakeDelegatingHandler fakeOne, FakeDelegatingHandler fakeTwo)
|
||||
{
|
||||
fakeOne.TimeCalled.ShouldBeGreaterThan(fakeTwo.TimeCalled);
|
||||
}
|
||||
|
||||
private void GivenTheFactoryReturns()
|
||||
{
|
||||
var handlers = new List<Func<DelegatingHandler>>() { () => new FakeDelegatingHandler() };
|
||||
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
|
||||
.Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void GivenTheFactoryReturnsNothing()
|
||||
{
|
||||
var handlers = new List<Func<DelegatingHandler>>();
|
||||
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
|
||||
.Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void GivenTheFactoryReturns(List<Func<DelegatingHandler>> handlers)
|
||||
{
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
|
||||
.Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void WhenIBuild()
|
||||
{
|
||||
_httpClient = _builder.Create(_context.Items.DownstreamReRoute());
|
||||
}
|
||||
|
||||
private void WhenIBuildTheFirstTime()
|
||||
{
|
||||
_firstHttpClient = _builder.Create(_context.Items.DownstreamReRoute());
|
||||
}
|
||||
|
||||
private void WhenIBuildAgain()
|
||||
{
|
||||
_builder = new HttpClientBuilder(_factory.Object, _realCache, _logger.Object);
|
||||
_againHttpClient = _builder.Create(_context.Items.DownstreamReRoute());
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientShouldNotBeNull()
|
||||
{
|
||||
_httpClient.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_response?.Dispose();
|
||||
_host?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
_context.Items.UpsertDownstreamRoute(downstream);
|
||||
_context.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri(url), Method = method }));
|
||||
}
|
||||
|
||||
private void ThenSomethingIsReturned()
|
||||
{
|
||||
_response.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void WhenICallTheClient()
|
||||
{
|
||||
_response = _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://test.com")).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheFakeAreHandledInOrder(FakeDelegatingHandler fakeOne, FakeDelegatingHandler fakeTwo)
|
||||
{
|
||||
fakeOne.TimeCalled.ShouldBeGreaterThan(fakeTwo.TimeCalled);
|
||||
}
|
||||
|
||||
private void GivenTheFactoryReturns()
|
||||
{
|
||||
var handlers = new List<Func<DelegatingHandler>>() { () => new FakeDelegatingHandler() };
|
||||
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamRoute>()))
|
||||
.Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void GivenTheFactoryReturnsNothing()
|
||||
{
|
||||
var handlers = new List<Func<DelegatingHandler>>();
|
||||
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamRoute>()))
|
||||
.Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void GivenTheFactoryReturns(List<Func<DelegatingHandler>> handlers)
|
||||
{
|
||||
_factory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamRoute>()))
|
||||
.Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void WhenIBuild()
|
||||
{
|
||||
_httpClient = _builder.Create(_context.Items.DownstreamRoute());
|
||||
}
|
||||
|
||||
private void WhenIBuildTheFirstTime()
|
||||
{
|
||||
_firstHttpClient = _builder.Create(_context.Items.DownstreamRoute());
|
||||
}
|
||||
|
||||
private void WhenIBuildAgain()
|
||||
{
|
||||
_builder = new HttpClientBuilder(_factory.Object, _realCache, _logger.Object);
|
||||
_againHttpClient = _builder.Create(_context.Items.DownstreamRoute());
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientShouldNotBeNull()
|
||||
{
|
||||
_httpClient.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_response?.Dispose();
|
||||
_host?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
@ -34,7 +34,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_factory = new Mock<IDelegatingHandlerHandlerFactory>();
|
||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(new List<Func<DelegatingHandler>>()));
|
||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(new List<Func<DelegatingHandler>>()));
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
@ -57,18 +57,18 @@ namespace Ocelot.UnitTests.Requester
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(upstreamTemplate)
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Items.UpsertDownstreamReRoute(reRoute);
|
||||
httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") }));
|
||||
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Items.UpsertDownstreamRoute(route);
|
||||
httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") }));
|
||||
|
||||
this.Given(x => x.GivenTheRequestIs(httpContext))
|
||||
.And(x => GivenTheHouseReturnsOkHandler())
|
||||
.When(x => x.WhenIGetResponse())
|
||||
@ -84,17 +84,17 @@ namespace Ocelot.UnitTests.Requester
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(upstreamTemplate)
|
||||
.WithQosOptions(new QoSOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Items.UpsertDownstreamReRoute(reRoute);
|
||||
httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }));
|
||||
.Build();
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Items.UpsertDownstreamRoute(route);
|
||||
httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }));
|
||||
|
||||
this.Given(x => x.GivenTheRequestIs(httpContext))
|
||||
.When(x => x.WhenIGetResponse())
|
||||
@ -110,17 +110,17 @@ namespace Ocelot.UnitTests.Requester
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
|
||||
.WithLoadBalancerKey("")
|
||||
.WithUpstreamPathTemplate(upstreamTemplate)
|
||||
.WithQosOptions(new QoSOptionsBuilder().WithTimeoutValue(1).Build())
|
||||
.Build();
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Items.UpsertDownstreamReRoute(reRoute);
|
||||
httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }));
|
||||
.Build();
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Items.UpsertDownstreamRoute(route);
|
||||
httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }));
|
||||
|
||||
this.Given(_ => GivenTheRequestIs(httpContext))
|
||||
.And(_ => GivenTheHouseReturnsTimeoutHandler())
|
||||
@ -163,7 +163,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
() => new OkDelegatingHandler()
|
||||
};
|
||||
|
||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
}
|
||||
|
||||
private void GivenTheHouseReturnsTimeoutHandler()
|
||||
@ -173,7 +173,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
() => new TimeoutDelegatingHandler()
|
||||
};
|
||||
|
||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||
|
||||
_mapper.Setup(x => x.Map(It.IsAny<Exception>())).Returns(new UnableToCompleteRequestError(new Exception()));
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ namespace Ocelot.UnitTests.Requester
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
using Xunit;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
|
||||
public class HttpRequesterMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IHttpRequester> _requester;
|
||||
@ -84,8 +84,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
}
|
||||
|
||||
private void GivenTheRequestIs()
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamReRoute(new DownstreamReRouteBuilder().Build());
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamRoute(new DownstreamRouteBuilder().Build());
|
||||
}
|
||||
|
||||
private void GivenTheRequesterReturns(Response<HttpResponseMessage> response)
|
||||
|
@ -1,55 +1,55 @@
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Shouldly;
|
||||
using System.Net.Http;
|
||||
using Xunit;
|
||||
|
||||
public class QoSFactoryTests
|
||||
{
|
||||
private QoSFactory _factory;
|
||||
private ServiceCollection _services;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
public QoSFactoryTests()
|
||||
{
|
||||
_services = new ServiceCollection();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_factory = new QoSFactory(provider, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder().Build();
|
||||
var handler = _factory.Get(downstreamReRoute);
|
||||
handler.IsError.ShouldBeTrue();
|
||||
handler.Errors[0].ShouldBeOfType<UnableToFindQoSProviderError>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_handler()
|
||||
{
|
||||
_services = new ServiceCollection();
|
||||
DelegatingHandler QosDelegatingHandlerDelegate(DownstreamReRoute a, IOcelotLoggerFactory b) => new FakeDelegatingHandler();
|
||||
_services.AddSingleton<QosDelegatingHandlerDelegate>(QosDelegatingHandlerDelegate);
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_factory = new QoSFactory(provider, _loggerFactory.Object);
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder().Build();
|
||||
var handler = _factory.Get(downstreamReRoute);
|
||||
handler.IsError.ShouldBeFalse();
|
||||
handler.Data.ShouldBeOfType<FakeDelegatingHandler>();
|
||||
}
|
||||
|
||||
private class FakeDelegatingHandler : DelegatingHandler
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Shouldly;
|
||||
using System.Net.Http;
|
||||
using Xunit;
|
||||
|
||||
public class QoSFactoryTests
|
||||
{
|
||||
private QoSFactory _factory;
|
||||
private ServiceCollection _services;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
public QoSFactoryTests()
|
||||
{
|
||||
_services = new ServiceCollection();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_factory = new QoSFactory(provider, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRouteBuilder().Build();
|
||||
var handler = _factory.Get(downstreamRoute);
|
||||
handler.IsError.ShouldBeTrue();
|
||||
handler.Errors[0].ShouldBeOfType<UnableToFindQoSProviderError>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_handler()
|
||||
{
|
||||
_services = new ServiceCollection();
|
||||
DelegatingHandler QosDelegatingHandlerDelegate(DownstreamRoute a, IOcelotLoggerFactory b) => new FakeDelegatingHandler();
|
||||
_services.AddSingleton<QosDelegatingHandlerDelegate>(QosDelegatingHandlerDelegate);
|
||||
var provider = _services.BuildServiceProvider();
|
||||
_factory = new QoSFactory(provider, _loggerFactory.Object);
|
||||
var downstreamRoute = new DownstreamRouteBuilder().Build();
|
||||
var handler = _factory.Get(downstreamRoute);
|
||||
handler.IsError.ShouldBeFalse();
|
||||
handler.Data.ShouldBeOfType<FakeDelegatingHandler>();
|
||||
}
|
||||
|
||||
private class FakeDelegatingHandler : DelegatingHandler
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
@ -16,7 +15,7 @@
|
||||
|
||||
public class IPSecurityPolicyTests
|
||||
{
|
||||
private readonly DownstreamReRouteBuilder _downstreamReRouteBuilder;
|
||||
private readonly DownstreamRouteBuilder _downstreamRouteBuilder;
|
||||
private readonly IPSecurityPolicy _ipSecurityPolicy;
|
||||
private Response response;
|
||||
private HttpContext _httpContext;
|
||||
@ -26,14 +25,14 @@
|
||||
_httpContext = new DefaultHttpContext();
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com")));
|
||||
_httpContext.Connection.RemoteIpAddress = Dns.GetHostAddresses("192.168.1.1")[0];
|
||||
_downstreamReRouteBuilder = new DownstreamReRouteBuilder();
|
||||
_downstreamRouteBuilder = new DownstreamRouteBuilder();
|
||||
_ipSecurityPolicy = new IPSecurityPolicy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_No_blocked_Ip_and_allowed_Ip()
|
||||
{
|
||||
this.Given(x => x.GivenSetDownstreamReRoute())
|
||||
this.Given(x => x.GivenSetDownstreamRoute())
|
||||
.When(x => x.WhenTheSecurityPolicy())
|
||||
.Then(x => x.ThenSecurityPassing())
|
||||
.BDDfy();
|
||||
@ -44,7 +43,7 @@
|
||||
{
|
||||
_httpContext.Connection.RemoteIpAddress = Dns.GetHostAddresses("192.168.1.1")[0];
|
||||
this.Given(x => x.GivenSetBlockedIP())
|
||||
.Given(x => x.GivenSetDownstreamReRoute())
|
||||
.Given(x => x.GivenSetDownstreamRoute())
|
||||
.When(x => x.WhenTheSecurityPolicy())
|
||||
.Then(x => x.ThenNotSecurityPassing())
|
||||
.BDDfy();
|
||||
@ -55,7 +54,7 @@
|
||||
{
|
||||
_httpContext.Connection.RemoteIpAddress = Dns.GetHostAddresses("192.168.1.2")[0];
|
||||
this.Given(x => x.GivenSetBlockedIP())
|
||||
.Given(x => x.GivenSetDownstreamReRoute())
|
||||
.Given(x => x.GivenSetDownstreamRoute())
|
||||
.When(x => x.WhenTheSecurityPolicy())
|
||||
.Then(x => x.ThenSecurityPassing())
|
||||
.BDDfy();
|
||||
@ -66,7 +65,7 @@
|
||||
{
|
||||
_httpContext.Connection.RemoteIpAddress = Dns.GetHostAddresses("192.168.1.1")[0];
|
||||
this.Given(x => x.GivenSetAllowedIP())
|
||||
.Given(x => x.GivenSetDownstreamReRoute())
|
||||
.Given(x => x.GivenSetDownstreamRoute())
|
||||
.When(x => x.WhenTheSecurityPolicy())
|
||||
.Then(x => x.ThenSecurityPassing())
|
||||
.BDDfy();
|
||||
@ -77,7 +76,7 @@
|
||||
{
|
||||
_httpContext.Connection.RemoteIpAddress = Dns.GetHostAddresses("192.168.1.2")[0];
|
||||
this.Given(x => x.GivenSetAllowedIP())
|
||||
.Given(x => x.GivenSetDownstreamReRoute())
|
||||
.Given(x => x.GivenSetDownstreamRoute())
|
||||
.When(x => x.WhenTheSecurityPolicy())
|
||||
.Then(x => x.ThenNotSecurityPassing())
|
||||
.BDDfy();
|
||||
@ -85,22 +84,22 @@
|
||||
|
||||
private void GivenSetAllowedIP()
|
||||
{
|
||||
_downstreamReRouteBuilder.WithSecurityOptions(new SecurityOptions(new List<string> { "192.168.1.1" }, new List<string>()));
|
||||
_downstreamRouteBuilder.WithSecurityOptions(new SecurityOptions(new List<string> { "192.168.1.1" }, new List<string>()));
|
||||
}
|
||||
|
||||
private void GivenSetBlockedIP()
|
||||
{
|
||||
_downstreamReRouteBuilder.WithSecurityOptions(new SecurityOptions(new List<string>(), new List<string> { "192.168.1.1" }));
|
||||
_downstreamRouteBuilder.WithSecurityOptions(new SecurityOptions(new List<string>(), new List<string> { "192.168.1.1" }));
|
||||
}
|
||||
|
||||
private void GivenSetDownstreamReRoute()
|
||||
private void GivenSetDownstreamRoute()
|
||||
{
|
||||
_httpContext.Items.UpsertDownstreamReRoute(_downstreamReRouteBuilder.Build());
|
||||
_httpContext.Items.UpsertDownstreamRoute(_downstreamRouteBuilder.Build());
|
||||
}
|
||||
|
||||
private void WhenTheSecurityPolicy()
|
||||
{
|
||||
response = _ipSecurityPolicy.Security(_httpContext.Items.DownstreamReRoute(), _httpContext).GetAwaiter().GetResult();
|
||||
response = _ipSecurityPolicy.Security(_httpContext.Items.DownstreamRoute(), _httpContext).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenSecurityPassing()
|
||||
|
@ -15,11 +15,11 @@ using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Security
|
||||
{
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Shouldly;
|
||||
|
||||
{
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Shouldly;
|
||||
|
||||
public class SecurityMiddlewareTests
|
||||
{
|
||||
private List<Mock<ISecurityPolicy>> _securityPolicyList;
|
||||
@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Security
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
_middleware = new SecurityMiddleware(_next, _loggerFactory.Object, _securityPolicyList.Select(f => f.Object).ToList());
|
||||
_middleware = new SecurityMiddleware(_next, _loggerFactory.Object, _securityPolicyList.Select(f => f.Object).ToList());
|
||||
_httpContext.Items.UpsertDownstreamRequest(new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com")));
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ namespace Ocelot.UnitTests.Security
|
||||
foreach (var item in _securityPolicyList)
|
||||
{
|
||||
Response response = new OkResponse();
|
||||
item.Setup(x => x.Security(_httpContext.Items.DownstreamReRoute(), _httpContext)).Returns(Task.FromResult(response));
|
||||
item.Setup(x => x.Security(_httpContext.Items.DownstreamRoute(), _httpContext)).Returns(Task.FromResult(response));
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,12 +82,12 @@ namespace Ocelot.UnitTests.Security
|
||||
{
|
||||
Error error = new UnauthenticatedError($"Not passing security verification");
|
||||
Response response = new ErrorResponse(error);
|
||||
item.Setup(x => x.Security(_httpContext.Items.DownstreamReRoute(), _httpContext)).Returns(Task.FromResult(response));
|
||||
item.Setup(x => x.Security(_httpContext.Items.DownstreamRoute(), _httpContext)).Returns(Task.FromResult(response));
|
||||
}
|
||||
else
|
||||
{
|
||||
Response response = new OkResponse();
|
||||
item.Setup(x => x.Security(_httpContext.Items.DownstreamReRoute(), _httpContext)).Returns(Task.FromResult(response));
|
||||
item.Setup(x => x.Security(_httpContext.Items.DownstreamRoute(), _httpContext)).Returns(Task.FromResult(response));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,12 +98,12 @@ namespace Ocelot.UnitTests.Security
|
||||
}
|
||||
|
||||
private void ThenTheRequestIsPassingSecurity()
|
||||
{
|
||||
{
|
||||
_httpContext.Items.Errors().Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheRequestIsNotPassingSecurity()
|
||||
{
|
||||
{
|
||||
_httpContext.Items.Errors().Count.ShouldBeGreaterThan(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,187 +1,187 @@
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Values;
|
||||
using Xunit;
|
||||
|
||||
public class ServiceDiscoveryProviderFactoryTests
|
||||
{
|
||||
private ServiceProviderConfiguration _serviceConfig;
|
||||
private Response<IServiceDiscoveryProvider> _result;
|
||||
private ServiceDiscoveryProviderFactory _factory;
|
||||
private DownstreamReRoute _reRoute;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private IServiceProvider _provider;
|
||||
private readonly IServiceCollection _collection;
|
||||
|
||||
public ServiceDiscoveryProviderFactoryTests()
|
||||
{
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_collection = new ServiceCollection();
|
||||
_provider = _collection.BuildServiceProvider();
|
||||
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object, _provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_service_provider()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_list_of_configuration_services()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamAddresses = new List<DownstreamHostAndPort>()
|
||||
{
|
||||
new DownstreamHostAndPort("asdf.com", 80),
|
||||
new DownstreamHostAndPort("abc.com", 80)
|
||||
};
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.Then(x => ThenTheFollowingServicesAreReturned(downstreamAddresses))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_provider_because_type_matches_reflected_type_from_delegate()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.WithType(nameof(Fake))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.And(x => GivenAFakeDelegate())
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheDelegateIsCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_provider_because_type_doesnt_match_reflected_type_from_delegate()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("Wookie")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.And(x => GivenAFakeDelegate())
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_service_fabric_provider()
|
||||
{
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ServiceFabricServiceDiscoveryProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAFakeDelegate()
|
||||
{
|
||||
ServiceDiscoveryFinderDelegate fake = (provider, config, name) => new Fake();
|
||||
_collection.AddSingleton(fake);
|
||||
_provider = _collection.BuildServiceProvider();
|
||||
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object, _provider);
|
||||
}
|
||||
|
||||
private class Fake : IServiceDiscoveryProvider
|
||||
{
|
||||
public Task<List<Service>> Get()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheDelegateIsCalled()
|
||||
{
|
||||
_result.Data.GetType().Name.ShouldBe("Fake");
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheFollowingServicesAreReturned(List<DownstreamHostAndPort> downstreamAddresses)
|
||||
{
|
||||
var result = (ConfigurationServiceProvider)_result.Data;
|
||||
var services = result.Get().Result;
|
||||
|
||||
for (int i = 0; i < services.Count; i++)
|
||||
{
|
||||
var service = services[i];
|
||||
var downstreamAddress = downstreamAddresses[i];
|
||||
|
||||
service.HostAndPort.DownstreamHost.ShouldBe(downstreamAddress.Host);
|
||||
service.HostAndPort.DownstreamPort.ShouldBe(downstreamAddress.Port);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
|
||||
{
|
||||
_serviceConfig = serviceConfig;
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheServiceProvider()
|
||||
{
|
||||
_result = _factory.Get(_serviceConfig, _reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIs<T>()
|
||||
{
|
||||
_result.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Ocelot.ServiceDiscovery.Providers;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestStack.BDDfy;
|
||||
using Values;
|
||||
using Xunit;
|
||||
|
||||
public class ServiceDiscoveryProviderFactoryTests
|
||||
{
|
||||
private ServiceProviderConfiguration _serviceConfig;
|
||||
private Response<IServiceDiscoveryProvider> _result;
|
||||
private ServiceDiscoveryProviderFactory _factory;
|
||||
private DownstreamRoute _route;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
private IServiceProvider _provider;
|
||||
private readonly IServiceCollection _collection;
|
||||
|
||||
public ServiceDiscoveryProviderFactoryTests()
|
||||
{
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_collection = new ServiceCollection();
|
||||
_provider = _collection.BuildServiceProvider();
|
||||
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object, _provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_service_provider()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var route = new DownstreamRouteBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenTheRoute(serviceConfig, route))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_list_of_configuration_services()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamAddresses = new List<DownstreamHostAndPort>()
|
||||
{
|
||||
new DownstreamHostAndPort("asdf.com", 80),
|
||||
new DownstreamHostAndPort("abc.com", 80)
|
||||
};
|
||||
|
||||
var route = new DownstreamRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
|
||||
|
||||
this.Given(x => x.GivenTheRoute(serviceConfig, route))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.Then(x => ThenTheFollowingServicesAreReturned(downstreamAddresses))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_provider_because_type_matches_reflected_type_from_delegate()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.WithType(nameof(Fake))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheRoute(serviceConfig, route))
|
||||
.And(x => GivenAFakeDelegate())
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheDelegateIsCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_provider_because_type_doesnt_match_reflected_type_from_delegate()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("Wookie")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheRoute(serviceConfig, route))
|
||||
.And(x => GivenAFakeDelegate())
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_service_fabric_provider()
|
||||
{
|
||||
var route = new DownstreamRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.WithType("ServiceFabric")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheRoute(serviceConfig, route))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ServiceFabricServiceDiscoveryProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAFakeDelegate()
|
||||
{
|
||||
ServiceDiscoveryFinderDelegate fake = (provider, config, name) => new Fake();
|
||||
_collection.AddSingleton(fake);
|
||||
_provider = _collection.BuildServiceProvider();
|
||||
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object, _provider);
|
||||
}
|
||||
|
||||
private class Fake : IServiceDiscoveryProvider
|
||||
{
|
||||
public Task<List<Service>> Get()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheDelegateIsCalled()
|
||||
{
|
||||
_result.Data.GetType().Name.ShouldBe("Fake");
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheFollowingServicesAreReturned(List<DownstreamHostAndPort> downstreamAddresses)
|
||||
{
|
||||
var result = (ConfigurationServiceProvider)_result.Data;
|
||||
var services = result.Get().Result;
|
||||
|
||||
for (int i = 0; i < services.Count; i++)
|
||||
{
|
||||
var service = services[i];
|
||||
var downstreamAddress = downstreamAddresses[i];
|
||||
|
||||
service.HostAndPort.DownstreamHost.ShouldBe(downstreamAddress.Host);
|
||||
service.HostAndPort.DownstreamPort.ShouldBe(downstreamAddress.Port);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheRoute(ServiceProviderConfiguration serviceConfig, DownstreamRoute route)
|
||||
{
|
||||
_serviceConfig = serviceConfig;
|
||||
_route = route;
|
||||
}
|
||||
|
||||
private void WhenIGetTheServiceProvider()
|
||||
{
|
||||
_result = _factory.Get(_serviceConfig, _route);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIs<T>()
|
||||
{
|
||||
_result.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user