+semver: upgrade to net5.0 (#1390)

* breaking upgrade base build image to net5.0

* add make and build tools to image

* fix code broken after net5.0 upgrade

* fix warnings

* fix tests and line endings

* upgrade dotnet test and coverages packages

* update circle build image

* removed rafty and updated more packages

* bring back develop

* rename authorisation to authorization
This commit is contained in:
Tom Pallister
2020-12-11 09:54:08 +00:00
committed by GitHub
parent c3a0cf1160
commit b74a1197a2
130 changed files with 4766 additions and 6210 deletions

View File

@ -1,101 +1,102 @@
namespace Ocelot.UnitTests.Administration
{
namespace Ocelot.UnitTests.Administration
{
using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Hosting;
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;
public class OcelotAdministrationBuilderTests
{
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private readonly IConfiguration _configRoot;
private IOcelotBuilder _ocelotBuilder;
private Exception _ex;
public OcelotAdministrationBuilderTests()
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_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]
public void should_set_up_administration_with_identity_server_options()
{
Action<IdentityServerAuthenticationOptions> options = o => { };
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpAdministration(options))
.Then(x => ThenAnExceptionIsntThrown())
.Then(x => ThenTheCorrectAdminPathIsRegitered())
.BDDfy();
}
//keep
[Fact]
public void should_set_up_administration()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpAdministration())
.Then(x => ThenAnExceptionIsntThrown())
.Then(x => ThenTheCorrectAdminPathIsRegitered())
.BDDfy();
}
private void WhenISetUpAdministration()
{
_ocelotBuilder.AddAdministration("/administration", "secret");
}
private void WhenISetUpAdministration(Action<IdentityServerAuthenticationOptions> options)
{
_ocelotBuilder.AddAdministration("/administration", options);
}
private void ThenTheCorrectAdminPathIsRegitered()
{
_serviceProvider = _services.BuildServiceProvider();
var path = _serviceProvider.GetService<IAdministrationPath>();
path.Path.ShouldBe("/administration");
}
private void WhenISetUpOcelotServices()
{
try
{
_ocelotBuilder = _services.AddOcelot(_configRoot);
}
catch (Exception e)
{
_ex = e;
}
}
private void ThenAnExceptionIsntThrown()
{
_ex.ShouldBeNull();
}
}
}
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Hosting;
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;
public class OcelotAdministrationBuilderTests
{
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private readonly IConfiguration _configRoot;
private IOcelotBuilder _ocelotBuilder;
private Exception _ex;
public OcelotAdministrationBuilderTests()
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_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]
public void should_set_up_administration_with_identity_server_options()
{
Action<JwtBearerOptions> options = o => { };
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpAdministration(options))
.Then(x => ThenAnExceptionIsntThrown())
.Then(x => ThenTheCorrectAdminPathIsRegitered())
.BDDfy();
}
//keep
[Fact]
public void should_set_up_administration()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpAdministration())
.Then(x => ThenAnExceptionIsntThrown())
.Then(x => ThenTheCorrectAdminPathIsRegitered())
.BDDfy();
}
private void WhenISetUpAdministration()
{
_ocelotBuilder.AddAdministration("/administration", "secret");
}
private void WhenISetUpAdministration(Action<JwtBearerOptions> options)
{
_ocelotBuilder.AddAdministration("/administration", options);
}
private void ThenTheCorrectAdminPathIsRegitered()
{
_serviceProvider = _services.BuildServiceProvider();
var path = _serviceProvider.GetService<IAdministrationPath>();
path.Path.ShouldBe("/administration");
}
private void WhenISetUpOcelotServices()
{
try
{
_ocelotBuilder = _services.AddOcelot(_configRoot);
}
catch (Exception e)
{
_ex = e;
}
}
private void ThenAnExceptionIsntThrown()
{
_ex.ShouldBeNull();
}
}
}

View File

