wip tests failing

This commit is contained in:
TomPallister
2020-11-27 19:01:27 +00:00
parent 6eed692c29
commit 32551624bb
19 changed files with 1104 additions and 1068 deletions

View File

@ -1,299 +1,304 @@
namespace Ocelot.UnitTests.Consul
{
using global::Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Moq;
using Newtonsoft.Json;
using Ocelot.Logging;
using Provider.Consul;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using TestStack.BDDfy;
using Values;
using Xunit;
public class ConsulServiceDiscoveryProviderTests : IDisposable
{
private IWebHost _fakeConsulBuilder;
private readonly List<ServiceEntry> _serviceEntries;
private Consul _provider;
private readonly string _serviceName;
private readonly int _port;
private readonly string _consulHost;
private readonly string _consulScheme;
private readonly string _fakeConsulServiceDiscoveryUrl;
private List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
private string _receivedToken;
private readonly IConsulClientFactory _clientFactory;
public ConsulServiceDiscoveryProviderTests()
{
_serviceName = "test";
_port = 8500;
_consulHost = "localhost";
_consulScheme = "http";
_fakeConsulServiceDiscoveryUrl = $"{_consulScheme}://{_consulHost}:{_port}";
_serviceEntries = new List<ServiceEntry>();
_factory = new Mock<IOcelotLoggerFactory>();
_clientFactory = new ConsulClientFactory();
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<Consul>()).Returns(_logger.Object);
_factory.Setup(x => x.CreateLogger<PollConsul>()).Returns(_logger.Object);
var config = new ConsulRegistryConfiguration(_consulScheme, _consulHost, _port, _serviceName, null);
_provider = new Consul(config, _factory.Object, _clientFactory);
namespace Ocelot.UnitTests.Consul
{
using global::Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Moq;
using Newtonsoft.Json;
using Ocelot.Logging;
using Provider.Consul;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using TestStack.BDDfy;
using Values;
using Xunit;
public class ConsulServiceDiscoveryProviderTests : IDisposable
{
private IWebHost _fakeConsulBuilder;
private readonly List<ServiceEntry> _serviceEntries;
private Consul _provider;
private readonly string _serviceName;
private readonly int _port;
private readonly string _consulHost;
private readonly string _consulScheme;
private readonly string _fakeConsulServiceDiscoveryUrl;
private List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
private string _receivedToken;
private readonly IConsulClientFactory _clientFactory;
public ConsulServiceDiscoveryProviderTests()
{
_serviceName = "test";
_port = 8500;
_consulHost = "localhost";
_consulScheme = "http";
_fakeConsulServiceDiscoveryUrl = $"{_consulScheme}://{_consulHost}:{_port}";
_serviceEntries = new List<ServiceEntry>();
_factory = new Mock<IOcelotLoggerFactory>();
_clientFactory = new ConsulClientFactory();
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<Consul>()).Returns(_logger.Object);
_factory.Setup(x => x.CreateLogger<PollConsul>()).Returns(_logger.Object);
var config = new ConsulRegistryConfiguration(_consulScheme, _consulHost, _port, _serviceName, null);
_provider = new Consul(config, _factory.Object, _clientFactory);
}
[Fact]
public void should_return_service_from_consul()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(1))
.BDDfy();
}
[Fact]
public void should_use_token()
{
var token = "test token";
var config = new ConsulRegistryConfiguration(_consulScheme, _consulHost, _port, _serviceName, token);
_provider = new Consul(config, _factory.Object, _clientFactory);
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0],
},
};
this.Given(_ => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(_ => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
.When(_ => WhenIGetTheServices())
.Then(_ => ThenTheCountIs(1))
.And(_ => ThenTheTokenIs(token))
.BDDfy();
}
[Fact]
public void should_not_return_services_with_invalid_address()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "http://localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
var serviceEntryTwo = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "http://localhost",
Port = 50888,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(0))
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForInvalidAddress())
.BDDfy();
}
[Fact]
public void should_not_return_services_with_empty_address()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
var serviceEntryTwo = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = null,
Port = 50888,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(0))
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForEmptyAddress())
.BDDfy();
}
[Fact]
public void should_not_return_services_with_invalid_port()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = -1,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
var serviceEntryTwo = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = 0,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(0))
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForInvalidPorts())
.BDDfy();
}
private void ThenTheLoggerHasBeenCalledCorrectlyForInvalidAddress()
{
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: http://localhost and Port: 50881 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: http://localhost and Port: 50888 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
}
private void ThenTheLoggerHasBeenCalledCorrectlyForEmptyAddress()
{
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: and Port: 50881 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: and Port: 50888 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
}
private void ThenTheLoggerHasBeenCalledCorrectlyForInvalidPorts()
{
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: localhost and Port: -1 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: localhost and Port: 0 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
}
private void ThenTheCountIs(int count)
{
_services.Count.ShouldBe(count);
}
private void WhenIGetTheServices()
{
_services = _provider.Get().GetAwaiter().GetResult();
}
[Fact]
public void should_return_service_from_consul()
private void ThenTheTokenIs(string token)
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(1))
.BDDfy();
}
[Fact]
public void should_use_token()
{
var token = "test token";
var config = new ConsulRegistryConfiguration(_consulScheme, _consulHost, _port, _serviceName, token);
_provider = new Consul(config, _factory.Object, _clientFactory);
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(_ => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(_ => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
.When(_ => WhenIGetTheServices())
.Then(_ => ThenTheCountIs(1))
.And(_ => _receivedToken.ShouldBe(token))
.BDDfy();
}
[Fact]
public void should_not_return_services_with_invalid_address()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "http://localhost",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
var serviceEntryTwo = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "http://localhost",
Port = 50888,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(0))
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForInvalidAddress())
.BDDfy();
}
[Fact]
public void should_not_return_services_with_empty_address()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "",
Port = 50881,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
var serviceEntryTwo = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = null,
Port = 50888,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(0))
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForEmptyAddress())
.BDDfy();
}
[Fact]
public void should_not_return_services_with_invalid_port()
{
var serviceEntryOne = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = -1,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
var serviceEntryTwo = new ServiceEntry()
{
Service = new AgentService()
{
Service = _serviceName,
Address = "localhost",
Port = 0,
ID = Guid.NewGuid().ToString(),
Tags = new string[0]
},
};
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
.And(x => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo))
.When(x => WhenIGetTheServices())
.Then(x => ThenTheCountIs(0))
.And(x => ThenTheLoggerHasBeenCalledCorrectlyForInvalidPorts())
.BDDfy();
}
private void ThenTheLoggerHasBeenCalledCorrectlyForInvalidAddress()
{
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: http://localhost and Port: 50881 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: http://localhost and Port: 50888 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
}
private void ThenTheLoggerHasBeenCalledCorrectlyForEmptyAddress()
{
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: and Port: 50881 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: and Port: 50888 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
}
private void ThenTheLoggerHasBeenCalledCorrectlyForInvalidPorts()
{
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: localhost and Port: -1 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
_logger.Verify(
x => x.LogWarning(
"Unable to use service Address: localhost and Port: 0 as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0"),
Times.Once);
}
private void ThenTheCountIs(int count)
{
_services.Count.ShouldBe(count);
}
private void WhenIGetTheServices()
{
_services = _provider.Get().GetAwaiter().GetResult();
}
private void GivenTheServicesAreRegisteredWithConsul(params ServiceEntry[] serviceEntries)
{
foreach (var serviceEntry in serviceEntries)
{
_serviceEntries.Add(serviceEntry);
}
}
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
{
_fakeConsulBuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
{
app.Run(async context =>
{
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
{
if (context.Request.Headers.TryGetValue("X-Consul-Token", out var values))
{
_receivedToken = values.First();
}
var json = JsonConvert.SerializeObject(_serviceEntries);
context.Response.Headers.Add("Content-Type", "application/json");
await context.Response.WriteAsync(json);
}
});
})
.Build();
_fakeConsulBuilder.Start();
}
public void Dispose()
{
_fakeConsulBuilder?.Dispose();
}
}
}
_receivedToken.ShouldBe(token);
}
private void GivenTheServicesAreRegisteredWithConsul(params ServiceEntry[] serviceEntries)
{
foreach (var serviceEntry in serviceEntries)
{
_serviceEntries.Add(serviceEntry);
}
}
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
{
_fakeConsulBuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
{
app.Run(async context =>
{
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
{
if (context.Request.Headers.TryGetValue("X-Consul-Token", out var values))
{
_receivedToken = values.First();
}
var json = JsonConvert.SerializeObject(_serviceEntries);
context.Response.Headers.Add("Content-Type", "application/json");
await context.Response.WriteAsync(json);
}
});
})
.Build();
_fakeConsulBuilder.Start();
}
public void Dispose()
{
_fakeConsulBuilder?.Dispose();
}
}
}

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;

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

@ -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,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

@ -54,7 +54,7 @@
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -67,13 +67,13 @@
<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.0-beta0002" />
<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="3.1.1" />
<PackageReference Include="Steeltoe.Discovery.ClientCore" Version="2.4.2" />
<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" />

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)
{