mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 10:38:15 +08:00
Feature/move polly (#561)
* added delegate to select last handler * #529 implemented a way we can inject the last delegating handler * wip - moving code * #529 removed loads of qos code and moved it into Ocelot.Provider.Polly
This commit is contained in:
@ -1,272 +0,0 @@
|
||||
namespace Ocelot.AcceptanceTests
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration.File;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class QoSTests : IDisposable
|
||||
{
|
||||
private readonly Steps _steps;
|
||||
private int _requestCount;
|
||||
private readonly ServiceHandler _serviceHandler;
|
||||
|
||||
public QoSTests()
|
||||
{
|
||||
_serviceHandler = new ServiceHandler();
|
||||
_steps = new Steps();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_timeout()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51569,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "http",
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHttpMethod = new List<string> { "Post" },
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
TimeoutValue = 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51569", 200, string.Empty, 10))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_timeout()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51579,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "http",
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHttpMethod = new List<string> { "Post" },
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
TimeoutValue = 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51579", 201, string.Empty, 1000))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_open_circuit_breaker_then_close()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51892,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
TimeoutValue = 500,
|
||||
DurationOfBreak = 1000
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51892", "Hello from Laura"))
|
||||
.Given(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.Given(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||
.Given(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.Given(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.Given(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.Given(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.Given(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.Given(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.Given(x => x.GivenIWaitMilliseconds(3000))
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void open_circuit_should_not_effect_different_reRoute()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51872,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
TimeoutValue = 500,
|
||||
DurationOfBreak = 1000
|
||||
}
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/working",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51872", "Hello from Laura"))
|
||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", 200, "Hello from Tom", 0))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.And(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.And(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||
.And(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.And(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.And(x => _steps.WhenIGetUrlOnTheApiGateway("/working"))
|
||||
.And(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Tom"))
|
||||
.And(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.And(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.And(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.And(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable))
|
||||
.And(x => x.GivenIWaitMilliseconds(3000))
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenIWaitMilliseconds(int ms)
|
||||
{
|
||||
Thread.Sleep(ms);
|
||||
}
|
||||
|
||||
private void GivenThereIsAPossiblyBrokenServiceRunningOn(string url, string responseBody)
|
||||
{
|
||||
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||
{
|
||||
//circuit starts closed
|
||||
if (_requestCount == 0)
|
||||
{
|
||||
_requestCount++;
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsync(responseBody);
|
||||
return;
|
||||
}
|
||||
|
||||
//request one times out and polly throws exception, circuit opens
|
||||
if (_requestCount == 1)
|
||||
{
|
||||
_requestCount++;
|
||||
await Task.Delay(1000);
|
||||
context.Response.StatusCode = 200;
|
||||
return;
|
||||
}
|
||||
|
||||
//after break closes we return 200 OK
|
||||
if (_requestCount == 2)
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsync(responseBody);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody, int timeout)
|
||||
{
|
||||
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||
{
|
||||
Thread.Sleep(timeout);
|
||||
context.Response.StatusCode = statusCode;
|
||||
await context.Response.WriteAsync(responseBody);
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_serviceHandler?.Dispose();
|
||||
_steps.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -831,7 +831,7 @@ namespace Ocelot.AcceptanceTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_fix_145()
|
||||
public void should_not_set_trailing_slash_on_url_template()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
@ -851,11 +851,6 @@ namespace Ocelot.AcceptanceTests
|
||||
},
|
||||
UpstreamPathTemplate = "/platform/{url}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
QoSOptions = new FileQoSOptions {
|
||||
ExceptionsAllowedBeforeBreaking = 3,
|
||||
DurationOfBreak = 10,
|
||||
TimeoutValue = 5000
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -36,9 +36,8 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.1.1" />
|
||||
<PackageReference Include="Polly" Version="6.0.1" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -16,23 +16,28 @@ using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using Responder;
|
||||
|
||||
public class DelegatingHandlerHandlerProviderFactoryTests
|
||||
{
|
||||
private DelegatingHandlerHandlerFactory _factory;
|
||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private DownstreamReRoute _request;
|
||||
private Response<List<Func<DelegatingHandler>>> _result;
|
||||
private readonly Mock<IQosProviderHouse> _qosProviderHouse;
|
||||
private readonly Mock<IQoSFactory> _qosFactory;
|
||||
private readonly Mock<ITracingHandlerFactory> _tracingFactory;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private readonly IServiceCollection _services;
|
||||
private readonly QosDelegatingHandlerDelegate _qosDelegate;
|
||||
|
||||
public DelegatingHandlerHandlerProviderFactoryTests()
|
||||
{
|
||||
_qosDelegate = (a, b) => new FakeQoSHandler();
|
||||
_tracingFactory = new Mock<ITracingHandlerFactory>();
|
||||
_qosProviderHouse = new Mock<IQosProviderHouse>();
|
||||
_qosFactory = new Mock<IQoSFactory>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_services = new ServiceCollection();
|
||||
_services.AddSingleton(_qosDelegate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -56,8 +61,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheTracingFactoryReturns())
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerThree, FakeDelegatingHandlerFour>())
|
||||
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
@ -67,7 +72,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(2))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerTwo>(3))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(4))
|
||||
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(5))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(5))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -93,8 +98,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheTracingFactoryReturns())
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerFour, FakeDelegatingHandlerThree>())
|
||||
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
@ -104,7 +109,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(2)) //second from config
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerFour>(3)) //third from config (global)
|
||||
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(4))
|
||||
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(5))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(5))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -129,8 +134,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheTracingFactoryReturns())
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerThree, FakeDelegatingHandlerFour>())
|
||||
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
@ -140,7 +145,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerTwo>(2))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(3))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(4))
|
||||
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(5))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(5))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -164,8 +169,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheTracingFactoryReturns())
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerThree, FakeDelegatingHandlerFour>())
|
||||
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
@ -174,7 +179,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerFour>(1))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(2))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(3))
|
||||
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(4))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(4))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -194,8 +199,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheTracingFactoryReturns())
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
@ -203,7 +208,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(0))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerTwo>(1))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(2))
|
||||
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(3))
|
||||
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(3))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -225,7 +230,6 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenThereIsDelegatesInProvider(2))
|
||||
@ -247,12 +251,12 @@ namespace Ocelot.UnitTests.Requester
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenThereIsDelegatesInProvider(3))
|
||||
.And(x => ThenTheDelegatesAreAddedCorrectly())
|
||||
.And(x => ThenItIsPolly(2))
|
||||
.And(x => ThenItIsQosHandler(2))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -287,11 +291,11 @@ namespace Ocelot.UnitTests.Requester
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
|
||||
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
|
||||
.And(x => GivenTheServiceProviderReturnsNothing())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenThereIsDelegatesInProvider(1))
|
||||
.And(x => ThenItIsPolly(0))
|
||||
.And(x => ThenItIsQosHandler(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -309,7 +313,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
|
||||
|
||||
this.Given(x => GivenTheFollowingRequest(reRoute))
|
||||
.And(x => GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
|
||||
.And(x => GivenTheQosFactoryReturnsError())
|
||||
.And(x => GivenTheServiceProviderReturnsNothing())
|
||||
.When(x => WhenIGet())
|
||||
.Then(x => ThenAnErrorIsReturned())
|
||||
@ -378,18 +382,25 @@ namespace Ocelot.UnitTests.Requester
|
||||
handlerTwo.Order.ShouldBe(2);
|
||||
}
|
||||
|
||||
private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
|
||||
private void GivenTheQosFactoryReturns(DelegatingHandler handler)
|
||||
{
|
||||
_qosProviderHouse
|
||||
_qosFactory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
|
||||
.Returns(qosProvider);
|
||||
.Returns(new OkResponse<DelegatingHandler>(handler));
|
||||
}
|
||||
|
||||
private void ThenItIsPolly(int i)
|
||||
private void GivenTheQosFactoryReturnsError()
|
||||
{
|
||||
_qosFactory
|
||||
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
|
||||
.Returns(new ErrorResponse<DelegatingHandler>(new AnyError()));
|
||||
}
|
||||
|
||||
private void ThenItIsQosHandler(int i)
|
||||
{
|
||||
var delegates = _result.Data;
|
||||
var del = delegates[i].Invoke();
|
||||
del.ShouldBeOfType<PollyCircuitBreakingDelegatingHandler>();
|
||||
del.ShouldBeOfType<FakeQoSHandler>();
|
||||
}
|
||||
|
||||
private void ThenThereIsDelegatesInProvider(int count)
|
||||
@ -406,7 +417,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
private void WhenIGet()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
_factory = new DelegatingHandlerHandlerFactory(_loggerFactory.Object, _tracingFactory.Object, _qosProviderHouse.Object, _serviceProvider);
|
||||
_factory = new DelegatingHandlerHandlerFactory(_tracingFactory.Object, _qosFactory.Object, _serviceProvider);
|
||||
_result = _factory.Get(_request);
|
||||
}
|
||||
|
||||
@ -420,4 +431,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
internal class FakeTracingHandler : DelegatingHandler, ITracingHandler
|
||||
{
|
||||
}
|
||||
|
||||
internal class FakeQoSHandler : DelegatingHandler
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
|
||||
private void ThenTheErrorIsTimeout()
|
||||
{
|
||||
_response.Errors[0].ShouldBeOfType<RequestTimedOutError>();
|
||||
_response.Errors[0].ShouldBeOfType<UnableToCompleteRequestError>();
|
||||
}
|
||||
|
||||
private void GivenTheHouseReturnsOkHandler()
|
||||
|
@ -1,15 +1,17 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
/*
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class QoSProviderFactoryTests
|
||||
{
|
||||
private readonly IQoSProviderFactory _factory;
|
||||
@ -22,10 +24,9 @@ namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
.Setup(x => x.CreateLogger<PollyQoSProvider>())
|
||||
.Returns(_logger.Object);
|
||||
_factory = new QoSProviderFactory(_loggerFactory.Object);
|
||||
var services = new ServiceCollection();
|
||||
var provider = services.BuildServiceProvider();
|
||||
_factory = new QoSProviderFactory(_loggerFactory.Object, provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -46,7 +47,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_polly_qos_provider()
|
||||
public void should_return_delegate_provider()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
@ -55,13 +56,13 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheQoSProvider())
|
||||
.Then(x => x.ThenTheQoSProviderIsReturned<PollyQoSProvider>())
|
||||
.Then(x => x.ThenTheQoSProviderIsReturned<FakeProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -80,4 +81,13 @@ namespace Ocelot.UnitTests.Requester
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
|
||||
internal class FakeProvider : IQoSProvider
|
||||
{
|
||||
public T CircuitBreaker<T>()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Moq;
|
||||
/*
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Requester.QoS;
|
||||
@ -25,13 +26,13 @@ namespace Ocelot.UnitTests.Requester
|
||||
|
||||
[Fact]
|
||||
public void should_store_qos_provider_on_first_request()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.WithKey("test")
|
||||
.Build();
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.WithKey("test")
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
@ -47,7 +48,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
@ -68,8 +69,8 @@ namespace Ocelot.UnitTests.Requester
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptionsTwo)
|
||||
@ -88,10 +89,10 @@ namespace Ocelot.UnitTests.Requester
|
||||
public void should_return_error_if_no_qos_provider_with_key()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.Build();
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
@ -109,16 +110,16 @@ namespace Ocelot.UnitTests.Requester
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.Build();
|
||||
|
||||
var dontUseQoSOptions = new QoSOptionsBuilder()
|
||||
var dontUseQoSOptions = new QoSOptionsBuilder()
|
||||
.WithKey("test")
|
||||
.Build();
|
||||
|
||||
.Build();
|
||||
|
||||
var reRoute = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(dontUseQoSOptions)
|
||||
.Build();
|
||||
|
||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(useQoSOptions)
|
||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
||||
.WithQosOptions(useQoSOptions)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
@ -176,12 +177,19 @@ namespace Ocelot.UnitTests.Requester
|
||||
|
||||
class FakeQoSProvider : IQoSProvider
|
||||
{
|
||||
public CircuitBreaker CircuitBreaker { get; }
|
||||
T IQoSProvider.CircuitBreaker<T>()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
class FakePollyQoSProvider : IQoSProvider
|
||||
{
|
||||
public CircuitBreaker CircuitBreaker { get; }
|
||||
T IQoSProvider.CircuitBreaker<T>()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
Reference in New Issue
Block a user