Merge branch 'release/13.8.0'

This commit is contained in:
TomPallister
2019-10-28 07:34:56 +00:00
93 changed files with 1747 additions and 553 deletions

View File

@ -2,14 +2,15 @@ namespace Ocelot.UnitTests.Administration
{
using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Administration;
using Ocelot.DependencyInjection;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -25,9 +26,19 @@ namespace Ocelot.UnitTests.Administration
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotAdministrationBuilderTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
//keep
[Fact]

View File

@ -2,9 +2,10 @@
{
using global::CacheManager.Core;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting.Internal;
using Moq;
using Ocelot.Cache;
using Ocelot.Cache.CacheManager;
using Ocelot.Configuration;
@ -14,6 +15,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -30,11 +32,21 @@
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
_maxRetries = 100;
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_cache_manager()
{

View File

@ -15,7 +15,7 @@ namespace Ocelot.UnitTests.Configuration
public class DiskFileConfigurationRepositoryTests : IDisposable
{
private readonly Mock<IHostingEnvironment> _hostingEnvironment;
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
private IFileConfigurationRepository _repo;
private string _environmentSpecificPath;
private string _ocelotJsonPath;
@ -33,7 +33,7 @@ namespace Ocelot.UnitTests.Configuration
{
_semaphore = new SemaphoreSlim(1, 1);
_semaphore.Wait();
_hostingEnvironment = new Mock<IHostingEnvironment>();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
}

View File

@ -1,6 +1,7 @@
namespace Ocelot.UnitTests.Consul
{
using global::Consul;
using Microsoft.Extensions.Options;
using Moq;
using Newtonsoft.Json;
using Ocelot.Cache;
@ -23,8 +24,8 @@
public class ConsulFileConfigurationRepositoryTests
{
private ConsulFileConfigurationRepository _repo;
private Mock<IOptions<FileConfiguration>> _options;
private Mock<IOcelotCache<FileConfiguration>> _cache;
private Mock<IInternalConfigurationRepository> _internalRepo;
private Mock<IConsulClientFactory> _factory;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IConsulClient> _client;
@ -36,9 +37,9 @@
public ConsulFileConfigurationRepositoryTests()
{
_cache = new Mock<IOcelotCache<FileConfiguration>>();
_internalRepo = new Mock<IInternalConfigurationRepository>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_options = new Mock<IOptions<FileConfiguration>>();
_factory = new Mock<IConsulClientFactory>();
_client = new Mock<IConsulClient>();
_kvEndpoint = new Mock<IKVEndpoint>();
@ -51,11 +52,9 @@
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
.Returns(_client.Object);
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "", It.IsAny<LoadBalancerOptions>(), It.IsAny<string>(), It.IsAny<QoSOptions>(), It.IsAny<HttpHandlerOptions>())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
_options
.SetupGet(x => x.Value)
.Returns(() => _fileConfiguration);
}
[Fact]
@ -85,7 +84,10 @@
[Fact]
public void should_get_null_config()
{
this.Given(_ => GivenFetchFromConsulReturnsNull())
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.Given(_ => GivenFetchFromConsulReturnsNull())
.When(_ => WhenIGetTheConfiguration())
.Then(_ => ThenTheConfigurationIsNull())
.BDDfy();
@ -136,14 +138,8 @@
private void GivenTheConfigKeyComesFromFileConfig(string key)
{
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "",
new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "",
new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(),
new HttpHandlerOptionsBuilder().Build())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
_fileConfiguration.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = key;
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
}
private void ThenTheConfigurationIsNull()
@ -221,6 +217,8 @@
private void GivenIHaveAConfiguration(FileConfiguration config)
{
_fileConfiguration = config;
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
}
private FileConfiguration FakeFileConfiguration()

View File

@ -1,14 +1,15 @@
namespace Ocelot.UnitTests.Consul
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DependencyInjection;
using Provider.Consul;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -24,10 +25,21 @@
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_consul()
{

View File

@ -15,7 +15,6 @@
public class PollingConsulServiceDiscoveryProviderTests
{
private readonly int _delay;
private PollConsul _provider;
private readonly List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
@ -56,27 +55,28 @@
private void WhenIGetTheServices(int expected)
{
_provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object);
var result = Wait.WaitFor(3000).Until(() =>
using (var provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object))
{
try
var result = Wait.WaitFor(3000).Until(() =>
{
_result = _provider.Get().GetAwaiter().GetResult();
if (_result.Count == expected)
try
{
return true;
_result = provider.Get().GetAwaiter().GetResult();
if (_result.Count == expected)
{
return true;
}
return false;
}
catch (Exception)
{
return false;
}
});
return false;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
result.ShouldBeTrue();
}
}
}
}

View File

@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.Consul
using Ocelot.Configuration.Builder;
namespace Ocelot.UnitTests.Consul
{
using Microsoft.Extensions.DependencyInjection;
using Moq;
@ -29,7 +31,11 @@
[Fact]
public void should_return_ConsulServiceDiscoveryProvider()
{
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), "");
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("")
.Build();
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), reRoute);
provider.ShouldBeOfType<Consul>();
}
@ -37,8 +43,15 @@
public void should_return_PollingConsulServiceDiscoveryProvider()
{
var stopsPollerFromPolling = 10000;
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), "");
provider.ShouldBeOfType<PollConsul>();
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("")
.Build();
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), reRoute);
var pollProvider = provider as PollConsul;
pollProvider.ShouldNotBeNull();
pollProvider.Dispose();
}
}
}