@ -3,8 +3,8 @@ namespace Ocelot.UnitTests.Authorization
{
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Authorisation;
using Ocelot.Authorisation.Middleware;
using Ocelot.Authorization;
using Ocelot.Authorization.Middleware;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder.Middleware;
@ -18,35 +18,35 @@ namespace Ocelot.UnitTests.Authorization
using TestStack.BDDfy;
using Xunit;
public class AuthorisationMiddlewareTests
public class AuthorizationMiddlewareTests
{
private readonly Mock<IClaimsAuthoriser> _authService;
private readonly Mock<IScopesAuthoriser> _authScopesService;
private readonly Mock<IClaimsAuthorizer> _authService;
private readonly Mock<IScopesAuthorizer> _authScopesService;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly AuthorisationMiddleware _middleware;
private readonly AuthorizationMiddleware _middleware;
private RequestDelegate _next;
private HttpContext _httpContext;
public AuthorisationMiddlewareTests()
public AuthorizationMiddlewareTests()
{
_httpContext = new DefaultHttpContext();
_authService = new Mock<IClaimsAuthoriser>();
_authScopesService = new Mock<IScopesAuthoriser>();
_authService = new Mock<IClaimsAuthorizer>();
_authScopesService = new Mock<IScopesAuthorizer>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
_loggerFactory.Setup(x => x.CreateLogger<AuthorizationMiddleware>()).Returns(_logger.Object);
_next = context => Task.CompletedTask;
_middleware = new AuthorisationMiddleware(_next, _authService.Object, _authScopesService.Object, _loggerFactory.Object);
_middleware = new AuthorizationMiddleware(_next, _authService.Object, _authScopesService.Object, _loggerFactory.Object);
}
[Fact]
public void should_call_authorisation_service()
public void should_call_authorization_service()
{
this.Given(x => x.GivenTheDownStreamRouteIs(new List<PlaceholderNameAndValue>(),
new DownstreamRouteBuilder()
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().Build())
.WithIsAuthorised(true)
.WithIsAuthorized(true)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()))
.And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
@ -69,7 +69,7 @@ namespace Ocelot.UnitTests.Authorization
private void GivenTheAuthServiceReturns(Response<bool> expected)
{
_authService
.Setup(x => x.Authorise(
.Setup(x => x.Authorize(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<Dictionary<string, string>>(),
It.IsAny<List<PlaceholderNameAndValue>>()))
@ -79,7 +79,7 @@ namespace Ocelot.UnitTests.Authorization
private void ThenTheAuthServiceIsCalledCorrectly()
{
_authService
.Verify(x => x.Authorise(
.Verify(x => x.Authorize(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<Dictionary<string, string>>(),
It.IsAny<List<PlaceholderNameAndValue>>())

View File

@ -1,4 +1,4 @@
using Ocelot.Authorisation;
using Ocelot.Authorization;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Responses;
using Shouldly;
@ -11,21 +11,21 @@ namespace Ocelot.UnitTests.Authorization
{
using Ocelot.Infrastructure.Claims.Parser;
public class ClaimsAuthoriserTests
public class ClaimsAuthorizerTests
{
private readonly ClaimsAuthoriser _claimsAuthoriser;
private readonly ClaimsAuthorizer _claimsAuthorizer;
private ClaimsPrincipal _claimsPrincipal;
private Dictionary<string, string> _requirement;
private List<PlaceholderNameAndValue> _urlPathPlaceholderNameAndValues;
private Response<bool> _result;
public ClaimsAuthoriserTests()
public ClaimsAuthorizerTests()
{
_claimsAuthoriser = new ClaimsAuthoriser(new ClaimsParser());
_claimsAuthorizer = new ClaimsAuthorizer(new ClaimsParser());
}
[Fact]
public void should_authorise_user()
public void should_authorize_user()
{
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
@ -35,8 +35,8 @@ namespace Ocelot.UnitTests.Authorization
{
{"UserType", "registered"}
}))
.When(x => x.WhenICallTheAuthoriser())
.Then(x => x.ThenTheUserIsAuthorised())
.When(x => x.WhenICallTheAuthorizer())
.Then(x => x.ThenTheUserIsAuthorized())
.BDDfy();
}
@ -55,8 +55,8 @@ namespace Ocelot.UnitTests.Authorization
{
new PlaceholderNameAndValue("{userId}", "14")
}))
.When(x => x.WhenICallTheAuthoriser())
.Then(x => x.ThenTheUserIsAuthorised())
.When(x => x.WhenICallTheAuthorizer())
.Then(x => x.ThenTheUserIsAuthorized())
.BDDfy();
}
@ -75,13 +75,13 @@ namespace Ocelot.UnitTests.Authorization
{
new PlaceholderNameAndValue("{userId}", "14")
}))
.When(x => x.WhenICallTheAuthoriser())
.Then(x => x.ThenTheUserIsntAuthorised())
.When(x => x.WhenICallTheAuthorizer())
.Then(x => x.ThenTheUserIsntAuthorized())
.BDDfy();
}
}
[Fact]
public void should_authorise_user_multiple_claims_of_same_type()
public void should_authorize_user_multiple_claims_of_same_type()
{
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
@ -92,21 +92,21 @@ namespace Ocelot.UnitTests.Authorization
{
{"UserType", "registered"}
}))
.When(x => x.WhenICallTheAuthoriser())
.Then(x => x.ThenTheUserIsAuthorised())
.When(x => x.WhenICallTheAuthorizer())
.Then(x => x.ThenTheUserIsAuthorized())
.BDDfy();
}
[Fact]
public void should_not_authorise_user()
public void should_not_authorize_user()
{
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>()))))
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
{
{ "UserType", "registered" }
}))
.When(x => x.WhenICallTheAuthoriser())
.Then(x => x.ThenTheUserIsntAuthorised())
.When(x => x.WhenICallTheAuthorizer())
.Then(x => x.ThenTheUserIsntAuthorized())
.BDDfy();
}
@ -125,19 +125,19 @@ namespace Ocelot.UnitTests.Authorization
_urlPathPlaceholderNameAndValues = urlPathPlaceholderNameAndValues;
}
private void WhenICallTheAuthoriser()
private void WhenICallTheAuthorizer()
{
_result = _claimsAuthoriser.Authorise(_claimsPrincipal, _requirement, _urlPathPlaceholderNameAndValues);
_result = _claimsAuthorizer.Authorize(_claimsPrincipal, _requirement, _urlPathPlaceholderNameAndValues);
}
private void ThenTheUserIsAuthorised()
private void ThenTheUserIsAuthorized()
{
_result.Data.ShouldBe(true);
}
private void ThenTheUserIsntAuthorised()
private void ThenTheUserIsntAuthorized()
{
_result.Data.ShouldBe(false);
}
}
}
}

View File

@ -46,7 +46,7 @@ namespace Ocelot.UnitTests.Configuration
var expected = new RouteOptionsBuilder()
.WithIsAuthenticated(true)
.WithIsAuthorised(true)
.WithIsAuthorized(true)
.WithIsCached(true)
.WithRateLimiting(true)
.WithUseServiceDiscovery(true)
@ -71,7 +71,7 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheFollowingIsReturned(RouteOptions expected)
{
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
_result.IsAuthorized.ShouldBe(expected.IsAuthorized);
_result.IsCached.ShouldBe(expected.IsCached);
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
_result.UseServiceDiscovery.ShouldBe(expected.UseServiceDiscovery);

View File

@ -218,7 +218,7 @@
{
_result[routeIndex].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_expectedVersion);
_result[routeIndex].DownstreamRoute[0].IsAuthenticated.ShouldBe(_rro.IsAuthenticated);
_result[routeIndex].DownstreamRoute[0].IsAuthorised.ShouldBe(_rro.IsAuthorised);
_result[routeIndex].DownstreamRoute[0].IsAuthorized.ShouldBe(_rro.IsAuthorized);
_result[routeIndex].DownstreamRoute[0].IsCached.ShouldBe(_rro.IsCached);
_result[routeIndex].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBe(_rro.EnableRateLimiting);
_result[routeIndex].DownstreamRoute[0].RequestIdKey.ShouldBe(_requestId);

View File

@ -87,7 +87,7 @@
Address = "localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
Tags = new string[0],
},
};
@ -95,7 +95,7 @@
.And(_ => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
.When(_ => WhenIGetTheServices())
.Then(_ => ThenTheCountIs(1))
.And(_ => _receivedToken.ShouldBe(token))
.And(_ => ThenTheTokenIs(token))
.BDDfy();
}
@ -253,6 +253,11 @@
_services = _provider.Get().GetAwaiter().GetResult();
}
private void ThenTheTokenIs(string token)
{
_receivedToken.ShouldBe(token);
}
private void GivenTheServicesAreRegisteredWithConsul(params ServiceEntry[] serviceEntries)
{
foreach (var serviceEntry in serviceEntries)

View File

@ -6,10 +6,10 @@
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Repository;
using Provider.Eureka;
using Responses;
using Ocelot.Provider.Eureka;
using Ocelot.Responses;
using Shouldly;
using Steeltoe.Common.Discovery;
using Steeltoe.Discovery;
using System.Threading.Tasks;
using Xunit;
@ -25,7 +25,7 @@
services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaMiddlewareConfigurationProvider.Get(new ApplicationBuilder(sp));
provider.ShouldBeOfType<Task>();
provider.Status.ShouldBe(TaskStatus.RanToCompletion);
}
[Fact]
@ -41,7 +41,7 @@
services.AddSingleton<IDiscoveryClient>(client.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaMiddlewareConfigurationProvider.Get(new ApplicationBuilder(sp));
provider.ShouldBeOfType<Task>();
provider.Status.ShouldBe(TaskStatus.RanToCompletion);
}
}
}

