Merge branch 'master' into pitming-feature/MethodTransformer

This commit is contained in:
TomPallister
2020-02-09 16:55:14 +00:00
22 changed files with 1566 additions and 1130 deletions

View File

@ -1,5 +1,6 @@
using Ocelot.Configuration.File;
using System;
using Ocelot.Configuration.ChangeTracking;
using TestStack.BDDfy;
using Xunit;
@ -54,6 +55,33 @@ namespace Ocelot.AcceptanceTests
.BDDfy();
}
[Fact]
public void should_trigger_change_token_on_change()
{
this.Given(x => _steps.GivenThereIsAConfiguration(_initialConfig))
.And(x => _steps.GivenOcelotIsRunningReloadingConfig(true))
.And(x => _steps.GivenIHaveAChangeToken())
.And(x => _steps.GivenThereIsAConfiguration(_anotherConfig))
.And(x => _steps.GivenIWait(MillisecondsToWaitForChangeToken))
.Then(x => _steps.TheChangeTokenShouldBeActive(true))
.BDDfy();
}
[Fact]
public void should_not_trigger_change_token_with_no_change()
{
this.Given(x => _steps.GivenThereIsAConfiguration(_initialConfig))
.And(x => _steps.GivenOcelotIsRunningReloadingConfig(false))
.And(x => _steps.GivenIHaveAChangeToken())
.And(x => _steps.GivenIWait(MillisecondsToWaitForChangeToken)) // Wait for prior activation to expire.
.And(x => _steps.GivenThereIsAConfiguration(_anotherConfig))
.And(x => _steps.GivenIWait(MillisecondsToWaitForChangeToken))
.Then(x => _steps.TheChangeTokenShouldBeActive(false))
.BDDfy();
}
private const int MillisecondsToWaitForChangeToken = (int) (OcelotConfigurationChangeToken.PollingIntervalSeconds*1000) - 100;
public void Dispose()
{
_steps.Dispose();

View File

@ -1,4 +1,6 @@
namespace Ocelot.AcceptanceTests
using Ocelot.Configuration.ChangeTracking;
namespace Ocelot.AcceptanceTests
{
using Caching;
using Configuration.Repository;
@ -54,6 +56,7 @@
private IWebHostBuilder _webHostBuilder;
private WebHostBuilder _ocelotBuilder;
private IWebHost _ocelotHost;
private IOcelotConfigurationChangeTokenSource _changeToken;
public Steps()
{
@ -216,6 +219,11 @@
_ocelotClient = _ocelotServer.CreateClient();
}
public void GivenIHaveAChangeToken()
{
_changeToken = _ocelotServer.Host.Services.GetRequiredService<IOcelotConfigurationChangeTokenSource>();
}
/// <summary>
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
/// </summary>
@ -1135,6 +1143,11 @@
_ocelotClient = _ocelotServer.CreateClient();
}
public void TheChangeTokenShouldBeActive(bool itShouldBeActive)
{
_changeToken.ChangeToken.HasChanged.ShouldBe(itShouldBeActive);
}
public void GivenOcelotIsRunningWithLogger()
{
_webHostBuilder = new WebHostBuilder();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
namespace Ocelot.UnitTests.Configuration.ChangeTracking
{
using Ocelot.Configuration.ChangeTracking;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class OcelotConfigurationChangeTokenSourceTests
{
private readonly IOcelotConfigurationChangeTokenSource _source;
public OcelotConfigurationChangeTokenSourceTests()
{
_source = new OcelotConfigurationChangeTokenSource();
}
[Fact]
public void should_activate_change_token()
{
this.Given(_ => GivenIActivateTheChangeTokenSource())
.Then(_ => ThenTheChangeTokenShouldBeActivated())
.BDDfy();
}
private void GivenIActivateTheChangeTokenSource()
{
_source.Activate();
}
private void ThenTheChangeTokenShouldBeActivated()
{
_source.ChangeToken.HasChanged.ShouldBeTrue();
}
}
}

View File

@ -0,0 +1,91 @@
using Xunit;
namespace Ocelot.UnitTests.Configuration.ChangeTracking
{
using System;
using Shouldly;
using Ocelot.Configuration.ChangeTracking;
using TestStack.BDDfy;
public class OcelotConfigurationChangeTokenTests
{
[Fact]
public void should_call_callback_with_state()
{
this.Given(_ => GivenIHaveAChangeToken())
.And(_ => AndIRegisterACallback())
.Then(_ => ThenIShouldGetADisposableWrapper())
.Given(_ => GivenIActivateTheToken())
.Then(_ => ThenTheCallbackShouldBeCalled())
.BDDfy();
}
[Fact]
public void should_not_call_callback_if_it_is_disposed()
{
this.Given(_ => GivenIHaveAChangeToken())
.And(_ => AndIRegisterACallback())
.Then(_ => ThenIShouldGetADisposableWrapper())
.And(_ => GivenIActivateTheToken())
.And(_ => AndIDisposeTheCallbackWrapper())
.And(_ => GivenIActivateTheToken())
.Then(_ => ThenTheCallbackShouldNotBeCalled())
.BDDfy();
}
private OcelotConfigurationChangeToken _changeToken;
private IDisposable _callbackWrapper;
private int _callbackCounter;
private readonly object _callbackInitialState = new object();
private object _callbackState;
private void Callback(object state)
{
_callbackCounter++;
_callbackState = state;
_changeToken.HasChanged.ShouldBeTrue();
}
private void GivenIHaveAChangeToken()
{
_changeToken = new OcelotConfigurationChangeToken();
}
private void AndIRegisterACallback()
{
_callbackWrapper = _changeToken.RegisterChangeCallback(Callback, _callbackInitialState);
}
private void ThenIShouldGetADisposableWrapper()
{
_callbackWrapper.ShouldNotBeNull();
}
private void GivenIActivateTheToken()
{
_callbackCounter = 0;
_callbackState = null;
_changeToken.Activate();
}
private void ThenTheCallbackShouldBeCalled()
{
_callbackCounter.ShouldBe(1);
_callbackState.ShouldNotBeNull();
_callbackState.ShouldBeSameAs(_callbackInitialState);
}
private void ThenTheCallbackShouldNotBeCalled()
{
_callbackCounter.ShouldBe(0);
_callbackState.ShouldBeNull();
}
private void AndIDisposeTheCallbackWrapper()
{
_callbackState = null;
_callbackCounter = 0;
_callbackWrapper.Dispose();
}
}
}

View File

@ -3,6 +3,7 @@ namespace Ocelot.UnitTests.Configuration
using Microsoft.AspNetCore.Hosting;
using Moq;
using Newtonsoft.Json;
using Ocelot.Configuration.ChangeTracking;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Shouldly;
@ -16,6 +17,7 @@ namespace Ocelot.UnitTests.Configuration
public class DiskFileConfigurationRepositoryTests : IDisposable
{
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
private IFileConfigurationRepository _repo;
private string _environmentSpecificPath;
private string _ocelotJsonPath;
@ -35,7 +37,9 @@ namespace Ocelot.UnitTests.Configuration
_semaphore.Wait();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
_changeTokenSource.Setup(m => m.Activate());
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
}
[Fact]
@ -70,6 +74,7 @@ namespace Ocelot.UnitTests.Configuration
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.And(x => AndTheChangeTokenIsActivated())
.BDDfy();
}
@ -117,7 +122,7 @@ namespace Ocelot.UnitTests.Configuration
{
_environmentName = null;
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
}
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
@ -210,6 +215,11 @@ namespace Ocelot.UnitTests.Configuration
}
}
private void AndTheChangeTokenIsActivated()
{
_changeTokenSource.Verify(m => m.Activate(), Times.Once);
}
private FileConfiguration FakeFileConfigurationForSet()
{
var reRoutes = new List<FileReRoute>
@ -222,11 +232,11 @@ namespace Ocelot.UnitTests.Configuration
{
Host = "123.12.12.12",
Port = 80,
}
},
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/asdfs/test/{test}"
}
DownstreamPathTemplate = "/asdfs/test/{test}",
},
};
var globalConfiguration = new FileGlobalConfiguration