View File

@ -22,11 +22,11 @@
private FileConfiguration _reRouteB;
private FileConfiguration _aggregate;
private FileConfiguration _envSpecific;
private Mock<IHostingEnvironment> _hostingEnvironment;
private Mock<IWebHostEnvironment> _hostingEnvironment;
public ConfigurationBuilderExtensionsTests()
{
_hostingEnvironment = new Mock<IHostingEnvironment>();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
// Clean up config files before each test
var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");

View File

@ -1,11 +1,12 @@
namespace Ocelot.UnitTests.DependencyInjection
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration.Setter;
using Ocelot.DependencyInjection;
using Ocelot.Infrastructure;
using Ocelot.Middleware.Multiplexer;
using Ocelot.Requester;
using Ocelot.UnitTests.Requester;
@ -14,6 +15,7 @@ namespace Ocelot.UnitTests.DependencyInjection
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests;
@ -31,11 +33,21 @@ namespace Ocelot.UnitTests.DependencyInjection
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
_maxRetries = 100;
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_add_specific_delegating_handlers_transient()
{
@ -47,6 +59,17 @@ namespace Ocelot.UnitTests.DependencyInjection
.BDDfy();
}
[Fact]
public void should_add_type_specific_delegating_handlers_transient()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandler)))
.And(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandlerTwo)))
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.And(x => ThenTheSpecificHandlersAreTransient())
.BDDfy();
}
[Fact]
public void should_add_global_delegating_handlers_transient()
{
@ -58,6 +81,17 @@ namespace Ocelot.UnitTests.DependencyInjection
.BDDfy();
}
[Fact]
public void should_add_global_type_delegating_handlers_transient()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.And(x => ThenTheGlobalHandlersAreTransient())
.BDDfy();
}
[Fact]
public void should_set_up_services()
{
@ -114,6 +148,16 @@ namespace Ocelot.UnitTests.DependencyInjection
.BDDfy();
}
[Fact]
public void should_replace_iplaceholder()
{
this.Given(x => x.WhenISetUpOcelotServices())
.When(x => AddConfigPlaceholders())
.Then(x => ThenAnExceptionIsntThrown())
.And(x => ThenTheIPlaceholderInstanceIsReplaced())
.BDDfy();
}
private void AddSingletonDefinedAggregator<T>()
where T : class, IDefinedAggregator
{
@ -126,6 +170,11 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.AddTransientDefinedAggregator<T>();
}
private void AddConfigPlaceholders()
{
_ocelotBuilder.AddConfigPlaceholders();
}
private void ThenTheSpecificHandlersAreTransient()
{
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
@ -156,6 +205,16 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.AddDelegatingHandler<T>();
}
private void AddTypeTransientGlobalDelegatingHandler(Type type)
{
_ocelotBuilder.AddDelegatingHandler(type, true);
}
private void AddTypeSpecificTransientDelegatingHandler(Type type)
{
_ocelotBuilder.AddDelegatingHandler(type);
}
private void ThenTheProviderIsRegisteredAndReturnsHandlers<TOne, TWo>()
{
_serviceProvider = _services.BuildServiceProvider();
@ -203,6 +262,13 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
}
private void ThenTheIPlaceholderInstanceIsReplaced()
{
_serviceProvider = _services.BuildServiceProvider();
var placeholders = _serviceProvider.GetService<IPlaceholders>();
placeholders.ShouldBeOfType<ConfigAwarePlaceholders>();
}
private void WhenISetUpOcelotServices()
{
try

View File

@ -0,0 +1,196 @@
using Moq;
using Ocelot.Configuration;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Errors;
using Ocelot.Infrastructure;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.PathManipulation;
using Ocelot.Responses;
using Ocelot.UnitTests.Responder;
using Ocelot.Values;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamPathManipulation
{
public class ChangeDownstreamPathTemplateTests
{
private readonly ChangeDownstreamPathTemplate _changeDownstreamPath;
private DownstreamPathTemplate _downstreamPathTemplate;
private readonly Mock<IClaimsParser> _parser;
private List<ClaimToThing> _configuration;
private List<Claim> _claims;
private Response _result;
private Response<string> _claimValue;
private List<PlaceholderNameAndValue> _placeholderValues;
public ChangeDownstreamPathTemplateTests()
{
_parser = new Mock<IClaimsParser>();
_changeDownstreamPath = new ChangeDownstreamPathTemplate(_parser.Object);
}
[Fact]
public void should_change_downstream_path_request()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>();
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsSuccess())
.And(x => x.ThenClaimDataIsContainedInPlaceHolder("{path-key}", "value"))
.BDDfy();
}
[Fact]
public void should_replace_existing_placeholder_value()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue ("{path-key}", "old_value"),
};
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsSuccess())
.And(x => x.ThenClaimDataIsContainedInPlaceHolder("{path-key}", "value"))
.BDDfy();
}
[Fact]
public void should_return_error_when_no_placeholder_in_downstream_path()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>();
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsCouldNotFindPlaceholderError())
.BDDfy();
}
[Fact]
private void should_return_error_when_claim_parser_returns_error()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>();
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
{
new AnyError(),
})))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsError())
.BDDfy();
}
private void GivenAClaimToThing(List<ClaimToThing> configuration)
{
_configuration = configuration;
}
private void GivenClaims(List<Claim> claims)
{
_claims = claims;
}
private void GivenDownstreamPathTemplate(string template)
{
_downstreamPathTemplate = new DownstreamPathTemplate(template);
}
private void GivenPlaceholderNameAndValues(List<PlaceholderNameAndValue> placeholders)
{
_placeholderValues = placeholders;
}
private void GivenTheClaimParserReturns(Response<string> claimValue)
{
_claimValue = claimValue;
_parser
.Setup(
x =>
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<int>()))
.Returns(_claimValue);
}
private void WhenIChangeDownstreamPath()
{
_result = _changeDownstreamPath.ChangeDownstreamPath(_configuration, _claims,
_downstreamPathTemplate, _placeholderValues);
}
private void ThenTheResultIsSuccess()
{
_result.IsError.ShouldBe(false);
}
private void ThenTheResultIsCouldNotFindPlaceholderError()
{
_result.IsError.ShouldBe(true);
_result.Errors.Count.ShouldBe(1);
_result.Errors.First().ShouldBeOfType<CouldNotFindPlaceholderError>();
}
private void ThenTheResultIsError()
{
_result.IsError.ShouldBe(true);
}
private void ThenClaimDataIsContainedInPlaceHolder(string name, string value)
{
var placeHolder = _placeholderValues.FirstOrDefault(ph => ph.Name == name && ph.Value == value);
placeHolder.ShouldNotBeNull();
_placeholderValues.Count.ShouldBe(1);
}
}
}