View File

@ -5,7 +5,7 @@
using Ocelot.Configuration.Builder;
using Provider.Eureka;
using Shouldly;
using Steeltoe.Common.Discovery;
using Steeltoe.Discovery;
using Xunit;
public class EurekaProviderFactoryTests

View File

@ -1,117 +1,118 @@
namespace Ocelot.UnitTests.Eureka
{
using Moq;
using Provider.Eureka;
using Shouldly;
namespace Ocelot.UnitTests.Eureka
{
using Moq;
using Ocelot.Provider.Eureka;
using Shouldly;
using Steeltoe.Common.Discovery;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Values;
using Xunit;
public class EurekaServiceDiscoveryProviderTests
{
private readonly Eureka _provider;
private readonly Mock<IDiscoveryClient> _client;
private readonly string _serviceId;
private List<IServiceInstance> _instances;
private List<Service> _result;
public EurekaServiceDiscoveryProviderTests()
{
_serviceId = "Laura";
_client = new Mock<IDiscoveryClient>();
_provider = new Eureka(_serviceId, _client.Object);
}
[Fact]
public void should_return_empty_services()
{
this.When(_ => WhenIGet())
.Then(_ => ThenTheCountIs(0))
.BDDfy();
}
[Fact]
public void should_return_service_from_client()
{
var instances = new List<IServiceInstance>
{
new EurekaService(_serviceId, "somehost", 801, false, new Uri("http://somehost:801"), new Dictionary<string, string>())
};
this.Given(_ => GivenThe(instances))
.When(_ => WhenIGet())
.Then(_ => ThenTheCountIs(1))
.And(_ => ThenTheClientIsCalledCorrectly())
.And(_ => ThenTheServiceIsMapped())
.BDDfy();
}
[Fact]
public void should_return_services_from_client()
{
var instances = new List<IServiceInstance>
{
new EurekaService(_serviceId, "somehost", 801, false, new Uri("http://somehost:801"), new Dictionary<string, string>()),
new EurekaService(_serviceId, "somehost", 801, false, new Uri("http://somehost:801"), new Dictionary<string, string>())
};
this.Given(_ => GivenThe(instances))
.When(_ => WhenIGet())
.Then(_ => ThenTheCountIs(2))
.And(_ => ThenTheClientIsCalledCorrectly())
.BDDfy();
}
private void ThenTheServiceIsMapped()
{
_result[0].HostAndPort.DownstreamHost.ShouldBe("somehost");
_result[0].HostAndPort.DownstreamPort.ShouldBe(801);
_result[0].Name.ShouldBe(_serviceId);
}
private void ThenTheCountIs(int expected)
{
_result.Count.ShouldBe(expected);
}
private void ThenTheClientIsCalledCorrectly()
{
_client.Verify(x => x.GetInstances(_serviceId), Times.Once);
}
private async Task WhenIGet()
{
_result = await _provider.Get();
}
private void GivenThe(List<IServiceInstance> instances)
{
_instances = instances;
_client.Setup(x => x.GetInstances(It.IsAny<string>())).Returns(instances);
}
}
public class EurekaService : IServiceInstance
{
public EurekaService(string serviceId, string host, int port, bool isSecure, Uri uri, IDictionary<string, string> metadata)
{
ServiceId = serviceId;
Host = host;
Port = port;
IsSecure = isSecure;
Uri = uri;
Metadata = metadata;
}
public string ServiceId { get; }
public string Host { get; }
public int Port { get; }
public bool IsSecure { get; }
public Uri Uri { get; }
public IDictionary<string, string> Metadata { get; }
}
}
using Steeltoe.Discovery;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Ocelot.Values;
using Xunit;
public class EurekaServiceDiscoveryProviderTests
{
private readonly Eureka _provider;
private readonly Mock<IDiscoveryClient> _client;
private readonly string _serviceId;
private List<IServiceInstance> _instances;
private List<Service> _result;
public EurekaServiceDiscoveryProviderTests()
{
_serviceId = "Laura";
_client = new Mock<IDiscoveryClient>();
_provider = new Eureka(_serviceId, _client.Object);
}
[Fact]
public void should_return_empty_services()
{
this.When(_ => WhenIGet())
.Then(_ => ThenTheCountIs(0))
.BDDfy();
}
[Fact]
public void should_return_service_from_client()
{
var instances = new List<IServiceInstance>
{
new EurekaService(_serviceId, "somehost", 801, false, new Uri("http://somehost:801"), new Dictionary<string, string>())
};
this.Given(_ => GivenThe(instances))
.When(_ => WhenIGet())
.Then(_ => ThenTheCountIs(1))
.And(_ => ThenTheClientIsCalledCorrectly())
.And(_ => ThenTheServiceIsMapped())
.BDDfy();
}
[Fact]
public void should_return_services_from_client()
{
var instances = new List<IServiceInstance>
{
new EurekaService(_serviceId, "somehost", 801, false, new Uri("http://somehost:801"), new Dictionary<string, string>()),
new EurekaService(_serviceId, "somehost", 801, false, new Uri("http://somehost:801"), new Dictionary<string, string>())
};
this.Given(_ => GivenThe(instances))
.When(_ => WhenIGet())
.Then(_ => ThenTheCountIs(2))
.And(_ => ThenTheClientIsCalledCorrectly())
.BDDfy();
}
private void ThenTheServiceIsMapped()
{
_result[0].HostAndPort.DownstreamHost.ShouldBe("somehost");
_result[0].HostAndPort.DownstreamPort.ShouldBe(801);
_result[0].Name.ShouldBe(_serviceId);
}
private void ThenTheCountIs(int expected)
{
_result.Count.ShouldBe(expected);
}
private void ThenTheClientIsCalledCorrectly()
{
_client.Verify(x => x.GetInstances(_serviceId), Times.Once);
}
private async Task WhenIGet()
{
_result = await _provider.Get();
}
private void GivenThe(List<IServiceInstance> instances)
{
_instances = instances;
_client.Setup(x => x.GetInstances(It.IsAny<string>())).Returns(instances);
}
}
public class EurekaService : IServiceInstance
{
public EurekaService(string serviceId, string host, int port, bool isSecure, Uri uri, IDictionary<string, string> metadata)
{
ServiceId = serviceId;
Host = host;
Port = port;
IsSecure = isSecure;
Uri = uri;
Metadata = metadata;
}
public string ServiceId { get; }
public string Host { get; }
public int Port { get; }
public bool IsSecure { get; }
public Uri Uri { get; }
public IDictionary<string, string> Metadata { get; }
}
}

