refactoring configuration code so its not so crazy, still need to work on the creator class

This commit is contained in:
TomPallister
2016-10-18 18:32:34 +01:00
parent 707f1d6908
commit 2e6640c6ef
23 changed files with 561 additions and 178 deletions

View File

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ocelot.Library.Configuration;
using Ocelot.Library.Configuration.Builder;
using Ocelot.Library.Configuration.Repository;
using Ocelot.Library.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class InMemoryConfigurationRepositoryTests
{
private readonly InMemoryOcelotConfigurationRepository _repo;
private IOcelotConfiguration _config;
private Response _result;
private Response<IOcelotConfiguration> _getResult;
public InMemoryConfigurationRepositoryTests()
{
_repo = new InMemoryOcelotConfigurationRepository();
}
[Fact]
public void can_add_config()
{
this.Given(x => x.GivenTheConfigurationIs(new FakeConfig("initial")))
.When(x => x.WhenIAddOrReplaceTheConfig())
.Then(x => x.ThenNoErrorsAreReturned())
.BDDfy();
}
[Fact]
public void can_get_config()
{
this.Given(x => x.GivenThereIsASavedConfiguration())
.When(x => x.WhenIGetTheConfiguration())
.Then(x => x.ThenTheConfigurationIsReturned())
.BDDfy();
}
/// <summary>
/// long runnnig unit test to make sure repo thread safeok on
/// </summary>
[Fact]
public void repo_is_thread_safe()
{
var tasks = new Task[100000];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Fire();
}
Task.WaitAll(tasks);
}
private async Task Fire()
{
var taskGuid = Guid.NewGuid().ToString();
_repo.AddOrReplace(new FakeConfig(taskGuid));
var configuration = _repo.Get();
configuration.Data.ReRoutes[0].DownstreamTemplate.ShouldBe(taskGuid);
}
private void ThenTheConfigurationIsReturned()
{
_getResult.Data.ReRoutes[0].DownstreamTemplate.ShouldBe("initial");
}
private void WhenIGetTheConfiguration()
{
_getResult = _repo.Get();
}
private void GivenThereIsASavedConfiguration()
{
GivenTheConfigurationIs(new FakeConfig("initial"));
WhenIAddOrReplaceTheConfig();
}
private void GivenTheConfigurationIs(IOcelotConfiguration config)
{
_config = config;
}
private void WhenIAddOrReplaceTheConfig()
{
_result = _repo.AddOrReplace(_config);
}
private void ThenNoErrorsAreReturned()
{
_result.IsError.ShouldBeFalse();
}
class FakeConfig : IOcelotConfiguration
{
private readonly string _downstreamTemplate;
public FakeConfig(string downstreamTemplate)
{
_downstreamTemplate = downstreamTemplate;
}
public List<ReRoute> ReRoutes => new List<ReRoute>
{
new ReRouteBuilder().WithDownstreamTemplate(_downstreamTemplate).Build()
};
}
}
}

View File

