Feat/monorepo (#734)

* copied everything from repos back to ocelot repo

* added src projects to sln

* removed all test projects that have no tests

* added all test projects to sln

* removed test not on master

* merged unit tests

* merged acceptance tests

* merged integration tests

* fixed namepaces

* build script creates packages for all projects

* updated docs to make sure no references to external repos that we will remove

* +semver: breaking
This commit is contained in:
Tom Pallister
2019-01-07 19:52:53 +00:00
committed by GitHub
parent 35253025c7
commit 11a2d13f18
107 changed files with 9483 additions and 585 deletions

View File

@ -0,0 +1,91 @@
namespace Ocelot.UnitTests.Administration
{
using System;
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Administration;
using Ocelot.DependencyInjection;
using Shouldly;
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<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton(_configRoot);
}
//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();
}
}
}

View File

@ -0,0 +1,98 @@
namespace Ocelot.UnitTests.CacheManager
{
using System;
using System.Collections.Generic;
using System.Linq;
using global::CacheManager.Core;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Cache;
using Ocelot.Cache.CacheManager;
using Ocelot.Configuration;
using Ocelot.Configuration.File;
using Ocelot.DependencyInjection;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class OcelotBuilderExtensionsTests
{
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private readonly IConfiguration _configRoot;
private IOcelotBuilder _ocelotBuilder;
private readonly int _maxRetries;
private Exception _ex;
public OcelotBuilderExtensionsTests()
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton(_configRoot);
_maxRetries = 100;
}
[Fact]
public void should_set_up_cache_manager()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpCacheManager())
.Then(x => ThenAnExceptionIsntThrown())
.And(x => OnlyOneVersionOfEachCacheIsRegistered())
.BDDfy();
}
private void OnlyOneVersionOfEachCacheIsRegistered()
{
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
var instance = (ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IInternalConfiguration>));
var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IInternalConfiguration>));
var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
instance.Configuration.MaxRetries.ShouldBe(_maxRetries);
outputCache.ShouldNotBeNull();
ocelotConfigCache.ShouldNotBeNull();
ocelotConfigCacheManager.ShouldNotBeNull();
fileConfigCache.ShouldNotBeNull();
fileConfigCacheManager.ShouldNotBeNull();
}
private void WhenISetUpOcelotServices()
{
try
{
_ocelotBuilder = _services.AddOcelot(_configRoot);
}
catch (Exception e)
{
_ex = e;
}
}
private void WhenISetUpCacheManager()
{
try
{
_ocelotBuilder.AddCacheManager(x => {
x.WithMaxRetries(_maxRetries);
x.WithDictionaryHandle();
});
}
catch (Exception e)
{
_ex = e;
}
}
private void ThenAnExceptionIsntThrown()
{
_ex.ShouldBeNull();
}
}
}

View File