View File

@ -1,128 +1,129 @@
namespace Ocelot.UnitTests.Headers
{
namespace Ocelot.UnitTests.Headers
{
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Configuration.Creator;
using Ocelot.Headers;
using Ocelot.Infrastructure;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.Logging;
using Responder;
using Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class AddHeadersToRequestPlainTests
{
private readonly AddHeadersToRequest _addHeadersToRequest;
private HttpContext _context;
private AddHeader _addedHeader;
private readonly Mock<IPlaceholders> _placeholders;
private Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
public AddHeadersToRequestPlainTests()
{
_placeholders = new Mock<IPlaceholders>();
_factory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<AddHeadersToRequest>()).Returns(_logger.Object);
_addHeadersToRequest = new AddHeadersToRequest(Mock.Of<IClaimsParser>(), _placeholders.Object, _factory.Object);
}
[Fact]
public void should_log_error_if_cannot_find_placeholder()
{
_placeholders.Setup(x => x.Get(It.IsAny<string>())).Returns(new ErrorResponse<string>(new AnyError()));
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Forwarded-For", "{RemoteIdAddress}"))
.Then(_ => ThenAnErrorIsLogged("X-Forwarded-For", "{RemoteIdAddress}"))
.BDDfy();
}
[Fact]
public void should_add_placeholder_to_downstream_request()
{
_placeholders.Setup(x => x.Get(It.IsAny<string>())).Returns(new OkResponse<string>("replaced"));
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Forwarded-For", "{RemoteIdAddress}"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders("replaced"))
.BDDfy();
}
[Fact]
public void should_add_plain_text_header_to_downstream_request()
{
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Custom-Header", "PlainValue"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders())
.BDDfy();
}
[Fact]
public void should_overwrite_existing_header_with_added_header()
{
this.Given(_ => GivenHttpRequestWithHeader("X-Custom-Header", "This should get overwritten"))
.When(_ => WhenAddingHeader("X-Custom-Header", "PlainValue"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders())
.BDDfy();
}
private void ThenAnErrorIsLogged(string key, string value)
{
_logger.Verify(x => x.LogWarning($"Unable to add header to response {key}: {value}"), Times.Once);
}
private void GivenHttpRequestWithoutHeaders()
{
_context = new DefaultHttpContext
{
Request =
{
Headers =
{
}
}
};
}
private void GivenHttpRequestWithHeader(string headerKey, string headerValue)
{
_context = new DefaultHttpContext
{
Request =
{
Headers =
{
{ headerKey, headerValue }
}
}
};
}
private void WhenAddingHeader(string headerKey, string headerValue)
{
_addedHeader = new AddHeader(headerKey, headerValue);
_addHeadersToRequest.SetHeadersOnDownstreamRequest(new[] { _addedHeader }, _context);
}
private void ThenTheHeaderGetsTakenOverToTheRequestHeaders()
{
var requestHeaders = _context.Request.Headers;
requestHeaders.ContainsKey(_addedHeader.Key).ShouldBeTrue($"Header {_addedHeader.Key} was expected but not there.");
var value = requestHeaders[_addedHeader.Key];
value.ShouldNotBeNull($"Value of header {_addedHeader.Key} was expected to not be null.");
value.ToString().ShouldBe(_addedHeader.Value);
}
private void ThenTheHeaderGetsTakenOverToTheRequestHeaders(string expected)
{
var requestHeaders = _context.Request.Headers;
var value = requestHeaders[_addedHeader.Key];
value.ToString().ShouldBe(expected);
}
}
}
using Microsoft.Extensions.Primitives;
using Moq;
using Ocelot.Configuration.Creator;
using Ocelot.Headers;
using Ocelot.Infrastructure;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.Logging;
using Responder;
using Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class AddHeadersToRequestPlainTests
{
private readonly AddHeadersToRequest _addHeadersToRequest;
private HttpContext _context;
private AddHeader _addedHeader;
private readonly Mock<IPlaceholders> _placeholders;
private Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
public AddHeadersToRequestPlainTests()
{
_placeholders = new Mock<IPlaceholders>();
_factory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<AddHeadersToRequest>()).Returns(_logger.Object);
_addHeadersToRequest = new AddHeadersToRequest(Mock.Of<IClaimsParser>(), _placeholders.Object, _factory.Object);
}
[Fact]
public void should_log_error_if_cannot_find_placeholder()
{
_placeholders.Setup(x => x.Get(It.IsAny<string>())).Returns(new ErrorResponse<string>(new AnyError()));
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Forwarded-For", "{RemoteIdAddress}"))
.Then(_ => ThenAnErrorIsLogged("X-Forwarded-For", "{RemoteIdAddress}"))
.BDDfy();
}
[Fact]
public void should_add_placeholder_to_downstream_request()
{
_placeholders.Setup(x => x.Get(It.IsAny<string>())).Returns(new OkResponse<string>("replaced"));
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Forwarded-For", "{RemoteIdAddress}"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders("replaced"))
.BDDfy();
}
[Fact]
public void should_add_plain_text_header_to_downstream_request()
{
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Custom-Header", "PlainValue"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders())
.BDDfy();
}
[Fact]
public void should_overwrite_existing_header_with_added_header()
{
this.Given(_ => GivenHttpRequestWithHeader("X-Custom-Header", "This should get overwritten"))
.When(_ => WhenAddingHeader("X-Custom-Header", "PlainValue"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders())
.BDDfy();
}
private void ThenAnErrorIsLogged(string key, string value)
{
_logger.Verify(x => x.LogWarning($"Unable to add header to response {key}: {value}"), Times.Once);
}
private void GivenHttpRequestWithoutHeaders()
{
_context = new DefaultHttpContext
{
Request =
{
Headers =
{
}
}
};
}
private void GivenHttpRequestWithHeader(string headerKey, string headerValue)
{
_context = new DefaultHttpContext
{
Request =
{
Headers =
{
{ headerKey, headerValue }
}
}
};
}
private void WhenAddingHeader(string headerKey, string headerValue)
{
_addedHeader = new AddHeader(headerKey, headerValue);
_addHeadersToRequest.SetHeadersOnDownstreamRequest(new[] { _addedHeader }, _context);
}
private void ThenTheHeaderGetsTakenOverToTheRequestHeaders()
{
var requestHeaders = _context.Request.Headers;
requestHeaders.ContainsKey(_addedHeader.Key).ShouldBeTrue($"Header {_addedHeader.Key} was expected but not there.");
var value = requestHeaders[_addedHeader.Key];
value.ShouldNotBe(default(StringValues), $"Value of header {_addedHeader.Key} was expected to not be null.");
value.ToString().ShouldBe(_addedHeader.Value);
}
private void ThenTheHeaderGetsTakenOverToTheRequestHeaders(string expected)
{
var requestHeaders = _context.Request.Headers;
var value = requestHeaders[_addedHeader.Key];
value.ToString().ShouldBe(expected);
}
}
}