@ -2,6 +2,9 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using Ocelot.Library.Configuration.Builder;
using Ocelot.Library.Configuration.Parser;
using Ocelot.Library.Configuration.Repository;
using Ocelot.Library.RequestBuilder;
using Shouldly;
using TestStack.BDDfy;
@ -9,26 +12,28 @@ using Xunit;
namespace Ocelot.UnitTests.Configuration
{
using Library.Builder;
using Library.Configuration;
using Library.Configuration.Yaml;
using Library.Responses;
public class OcelotConfigurationTests
public class YamlConfigurationCreatorTests
{
private readonly Mock<IOptions<YamlConfiguration>> _yamlConfig;
private readonly Mock<IConfigurationValidator> _validator;
private OcelotConfiguration _config;
private Response<IOcelotConfiguration> _config;
private YamlConfiguration _yamlConfiguration;
private readonly Mock<IClaimToHeaderConfigurationParser> _configExtractor;
private readonly Mock<ILogger<OcelotConfiguration>> _logger;
private readonly Mock<IClaimToHeaderConfigurationParser> _configParser;
private readonly Mock<ILogger<YamlOcelotConfigurationCreator>> _logger;
private readonly YamlOcelotConfigurationCreator _ocelotConfigurationCreator;
public OcelotConfigurationTests()
public YamlConfigurationCreatorTests()
{
_logger = new Mock<ILogger<OcelotConfiguration>>();
_configExtractor = new Mock<IClaimToHeaderConfigurationParser>();
_logger = new Mock<ILogger<YamlOcelotConfigurationCreator>>();
_configParser = new Mock<IClaimToHeaderConfigurationParser>();
_validator = new Mock<IConfigurationValidator>();
_yamlConfig = new Mock<IOptions<YamlConfiguration>>();
_ocelotConfigurationCreator = new YamlOcelotConfigurationCreator(
_yamlConfig.Object, _validator.Object, _configParser.Object, _logger.Object);
}
[Fact]
@ -47,7 +52,7 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheYamlConfigIsValid())
.When(x => x.WhenIInstanciateTheOcelotConfig())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
@ -109,7 +114,7 @@ namespace Ocelot.UnitTests.Configuration
}))
.And(x => x.GivenTheYamlConfigIsValid())
.And(x => x.GivenTheConfigHeaderExtractorReturns(new ClaimToHeader("CustomerId", "CustomerId", "", 0)))
.When(x => x.WhenIInstanciateTheOcelotConfig())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(expected))
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
.BDDfy();
@ -117,7 +122,7 @@ namespace Ocelot.UnitTests.Configuration
private void GivenTheConfigHeaderExtractorReturns(ClaimToHeader expected)
{
_configExtractor
_configParser
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
.Returns(new OkResponse<ClaimToHeader>(expected));
}
@ -162,7 +167,7 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheYamlConfigIsValid())
.When(x => x.WhenIInstanciateTheOcelotConfig())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(expected))
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
.BDDfy();
@ -184,7 +189,7 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheYamlConfigIsValid())
.When(x => x.WhenIInstanciateTheOcelotConfig())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
@ -213,7 +218,7 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheYamlConfigIsValid())
.When(x => x.WhenIInstanciateTheOcelotConfig())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
@ -242,7 +247,7 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheYamlConfigIsValid())
.When(x => x.WhenIInstanciateTheOcelotConfig())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
@ -270,17 +275,16 @@ namespace Ocelot.UnitTests.Configuration
.Returns(_yamlConfiguration);
}
private void WhenIInstanciateTheOcelotConfig()
private void WhenICreateTheConfig()
{
_config = new OcelotConfiguration(_yamlConfig.Object, _validator.Object,
_configExtractor.Object, _logger.Object);
_config = _ocelotConfigurationCreator.Create();
}
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
{
for (int i = 0; i < _config.ReRoutes.Count; i++)
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
{
var result = _config.ReRoutes[i];
var result = _config.Data.ReRoutes[i];
var expected = expectedReRoutes[i];
result.DownstreamTemplate.ShouldBe(expected.DownstreamTemplate);
@ -292,9 +296,9 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes)
{
for (int i = 0; i < _config.ReRoutes.Count; i++)
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
{
var result = _config.ReRoutes[i].AuthenticationOptions;
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
var expected = expectedReRoutes[i].AuthenticationOptions;
result.AdditionalScopes.ShouldBe(expected.AdditionalScopes);

View File

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Moq;
using Ocelot.Library.Configuration;
using Ocelot.Library.Configuration.Creator;
using Ocelot.Library.Configuration.Provider;
using Ocelot.Library.Configuration.Repository;
using Ocelot.Library.Configuration.Yaml;
using Ocelot.Library.Errors;
using Ocelot.Library.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class YamlConfigurationProviderTests
{
private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
private readonly Mock<IOcelotConfigurationCreator> _creator;
private Response<IOcelotConfiguration> _result;
public YamlConfigurationProviderTests()
{
_creator = new Mock<IOcelotConfigurationCreator>();
_configurationRepository = new Mock<IOcelotConfigurationRepository>();
_ocelotConfigurationProvider = new YamlOcelotConfigurationProvider(_configurationRepository.Object, _creator.Object);
}
[Fact]
public void should_get_config()
{
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
.When(x => x.WhenIGetTheConfig())
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
.BDDfy();
}
[Fact]
public void should_create_config_if_it_doesnt_exist()
{
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(null)))
.And(x => x.GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
.When(x => x.WhenIGetTheConfig())
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
.BDDfy();
}
[Fact]
public void should_return_error()
{
this.Given(x => x.GivenTheRepoReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
{
new AnyError()
})))
.When(x => x.WhenIGetTheConfig())
.Then(x => x.TheFollowingIsReturned(
new ErrorResponse<IOcelotConfiguration>(new List<Error>
{
new AnyError()
})))
.BDDfy();
}
[Fact]
public void should_return_error_if_creator_errors()
{
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(null)))
.And(x => x.GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
{
new AnyError()
})))
.When(x => x.WhenIGetTheConfig())
.Then(x => x.TheFollowingIsReturned(new ErrorResponse<IOcelotConfiguration>(new List<Error>
{
new AnyError()
})))
.BDDfy();
}
private void GivenTheCreatorReturns(Response<IOcelotConfiguration> config)
{
_creator
.Setup(x => x.Create())
.Returns(config);
}
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
{
_configurationRepository
.Setup(x => x.Get())
.Returns(config);
}
private void WhenIGetTheConfig()
{
_result = _ocelotConfigurationProvider.Get();
}
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
{
_result.IsError.ShouldBe(expected.IsError);
}
class AnyError : Error
{
public AnyError()
: base("blamo", OcelotErrorCode.UnknownError)
{
}
}
}
}