@ -0,0 +1,103 @@
namespace Ocelot.UnitTests.CacheManager
{
using System;
using global::CacheManager.Core;
using Moq;
using Ocelot.Cache.CacheManager;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class OcelotCacheManagerCache
{
private OcelotCacheManagerCache<string> _ocelotOcelotCacheManager;
private Mock<ICacheManager<string>> _mockCacheManager;
private string _key;
private string _value;
private string _resultGet;
private TimeSpan _ttlSeconds;
private string _region;
public OcelotCacheManagerCache()
{
_mockCacheManager = new Mock<ICacheManager<string>>();
_ocelotOcelotCacheManager = new OcelotCacheManagerCache<string>(_mockCacheManager.Object);
}
[Fact]
public void should_get_from_cache()
{
this.Given(x => x.GivenTheFollowingIsCached("someKey", "someRegion", "someValue"))
.When(x => x.WhenIGetFromTheCache())
.Then(x => x.ThenTheResultIs("someValue"))
.BDDfy();
}
[Fact]
public void should_add_to_cache()
{
this.When(x => x.WhenIAddToTheCache("someKey", "someValue", TimeSpan.FromSeconds(1)))
.Then(x => x.ThenTheCacheIsCalledCorrectly())
.BDDfy();
}
[Fact]
public void should_delete_key_from_cache()
{
this.Given(_ => GivenTheFollowingRegion("fookey"))
.When(_ => WhenIDeleteTheRegion("fookey"))
.Then(_ => ThenTheRegionIsDeleted("fookey"))
.BDDfy();
}
private void WhenIDeleteTheRegion(string region)
{
_ocelotOcelotCacheManager.ClearRegion(region);
}
private void ThenTheRegionIsDeleted(string region)
{
_mockCacheManager
.Verify(x => x.ClearRegion(region), Times.Once);
}
private void GivenTheFollowingRegion(string key)
{
_ocelotOcelotCacheManager.Add(key, "doesnt matter", TimeSpan.FromSeconds(10), "region");
}
private void WhenIAddToTheCache(string key, string value, TimeSpan ttlSeconds)
{
_key = key;
_value = value;
_ttlSeconds = ttlSeconds;
_ocelotOcelotCacheManager.Add(_key, _value, _ttlSeconds, "region");
}
private void ThenTheCacheIsCalledCorrectly()
{
_mockCacheManager
.Verify(x => x.Add(It.IsAny<CacheItem<string>>()), Times.Once);
}
private void ThenTheResultIs(string expected)
{
_resultGet.ShouldBe(expected);
}
private void WhenIGetFromTheCache()
{
_resultGet = _ocelotOcelotCacheManager.Get(_key, _region);
}
private void GivenTheFollowingIsCached(string key, string region, string value)
{
_key = key;
_value = value;
_region = region;
_mockCacheManager
.Setup(x => x.Get<string>(It.IsAny<string>(), It.IsAny<string>()))
.Returns(value);
}
}
}

View File

@ -0,0 +1,93 @@
namespace Ocelot.UnitTests.CacheManager
{
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using global::CacheManager.Core;
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Cache;
using Ocelot.Cache.CacheManager;
using Ocelot.Cache.Middleware;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Logging;
using Ocelot.Middleware;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class OutputCacheMiddlewareRealCacheTests
{
private readonly IOcelotCache<CachedResponse> _cacheManager;
private readonly OutputCacheMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
public OutputCacheMiddlewareRealCacheTests()
{
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
{
x.WithDictionaryHandle();
});
_cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_downstreamContext.DownstreamRequest = new Ocelot.Request.Middleware.DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123"));
_next = context => Task.CompletedTask;
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager);
}
[Fact]
public void should_cache_content_headers()
{
var content = new StringContent("{\"Test\": 1}")
{
Headers = { ContentType = new MediaTypeHeaderValue("application/json")}
};
var response = new DownstreamResponse(content, HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "fooreason");
this.Given(x => x.GivenResponseIsNotCached(response))
.And(x => x.GivenTheDownstreamRouteIs())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheContentTypeHeaderIsCached())
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void ThenTheContentTypeHeaderIsCached()
{
var result = _cacheManager.Get("GET-https://some.url/blah?abcd=123", "kanken");
var header = result.ContentHeaders["Content-Type"];
header.First().ShouldBe("application/json");
}
private void GivenResponseIsNotCached(DownstreamResponse response)
{
_downstreamContext.DownstreamResponse = response;
}
private void GivenTheDownstreamRouteIs()
{
var reRoute = new DownstreamReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
_downstreamContext.DownstreamReRoute = reRoute;
}
}
}

View File