View File

@ -2,7 +2,7 @@ namespace Ocelot.UnitTests.Headers
{
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Authorisation.Middleware;
using Ocelot.Authorization.Middleware;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
@ -38,7 +38,7 @@ namespace Ocelot.UnitTests.Headers
_postReplacer = new Mock<IHttpResponseHeaderReplacer>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
_loggerFactory.Setup(x => x.CreateLogger<AuthorizationMiddleware>()).Returns(_logger.Object);
_next = context => Task.CompletedTask;
_addHeadersToResponse = new Mock<IAddHeadersToResponse>();
_addHeadersToRequest = new Mock<IAddHeadersToRequest>();

View File

@ -1,88 +1,88 @@
using Microsoft.AspNetCore.Http;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Infrastructure
{
public class HttpDataRepositoryTests
{
private readonly HttpContext _httpContext;
private IHttpContextAccessor _httpContextAccessor;
private readonly HttpDataRepository _httpDataRepository;
private object _result;
public HttpDataRepositoryTests()
{
_httpContext = new DefaultHttpContext();
_httpContextAccessor = new HttpContextAccessor { HttpContext = _httpContext };
_httpDataRepository = new HttpDataRepository(_httpContextAccessor);
}
/*
TODO - Additional tests -> Type mistmatch aka Add string, request int
TODO - Additional tests -> HttpContent null. This should never happen
*/
[Fact]
public void get_returns_correct_key_from_http_context()
{
this.Given(x => x.GivenAHttpContextContaining("key", "string"))
.When(x => x.GetIsCalledWithKey<string>("key"))
.Then(x => x.ThenTheResultIsAnOkResponse<string>("string"))
.BDDfy();
}
[Fact]
public void get_returns_error_response_if_the_key_is_not_found() //Therefore does not return null
{
this.Given(x => x.GivenAHttpContextContaining("key", "string"))
.When(x => x.GetIsCalledWithKey<string>("keyDoesNotExist"))
.Then(x => x.ThenTheResultIsAnErrorReposnse<string>("string1"))
.BDDfy();
}
[Fact]
public void should_update()
{
this.Given(x => x.GivenAHttpContextContaining("key", "string"))
.And(x => x.UpdateIsCalledWith<string>("key", "new string"))
.When(x => x.GetIsCalledWithKey<string>("key"))
.Then(x => x.ThenTheResultIsAnOkResponse<string>("new string"))
.BDDfy();
}
private void UpdateIsCalledWith<T>(string key, string value)
{
_httpDataRepository.Update(key, value);
}
private void GivenAHttpContextContaining(string key, object o)
{
_httpContext.Items.Add(key, o);
}
private void GetIsCalledWithKey<T>(string key)
{
_result = _httpDataRepository.Get<T>(key);
}
private void ThenTheResultIsAnErrorReposnse<T>(object resultValue)
{
_result.ShouldBeOfType<ErrorResponse<T>>();
((ErrorResponse<T>)_result).Data.ShouldBeNull();
((ErrorResponse<T>)_result).IsError.ShouldBe(true);
((ErrorResponse<T>)_result).Errors.ShouldHaveSingleItem()
.ShouldBeOfType<CannotFindDataError>()
.Message.ShouldStartWith("Unable to find data for key: ");
}
private void ThenTheResultIsAnOkResponse<T>(object resultValue)
{
_result.ShouldBeOfType<OkResponse<T>>();
((OkResponse<T>)_result).Data.ShouldBe(resultValue);
}
}
using Microsoft.AspNetCore.Http;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Infrastructure
{
public class HttpDataRepositoryTests
{
private readonly HttpContext _httpContext;
private IHttpContextAccessor _httpContextAccessor;
private readonly HttpDataRepository _httpDataRepository;
private object _result;
public HttpDataRepositoryTests()
{
_httpContext = new DefaultHttpContext();
_httpContextAccessor = new HttpContextAccessor { HttpContext = _httpContext };
_httpDataRepository = new HttpDataRepository(_httpContextAccessor);
}
/*
TODO - Additional tests -> Type mistmatch aka Add string, request int
TODO - Additional tests -> HttpContent null. This should never happen
*/
[Fact]
public void get_returns_correct_key_from_http_context()
{
this.Given(x => x.GivenAHttpContextContaining("key", "string"))
.When(x => x.GetIsCalledWithKey<string>("key"))
.Then(x => x.ThenTheResultIsAnOkResponse<string>("string"))
.BDDfy();
}
[Fact]
public void get_returns_error_response_if_the_key_is_not_found() //Therefore does not return null
{
this.Given(x => x.GivenAHttpContextContaining("key", "string"))
.When(x => x.GetIsCalledWithKey<string>("keyDoesNotExist"))
.Then(x => x.ThenTheResultIsAnErrorReposnse<string>("string1"))
.BDDfy();
}
[Fact]
public void should_update()
{
this.Given(x => x.GivenAHttpContextContaining("key", "string"))
.And(x => x.UpdateIsCalledWith<string>("key", "new string"))
.When(x => x.GetIsCalledWithKey<string>("key"))
.Then(x => x.ThenTheResultIsAnOkResponse<string>("new string"))
.BDDfy();
}
private void UpdateIsCalledWith<T>(string key, string value)
{
_httpDataRepository.Update(key, value);
}
private void GivenAHttpContextContaining(string key, object o)
{
_httpContext.Items.Add(key, o);
}
private void GetIsCalledWithKey<T>(string key)
{
_result = _httpDataRepository.Get<T>(key);
}
private void ThenTheResultIsAnErrorReposnse<T>(object resultValue)
{
_result.ShouldBeOfType<ErrorResponse<T>>();
((ErrorResponse<T>)_result).Data.ShouldBe(default(T));
((ErrorResponse<T>)_result).IsError.ShouldBe(true);
((ErrorResponse<T>)_result).Errors.ShouldHaveSingleItem()
.ShouldBeOfType<CannotFindDataError>()
.Message.ShouldStartWith("Unable to find data for key: ");
}
private void ThenTheResultIsAnOkResponse<T>(object resultValue)
{
_result.ShouldBeOfType<OkResponse<T>>();
((OkResponse<T>)_result).Data.ShouldBe(resultValue);
}
}
}

View File

@ -1,5 +1,5 @@
using Moq;
using Ocelot.Authorisation;
using Ocelot.Authorization;
using Ocelot.Errors;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.Responses;
@ -11,18 +11,18 @@ using Xunit;
namespace Ocelot.UnitTests.Infrastructure
{
public class ScopesAuthoriserTests
public class ScopesAuthorizerTests
{
private ScopesAuthoriser _authoriser;
private ScopesAuthorizer _authorizer;
public Mock<IClaimsParser> _parser;
private ClaimsPrincipal _principal;
private List<string> _allowedScopes;
private Response<bool> _result;
public ScopesAuthoriserTests()
public ScopesAuthorizerTests()
{
_parser = new Mock<IClaimsParser>();
_authoriser = new ScopesAuthoriser(_parser.Object);
_authorizer = new ScopesAuthorizer(_parser.Object);
}
[Fact]
@ -30,7 +30,7 @@ namespace Ocelot.UnitTests.Infrastructure
{
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
.And(_ => GivenTheFollowing(new List<string>()))
.When(_ => WhenIAuthorise())
.When(_ => WhenIAuthorize())
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
.BDDfy();
}
@ -40,7 +40,7 @@ namespace Ocelot.UnitTests.Infrastructure
{
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
.And(_ => GivenTheFollowing((List<string>)null))
.When(_ => WhenIAuthorise())
.When(_ => WhenIAuthorize())
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
.BDDfy();
}
@ -52,7 +52,7 @@ namespace Ocelot.UnitTests.Infrastructure
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
.And(_ => GivenTheParserReturns(new ErrorResponse<List<string>>(fakeError)))
.And(_ => GivenTheFollowing(new List<string>() { "doesntmatter" }))
.When(_ => WhenIAuthorise())
.When(_ => WhenIAuthorize())
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
.BDDfy();
}
@ -66,7 +66,7 @@ namespace Ocelot.UnitTests.Infrastructure
this.Given(_ => GivenTheFollowing(claimsPrincipal))
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(allowedScopes)))
.And(_ => GivenTheFollowing(allowedScopes))
.When(_ => WhenIAuthorise())
.When(_ => WhenIAuthorize())
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
.BDDfy();
}
@ -82,7 +82,7 @@ namespace Ocelot.UnitTests.Infrastructure
this.Given(_ => GivenTheFollowing(claimsPrincipal))
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(userScopes)))
.And(_ => GivenTheFollowing(allowedScopes))
.When(_ => WhenIAuthorise())
.When(_ => WhenIAuthorize())
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
.BDDfy();
}
@ -102,9 +102,9 @@ namespace Ocelot.UnitTests.Infrastructure
_allowedScopes = allowedScopes;
}
private void WhenIAuthorise()
private void WhenIAuthorize()
{
_result = _authoriser.Authorise(_principal, _allowedScopes);
_result = _authorizer.Authorize(_principal, _allowedScopes);
}
private void ThenTheFollowingIsReturned(Response<bool> expected)