View File

@ -0,0 +1,101 @@
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.PathManipulation;
using Ocelot.PathManipulation.Middleware;
using Ocelot.Request.Middleware;
using Ocelot.Responses;
using Ocelot.Values;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamPathManipulation
{
public class ClaimsToDownstreamPathMiddlewareTests
{
private readonly Mock<IChangeDownstreamPathTemplate> _changePath;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private ClaimsToDownstreamPathMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public ClaimsToDownstreamPathMiddlewareTests()
{
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToDownstreamPathMiddleware>()).Returns(_logger.Object);
_next = context => Task.CompletedTask;
_changePath = new Mock<IChangeDownstreamPathTemplate>();
_downstreamContext.DownstreamRequest = new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com"));
_middleware = new ClaimsToDownstreamPathMiddleware(_next, _loggerFactory.Object, _changePath.Object);
}
[Fact]
public void should_call_add_queries_correctly()
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToDownstreamPath(new List<ClaimToThing>
{
new ClaimToThing("UserId", "Subject", "", 0),
})
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheChangeDownstreamPathReturnsOk())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenChangeDownstreamPathIsCalledCorrectly())
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheChangeDownstreamPathReturnsOk()
{
_changePath
.Setup(x => x.ChangeDownstreamPath(
It.IsAny<List<ClaimToThing>>(),
It.IsAny<IEnumerable<Claim>>(),
It.IsAny<DownstreamPathTemplate>(),
It.IsAny<List<PlaceholderNameAndValue>>()))
.Returns(new OkResponse());
}
private void ThenChangeDownstreamPathIsCalledCorrectly()
{
_changePath
.Verify(x => x.ChangeDownstreamPath(
It.IsAny<List<ClaimToThing>>(),
It.IsAny<IEnumerable<Claim>>(),
_downstreamContext.DownstreamReRoute.DownstreamPathTemplate,
_downstreamContext.TemplatePlaceholderNameAndValues), Times.Once);
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
}
}