@ -0,0 +1,261 @@
namespace Ocelot.UnitTests.Consul
{
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using global::Consul;
using Moq;
using Newtonsoft.Json;
using Ocelot.Cache;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Logging;
using Provider.Consul;
using Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class ConsulFileConfigurationRepositoryTests
{
private ConsulFileConfigurationRepository _repo;
private Mock<IOcelotCache<FileConfiguration>> _cache;
private Mock<IInternalConfigurationRepository> _internalRepo;
private Mock<IConsulClientFactory> _factory;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IConsulClient> _client;
private Mock<IKVEndpoint> _kvEndpoint;
private FileConfiguration _fileConfiguration;
private Response _setResult;
private Response<FileConfiguration> _getResult;
public ConsulFileConfigurationRepositoryTests()
{
_cache = new Mock<IOcelotCache<FileConfiguration>>();
_internalRepo = new Mock<IInternalConfigurationRepository>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_factory = new Mock<IConsulClientFactory>();
_client = new Mock<IConsulClient>();
_kvEndpoint = new Mock<IKVEndpoint>();
_client
.Setup(x => x.KV)
.Returns(_kvEndpoint.Object);
_factory
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
.Returns(_client.Object);
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "", It.IsAny<LoadBalancerOptions>(), It.IsAny<string>(), It.IsAny<QoSOptions>(), It.IsAny<HttpHandlerOptions>())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
}
[Fact]
public void should_set_config()
{
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenWritingToConsulSucceeds())
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.BDDfy();
}
[Fact]
public void should_get_config()
{
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenFetchFromConsulSucceeds())
.When(_ => WhenIGetTheConfiguration())
.Then(_ => ThenTheConfigurationIs(config))
.BDDfy();
}
[Fact]
public void should_get_null_config()
{
this.Given(_ => GivenFetchFromConsulReturnsNull())
.When(_ => WhenIGetTheConfiguration())
.Then(_ => ThenTheConfigurationIsNull())
.BDDfy();
}
[Fact]
public void should_get_config_from_cache()
{
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenFetchFromCacheSucceeds())
.When(_ => WhenIGetTheConfiguration())
.Then(_ => ThenTheConfigurationIs(config))
.BDDfy();
}
[Fact]
public void should_set_config_key()
{
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheConfigKeyComesFromFileConfig("Tom"))
.And(_ => GivenFetchFromConsulSucceeds())
.When(_ => WhenIGetTheConfiguration())
.And(_ => ThenTheConfigKeyIs("Tom"))
.BDDfy();
}
[Fact]
public void should_set_default_config_key()
{
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenFetchFromConsulSucceeds())
.When(_ => WhenIGetTheConfiguration())
.And(_ => ThenTheConfigKeyIs("InternalConfiguration"))
.BDDfy();
}
private void ThenTheConfigKeyIs(string expected)
{
_kvEndpoint
.Verify(x => x.Get(expected, It.IsAny<CancellationToken>()), Times.Once);
}
private void GivenTheConfigKeyComesFromFileConfig(string key)
{
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "",
new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "",
new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(),
new HttpHandlerOptionsBuilder().Build())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
}
private void ThenTheConfigurationIsNull()
{
_getResult.Data.ShouldBeNull();
}
private void ThenTheConfigurationIs(FileConfiguration config)
{
var expected = JsonConvert.SerializeObject(config, Formatting.Indented);
var result = JsonConvert.SerializeObject(_getResult.Data, Formatting.Indented);
result.ShouldBe(expected);
}
private async Task WhenIGetTheConfiguration()
{
_getResult = await _repo.Get();
}
private void GivenWritingToConsulSucceeds()
{
var response = new WriteResult<bool>();
response.Response = true;
_kvEndpoint
.Setup(x => x.Put(It.IsAny<KVPair>(), It.IsAny<CancellationToken>())).ReturnsAsync(response);
}
private void GivenFetchFromCacheSucceeds()
{
_cache.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>())).Returns(_fileConfiguration);
}
private void GivenFetchFromConsulReturnsNull()
{
QueryResult<KVPair> result = new QueryResult<KVPair>();
_kvEndpoint
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(result);
}
private void GivenFetchFromConsulSucceeds()
{
var json = JsonConvert.SerializeObject(_fileConfiguration, Formatting.Indented);
var bytes = Encoding.UTF8.GetBytes(json);
var kvp = new KVPair("OcelotConfiguration");
kvp.Value = bytes;
var query = new QueryResult<KVPair>();
query.Response = kvp;
_kvEndpoint
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(query);
}
private void ThenTheConfigurationIsStoredAs(FileConfiguration config)
{
var json = JsonConvert.SerializeObject(config, Formatting.Indented);
var bytes = Encoding.UTF8.GetBytes(json);
_kvEndpoint
.Verify(x => x.Put(It.Is<KVPair>(k => k.Value.SequenceEqual(bytes)), It.IsAny<CancellationToken>()), Times.Once);
}
private async Task WhenISetTheConfiguration()
{
_setResult = await _repo.Set(_fileConfiguration);
}
private void GivenIHaveAConfiguration(FileConfiguration config)
{
_fileConfiguration = config;
}
private FileConfiguration FakeFileConfiguration()
{
var reRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "123.12.12.12",
Port = 80,
}
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/asdfs/test/{test}"
}
};
var globalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Port = 198,
Host = "blah"
}
};
return new FileConfiguration
{
GlobalConfiguration = globalConfiguration,
ReRoutes = reRoutes
};
}
}
}