View File

@ -1,149 +1,154 @@
using KubeClient;
using KubeClient.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Moq;
using Newtonsoft.Json;
using Ocelot.Logging;
using Ocelot.Provider.Kubernetes;
using Ocelot.Values;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Kubernetes
{
public class KubeServiceDiscoveryProviderTests : IDisposable
{
private IWebHost _fakeKubeBuilder;
private readonly KubernetesServiceDiscoveryProvider _provider;
private EndpointsV1 _endpointEntries;
private readonly string _serviceName;
private readonly string _namespaces;
private readonly int _port;
private readonly string _kubeHost;
private readonly string _fakekubeServiceDiscoveryUrl;
private List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
private string _receivedToken;
private readonly IKubeApiClient _clientFactory;
public KubeServiceDiscoveryProviderTests()
{
_serviceName = "test";
_namespaces = "dev";
_port = 86;
_kubeHost = "localhost";
_fakekubeServiceDiscoveryUrl = $"http://{_kubeHost}:{_port}";
_endpointEntries = new EndpointsV1();
_factory = new Mock<IOcelotLoggerFactory>();
var option = new KubeClientOptions
{
ApiEndPoint = new Uri(_fakekubeServiceDiscoveryUrl),
AccessToken = "txpc696iUhbVoudg164r93CxDTrKRVWG",
AuthStrategy = KubeClient.KubeAuthStrategy.BearerToken,
AllowInsecure = true,
};
_clientFactory = KubeApiClient.Create(option);
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<KubernetesServiceDiscoveryProvider>()).Returns(_logger.Object);
var config = new KubeRegistryConfiguration()
{
KeyOfServiceInK8s = _serviceName,
KubeNamespace = _namespaces,
};
_provider = new KubernetesServiceDiscoveryProvider(config, _factory.Object, _clientFactory);
using KubeClient;
using KubeClient.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Moq;
using Newtonsoft.Json;
using Ocelot.Logging;
using Ocelot.Provider.Kubernetes;
using Ocelot.Values;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Kubernetes
{
public class KubeServiceDiscoveryProviderTests : IDisposable
{
private IWebHost _fakeKubeBuilder;
private readonly KubernetesServiceDiscoveryProvider _provider;
private EndpointsV1 _endpointEntries;
private readonly string _serviceName;
private readonly string _namespaces;
private readonly int _port;
private readonly string _kubeHost;
private readonly string _fakekubeServiceDiscoveryUrl;
private List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
private string _receivedToken;
private readonly IKubeApiClient _clientFactory;
public KubeServiceDiscoveryProviderTests()
{
_serviceName = "test";
_namespaces = "dev";
_port = 86;
_kubeHost = "localhost";
_fakekubeServiceDiscoveryUrl = $"http://{_kubeHost}:{_port}";
_endpointEntries = new EndpointsV1();
_factory = new Mock<IOcelotLoggerFactory>();
var option = new KubeClientOptions
{
ApiEndPoint = new Uri(_fakekubeServiceDiscoveryUrl),
AccessToken = "txpc696iUhbVoudg164r93CxDTrKRVWG",
AuthStrategy = KubeClient.KubeAuthStrategy.BearerToken,
AllowInsecure = true,
};
_clientFactory = KubeApiClient.Create(option);
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<KubernetesServiceDiscoveryProvider>()).Returns(_logger.Object);
var config = new KubeRegistryConfiguration()
{
KeyOfServiceInK8s = _serviceName,
KubeNamespace = _namespaces,
};
_provider = new KubernetesServiceDiscoveryProvider(config, _factory.Object, _clientFactory);
}
[Fact]
public void should_return_service_from_k8s()
{
var token = "Bearer txpc696iUhbVoudg164r93CxDTrKRVWG";
var endPointEntryOne = new EndpointsV1
{
Kind = "endpoint",
ApiVersion = "1.0",
Metadata = new ObjectMetaV1()
{
Namespace = "dev",
},
};
var endpointSubsetV1 = new EndpointSubsetV1();
endpointSubsetV1.Addresses.Add(new EndpointAddressV1()
{
Ip = "127.0.0.1",
Hostname = "localhost",
});
endpointSubsetV1.Ports.Add(new EndpointPortV1()
{
Port = 80,
});
endPointEntryOne.Subsets.Add(endpointSubsetV1);
this.Given(x => GivenThereIsAFakeKubeServiceDiscoveryProvider(_fakekubeServiceDiscoveryUrl, _serviceName, _namespaces))
.And(x => GivenTheServicesAreRegisteredWithKube(endPointEntryOne))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(1))
.And(_ => ThenTheTokenIs(token))
.BDDfy();
}
[Fact]
public void should_return_service_from_k8s()
private void ThenTheTokenIs(string token)
{
var token = "Bearer txpc696iUhbVoudg164r93CxDTrKRVWG";
var endPointEntryOne = new EndpointsV1
{
Kind = "endpoint",
ApiVersion = "1.0",
Metadata = new ObjectMetaV1()
{
Namespace = "dev",
},
};
var endpointSubsetV1 = new EndpointSubsetV1();
endpointSubsetV1.Addresses.Add(new EndpointAddressV1()
{
Ip = "127.0.0.1",
Hostname = "localhost",
});
endpointSubsetV1.Ports.Add(new EndpointPortV1()
{
Port = 80,
});
endPointEntryOne.Subsets.Add(endpointSubsetV1);
this.Given(x => GivenThereIsAFakeKubeServiceDiscoveryProvider(_fakekubeServiceDiscoveryUrl, _serviceName, _namespaces))
.And(x => GivenTheServicesAreRegisteredWithKube(endPointEntryOne))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(1))
.And(_ => _receivedToken.ShouldBe(token))
.BDDfy();
}
private void ThenTheCountIs(int count)
{
_services.Count.ShouldBe(count);
}
private void WhenIGetTheServices()
{
_services = _provider.Get().GetAwaiter().GetResult();
}
private void GivenTheServicesAreRegisteredWithKube(EndpointsV1 endpointEntries)
{
_endpointEntries = endpointEntries;
}
private void GivenThereIsAFakeKubeServiceDiscoveryProvider(string url, string serviceName, string namespaces)
{
_fakeKubeBuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
{
app.Run(async context =>
{
if (context.Request.Path.Value == $"/api/v1/namespaces/{namespaces}/endpoints/{serviceName}")
{
if (context.Request.Headers.TryGetValue("Authorization", out var values))
{
_receivedToken = values.First();
}
var json = JsonConvert.SerializeObject(_endpointEntries);
context.Response.Headers.Add("Content-Type", "application/json");
await context.Response.WriteAsync(json);
}
});
})
.Build();
_fakeKubeBuilder.Start();
}
public void Dispose()
{
_fakeKubeBuilder?.Dispose();
}
}
}
_receivedToken.ShouldBe(token);
}
private void ThenTheCountIs(int count)
{
_services.Count.ShouldBe(count);
}
private void WhenIGetTheServices()
{
_services = _provider.Get().GetAwaiter().GetResult();
}
private void GivenTheServicesAreRegisteredWithKube(EndpointsV1 endpointEntries)
{
_endpointEntries = endpointEntries;
}
private void GivenThereIsAFakeKubeServiceDiscoveryProvider(string url, string serviceName, string namespaces)
{
_fakeKubeBuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
{
app.Run(async context =>
{
if (context.Request.Path.Value == $"/api/v1/namespaces/{namespaces}/endpoints/{serviceName}")
{
if (context.Request.Headers.TryGetValue("Authorization", out var values))
{
_receivedToken = values.First();
}
var json = JsonConvert.SerializeObject(_endpointEntries);
context.Response.Headers.Add("Content-Type", "application/json");
await context.Response.WriteAsync(json);
}
});
})
.Build();
_fakeKubeBuilder.Start();
}
public void Dispose()
{
_fakeKubeBuilder?.Dispose();
}
}
}