View File

@ -1,6 +1,6 @@
namespace Ocelot.UnitTests.Eureka
{
using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;

View File

@ -27,7 +27,10 @@
var services = new ServiceCollection();
services.AddSingleton<IDiscoveryClient>(client.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaProviderFactory.Get(sp, config, null);
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("")
.Build();
var provider = EurekaProviderFactory.Get(sp, config, reRoute);
provider.ShouldBeOfType<Eureka>();
}
}

View File

@ -0,0 +1,78 @@
namespace Ocelot.UnitTests.Infrastructure
{
using System;
using Moq;
using Ocelot.Infrastructure;
using Responses;
using Shouldly;
using Microsoft.Extensions.Configuration;
using Xunit;
public class ConfigAwarePlaceholdersTests
{
private readonly IPlaceholders _placeholders;
private readonly Mock<IPlaceholders> _basePlaceholders;
public ConfigAwarePlaceholdersTests()
{
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("appsettings.json");
var configuration = configurationBuilder.Build();
_basePlaceholders = new Mock<IPlaceholders>();
_placeholders = new ConfigAwarePlaceholders(configuration, _basePlaceholders.Object);
}
[Fact]
public void should_return_value_from_underlying_placeholders()
{
var baseUrl = "http://www.bbc.co.uk";
const string key = "{BaseUrl}";
_basePlaceholders.Setup(x => x.Get(key)).Returns(new OkResponse<string>(baseUrl));
var result = _placeholders.Get(key);
result.Data.ShouldBe(baseUrl);
}
[Fact]
public void should_return_value_from_config_with_same_name_as_placeholder_if_underlying_placeholder_not_found()
{
const string expected = "http://foo-bar.co.uk";
var baseUrl = "http://www.bbc.co.uk";
const string key = "{BaseUrl}";
_basePlaceholders.Setup(x => x.Get(key)).Returns(new ErrorResponse<string>(new FakeError()));
var result = _placeholders.Get(key);
result.Data.ShouldBe(expected);
}
[Theory]
[InlineData("{TestConfig}")]
[InlineData("{TestConfigNested:Child}")]
public void should_return_value_from_config(string key)
{
const string expected = "foo";
_basePlaceholders.Setup(x => x.Get(key)).Returns(new ErrorResponse<string>(new FakeError()));
var result = _placeholders.Get(key);
result.Data.ShouldBe(expected);
}
[Fact]
public void should_call_underyling_when_added()
{
const string key = "{Test}";
Func<Response<string>> func = () => new OkResponse<string>("test)");
_placeholders.Add(key, func);
_basePlaceholders.Verify(p => p.Add(key, func), Times.Once);
}
[Fact]
public void should_call_underyling_when_removed()
{
const string key = "{Test}";
_placeholders.Remove(key);
_basePlaceholders.Verify(p => p.Remove(key), Times.Once);
}
}
}

View File

@ -1,12 +1,13 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DependencyInjection;
using Ocelot.Provider.Kubernetes;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -24,10 +25,20 @@ namespace Ocelot.UnitTests.Kubernetes
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_kubernetes()
{

View File

@ -10,8 +10,8 @@ namespace Ocelot.UnitTests.Logging
public class AspDotNetLoggerTests
{
private readonly Mock<ILogger<object>> _coreLogger;
private readonly Mock<IRequestScopedDataRepository> _repo;
private readonly AspDotNetLogger _logger;
private Mock<IRequestScopedDataRepository> _repo;
private readonly string _b;
private readonly string _a;
private readonly Exception _ex;
@ -55,7 +55,7 @@ namespace Ocelot.UnitTests.Logging
{
_logger.LogError($"a message from {_a} to {_b}", _ex);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Error);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura", LogLevel.Error, _ex);
}
[Fact]
@ -63,18 +63,18 @@ namespace Ocelot.UnitTests.Logging
{
_logger.LogCritical($"a message from {_a} to {_b}", _ex);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Critical);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura", LogLevel.Critical, _ex);
}
private void ThenLevelIsLogged(string expected, LogLevel expectedLogLevel)
private void ThenLevelIsLogged(string expected, LogLevel expectedLogLevel, Exception ex = null)
{
_coreLogger.Verify(
x => x.Log(
expectedLogLevel,
It.IsAny<EventId>(),
It.Is<object>(o => o.ToString() == expected),
It.IsAny<Exception>(),
It.IsAny<Func<object, Exception, string>>()), Times.Once);
default(EventId),
expected,
ex,
It.IsAny<Func<string, Exception, string>>()), Times.Once);
}
}
}