View File

@ -0,0 +1,297 @@
namespace Ocelot.UnitTests.Consul
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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 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 _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";
_fakeConsulServiceDiscoveryUrl = $"http://{_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(_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(_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();
}
}
}

View File

@ -0,0 +1,69 @@
namespace Ocelot.UnitTests.Consul
{
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Provider.Consul;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class OcelotBuilderExtensionsTests
{
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private readonly IConfiguration _configRoot;
private IOcelotBuilder _ocelotBuilder;
private Exception _ex;
public OcelotBuilderExtensionsTests()
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton(_configRoot);
}
[Fact]
public void should_set_up_consul()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => WhenISetUpConsul())
.Then(x => ThenAnExceptionIsntThrown())
.BDDfy();
}
private void WhenISetUpOcelotServices()
{
try
{
_ocelotBuilder = _services.AddOcelot(_configRoot);
}
catch (Exception e)
{
_ex = e;
}
}
private void WhenISetUpConsul()
{
try
{
_ocelotBuilder.AddConsul().AddConfigStoredInConsul();
}
catch (Exception e)
{
_ex = e;
}
}
private void ThenAnExceptionIsntThrown()
{
_ex.ShouldBeNull();
}
}
}

View File

@ -0,0 +1,81 @@
namespace Ocelot.UnitTests.Consul
{
using System;
using System.Collections.Generic;
using Moq;
using Ocelot.Infrastructure;
using Ocelot.Logging;
using Ocelot.ServiceDiscovery.Providers;
using Provider.Consul;
using Shouldly;
using TestStack.BDDfy;
using Values;
using Xunit;
public class PollingConsulServiceDiscoveryProviderTests
{
private readonly int _delay;
private PollConsul _provider;
private readonly List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
private readonly Mock<IServiceDiscoveryProvider> _consulServiceDiscoveryProvider;
private List<Service> _result;
public PollingConsulServiceDiscoveryProviderTests()
{
_services = new List<Service>();
_delay = 1;
_factory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<PollConsul>()).Returns(_logger.Object);
_consulServiceDiscoveryProvider = new Mock<IServiceDiscoveryProvider>();
}
[Fact]
public void should_return_service_from_consul()
{
var service = new Service("", new ServiceHostAndPort("", 0), "", "", new List<string>());
this.Given(x => GivenConsulReturns(service))
.When(x => WhenIGetTheServices(1))
.Then(x => ThenTheCountIs(1))
.BDDfy();
}
private void GivenConsulReturns(Service service)
{
_services.Add(service);
_consulServiceDiscoveryProvider.Setup(x => x.Get()).ReturnsAsync(_services);
}
private void ThenTheCountIs(int count)
{
_result.Count.ShouldBe(count);
}
private void WhenIGetTheServices(int expected)
{
_provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object);
var result = Wait.WaitFor(3000).Until(() => {
try
{
_result = _provider.Get().GetAwaiter().GetResult();
if (_result.Count == expected)
{
return true;
}
return false;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
}
}
}

View File

@ -0,0 +1,44 @@
namespace Ocelot.UnitTests.Consul
{
using System;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Logging;
using Provider.Consul;
using Shouldly;
using Xunit;
public class ProviderFactoryTests
{
private readonly IServiceProvider _provider;
public ProviderFactoryTests()
{
var services = new ServiceCollection();
var loggerFactory = new Mock<IOcelotLoggerFactory>();
var logger = new Mock<IOcelotLogger>();
loggerFactory.Setup(x => x.CreateLogger<Consul>()).Returns(logger.Object);
loggerFactory.Setup(x => x.CreateLogger<PollConsul>()).Returns(logger.Object);
var consulFactory = new Mock<IConsulClientFactory>();
services.AddSingleton<IConsulClientFactory>(consulFactory.Object);
services.AddSingleton<IOcelotLoggerFactory>(loggerFactory.Object);
_provider = services.BuildServiceProvider();
}
[Fact]
public void should_return_ConsulServiceDiscoveryProvider()
{
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), "");
provider.ShouldBeOfType<Consul>();
}
[Fact]
public void should_return_PollingConsulServiceDiscoveryProvider()
{
var stopsPollerFromPolling = 10000;
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), "");
provider.ShouldBeOfType<PollConsul>();
}
}
}

