mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 19:38:16 +08:00
tests to handle some error cases and docs
This commit is contained in:
@ -6,7 +6,13 @@ namespace Ocelot.AcceptanceTests
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Configuration;
|
||||
using Middleware;
|
||||
using Responses;
|
||||
using ServiceDiscovery.Providers;
|
||||
using TestStack.BDDfy;
|
||||
using Values;
|
||||
using Xunit;
|
||||
|
||||
public class LoadBalancerTests : IDisposable
|
||||
@ -122,6 +128,88 @@ namespace Ocelot.AcceptanceTests
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_load_balance_request_with_custom_load_balancer()
|
||||
{
|
||||
var downstreamPortOne = RandomPortFinder.GetRandomPort();
|
||||
var downstreamPortTwo = RandomPortFinder.GetRandomPort();
|
||||
var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}";
|
||||
var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}";
|
||||
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
LoadBalancerOptions = new FileLoadBalancerOptions { Type = nameof(CustomLoadBalancer) },
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = downstreamPortOne,
|
||||
},
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = downstreamPortTwo,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
GlobalConfiguration = new FileGlobalConfiguration(),
|
||||
};
|
||||
|
||||
Func<IServiceProvider, DownstreamReRoute, IServiceDiscoveryProvider, CustomLoadBalancer> loadBalancerFactoryFunc = (serviceProvider, reRoute, serviceDiscoveryProvider) => new CustomLoadBalancer(serviceDiscoveryProvider.Get);
|
||||
|
||||
this.Given(x => x.GivenProductServiceOneIsRunning(downstreamServiceOneUrl, 200))
|
||||
.And(x => x.GivenProductServiceTwoIsRunning(downstreamServiceTwoUrl, 200))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunningWithCustomLoadBalancer(loadBalancerFactoryFunc))
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimes("/", 50))
|
||||
.Then(x => x.ThenTheTwoServicesShouldHaveBeenCalledTimes(50))
|
||||
.And(x => x.ThenBothServicesCalledRealisticAmountOfTimes(24, 26))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private class CustomLoadBalancer : ILoadBalancer
|
||||
{
|
||||
private readonly Func<Task<List<Service>>> _services;
|
||||
private readonly object _lock = new object();
|
||||
|
||||
private int _last;
|
||||
|
||||
public CustomLoadBalancer(Func<Task<List<Service>>> services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public async Task<Response<ServiceHostAndPort>> Lease(DownstreamContext downstreamContext)
|
||||
{
|
||||
var services = await _services();
|
||||
lock (_lock)
|
||||
{
|
||||
if (_last >= services.Count)
|
||||
{
|
||||
_last = 0;
|
||||
}
|
||||
|
||||
var next = services[_last];
|
||||
_last++;
|
||||
return new OkResponse<ServiceHostAndPort>(next.HostAndPort);
|
||||
}
|
||||
}
|
||||
|
||||
public void Release(ServiceHostAndPort hostAndPort)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenBothServicesCalledRealisticAmountOfTimes(int bottom, int top)
|
||||
{
|
||||
_counterOne.ShouldBeInRange(bottom, top);
|
||||
|
Reference in New Issue
Block a user