View File

@ -1,12 +1,13 @@
using System.Collections.Generic;
using Moq;
using Ocelot.Library.Configuration.Builder;
using Ocelot.Library.Configuration.Provider;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
using Library.Builder;
using Library.Configuration;
using Library.DownstreamRouteFinder;
using Library.Responses;
@ -15,7 +16,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public class DownstreamRouteFinderTests
{
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
private readonly Mock<IOcelotConfiguration> _mockConfig;
private readonly Mock<IOcelotConfigurationProvider> _mockConfig;
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
private readonly Mock<ITemplateVariableNameAndValueFinder> _finder;
private string _upstreamUrlPath;
@ -26,7 +27,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public DownstreamRouteFinderTests()
{
_mockConfig = new Mock<IOcelotConfiguration>();
_mockConfig = new Mock<IOcelotConfigurationProvider>();
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
_finder = new Mock<ITemplateVariableNameAndValueFinder>();
_downstreamRouteFinder = new DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object, _finder.Object);
@ -157,8 +158,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
{
_reRoutesConfig = reRoutesConfig;
_mockConfig
.Setup(x => x.ReRoutes)
.Returns(_reRoutesConfig);
.Setup(x => x.Get())
.Returns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig)));
}
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)

View File

@ -6,13 +6,13 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Library.Configuration.Builder;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Middleware
{
using Library.Authentication;
using Library.Builder;
using Library.DownstreamRouteFinder;
using Library.Middleware;
using Library.Repository;

View File

@ -6,12 +6,12 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Library.Configuration.Builder;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Middleware
{
using Library.Builder;
using Library.DownstreamRouteFinder;
using Library.Middleware;
using Library.Repository;

View File

@ -1,10 +1,11 @@
namespace Ocelot.UnitTests.Middleware
using Ocelot.Library.Configuration.Builder;
namespace Ocelot.UnitTests.Middleware
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using Library.Builder;
using Library.DownstreamRouteFinder;
using Library.Middleware;
using Library.Repository;

View File

@ -7,8 +7,8 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Library.Builder;
using Ocelot.Library.Configuration;
using Ocelot.Library.Configuration.Builder;
using Ocelot.Library.DownstreamRouteFinder;
using Ocelot.Library.Middleware;
using Ocelot.Library.Repository;

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Ocelot.Library.Configuration;
using Ocelot.Library.Configuration.Parser;
using Ocelot.Library.Errors;
using Ocelot.Library.RequestBuilder;
using Ocelot.Library.Responses;

View File

@ -1,11 +1,11 @@
using System.Collections.Generic;
using Ocelot.Library.Configuration.Builder;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.UrlTemplateReplacer
{
using Library.Builder;
using Library.DownstreamRouteFinder;
using Library.Responses;
using Library.UrlMatcher;