View File

@ -0,0 +1,47 @@
namespace Ocelot.UnitTests.Eureka
{
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Repository;
using Provider.Eureka;
using Responses;
using Shouldly;
using Steeltoe.Common.Discovery;
using Xunit;
public class EurekaMiddlewareConfigurationProviderTests
{
[Fact]
public void should_not_build()
{
var configRepo = new Mock<IInternalConfigurationRepository>();
configRepo.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, null, null, null, null, null, null)));
var services = new ServiceCollection();
services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaMiddlewareConfigurationProvider.Get(new ApplicationBuilder(sp));
provider.ShouldBeOfType<Task>();
}
[Fact]
public void should_build()
{
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().WithType("eureka").Build();
var client = new Mock<IDiscoveryClient>();
var configRepo = new Mock<IInternalConfigurationRepository>();
configRepo.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, serviceProviderConfig, null, null, null, null, null)));
var services = new ServiceCollection();
services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
services.AddSingleton<IDiscoveryClient>(client.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaMiddlewareConfigurationProvider.Get(new ApplicationBuilder(sp));
provider.ShouldBeOfType<Task>();
}
}
}

View File

@ -0,0 +1,34 @@
namespace Ocelot.UnitTests.Eureka
{
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration.Builder;
using Provider.Eureka;
using Shouldly;
using Steeltoe.Common.Discovery;
using Xunit;
public class EurekaProviderFactoryTests
{
[Fact]
public void should_not_get()
{
var config = new ServiceProviderConfigurationBuilder().Build();
var sp = new ServiceCollection().BuildServiceProvider();
var provider = EurekaProviderFactory.Get(sp, config, null);
provider.ShouldBeNull();
}
[Fact]
public void should_get()
{
var config = new ServiceProviderConfigurationBuilder().WithType("eureka").Build();
var client = new Mock<IDiscoveryClient>();
var services = new ServiceCollection();
services.AddSingleton<IDiscoveryClient>(client.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaProviderFactory.Get(sp, config, null);
provider.ShouldBeOfType<Eureka>();
}
}
}

View File

@ -0,0 +1,117 @@
namespace Ocelot.UnitTests.Eureka
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Moq;
using Provider.Eureka;
using Shouldly;
using Steeltoe.Common.Discovery;
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; }
}
}

View File

@ -0,0 +1,59 @@
namespace Ocelot.UnitTests.Eureka
{
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Middleware.Pipeline;
using Pivotal.Discovery.Client;
using Shouldly;
using Steeltoe.Common.Discovery;
using Steeltoe.Discovery.Eureka;
using TestStack.BDDfy;
using Xunit;
public class OcelotPipelineExtensionsTests
{
private OcelotPipelineBuilder _builder;
private OcelotRequestDelegate _handlers;
[Fact]
public void should_set_up_pipeline()
{
this.Given(_ => GivenTheDepedenciesAreSetUp())
.When(_ => WhenIBuild())
.Then(_ => ThenThePipelineIsBuilt())
.BDDfy();
}
private void ThenThePipelineIsBuilt()
{
_handlers.ShouldNotBeNull();
}
private void WhenIBuild()
{
_handlers = _builder.BuildOcelotPipeline(new OcelotPipelineConfiguration());
}
private void GivenTheDepedenciesAreSetUp()
{
IConfigurationBuilder test = new ConfigurationBuilder();
var root = test.Build();
var services = new ServiceCollection();
services.AddSingleton<IConfiguration>(root);
services.AddDiscoveryClient(new DiscoveryOptions
{
ClientType = DiscoveryClientType.EUREKA,
ClientOptions = new EurekaClientOptions()
{
ShouldFetchRegistry = false,
ShouldRegisterWithEureka = false
}
});
services.AddOcelot();
var provider = services.BuildServiceProvider();
_builder = new OcelotPipelineBuilder(provider);
}
}
}

