mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:42:50 +08:00
unit tests for cache clearing passing
This commit is contained in:
parent
239dcfb6bd
commit
e4e7fcc943
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@ -13,16 +14,19 @@ namespace Ocelot.Cache.Middleware
|
|||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
private readonly IOcelotCache<HttpResponseMessage> _outputCache;
|
private readonly IOcelotCache<HttpResponseMessage> _outputCache;
|
||||||
|
private readonly IRegionCreator _regionCreator;
|
||||||
|
|
||||||
public OutputCacheMiddleware(RequestDelegate next,
|
public OutputCacheMiddleware(RequestDelegate next,
|
||||||
IOcelotLoggerFactory loggerFactory,
|
IOcelotLoggerFactory loggerFactory,
|
||||||
IRequestScopedDataRepository scopedDataRepository,
|
IRequestScopedDataRepository scopedDataRepository,
|
||||||
IOcelotCache<HttpResponseMessage> outputCache)
|
IOcelotCache<HttpResponseMessage> outputCache,
|
||||||
|
IRegionCreator regionCreator)
|
||||||
:base(scopedDataRepository)
|
:base(scopedDataRepository)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_outputCache = outputCache;
|
_outputCache = outputCache;
|
||||||
_logger = loggerFactory.CreateLogger<OutputCacheMiddleware>();
|
_logger = loggerFactory.CreateLogger<OutputCacheMiddleware>();
|
||||||
|
_regionCreator = regionCreator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
@ -63,7 +67,7 @@ namespace Ocelot.Cache.Middleware
|
|||||||
|
|
||||||
var response = HttpResponseMessage;
|
var response = HttpResponseMessage;
|
||||||
|
|
||||||
var region = $"{DownstreamRoute.ReRoute.UpstreamHttpMethod}-{DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}";
|
var region = _regionCreator.Region(DownstreamRoute.ReRoute);
|
||||||
|
|
||||||
_outputCache.Add(downstreamUrlKey, response, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.FileCacheOptions.TtlSeconds), region);
|
_outputCache.Add(downstreamUrlKey, response, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.FileCacheOptions.TtlSeconds), region);
|
||||||
|
|
||||||
|
22
src/Ocelot/Cache/RegionBuilder.cs
Normal file
22
src/Ocelot/Cache/RegionBuilder.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
|
||||||
|
namespace Ocelot.Cache
|
||||||
|
{
|
||||||
|
public interface IRegionCreator
|
||||||
|
{
|
||||||
|
string Region(ReRoute reRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegionCreator : IRegionCreator
|
||||||
|
{
|
||||||
|
public string Region(ReRoute reRoute)
|
||||||
|
{
|
||||||
|
var methods = string.Join(",", reRoute.UpstreamHttpMethod.Select(m => m.Method));
|
||||||
|
|
||||||
|
var region = $"{methods} {reRoute.UpstreamPathTemplate.Value}";
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
src/Ocelot/Cache/RegionsGetter.cs
Normal file
47
src/Ocelot/Cache/RegionsGetter.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration.Provider;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
|
||||||
|
namespace Ocelot.Cache
|
||||||
|
{
|
||||||
|
public interface IRegionsGetter
|
||||||
|
{
|
||||||
|
Task<List<string>> Regions();
|
||||||
|
}
|
||||||
|
public class RegionsGetter : IRegionsGetter
|
||||||
|
{
|
||||||
|
private readonly IOcelotConfigurationProvider _provider;
|
||||||
|
private readonly IRegionCreator _creator;
|
||||||
|
private readonly IOcelotLogger _logger;
|
||||||
|
|
||||||
|
public RegionsGetter(IOcelotConfigurationProvider provider, IRegionCreator creator, IOcelotLoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
_logger = loggerFactory.CreateLogger<RegionsGetter>();
|
||||||
|
_provider = provider;
|
||||||
|
_creator = creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<string>> Regions()
|
||||||
|
{
|
||||||
|
var config = await _provider.Get();
|
||||||
|
|
||||||
|
if(config.IsError)
|
||||||
|
{
|
||||||
|
_logger.LogError("unable to find regions", new Exception(string.Join(",", config.Errors)));
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var regions = new List<string>();
|
||||||
|
|
||||||
|
foreach(var reRoute in config.Data.ReRoutes)
|
||||||
|
{
|
||||||
|
var region = _creator.Region(reRoute);
|
||||||
|
regions.Add(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ using System.Net.Http;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
|
using Ocelot.Configuration.Provider;
|
||||||
|
|
||||||
namespace Ocelot.Controllers
|
namespace Ocelot.Controllers
|
||||||
{
|
{
|
||||||
@ -10,16 +11,19 @@ namespace Ocelot.Controllers
|
|||||||
public class OutputCacheController : Controller
|
public class OutputCacheController : Controller
|
||||||
{
|
{
|
||||||
private IOcelotCache<HttpResponseMessage> _cache;
|
private IOcelotCache<HttpResponseMessage> _cache;
|
||||||
|
private IRegionsGetter _regionsGetter;
|
||||||
|
|
||||||
public OutputCacheController(IOcelotCache<HttpResponseMessage> cache)
|
public OutputCacheController(IOcelotCache<HttpResponseMessage> cache, IRegionsGetter regionsGetter)
|
||||||
{
|
{
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
|
_regionsGetter = regionsGetter;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult Get()
|
public IActionResult Get()
|
||||||
{
|
{
|
||||||
return new NotFoundResult();
|
var regions = _regionsGetter.Regions();
|
||||||
|
return new OkObjectResult(regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
|
@ -145,6 +145,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
.AddJsonFormatters();
|
.AddJsonFormatters();
|
||||||
|
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
|
services.TryAddSingleton<IRegionsGetter, RegionsGetter>();
|
||||||
|
services.TryAddSingleton<IRegionCreator, RegionCreator>();
|
||||||
services.TryAddSingleton<IFileConfigurationRepository, FileConfigurationRepository>();
|
services.TryAddSingleton<IFileConfigurationRepository, FileConfigurationRepository>();
|
||||||
services.TryAddSingleton<IFileConfigurationSetter, FileConfigurationSetter>();
|
services.TryAddSingleton<IFileConfigurationSetter, FileConfigurationSetter>();
|
||||||
services.TryAddSingleton<IFileConfigurationProvider, FileConfigurationProvider>();
|
services.TryAddSingleton<IFileConfigurationProvider, FileConfigurationProvider>();
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
|
||||||
|
@ -5,6 +5,7 @@ using System.Net.Http;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Ocelot.Cache.Middleware;
|
using Ocelot.Cache.Middleware;
|
||||||
@ -43,6 +44,7 @@ namespace Ocelot.UnitTests.Cache
|
|||||||
x.AddLogging();
|
x.AddLogging();
|
||||||
x.AddSingleton(_cacheManager.Object);
|
x.AddSingleton(_cacheManager.Object);
|
||||||
x.AddSingleton(_scopedRepo.Object);
|
x.AddSingleton(_scopedRepo.Object);
|
||||||
|
x.AddSingleton<IRegionCreator, RegionCreator>();
|
||||||
})
|
})
|
||||||
.UseUrls(_url)
|
.UseUrls(_url)
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
46
test/Ocelot.UnitTests/Cache/RegionCreatorTests.cs
Normal file
46
test/Ocelot.UnitTests/Cache/RegionCreatorTests.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Ocelot.Cache;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Cache
|
||||||
|
{
|
||||||
|
public class RegionCreatorTests
|
||||||
|
{
|
||||||
|
private string _result;
|
||||||
|
private ReRoute _reRoute;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_create_region()
|
||||||
|
{
|
||||||
|
var reRoute = new ReRouteBuilder()
|
||||||
|
.WithUpstreamHttpMethod(new List<string>{"Get"})
|
||||||
|
.WithUpstreamPathTemplate("/test/dummy")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
this.Given(_ => GivenTheReRoute(reRoute))
|
||||||
|
.When(_ => WhenICreateTheRegion())
|
||||||
|
.Then(_ => ThenTheRegionIs("Get /test/dummy"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheReRoute(ReRoute reRoute)
|
||||||
|
{
|
||||||
|
_reRoute = reRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenICreateTheRegion()
|
||||||
|
{
|
||||||
|
RegionCreator regionCreator = new RegionCreator();
|
||||||
|
_result = regionCreator.Region(_reRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheRegionIs(string expected)
|
||||||
|
{
|
||||||
|
_result.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
test/Ocelot.UnitTests/Cache/RegionsGetterTests.cs
Normal file
109
test/Ocelot.UnitTests/Cache/RegionsGetterTests.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
using Xunit;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Shouldly;
|
||||||
|
using Ocelot.Cache;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Configuration.Provider;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using System;
|
||||||
|
using Ocelot.Errors;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Cache
|
||||||
|
{
|
||||||
|
public class RegionsGetterTests
|
||||||
|
{
|
||||||
|
private RegionsGetter _regionsGetter;
|
||||||
|
private readonly Mock<IOcelotConfigurationProvider> _provider;
|
||||||
|
private readonly Mock<IRegionCreator> _creator;
|
||||||
|
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||||
|
private List<string> _result;
|
||||||
|
|
||||||
|
public RegionsGetterTests()
|
||||||
|
{
|
||||||
|
_provider = new Mock<IOcelotConfigurationProvider>();
|
||||||
|
_creator = new Mock<IRegionCreator>();
|
||||||
|
_factory = new Mock<IOcelotLoggerFactory>();
|
||||||
|
var logger = new Mock<IOcelotLogger>();
|
||||||
|
_factory
|
||||||
|
.Setup(x => x.CreateLogger<RegionsGetter>())
|
||||||
|
.Returns(logger.Object);
|
||||||
|
_regionsGetter = new RegionsGetter(_provider.Object, _creator.Object, _factory.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_get_regions()
|
||||||
|
{
|
||||||
|
var reRoute = new ReRouteBuilder()
|
||||||
|
.WithUpstreamHttpMethod(new List<string>{"Get"})
|
||||||
|
.WithUpstreamPathTemplate("/")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var reRoutes = new List<ReRoute>
|
||||||
|
{
|
||||||
|
reRoute
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = new OcelotConfiguration(reRoutes, "whocares!");
|
||||||
|
|
||||||
|
var expected = new List<string>
|
||||||
|
{
|
||||||
|
"balls"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(_ => GivenTheFollowingConfig(config))
|
||||||
|
.And(_ => GivenTheProviderReturns("balls"))
|
||||||
|
.When(_ => WhenIGetTheRegions())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(expected))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_empty_regions()
|
||||||
|
{
|
||||||
|
var expected = new List<string>();
|
||||||
|
|
||||||
|
this.Given(_ => GivenAnErrorGettingTheConfig())
|
||||||
|
.When(_ => WhenIGetTheRegions())
|
||||||
|
.Then(_ => ThenTheFollowingIsReturned(expected))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenAnErrorGettingTheConfig()
|
||||||
|
{
|
||||||
|
var config = new OcelotConfiguration(new List<ReRoute>(), "whocares!");
|
||||||
|
|
||||||
|
_provider
|
||||||
|
.Setup(x => x.Get())
|
||||||
|
.ReturnsAsync(new ErrorResponse<IOcelotConfiguration>(It.IsAny<Error>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheProviderReturns(string expected)
|
||||||
|
{
|
||||||
|
_creator
|
||||||
|
.Setup(x => x.Region(It.IsAny<ReRoute>()))
|
||||||
|
.Returns(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowingConfig(IOcelotConfiguration config)
|
||||||
|
{
|
||||||
|
_provider
|
||||||
|
.Setup(x => x.Get())
|
||||||
|
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIGetTheRegions()
|
||||||
|
{
|
||||||
|
_result = _regionsGetter.Regions().Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheFollowingIsReturned(List<string> expected)
|
||||||
|
{
|
||||||
|
_result.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,12 +15,14 @@ namespace Ocelot.UnitTests.Controllers
|
|||||||
{
|
{
|
||||||
private OutputCacheController _controller;
|
private OutputCacheController _controller;
|
||||||
private Mock<IOcelotCache<HttpResponseMessage>> _cache;
|
private Mock<IOcelotCache<HttpResponseMessage>> _cache;
|
||||||
|
private Mock<IRegionsGetter> _getter;
|
||||||
private IActionResult _result;
|
private IActionResult _result;
|
||||||
|
|
||||||
public OutputCacheControllerTests()
|
public OutputCacheControllerTests()
|
||||||
{
|
{
|
||||||
_cache = new Mock<IOcelotCache<HttpResponseMessage>>();
|
_cache = new Mock<IOcelotCache<HttpResponseMessage>>();
|
||||||
_controller = new OutputCacheController(_cache.Object);
|
_getter = new Mock<IRegionsGetter>();
|
||||||
|
_controller = new OutputCacheController(_cache.Object, _getter.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user