View File

@ -1,97 +1,95 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Ocelot.UnitTests</AssemblyName>
<PackageId>Ocelot.UnitTests</PackageId>
<OutputType>Exe</OutputType>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Kubernetes\KubeProviderFactoryTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Ocelot.Provider.Kubernetes\Ocelot.Provider.Kubernetes.csproj" />
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Administration\Ocelot.Administration.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Cache.CacheManager\Ocelot.Cache.CacheManager.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Consul\Ocelot.Provider.Consul.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Eureka\Ocelot.Provider.Eureka.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Rafty\Ocelot.Provider.Rafty.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Tracing.Butterfly\Ocelot.Tracing.Butterfly.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="idsrv3test.pfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<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="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.1" />
<PackageReference Include="Moq" Version="4.13.1" />
<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="3.0.1" />
<PackageReference Include="IdentityServer4" Version="3.1.1" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="2.4.2" />
<PackageReference Include="Consul" Version="0.7.2.6" />
<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.2.0" />
<PackageReference Include="Rafty" Version="0.4.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="WebSockets\" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Ocelot.UnitTests</AssemblyName>
<PackageId>Ocelot.UnitTests</PackageId>
<OutputType>Exe</OutputType>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Kubernetes\KubeProviderFactoryTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Ocelot.Provider.Kubernetes\Ocelot.Provider.Kubernetes.csproj" />
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Administration\Ocelot.Administration.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Cache.CacheManager\Ocelot.Cache.CacheManager.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Consul\Ocelot.Provider.Consul.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Eureka\Ocelot.Provider.Eureka.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Tracing.Butterfly\Ocelot.Tracing.Butterfly.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="idsrv3test.pfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<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="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<PackageReference Include="Moq" Version="4.15.2" />
<PackageReference Include="Shouldly" Version="4.0.1" />
<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="3.0.1" />
<PackageReference Include="IdentityServer4" Version="4.1.1" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="3.0.1" />
<PackageReference Include="Consul" Version="1.6.1.1" />
<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.2.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="WebSockets\" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
<PackageReference Include="coverlet.collector" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -1,89 +0,0 @@
namespace Ocelot.UnitTests.Rafty
{
using Microsoft.AspNetCore.Hosting;
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;
public class OcelotAdministrationBuilderExtensionsTests
{
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private readonly IConfiguration _configRoot;
private IOcelotBuilder _ocelotBuilder;
private Exception _ex;
public OcelotAdministrationBuilderExtensionsTests()
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_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()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpRafty())
.Then(x => ThenAnExceptionIsntThrown())
.Then(x => ThenTheCorrectAdminPathIsRegitered())
.BDDfy();
}
private void WhenISetUpRafty()
{
try
{
_ocelotBuilder.AddAdministration("/administration", "secret").AddRafty();
}
catch (Exception e)
{
_ex = e;
}
}
private void WhenISetUpOcelotServices()
{
try
{
_ocelotBuilder = _services.AddOcelot(_configRoot);
}
catch (Exception e)
{
_ex = e;
}
}
private void ThenAnExceptionIsntThrown()
{
_ex.ShouldBeNull();
}
private void ThenTheCorrectAdminPathIsRegitered()
{
_serviceProvider = _services.BuildServiceProvider();
var path = _serviceProvider.GetService<IAdministrationPath>();
path.Path.ShouldBe("/administration");
}
}
}