View File

@ -9,6 +9,7 @@ using Ocelot.Errors;
using Ocelot.Responses;
using Shouldly;
using System.Collections.Generic;
using Ocelot.Configuration.ChangeTracking;
using TestStack.BDDfy;
using Xunit;
@ -21,7 +22,7 @@ namespace Ocelot.UnitTests.Configuration
private Mock<IInternalConfigurationRepository> _configRepo;
private Mock<IInternalConfigurationCreator> _configCreator;
private Response<IInternalConfiguration> _configuration;
private object _result;
private object _result;
private Mock<IFileConfigurationRepository> _repo;
public FileConfigurationSetterTests()
@ -104,8 +105,7 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheConfigurationRepositoryIsCalledCorrectly()
{
_configRepo
.Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
_configRepo.Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
}
}
}
}

View File

@ -5,6 +5,8 @@ using Ocelot.Responses;
using Shouldly;
using System;
using System.Collections.Generic;
using Moq;
using Ocelot.Configuration.ChangeTracking;
using TestStack.BDDfy;
using Xunit;
@ -16,10 +18,13 @@ namespace Ocelot.UnitTests.Configuration
private IInternalConfiguration _config;
private Response _result;
private Response<IInternalConfiguration> _getResult;
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
public InMemoryConfigurationRepositoryTests()
{
_repo = new InMemoryInternalConfigurationRepository();
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
_changeTokenSource.Setup(m => m.Activate());
_repo = new InMemoryInternalConfigurationRepository(_changeTokenSource.Object);
}
[Fact]
@ -28,6 +33,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheConfigurationIs(new FakeConfig("initial", "adminath")))
.When(x => x.WhenIAddOrReplaceTheConfig())
.Then(x => x.ThenNoErrorsAreReturned())
.And(x => AndTheChangeTokenIsActivated())
.BDDfy();
}
@ -71,6 +77,11 @@ namespace Ocelot.UnitTests.Configuration
_result.IsError.ShouldBeFalse();
}
private void AndTheChangeTokenIsActivated()
{
_changeTokenSource.Verify(m => m.Activate(), Times.Once);
}
private class FakeConfig : IInternalConfiguration
{
private readonly string _downstreamTemplatePath;
@ -111,4 +122,4 @@ namespace Ocelot.UnitTests.Configuration
public HttpHandlerOptions HttpHandlerOptions { get; }
}
}
}
}