Ocelot/test/Ocelot.UnitTests/Cache/OutputCacheMiddlewareTests.cs
Charalampos Chomenidis 48b5a32676 Implement mapping of HttpResponseMessage to CachedResponse to fix #152 (#153)
* changed name to cache options to fix issue #146

* Add acceptance test that exposes JSON deserialization bug from issue #146

- Create InMemoryJsonHandle for CacheManager that mimics DictionaryHandle but uses ICacheSerializer to serialize/deserialize values instead of saving references
- Add CacheManager.Serialization.Json package
- Add StartupWithCustomCacheHandle class that extends Startup and overrides ConfigureServices to register InMemoryJsonHandle
- Add GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache method to initiate Ocelot with StartupWithCustomCacheHandle
- Add test should_return_response_200_with_simple_url_when_using_jsonserialized_cache

* Create Acceptance test that exposes issue #152

- Add GivenOcelotIsRunningUsingJsonSerializedCache() that initializes Ocelot with InMemoryJsonHandle
- Add should_return_cached_response_when_using_jsonserialized_cache test

* Change Consul port to 9502 on should_return_response_200_with_simple_url_when_using_jsonserialized_cache() test

* Implement mapping of HttpResponseMessage to CachedResponse to enable distributed caching

- Add CachedResponse class that holds HttpResponse data
- Add mapping methods in OutputCacheMiddleware to create HttpResponseMessage from CachedResponse and vice versa
- Replace HttpResponseMessage with CachedResponse in services registrations
- Replace HttpResponseMessage with CachedResponse in OutputCacheController's IOcelotCache

* Fix unit tests for OutputCacheMiddleware and OutputCacheController by replacing HttpResponseMessage with CachedResponse

* Add .editorconfig with default identation settings (spaces with size 4)

* Re-format broken files with new identation settings

* Add Startup_WithConsul_And_CustomCacheHandle class

- Use Startup_WithConsul_And_CustomCacheHandle in GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache step

* Do minor cleanups

- Rename StartupWithCustomCacheHandle to Startup_WithCustomCacheHandle for better readability
- Remove cachemanager settings Action in Startup since it is not used anymore

* Drop Task in CreateHttpResponseMessage - unnecessary overhead

* Make setters private in CachedResponse

- Rework CreateCachedResponse to use new CachedResponse constructor
2017-11-25 14:47:17 +00:00

131 lines
4.6 KiB
C#

namespace Ocelot.UnitTests.Cache
{
using System;
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
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.Responses;
using TestStack.BDDfy;
using Xunit;
public class OutputCacheMiddlewareTests : ServerHostedMiddlewareTest
{
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
private CachedResponse _response;
public OutputCacheMiddlewareTests()
{
_cacheManager = new Mock<IOcelotCache<CachedResponse>>();
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
GivenTheTestServerIsConfigured();
}
[Fact]
public void should_returned_cached_item_when_it_is_in_cache()
{
var cachedResponse = new CachedResponse();
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
.BDDfy();
}
[Fact]
public void should_continue_with_pipeline_and_cache_response()
{
this.Given(x => x.GivenResponseIsNotCached())
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereAreNoErrors())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_cacheManager.Object);
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IRegionCreator, RegionCreator>();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseOutputCacheMiddleware();
}
private void GivenThereIsACachedResponse(CachedResponse response)
{
_response = response;
_cacheManager
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
.Returns(_response);
}
private void GivenResponseIsNotCached()
{
ScopedRepository
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
.Returns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage()));
}
private void GivenTheDownstreamRouteIs()
{
var reRoute = new ReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), reRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
}
private void GivenThereAreNoErrors()
{
ScopedRepository
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
.Returns(new OkResponse<bool>(false));
}
private void GivenThereIsADownstreamUrl()
{
ScopedRepository
.Setup(x => x.Get<string>("DownstreamUrl"))
.Returns(new OkResponse<string>("anything"));
}
private void ThenTheCacheGetIsCalledCorrectly()
{
_cacheManager
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
}
private void ThenTheCacheAddIsCalledCorrectly()
{
_cacheManager
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
}
}
}