View File

@ -1,45 +0,0 @@
namespace Ocelot.UnitTests.Rafty
{
using Moq;
using Ocelot.Configuration.Setter;
using Provider.Rafty;
using TestStack.BDDfy;
using Xunit;
public class OcelotFiniteStateMachineTests
{
private UpdateFileConfiguration _command;
private readonly OcelotFiniteStateMachine _fsm;
private readonly Mock<IFileConfigurationSetter> _setter;
public OcelotFiniteStateMachineTests()
{
_setter = new Mock<IFileConfigurationSetter>();
_fsm = new OcelotFiniteStateMachine(_setter.Object);
}
[Fact]
public void should_handle_update_file_configuration_command()
{
this.Given(x => GivenACommand(new UpdateFileConfiguration(new Ocelot.Configuration.File.FileConfiguration())))
.When(x => WhenTheCommandIsHandled())
.Then(x => ThenTheStateIsUpdated())
.BDDfy();
}
private void GivenACommand(UpdateFileConfiguration command)
{
_command = command;
}
private void WhenTheCommandIsHandled()
{
_fsm.Handle(new global::Rafty.Log.LogEntry(_command, _command.GetType(), 0)).Wait();
}
private void ThenTheStateIsUpdated()
{
_setter.Verify(x => x.Set(_command.Configuration), Times.Once);
}
}
}

View File

@ -1,52 +0,0 @@
namespace Ocelot.UnitTests.Rafty
{
using global::Rafty.Concensus.Node;
using global::Rafty.Infrastructure;
using Moq;
using Ocelot.Configuration.File;
using Provider.Rafty;
using Shouldly;
using System.Threading.Tasks;
using Xunit;
public class RaftyFileConfigurationSetterTests
{
private readonly RaftyFileConfigurationSetter _setter;
private readonly Mock<INode> _node;
public RaftyFileConfigurationSetterTests()
{
_node = new Mock<INode>();
_setter = new RaftyFileConfigurationSetter(_node.Object);
}
[Fact]
public async Task should_return_ok()
{
var fileConfig = new FileConfiguration();
var response = new OkResponse<UpdateFileConfiguration>(new UpdateFileConfiguration(fileConfig));
_node.Setup(x => x.Accept(It.IsAny<UpdateFileConfiguration>()))
.ReturnsAsync(response);
var result = await _setter.Set(fileConfig);
result.IsError.ShouldBeFalse();
}
[Fact]
public async Task should_return_not_ok()
{
var fileConfig = new FileConfiguration();
var response = new ErrorResponse<UpdateFileConfiguration>("error", new UpdateFileConfiguration(fileConfig));
_node.Setup(x => x.Accept(It.IsAny<UpdateFileConfiguration>()))
.ReturnsAsync(response);
var result = await _setter.Set(fileConfig);
result.IsError.ShouldBeTrue();
}
}
}

View File

@ -452,7 +452,7 @@
foreach (var header in _mappedRequest.Data.Headers)
{
var inputHeader = _inputHeaders.First(h => h.Key == header.Key);
inputHeader.ShouldNotBeNull();
inputHeader.ShouldNotBe(default(KeyValuePair<string, StringValues>));
inputHeader.Value.Count().ShouldBe(header.Value.Count());
foreach (var inputHeaderValue in inputHeader.Value)
{

View File

@ -29,10 +29,10 @@ namespace Ocelot.UnitTests.Responder
[Theory]
[InlineData(OcelotErrorCode.CannotFindClaimError)]
[InlineData(OcelotErrorCode.ClaimValueNotAuthorisedError)]
[InlineData(OcelotErrorCode.ScopeNotAuthorisedError)]
[InlineData(OcelotErrorCode.ClaimValueNotAuthorizedError)]
[InlineData(OcelotErrorCode.ScopeNotAuthorizedError)]
[InlineData(OcelotErrorCode.UnauthorizedError)]
[InlineData(OcelotErrorCode.UserDoesNotHaveClaimError)]
[InlineData(OcelotErrorCode.UserDoesNotHaveClaimError)]
public void should_return_forbidden(OcelotErrorCode errorCode)
{
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.Forbidden);
@ -52,8 +52,8 @@ namespace Ocelot.UnitTests.Responder
public void should_return_internal_server_error(OcelotErrorCode errorCode)
{
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.InternalServerError);
}
}
[Theory]
[InlineData(OcelotErrorCode.ConnectionToDownstreamServiceError)]
public void should_return_bad_gateway_error(OcelotErrorCode errorCode)
@ -104,7 +104,7 @@ namespace Ocelot.UnitTests.Responder
}
[Fact]
public void AuthorisationErrorsHaveSecondHighestPriority()
public void AuthorizationErrorsHaveSecondHighestPriority()
{
var errors = new List<OcelotErrorCode>
{
@ -177,4 +177,4 @@ namespace Ocelot.UnitTests.Responder
_result.ShouldBe((int)expectedCode);
}
}
}
}

View File

@ -1,23 +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>
<?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>