View File

@ -21,6 +21,13 @@
<ItemGroup>
<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>
@ -57,6 +64,15 @@
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.6.0" />
<PackageReference Include="IdentityServer4" Version="2.2.0" />
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.0.1" />
<PackageReference Include="Consul" Version="0.7.2.6" />
<PackageReference Include="CacheManager.Core" Version="1.1.2" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.2" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.2" />
<PackageReference Include="Polly" Version="6.0.1" />
<PackageReference Include="Rafty" Version="0.4.4"/>
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,45 @@
namespace Ocelot.UnitTests.Polly
{
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration.Builder;
using Ocelot.DependencyInjection;
using Ocelot.Logging;
using Ocelot.Requester;
using Provider.Polly;
using Shouldly;
using Xunit;
public class OcelotBuilderExtensionsTests
{
[Fact]
public void should_build()
{
var loggerFactory = new Mock<IOcelotLoggerFactory>();
var services = new ServiceCollection();
var options = new QoSOptionsBuilder()
.WithTimeoutValue(100)
.WithExceptionsAllowedBeforeBreaking(1)
.WithDurationOfBreak(200)
.Build();
var reRoute = new DownstreamReRouteBuilder().WithQosOptions(options)
.Build();
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.Build();
services
.AddOcelot(configuration)
.AddPolly();
var provider = services.BuildServiceProvider();
var handler = provider.GetService<QosDelegatingHandlerDelegate>();
handler.ShouldNotBeNull();
var delgatingHandler = handler(reRoute, loggerFactory.Object);
delgatingHandler.ShouldNotBeNull();
}
}
}

View File

@ -0,0 +1,27 @@
namespace Ocelot.UnitTests.Polly
{
using Moq;
using Ocelot.Configuration.Builder;
using Ocelot.Logging;
using Provider.Polly;
using Shouldly;
using Xunit;
public class PollyQoSProviderTests
{
[Fact]
public void should_build()
{
var options = new QoSOptionsBuilder()
.WithTimeoutValue(100)
.WithExceptionsAllowedBeforeBreaking(1)
.WithDurationOfBreak(200)
.Build();
var reRoute = new DownstreamReRouteBuilder().WithQosOptions(options)
.Build();
var factory = new Mock<IOcelotLoggerFactory>();
var pollyQoSProvider = new PollyQoSProvider(reRoute, factory.Object);
pollyQoSProvider.CircuitBreaker.ShouldNotBeNull();
}
}
}

View File

@ -0,0 +1,78 @@
namespace Ocelot.UnitTests.Rafty
{
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Administration;
using Ocelot.DependencyInjection;
using Provider.Rafty;
using Shouldly;
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<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton(_configRoot);
}
[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

@ -0,0 +1,45 @@
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

@ -0,0 +1,52 @@
namespace Ocelot.UnitTests.Rafty
{
using System.Threading.Tasks;
using global::Rafty.Concensus.Node;
using global::Rafty.Infrastructure;
using Moq;
using Ocelot.Configuration.File;
using Provider.Rafty;
using Shouldly;
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

@ -0,0 +1,24 @@
{
"Logging": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Error",
"System": "Error",
"Microsoft": "Error"
}
},
"spring": {
"application": {
"name": "ocelot"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:8761/eureka/",
"shouldRegisterWithEureka": true,
"shouldFetchRegistry": true,
"port": 5000,
"hostName": "localhost"
}
}
}