mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 11:38:15 +08:00
Feature/expose http handlers (#224)
* temp commit * trying to work out how to expose the http handlers in a decent way.. * pissing about at lunch * changed to func so you can instanciate object or new it up each time * docs for dele handlers * upgraded to sdk 2.1.4 * some validation for consul services
This commit is contained in:
@ -1,4 +1,8 @@
|
||||
using CacheManager.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using CacheManager.Core;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Internal;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -9,10 +13,9 @@ using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.UnitTests.Requester;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
@ -20,11 +23,11 @@ namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
public class OcelotBuilderTests
|
||||
{
|
||||
private IServiceCollection _services;
|
||||
private readonly IServiceCollection _services;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IConfiguration _configRoot;
|
||||
private readonly IConfiguration _configRoot;
|
||||
private IOcelotBuilder _ocelotBuilder;
|
||||
private int _maxRetries;
|
||||
private readonly int _maxRetries;
|
||||
|
||||
public OcelotBuilderTests()
|
||||
{
|
||||
@ -38,6 +41,19 @@ namespace Ocelot.UnitTests.DependencyInjection
|
||||
}
|
||||
private Exception _ex;
|
||||
|
||||
[Fact]
|
||||
public void should_add_delegating_handlers()
|
||||
{
|
||||
var fakeOne = new FakeDelegatingHandler(0);
|
||||
var fakeTwo = new FakeDelegatingHandler(1);
|
||||
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => AddDelegate(fakeOne))
|
||||
.And(x => AddDelegate(fakeTwo))
|
||||
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_services()
|
||||
{
|
||||
@ -54,7 +70,7 @@ namespace Ocelot.UnitTests.DependencyInjection
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_cache_manager()
|
||||
{
|
||||
@ -74,7 +90,7 @@ namespace Ocelot.UnitTests.DependencyInjection
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact]
|
||||
public void should_set_up_rafty()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
@ -119,6 +135,17 @@ namespace Ocelot.UnitTests.DependencyInjection
|
||||
path.Path.ShouldBe("/administration");
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsRegisteredAndReturnsHandlers()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var provider = _serviceProvider.GetService<IDelegatingHandlerHandlerProvider>();
|
||||
var handlers = provider.Get();
|
||||
var handler = (FakeDelegatingHandler)handlers[0].Invoke();
|
||||
handler.Order.ShouldBe(0);
|
||||
handler = (FakeDelegatingHandler)handlers[1].Invoke();
|
||||
handler.Order.ShouldBe(1);
|
||||
}
|
||||
|
||||
private void OnlyOneVersionOfEachCacheIsRegistered()
|
||||
{
|
||||
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
|
||||
@ -157,6 +184,11 @@ namespace Ocelot.UnitTests.DependencyInjection
|
||||
}
|
||||
}
|
||||
|
||||
private void AddDelegate(DelegatingHandler handler)
|
||||
{
|
||||
_ocelotBuilder.AddDelegatingHandler(() => handler);
|
||||
}
|
||||
|
||||
private void ThenAnOcelotBuilderIsReturned()
|
||||
{
|
||||
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
||||
|
@ -58,7 +58,7 @@
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
|
||||
.And(x => x.GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(new NoQoSProvider())))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false,false)))
|
||||
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, "", false)))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
@ -78,7 +78,7 @@
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
|
||||
.And(x => x.GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, false)))
|
||||
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, "", false)))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedDataRepositoryQosProviderError())
|
||||
.BDDfy();
|
||||
@ -132,8 +132,8 @@
|
||||
It.IsAny<IQoSProvider>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>()
|
||||
))
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<bool>()))
|
||||
.ReturnsAsync(_request);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace Ocelot.UnitTests.Request
|
||||
namespace Ocelot.UnitTests.Request
|
||||
{
|
||||
using System.Net.Http;
|
||||
|
||||
@ -17,9 +17,9 @@
|
||||
private readonly HttpRequestMessage _requestMessage;
|
||||
private readonly bool _useCookieContainer;
|
||||
private readonly bool _allowAutoRedirect;
|
||||
private readonly bool _useTracing;
|
||||
|
||||
private Response<Ocelot.Request.Request> _response;
|
||||
private string _reRouteKey;
|
||||
private readonly bool _useTracing;
|
||||
|
||||
public HttpRequestCreatorTests()
|
||||
{
|
||||
@ -28,7 +28,7 @@
|
||||
_qoSProvider = new NoQoSProvider();
|
||||
_useCookieContainer = false;
|
||||
_allowAutoRedirect = false;
|
||||
_useTracing = false;
|
||||
|
||||
_requestMessage = new HttpRequestMessage();
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
private void WhenIBuildARequest()
|
||||
{
|
||||
_response = _requestCreator.Build(_requestMessage,
|
||||
_isQos, _qoSProvider, _useCookieContainer, _allowAutoRedirect, _useTracing)
|
||||
_isQos, _qoSProvider, _useCookieContainer, _allowAutoRedirect, _reRouteKey, _useTracing)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using Moq;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class DelegatingHandlerHandlerHouseTests
|
||||
{
|
||||
private readonly DelegatingHandlerHandlerHouse _house;
|
||||
private Mock<IDelegatingHandlerHandlerProviderFactory> _factory;
|
||||
private readonly Mock<IDelegatingHandlerHandlerProvider> _provider;
|
||||
private Ocelot.Request.Request _request;
|
||||
private Response<IDelegatingHandlerHandlerProvider> _result;
|
||||
|
||||
public DelegatingHandlerHandlerHouseTests()
|
||||
{
|
||||
_provider = new Mock<IDelegatingHandlerHandlerProvider>();
|
||||
_factory = new Mock<IDelegatingHandlerHandlerProviderFactory>();
|
||||
_house = new DelegatingHandlerHandlerHouse(_factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_and_store_provider()
|
||||
{
|
||||
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
|
||||
|
||||
this.Given(x => GivenTheRequest(request))
|
||||
.And(x => GivenTheProviderReturns())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenTheFactoryIsCalled(1))
|
||||
.And(x => ThenTheProviderIsNotNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_provider()
|
||||
{
|
||||
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
|
||||
|
||||
this.Given(x => GivenTheRequest(request))
|
||||
.And(x => GivenTheProviderReturns())
|
||||
.And(x => WhenIGet())
|
||||
.And(x => GivenTheFactoryIsCleared())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenTheFactoryIsCalled(0))
|
||||
.And(x => ThenTheProviderIsNotNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
|
||||
|
||||
this.Given(x => GivenTheRequest(request))
|
||||
.And(x => GivenTheProviderThrows())
|
||||
.When(x => WhenIGet())
|
||||
.And(x => ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
_result.Errors[0].ShouldBeOfType<UnableToFindDelegatingHandlerProviderError>();
|
||||
}
|
||||
|
||||
private void GivenTheProviderThrows()
|
||||
{
|
||||
_factory.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Throws<Exception>();
|
||||
}
|
||||
|
||||
private void GivenTheFactoryIsCleared()
|
||||
{
|
||||
_factory = new Mock<IDelegatingHandlerHandlerProviderFactory>();
|
||||
}
|
||||
|
||||
private void ThenTheProviderIsNotNull()
|
||||
{
|
||||
_result.Data.ShouldBe(_provider.Object);
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_result = _house.Get(_request);
|
||||
}
|
||||
|
||||
private void GivenTheRequest(Ocelot.Request.Request request)
|
||||
{
|
||||
_request = request;
|
||||
}
|
||||
|
||||
private void GivenTheProviderReturns()
|
||||
{
|
||||
_factory.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Returns(_provider.Object);
|
||||
}
|
||||
|
||||
private void ThenTheFactoryIsCalled(int times)
|
||||
{
|
||||
_factory.Verify(x => x.Get(_request), Times.Exactly(times));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class DelegatingHandlerHandlerProviderFactoryTests
|
||||
{
|
||||
private readonly DelegatingHandlerHandlerProviderFactory _factory;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Ocelot.Request.Request _request;
|
||||
private IDelegatingHandlerHandlerProvider _provider;
|
||||
private readonly Mock<IDelegatingHandlerHandlerProvider> _allRoutesProvider;
|
||||
|
||||
public DelegatingHandlerHandlerProviderFactoryTests()
|
||||
{
|
||||
_allRoutesProvider = new Mock<IDelegatingHandlerHandlerProvider>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_factory = new DelegatingHandlerHandlerProviderFactory(_loggerFactory.Object, _allRoutesProvider.Object, null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_all_from_all_routes_provider_and_qos()
|
||||
{
|
||||
var handlers = new List<Func<DelegatingHandler>>
|
||||
{
|
||||
() => new FakeDelegatingHandler(0),
|
||||
() => new FakeDelegatingHandler(1)
|
||||
};
|
||||
|
||||
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "", false);
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(request))
|
||||
.And(x => GivenTheAllRoutesProviderReturns(handlers))
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenThereIsDelegatesInProvider(3))
|
||||
.And(x => ThenTheDelegatesAreAddedCorrectly())
|
||||
.And(x => ThenItIsPolly(2))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_provider_with_no_delegates()
|
||||
{
|
||||
var request = new Ocelot.Request.Request(new HttpRequestMessage(), false, null, true, true, "", false);
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(request))
|
||||
.And(x => GivenTheAllRoutesProviderReturns())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenNoDelegatesAreInTheProvider())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_provider_with_qos_delegate()
|
||||
{
|
||||
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "", false);
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(request))
|
||||
.And(x => GivenTheAllRoutesProviderReturns())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenThereIsDelegatesInProvider(1))
|
||||
.And(x => ThenItIsPolly(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheDelegatesAreAddedCorrectly()
|
||||
{
|
||||
var delegates = _provider.Get();
|
||||
var del = delegates[0].Invoke();
|
||||
var handler = (FakeDelegatingHandler) del;
|
||||
handler.Order.ShouldBe(0);
|
||||
|
||||
del = delegates[1].Invoke();
|
||||
handler = (FakeDelegatingHandler)del;
|
||||
handler.Order.ShouldBe(1);
|
||||
}
|
||||
|
||||
private void GivenTheAllRoutesProviderReturns()
|
||||
{
|
||||
_allRoutesProvider.Setup(x => x.Get()).Returns(new List<Func<DelegatingHandler>>());
|
||||
}
|
||||
|
||||
private void GivenTheAllRoutesProviderReturns(List<Func<DelegatingHandler>> handlers)
|
||||
{
|
||||
_allRoutesProvider.Setup(x => x.Get()).Returns(handlers);
|
||||
}
|
||||
|
||||
private void ThenItIsPolly(int i)
|
||||
{
|
||||
var delegates = _provider.Get();
|
||||
var del = delegates[i].Invoke();
|
||||
del.ShouldBeOfType<PollyCircuitBreakingDelegatingHandler>();
|
||||
}
|
||||
|
||||
private void ThenThereIsDelegatesInProvider(int count)
|
||||
{
|
||||
_provider.ShouldNotBeNull();
|
||||
_provider.Get().Count.ShouldBe(count);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingRequest(Ocelot.Request.Request request)
|
||||
{
|
||||
_request = request;
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_provider = _factory.Get(_request);
|
||||
}
|
||||
|
||||
private void ThenNoDelegatesAreInTheProvider()
|
||||
{
|
||||
_provider.ShouldNotBeNull();
|
||||
_provider.Get().Count.ShouldBe(0);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Requester;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class DelegatingHandlerHandlerProviderTests
|
||||
{
|
||||
private readonly DelegatingHandlerHandlerProvider _provider;
|
||||
private List<Func<DelegatingHandler>> _handlers;
|
||||
|
||||
public DelegatingHandlerHandlerProviderTests()
|
||||
{
|
||||
_provider = new DelegatingHandlerHandlerProvider();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_empty_list()
|
||||
{
|
||||
this.When(x => WhenIGet())
|
||||
.Then(x => ThenAnEmptyListIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_delegating_handlers_in_order_first_in_first_out()
|
||||
{
|
||||
this.Given(x => GivenTheHandlers())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenTheHandlersAreReturnedInOrder())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenAnEmptyListIsReturned()
|
||||
{
|
||||
_handlers.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheHandlersAreReturnedInOrder()
|
||||
{
|
||||
var handler = (FakeDelegatingHandler)_handlers[0].Invoke();
|
||||
handler.Order.ShouldBe(0);
|
||||
handler = (FakeDelegatingHandler)_handlers[1].Invoke();
|
||||
handler.Order.ShouldBe(1);
|
||||
}
|
||||
|
||||
private void WhenIGet()
|
||||
{
|
||||
_handlers = _provider.Get();
|
||||
}
|
||||
|
||||
private void GivenTheHandlers()
|
||||
{
|
||||
_provider.Add(() => new FakeDelegatingHandler(0));
|
||||
_provider.Add(() => new FakeDelegatingHandler(1));
|
||||
}
|
||||
}
|
||||
}
|
28
test/Ocelot.UnitTests/Requester/FakeDelegatingHandler.cs
Normal file
28
test/Ocelot.UnitTests/Requester/FakeDelegatingHandler.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class FakeDelegatingHandler : DelegatingHandler
|
||||
{
|
||||
public FakeDelegatingHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public FakeDelegatingHandler(int order)
|
||||
{
|
||||
Order = order;
|
||||
}
|
||||
public int Order {get;private set;}
|
||||
public DateTime TimeCalled {get;private set;}
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
TimeCalled = DateTime.Now;
|
||||
return new HttpResponseMessage();
|
||||
}
|
||||
}
|
||||
}
|
114
test/Ocelot.UnitTests/Requester/HttpClientBuilderTests.cs
Normal file
114
test/Ocelot.UnitTests/Requester/HttpClientBuilderTests.cs
Normal file
@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Moq;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class HttpClientBuilderTests
|
||||
{
|
||||
private readonly HttpClientBuilder _builder;
|
||||
private readonly Mock<IDelegatingHandlerHandlerHouse> _house;
|
||||
private readonly Mock<IDelegatingHandlerHandlerProvider> _provider;
|
||||
private IHttpClientBuilder _builderResult;
|
||||
private IHttpClient _httpClient;
|
||||
private HttpResponseMessage _response;
|
||||
private Ocelot.Request.Request _request;
|
||||
|
||||
public HttpClientBuilderTests()
|
||||
{
|
||||
_provider = new Mock<IDelegatingHandlerHandlerProvider>();
|
||||
_house = new Mock<IDelegatingHandlerHandlerHouse>();
|
||||
_builder = new HttpClientBuilder(_house.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_http_client()
|
||||
{
|
||||
this.Given(x => GivenTheProviderReturns())
|
||||
.And(x => GivenARequest())
|
||||
.And(x => GivenTheHouseReturns())
|
||||
.When(x => WhenIBuild())
|
||||
.Then(x => ThenTheHttpClientShouldNotBeNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_delegating_handlers_in_order()
|
||||
{
|
||||
var fakeOne = new FakeDelegatingHandler();
|
||||
var fakeTwo = new FakeDelegatingHandler();
|
||||
|
||||
var handlers = new List<Func<DelegatingHandler>>()
|
||||
{
|
||||
() => fakeOne,
|
||||
() => fakeTwo
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheProviderReturns(handlers))
|
||||
.And(x => GivenARequest())
|
||||
.And(x => GivenTheHouseReturns())
|
||||
.And(x => WhenIBuild())
|
||||
.When(x => WhenICallTheClient())
|
||||
.Then(x => ThenTheFakeAreHandledInOrder(fakeOne, fakeTwo))
|
||||
.And(x => ThenSomethingIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenARequest()
|
||||
{
|
||||
_request = new Ocelot.Request.Request(null, false, null, false, false, "", false);
|
||||
}
|
||||
|
||||
private void GivenTheHouseReturns()
|
||||
{
|
||||
_house
|
||||
.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>()))
|
||||
.Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
|
||||
}
|
||||
|
||||
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 GivenTheProviderReturns()
|
||||
{
|
||||
_provider
|
||||
.Setup(x => x.Get())
|
||||
.Returns(new List<Func<DelegatingHandler>>(){ () => new FakeDelegatingHandler()});
|
||||
}
|
||||
|
||||
private void GivenTheProviderReturns(List<Func<DelegatingHandler>> handlers)
|
||||
{
|
||||
_provider
|
||||
.Setup(x => x.Get())
|
||||
.Returns(handlers);
|
||||
}
|
||||
|
||||
private void WhenIBuild()
|
||||
{
|
||||
_httpClient = _builder.Create(_request);
|
||||
}
|
||||
|
||||
private void ThenTheHttpClientShouldNotBeNull()
|
||||
{
|
||||
_httpClient.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
}
|
@ -10,13 +10,15 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class HttpClientHttpRequesterTest
|
||||
{
|
||||
private readonly Mock<IHttpClientCache> _cacheHandlers;
|
||||
private Mock<IServiceProvider> _serviceProvider;
|
||||
private Mock<IDelegatingHandlerHandlerHouse> _house;
|
||||
private Mock<IDelegatingHandlerHandlerProvider> _provider;
|
||||
private Response<HttpResponseMessage> _response;
|
||||
private readonly HttpClientHttpRequester _httpClientRequester;
|
||||
private Ocelot.Request.Request _request;
|
||||
@ -25,29 +27,32 @@ namespace Ocelot.UnitTests.Requester
|
||||
|
||||
public HttpClientHttpRequesterTest()
|
||||
{
|
||||
_serviceProvider = new Mock<IServiceProvider>();
|
||||
_provider = new Mock<IDelegatingHandlerHandlerProvider>();
|
||||
_provider.Setup(x => x.Get()).Returns(new List<Func<DelegatingHandler>>());
|
||||
_house = new Mock<IDelegatingHandlerHandlerHouse>();
|
||||
_house.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
.Setup(x => x.CreateLogger<HttpClientHttpRequester>())
|
||||
.Returns(_logger.Object);
|
||||
_cacheHandlers = new Mock<IHttpClientCache>();
|
||||
_httpClientRequester = new HttpClientHttpRequester(_loggerFactory.Object, _cacheHandlers.Object, _serviceProvider.Object);
|
||||
_httpClientRequester = new HttpClientHttpRequester(_loggerFactory.Object, _cacheHandlers.Object, _house.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_request_correctly()
|
||||
{
|
||||
this.Given(x=>x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") }, false, new NoQoSProvider(), false, false, false)))
|
||||
this.Given(x=>x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") }, false, new NoQoSProvider(), false, false, "", false)))
|
||||
.When(x=>x.WhenIGetResponse())
|
||||
.Then(x => x.ThenTheResponseIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_request_UnableToCompleteRequest()
|
||||
public void should_call_request_unable_to_complete_request()
|
||||
{
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }, false, new NoQoSProvider(), false, false, false)))
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }, false, new NoQoSProvider(), false, false, "", false)))
|
||||
.When(x => x.WhenIGetResponse())
|
||||
.Then(x => x.ThenTheResponseIsCalledError())
|
||||
.BDDfy();
|
||||
@ -65,12 +70,12 @@ namespace Ocelot.UnitTests.Requester
|
||||
|
||||
private void ThenTheResponseIsCalledCorrectly()
|
||||
{
|
||||
Assert.True(_response.IsError == false);
|
||||
_response.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsCalledError()
|
||||
{
|
||||
Assert.True(_response.IsError == true);
|
||||
_response.IsError.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -28,7 +28,7 @@
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false,false)))
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false, "", false)))
|
||||
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
|
||||
.And(x => x.GivenTheScopedRepoReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
|
@ -1,10 +1,8 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.LoadBalancer;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
@ -121,7 +121,7 @@ namespace Ocelot.UnitTests.Responder
|
||||
// If this test fails then it's because the number of error codes has changed.
|
||||
// You should make the appropriate changes to the test cases here to ensure
|
||||
// they cover all the error codes, and then modify this assertion.
|
||||
Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(32, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
|
||||
Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(33, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
|
||||
}
|
||||
|
||||
private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)
|
||||
|
@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Consul;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Ocelot.Values;
|
||||
using Xunit;
|
||||
using TestStack.BDDfy;
|
||||
using Shouldly;
|
||||
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ConsulServiceDiscoveryProviderTests : IDisposable
|
||||
{
|
||||
private IWebHost _fakeConsulBuilder;
|
||||
private readonly List<ServiceEntry> _serviceEntries;
|
||||
private readonly ConsulServiceDiscoveryProvider _provider;
|
||||
private readonly string _serviceName;
|
||||
private readonly int _port;
|
||||
private readonly string _consulHost;
|
||||
private readonly string _fakeConsulServiceDiscoveryUrl;
|
||||
private List<Service> _services;
|
||||
private Mock<IOcelotLoggerFactory> _factory;
|
||||
private readonly Mock<IOcelotLogger> _logger;
|
||||
|
||||
public ConsulServiceDiscoveryProviderTests()
|
||||
{
|
||||
_serviceName = "test";
|
||||
_port = 8500;
|
||||
_consulHost = "localhost";
|
||||
_fakeConsulServiceDiscoveryUrl = $"http://{_consulHost}:{_port}";
|
||||
_serviceEntries = new List<ServiceEntry>();
|
||||
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_factory.Setup(x => x.CreateLogger<ConsulServiceDiscoveryProvider>()).Returns(_logger.Object);
|
||||
|
||||
var config = new ConsulRegistryConfiguration(_consulHost, _port, _serviceName);
|
||||
_provider = new ConsulServiceDiscoveryProvider(config, _factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_service_from_consul()
|
||||
{
|
||||
var serviceEntryOne = new ServiceEntry()
|
||||
{
|
||||
Service = new AgentService()
|
||||
{
|
||||
Service = _serviceName,
|
||||
Address = "localhost",
|
||||
Port = 50881,
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Tags = new string[0]
|
||||
},
|
||||
};
|
||||
|
||||
this.Given(x =>GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
|
||||
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
|
||||
.When(x => WhenIGetTheServices())
|
||||
.Then(x => ThenTheCountIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_services_with_invalid_address()
|
||||
{
|
||||
var serviceEntryOne = new ServiceEntry()
|
||||
{
|
||||
Service = new AgentService()
|
||||
{
|
||||
Service = _serviceName,
|
||||
Address = "http://localhost",
|
||||
Port = 50881,
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Tags = new string[0]
|
||||
},
|
||||
};
|
||||
|
||||
var serviceEntryTwo = new ServiceEntry()
|
||||
{
|
||||
Service = new AgentService()
|
||||
{
|
||||
Service = _serviceName,
|
||||
Address = "http://localhost",
|
||||
Port = 50888,
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Tags = new string[0]
|
||||
},
|
||||
};
|
||||
|
||||
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
|
||||
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
|
||||
.When(x => WhenIGetTheServices())
|
||||
.Then(x => ThenTheCountIs(0))
|
||||
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForInvalidAddress())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_services_with_invalid_port()
|
||||
{
|
||||
var serviceEntryOne = new ServiceEntry()
|
||||
{
|
||||
Service = new AgentService()
|
||||
{
|
||||
Service = _serviceName,
|
||||
Address = "localhost",
|
||||
Port = -1,
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Tags = new string[0]
|
||||
},
|
||||
};
|
||||
|
||||
var serviceEntryTwo = new ServiceEntry()
|
||||
{
|
||||
Service = new AgentService()
|
||||
{
|
||||
Service = _serviceName,
|
||||
Address = "localhost",
|
||||
Port = 0,
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Tags = new string[0]
|
||||
},
|
||||
};
|
||||
|
||||
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
|
||||
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
|
||||
.When(x => WhenIGetTheServices())
|
||||
.Then(x => ThenTheCountIs(0))
|
||||
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForInvalidPorts())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheLoggerHasBeenCalledCorrectlyForInvalidAddress()
|
||||
{
|
||||
_logger.Verify(
|
||||
x => x.LogError(
|
||||
"Unable to use service Address: http://localhost and Port: 50881 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
|
||||
Times.Once);
|
||||
|
||||
_logger.Verify(
|
||||
x => x.LogError(
|
||||
"Unable to use service Address: http://localhost and Port: 50888 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheLoggerHasBeenCalledCorrectlyForInvalidPorts()
|
||||
{
|
||||
_logger.Verify(
|
||||
x => x.LogError(
|
||||
"Unable to use service Address: localhost and Port: -1 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
|
||||
Times.Once);
|
||||
|
||||
_logger.Verify(
|
||||
x => x.LogError(
|
||||
"Unable to use service Address: localhost and Port: 0 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheCountIs(int count)
|
||||
{
|
||||
_services.Count.ShouldBe(count);
|
||||
}
|
||||
|
||||
private void WhenIGetTheServices()
|
||||
{
|
||||
_services = _provider.Get().GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void GivenTheServicesAreRegisteredWithConsul(params ServiceEntry[] serviceEntries)
|
||||
{
|
||||
foreach (var serviceEntry in serviceEntries)
|
||||
{
|
||||
_serviceEntries.Add(serviceEntry);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
||||
{
|
||||
_fakeConsulBuilder = new WebHostBuilder()
|
||||
.UseUrls(url)
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.UseUrls(url)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
||||
{
|
||||
await context.Response.WriteJsonAsync(_serviceEntries);
|
||||
}
|
||||
});
|
||||
})
|
||||
.Build();
|
||||
|
||||
_fakeConsulBuilder.Start();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_fakeConsulBuilder?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
@ -15,10 +17,12 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
private IServiceDiscoveryProvider _result;
|
||||
private readonly ServiceDiscoveryProviderFactory _factory;
|
||||
private ReRoute _reRoute;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
public ServiceProviderFactoryTests()
|
||||
{
|
||||
_factory = new ServiceDiscoveryProviderFactory();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -104,4 +108,4 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user