View File

@ -4,16 +4,17 @@ using System.Threading.Tasks;
namespace Ocelot.UnitTests.Middleware
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DependencyInjection;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.Middleware.Pipeline;
using Shouldly;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -28,11 +29,22 @@ namespace Ocelot.UnitTests.Middleware
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton<IConfiguration>(_configRoot);
_services.AddOcelot();
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotPiplineBuilderTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_build_generic()
{

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Ocelot.UnitTests</AssemblyName>
<PackageId>Ocelot.UnitTests</PackageId>
<OutputType>Exe</OutputType>
@ -46,13 +46,13 @@
<None Update="idsrv3test.pfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
@ -60,30 +60,38 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="Moq" Version="4.10.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
<PackageReference Include="Moq" Version="4.13.0" />
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4" Version="2.4.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4" Version="3.0.1" />
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
<PackageReference Include="Consul" Version="0.7.2.6" />
<PackageReference Include="CacheManager.Core" Version="1.2.0" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.2.0" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.2.0" />
<PackageReference Include="Polly" Version="7.1.0" />
<PackageReference Include="CacheManager.Core" Version="2.0.0-beta-1629" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="2.0.0-beta-1629" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
<PackageReference Include="Polly" Version="7.1.1" />
<PackageReference Include="Rafty" Version="0.4.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="WebSockets\" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
<PackageReference Include="coverlet.collector" Version="1.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -1,15 +1,16 @@
namespace Ocelot.UnitTests.Rafty
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Administration;
using Ocelot.DependencyInjection;
using Provider.Rafty;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -25,10 +26,20 @@
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotAdministrationBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_rafty()
{

View File

@ -69,7 +69,7 @@ namespace Ocelot.UnitTests.RateLimit
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
.Then(x => x.ThenresponseStatusCodeIs200())
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
.When(x => x.WhenICallTheMiddlewareMultipleTime(3))
.Then(x => x.ThenresponseStatusCodeIs429())
.BDDfy();
}
@ -145,8 +145,9 @@ namespace Ocelot.UnitTests.RateLimit
internal class FakeStream : Stream
{
public override void Flush()
{
throw new System.NotImplementedException();
{
//do nothing
//throw new System.NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)

View File

@ -1,7 +1,6 @@
namespace Ocelot.UnitTests.Request.Mapper
{
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.Extensions.Primitives;
using Ocelot.Request.Mapper;
using Ocelot.Responses;
@ -19,6 +18,7 @@
public class RequestMapperTests
{
private readonly HttpContext _httpContext;
private readonly HttpRequest _inputRequest;
private readonly RequestMapper _requestMapper;
@ -29,8 +29,8 @@
public RequestMapperTests()
{
_inputRequest = new DefaultHttpRequest(new DefaultHttpContext());
_httpContext = new DefaultHttpContext();
_inputRequest = _httpContext.Request;
_requestMapper = new RequestMapper();
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat code coverage">
<Configuration>
<Format>opencover</Format>
<SingleHit>false</SingleHit>
<UseSourceLink>true</UseSourceLink>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
<!-- This is a workaround for an issue with Coverlet.Collector > 1.0.0 (see https://github.com/microsoft/vstest/issues/2205)-->
<InProcDataCollectionRunSettings>
<InProcDataCollectors>
<InProcDataCollector assemblyQualifiedName="Coverlet.Collector.DataCollection.CoverletInProcDataCollector, coverlet.collector, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null"
friendlyName="XPlat Code Coverage"
enabled="True"
codebase="coverlet.collector.dll" />
</InProcDataCollectors>
</InProcDataCollectionRunSettings>
</RunSettings>

View File

@ -20,5 +20,10 @@
"port": 5000,
"hostName": "localhost"
}
},
"BaseUrl": "http://foo-bar.co.uk",
"TestConfig": "foo",
"TestConfigNested":{
"Child": "foo"
}
}