Merge branch 'master' into jlukawska-feature/1115-find-available-port-in-acceptance-tests

This commit is contained in:
TomPallister
2020-03-11 20:00:55 +00:00
66 changed files with 2439 additions and 1197 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

@ -0,0 +1,243 @@
namespace Ocelot.AcceptanceTests
{
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using TestStack.BDDfy;
using Xunit;
public class HttpTests : IDisposable
{
private readonly Steps _steps;
private readonly ServiceHandler _serviceHandler;
public HttpTests()
{
_serviceHandler = new ServiceHandler();
_steps = new Steps();
}
[Fact]
public void should_return_response_200_when_using_http_one()
{
const int port = 53219;
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "https",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
},
},
DownstreamHttpMethod = "POST",
DownstreamHttpVersion = "1.0",
DangerousAcceptAnyServerCertificateValidator = true
},
},
};
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.BDDfy();
}
[Fact]
public void should_return_response_200_when_using_http_one_point_one()
{
const int port = 53279;
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "https",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
},
},
DownstreamHttpMethod = "POST",
DownstreamHttpVersion = "1.1",
DangerousAcceptAnyServerCertificateValidator = true
},
},
};
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.BDDfy();
}
[Fact]
public void should_return_response_200_when_using_http_two_point_zero()
{
const int port = 53675;
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "https",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
},
},
DownstreamHttpMethod = "POST",
DownstreamHttpVersion = "2.0",
DangerousAcceptAnyServerCertificateValidator = true
},
},
};
const string expected = "here is some content";
var httpContent = new StringContent(expected);
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http2))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
.BDDfy();
}
[Fact]
public void should_return_response_500_when_using_http_one_to_talk_to_server_running_http_two()
{
const int port = 53677;
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "https",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
},
},
DownstreamHttpMethod = "POST",
DownstreamHttpVersion = "1.1",
DangerousAcceptAnyServerCertificateValidator = true
},
},
};
const string expected = "here is some content";
var httpContent = new StringContent(expected);
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http2))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.InternalServerError))
.BDDfy();
}
[Fact]
public void should_return_response_200_when_using_http_two_to_talk_to_server_running_http_one_point_one()
{
const int port = 53679;
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "https",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
},
},
DownstreamHttpMethod = "POST",
DownstreamHttpVersion = "2.0",
DangerousAcceptAnyServerCertificateValidator = true
},
},
};
const string expected = "here is some content";
var httpContent = new StringContent(expected);
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int port, HttpProtocols protocols)
{
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
{
context.Response.StatusCode = 200;
var reader = new StreamReader(context.Request.Body);
var body = await reader.ReadToEndAsync();
await context.Response.WriteAsync(body);
}, port, protocols);
}
public void Dispose()
{
_serviceHandler.Dispose();
_steps.Dispose();
}
}
}

View File

@ -0,0 +1,158 @@
namespace Ocelot.AcceptanceTests
{
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using TestStack.BDDfy;
using Xunit;
public class MethodTests : IDisposable
{
private readonly Steps _steps;
private readonly ServiceHandler _serviceHandler;
public MethodTests()
{
_serviceHandler = new ServiceHandler();
_steps = new Steps();
}
[Fact]
public void should_return_response_200_when_get_converted_to_post()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 53171,
},
},
DownstreamHttpMethod = "POST",
},
},
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53171/", "/", "POST"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.BDDfy();
}
[Fact]
public void should_return_response_200_when_get_converted_to_post_with_content()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 53271,
},
},
DownstreamHttpMethod = "POST",
},
},
};
const string expected = "here is some content";
var httpContent = new StringContent(expected);
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53271/", "/", "POST"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
.BDDfy();
}
[Fact]
public void should_return_response_200_when_get_converted_to_get_with_content()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Post" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 53272,
},
},
DownstreamHttpMethod = "GET",
},
},
};
const string expected = "here is some content";
var httpContent = new StringContent(expected);
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53272/", "/", "GET"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/", httpContent))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string expected)
{
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
{
if (context.Request.Method == expected)
{
context.Response.StatusCode = 200;
var reader = new StreamReader(context.Request.Body);
var body = await reader.ReadToEndAsync();
await context.Response.WriteAsync(body);
}
else
{
context.Response.StatusCode = 500;
}
});
}
public void Dispose()
{
_serviceHandler.Dispose();
_steps.Dispose();
}
}
}

View File

@ -6,9 +6,11 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Core;
public class ServiceHandler : IDisposable
{
@ -47,6 +49,31 @@
_builder.Start();
}
public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, RequestDelegate del, int port, HttpProtocols protocols)
{
_builder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Loopback, port, listenOptions =>
{
listenOptions.UseHttps("idsrv3test.pfx", "idsrv3test");
listenOptions.Protocols = protocols;
});
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
{
app.UsePathBase(basePath);
app.Run(del);
})
.Build();
_builder.Start();
}
public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string fileName, string password, int port, RequestDelegate del)
{
_builder = new WebHostBuilder()

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>
@ -384,6 +392,7 @@
_ocelotServer = new TestServer(_webHostBuilder);
_ocelotClient = _ocelotServer.CreateClient();
Thread.Sleep(1000);
}
public void WhenIGetUrlOnTheApiGatewayWaitingForTheResponseToBeOk(string url)
@ -901,6 +910,18 @@
_response = _ocelotClient.GetAsync(url).Result;
}
public void WhenIGetUrlOnTheApiGateway(string url, HttpContent content)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url) {Content = content};
_response = _ocelotClient.SendAsync(httpRequestMessage).Result;
}
public void WhenIPostUrlOnTheApiGateway(string url, HttpContent content)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
_response = _ocelotClient.SendAsync(httpRequestMessage).Result;
}
public void WhenIGetUrlOnTheApiGateway(string url, string cookie, string value)
{
var request = _ocelotServer.CreateRequest(url);
@ -1123,6 +1144,11 @@
_ocelotClient = _ocelotServer.CreateClient();
}
public void TheChangeTokenShouldBeActive(bool itShouldBeActive)
{
_changeToken.ChangeToken.HasChanged.ShouldBe(itShouldBeActive);
}
public void GivenOcelotIsRunningWithLogger()
{
_webHostBuilder = new WebHostBuilder();

View File

@ -59,7 +59,7 @@ namespace Ocelot.Benchmarks
_downstreamContext = new DownstreamContext(httpContext)
{
Configuration = new InternalConfiguration(new List<ReRoute>(), null, null, null, null, null, null, null)
Configuration = new InternalConfiguration(new List<ReRoute>(), null, null, null, null, null, null, null, null)
};
}

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

@ -19,6 +19,7 @@ namespace Ocelot.UnitTests.Configuration
private readonly Mock<IQoSOptionsCreator> _qosCreator;
private readonly Mock<IHttpHandlerOptionsCreator> _hhoCreator;
private readonly Mock<ILoadBalancerOptionsCreator> _lboCreator;
private readonly Mock<IVersionCreator> _vCreator;
private FileConfiguration _fileConfig;
private List<ReRoute> _reRoutes;
private ServiceProviderConfiguration _spc;
@ -30,6 +31,7 @@ namespace Ocelot.UnitTests.Configuration
public ConfigurationCreatorTests()
{
_vCreator = new Mock<IVersionCreator>();
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
_qosCreator = new Mock<IQoSOptionsCreator>();
@ -117,7 +119,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenICreate()
{
var serviceProvider = _serviceCollection.BuildServiceProvider();
_creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object);
_creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object, _vCreator.Object);
_result = _creator.Create(_fileConfig, _reRoutes);
}
}

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

@ -1,5 +1,6 @@
namespace Ocelot.UnitTests.Configuration
{
using System;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
@ -14,15 +15,18 @@
{
private readonly DynamicsCreator _creator;
private readonly Mock<IRateLimitOptionsCreator> _rloCreator;
private readonly Mock<IVersionCreator> _versionCreator;
private List<ReRoute> _result;
private FileConfiguration _fileConfig;
private RateLimitOptions _rlo1;
private RateLimitOptions _rlo2;
private Version _version;
public DynamicsCreatorTests()
{
_versionCreator = new Mock<IVersionCreator>();
_rloCreator = new Mock<IRateLimitOptionsCreator>();
_creator = new DynamicsCreator(_rloCreator.Object);
_creator = new DynamicsCreator(_rloCreator.Object, _versionCreator.Object);
}
[Fact]
@ -50,7 +54,8 @@
RateLimitRule = new FileRateLimitRule
{
EnableRateLimiting = false
}
},
DownstreamHttpVersion = "1.1"
},
new FileDynamicReRoute
{
@ -58,16 +63,19 @@
RateLimitRule = new FileRateLimitRule
{
EnableRateLimiting = true
}
},
DownstreamHttpVersion = "2.0"
}
}
};
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenTheRloCreatorReturns())
.And(_ => GivenTheVersionCreatorReturns())
.When(_ => WhenICreate())
.Then(_ => ThenTheReRoutesAreReturned())
.And(_ => ThenTheRloCreatorIsCalledCorrectly())
.And(_ => ThenTheVersionCreatorIsCalledCorrectly())
.BDDfy();
}
@ -80,18 +88,32 @@
_fileConfig.GlobalConfiguration), Times.Once);
}
private void ThenTheVersionCreatorIsCalledCorrectly()
{
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[0].DownstreamHttpVersion), Times.Once);
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[1].DownstreamHttpVersion), Times.Once);
}
private void ThenTheReRoutesAreReturned()
{
_result.Count.ShouldBe(2);
_result[0].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeFalse();
_result[0].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo1);
_result[0].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_version);
_result[0].DownstreamReRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicReRoutes[0].ServiceName);
_result[1].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
_result[1].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo2);
_result[1].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_version);
_result[1].DownstreamReRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicReRoutes[1].ServiceName);
}
private void GivenTheVersionCreatorReturns()
{
_version = new Version("1.1");
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_version);
}
private void GivenTheRloCreatorReturns()
{
_rlo1 = new RateLimitOptionsBuilder().Build();

View File

@ -9,11 +9,14 @@ using Ocelot.Errors;
using Ocelot.Responses;
using Shouldly;
using System.Collections.Generic;
using Ocelot.Configuration.ChangeTracking;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
using System;
public class FileConfigurationSetterTests
{
private FileConfiguration _fileConfiguration;
@ -21,7 +24,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()
@ -37,7 +40,7 @@ namespace Ocelot.UnitTests.Configuration
{
var fileConfig = new FileConfiguration();
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
.And(x => GivenTheRepoReturns(new OkResponse()))
@ -104,8 +107,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

@ -87,7 +87,7 @@
_reRoutes = new List<ReRoute> { new ReRouteBuilder().Build() };
_aggregates = new List<ReRoute> { new ReRouteBuilder().Build() };
_dynamics = new List<ReRoute> { new ReRouteBuilder().Build() };
_internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null);
_internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null, null);
_reRoutesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_reRoutes);
_aggregatesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<ReRoute>>())).Returns(_aggregates);

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;
@ -109,6 +120,7 @@ namespace Ocelot.UnitTests.Configuration
public string DownstreamScheme { get; }
public QoSOptions QoSOptions { get; }
public HttpHandlerOptions HttpHandlerOptions { get; }
public Version DownstreamHttpVersion { get; }
}
}
}
}

View File

@ -1,5 +1,6 @@
namespace Ocelot.UnitTests.Configuration
{
using System;
using Moq;
using Ocelot.Cache;
using Ocelot.Configuration;
@ -30,6 +31,7 @@
private Mock<ILoadBalancerOptionsCreator> _lboCreator;
private Mock<IReRouteKeyCreator> _rrkCreator;
private Mock<ISecurityOptionsCreator> _soCreator;
private Mock<IVersionCreator> _versionCreator;
private FileConfiguration _fileConfig;
private ReRouteOptions _rro;
private string _requestId;
@ -46,6 +48,7 @@
private LoadBalancerOptions _lbo;
private List<ReRoute> _result;
private SecurityOptions _securityOptions;
private Version _expectedVersion;
public ReRoutesCreatorTests()
{
@ -63,6 +66,7 @@
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
_rrkCreator = new Mock<IReRouteKeyCreator>();
_soCreator = new Mock<ISecurityOptionsCreator>();
_versionCreator = new Mock<IVersionCreator>();
_creator = new ReRoutesCreator(
_cthCreator.Object,
@ -78,7 +82,8 @@
_daCreator.Object,
_lboCreator.Object,
_rrkCreator.Object,
_soCreator.Object
_soCreator.Object,
_versionCreator.Object
);
}
@ -155,6 +160,7 @@
private void GivenTheDependenciesAreSetUpCorrectly()
{
_expectedVersion = new Version("1.1");
_rro = new ReRouteOptions(false, false, false, false, false);
_requestId = "testy";
_rrk = "besty";
@ -182,6 +188,7 @@
_hfarCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_ht);
_daCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_dhp);
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_expectedVersion);
}
private void ThenTheReRoutesAreCreated()
@ -209,6 +216,7 @@
private void ThenTheReRouteIsSet(FileReRoute expected, int reRouteIndex)
{
_result[reRouteIndex].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_expectedVersion);
_result[reRouteIndex].DownstreamReRoute[0].IsAuthenticated.ShouldBe(_rro.IsAuthenticated);
_result[reRouteIndex].DownstreamReRoute[0].IsAuthorised.ShouldBe(_rro.IsAuthorised);
_result[reRouteIndex].DownstreamReRoute[0].IsCached.ShouldBe(_rro.IsCached);

View File

@ -305,6 +305,71 @@
.BDDfy();
}
[Theory]
[InlineData("1.0")]
[InlineData("1.1")]
[InlineData("2.0")]
[InlineData("1,0")]
[InlineData("1,1")]
[InlineData("2,0")]
[InlineData("1")]
[InlineData("2")]
[InlineData("")]
[InlineData(null)]
public void should_be_valid_re_route_using_downstream_http_version(string version)
{
var fileReRoute = new FileReRoute
{
DownstreamPathTemplate = "/test",
UpstreamPathTemplate = "/test",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 5000,
},
},
DownstreamHttpVersion = version,
};
this.Given(_ => GivenThe(fileReRoute))
.When(_ => WhenIValidate())
.Then(_ => ThenTheResultIsValid())
.BDDfy();
}
[Theory]
[InlineData("retg1.1")]
[InlineData("re2.0")]
[InlineData("1,0a")]
[InlineData("a1,1")]
[InlineData("12,0")]
[InlineData("asdf")]
public void should_be_invalid_re_route_using_downstream_http_version(string version)
{
var fileReRoute = new FileReRoute
{
DownstreamPathTemplate = "/test",
UpstreamPathTemplate = "/test",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 5000,
},
},
DownstreamHttpVersion = version,
};
this.Given(_ => GivenThe(fileReRoute))
.When(_ => WhenIValidate())
.Then(_ => ThenTheResultIsInvalid())
.And(_ => ThenTheErrorsContains("'Downstream Http Version' is not in the correct format."))
.BDDfy();
}
private void GivenAnAuthProvider(string key)
{
var schemes = new List<AuthenticationScheme>

View File

@ -0,0 +1,54 @@
namespace Ocelot.UnitTests.Configuration
{
using System;
using Ocelot.Configuration.Creator;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class VersionCreatorTests
{
private readonly HttpVersionCreator _creator;
private string _input;
private Version _result;
public VersionCreatorTests()
{
_creator = new HttpVersionCreator();
}
[Fact]
public void should_create_version_based_on_input()
{
this.Given(_ => GivenTheInput("2.0"))
.When(_ => WhenICreate())
.Then(_ => ThenTheResultIs(2, 0))
.BDDfy();
}
[Fact]
public void should_default_to_version_one_point_one()
{
this.Given(_ => GivenTheInput(""))
.When(_ => WhenICreate())
.Then(_ => ThenTheResultIs(1, 1))
.BDDfy();
}
private void GivenTheInput(string input)
{
_input = input;
}
private void WhenICreate()
{
_result = _creator.Create(_input);
}
private void ThenTheResultIs(int major, int minor)
{
_result.Major.ShouldBe(major);
_result.Minor.ShouldBe(minor);
}
}
}

View File

@ -1,5 +1,6 @@
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
using System;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
@ -44,7 +45,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
[Fact]
public void should_create_downstream_route()
{
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration))
.When(_ => WhenICreate())
@ -71,7 +72,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
var reRoutes = new List<ReRoute> { reRoute };
var configuration = new InternalConfiguration(reRoutes, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(reRoutes, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration))
.When(_ => WhenICreate())
@ -83,7 +84,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
[Fact]
public void should_cache_downstream_route()
{
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
.When(_ => WhenICreate())
@ -96,7 +97,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
[Fact]
public void should_not_cache_downstream_route()
{
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration, "/geoffistheworst/"))
.When(_ => WhenICreate())
@ -110,7 +111,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public void should_create_downstream_route_with_no_path()
{
var upstreamUrlPath = "/auth/";
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
.When(_ => WhenICreate())
@ -122,7 +123,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public void should_create_downstream_route_with_only_first_segment_no_traling_slash()
{
var upstreamUrlPath = "/auth";
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
.When(_ => WhenICreate())
@ -134,7 +135,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public void should_create_downstream_route_with_segments_no_traling_slash()
{
var upstreamUrlPath = "/auth/test";
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
.When(_ => WhenICreate())
@ -146,7 +147,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public void should_create_downstream_route_and_remove_query_string()
{
var upstreamUrlPath = "/auth/test?test=1&best=2";
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
.When(_ => WhenICreate())
@ -158,7 +159,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public void should_create_downstream_route_for_sticky_sessions()
{
var loadBalancerOptions = new LoadBalancerOptionsBuilder().WithType(nameof(CookieStickySessions)).WithKey("boom").WithExpiryInMs(1).Build();
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration))
.When(_ => WhenICreate())
@ -174,7 +175,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithTimeoutValue(1)
.Build();
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration))
.And(_ => GivenTheQosCreatorReturns(qoSOptions))
@ -186,7 +187,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
[Fact]
public void should_create_downstream_route_with_handler_options()
{
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
this.Given(_ => GivenTheConfiguration(configuration))
.When(_ => WhenICreate())

View File

@ -1,5 +1,6 @@
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
using System;
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Configuration;
@ -48,7 +49,7 @@
[Fact]
public void should_call_scoped_data_repository_correctly()
{
var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")

View File

@ -13,6 +13,8 @@ using Xunit;
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
using System;
public class DownstreamRouteFinderTests
{
private readonly IDownstreamRouteProvider _downstreamRouteFinder;
@ -739,7 +741,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
{
_reRoutesConfig = reRoutesConfig;
_config = new InternalConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
_config = new InternalConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
}
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)

View File

@ -1,5 +1,6 @@
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
using System;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
@ -140,12 +141,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void GivenTheReRoutes(List<ReRoute> reRoutes)
{
_config = new InternalConfiguration(reRoutes, "", null, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
_config = new InternalConfiguration(reRoutes, "", null, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
}
private void GivenTheReRoutes(List<ReRoute> reRoutes, ServiceProviderConfiguration config)
{
_config = new InternalConfiguration(reRoutes, "", config, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
_config = new InternalConfiguration(reRoutes, "", config, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
}
}
}

View File

@ -382,7 +382,7 @@
private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
{
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null, null);
_downstreamContext.Configuration = configuration;
}

View File

@ -52,7 +52,7 @@ namespace Ocelot.UnitTests.Errors
[Fact]
public void NoDownstreamException()
{
var config = new InternalConfiguration(null, null, null, null, null, null, null, null);
var config = new InternalConfiguration(null, null, null, null, null, null, null, null, null);
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
@ -65,7 +65,7 @@ namespace Ocelot.UnitTests.Errors
[Fact]
public void DownstreamException()
{
var config = new InternalConfiguration(null, null, null, null, null, null, null, null);
var config = new InternalConfiguration(null, null, null, null, null, null, null, null, null);
this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
@ -77,7 +77,7 @@ namespace Ocelot.UnitTests.Errors
[Fact]
public void ShouldSetRequestId()
{
var config = new InternalConfiguration(null, null, null, "requestidkey", null, null, null, null);
var config = new InternalConfiguration(null, null, null, "requestidkey", null, null, null, null, null);
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.Errors
[Fact]
public void ShouldSetAspDotNetRequestId()
{
var config = new InternalConfiguration(null, null, null, null, null, null, null, null);
var config = new InternalConfiguration(null, null, null, null, null, null, null, null, null);
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))

View File

@ -20,7 +20,7 @@
{
var configRepo = new Mock<IInternalConfigurationRepository>();
configRepo.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, null, null, null, null, null, null)));
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, null, null, null, null, null, null, null)));
var services = new ServiceCollection();
services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
var sp = services.BuildServiceProvider();
@ -35,7 +35,7 @@
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)));
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, serviceProviderConfig, null, null, null, null, null, null)));
var services = new ServiceCollection();
services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
services.AddSingleton<IDiscoveryClient>(client.Object);

View File

@ -139,7 +139,7 @@ namespace Ocelot.UnitTests.LoadBalancer
private void GivenTheConfigurationIs(ServiceProviderConfiguration config)
{
_config = config;
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null, null);
_downstreamContext.Configuration = configuration;
}

View File

@ -1,6 +1,4 @@
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Request
namespace Ocelot.UnitTests.Request
{
using Microsoft.AspNetCore.Http;
using Moq;
@ -9,9 +7,12 @@ namespace Ocelot.UnitTests.Request
using Ocelot.Request.Creator;
using Ocelot.Request.Mapper;
using Ocelot.Request.Middleware;
using Ocelot.Configuration.Builder;
using Ocelot.Middleware;
using Ocelot.Responses;
using Shouldly;
using System.Net.Http;
using Ocelot.Configuration;
using TestStack.BDDfy;
using Xunit;
@ -65,6 +66,20 @@ namespace Ocelot.UnitTests.Request
.Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest())
.And(_ => ThenTheDownstreamRequestIsStored())
.And(_ => ThenTheNextMiddlewareIsInvoked())
.And(_ => ThenTheDownstreamRequestMethodIs("GET"))
.BDDfy();
}
[Fact]
public void Should_map_downstream_reroute_method_to_downstream_request()
{
this.Given(_ => GivenTheHttpContextContainsARequest())
.And(_ => GivenTheMapperWillReturnAMappedRequest())
.When(_ => WhenTheMiddlewareIsInvoked())
.Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest())
.And(_ => ThenTheDownstreamRequestIsStored())
.And(_ => ThenTheNextMiddlewareIsInvoked())
.And(_ => ThenTheDownstreamRequestMethodIs("GET"))
.BDDfy();
}
@ -80,6 +95,11 @@ namespace Ocelot.UnitTests.Request
.BDDfy();
}
private void ThenTheDownstreamRequestMethodIs(string expected)
{
_downstreamContext.DownstreamRequest.Method.ShouldBe(expected);
}
private void GivenTheHttpContextContainsARequest()
{
_httpContext
@ -92,7 +112,7 @@ namespace Ocelot.UnitTests.Request
_mappedRequest = new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "http://www.bbc.co.uk"));
_requestMapper
.Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
.Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>()))
.ReturnsAsync(_mappedRequest);
}
@ -101,7 +121,7 @@ namespace Ocelot.UnitTests.Request
_mappedRequest = new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(new System.Exception("boooom!")));
_requestMapper
.Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
.Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>()))
.ReturnsAsync(_mappedRequest);
}
@ -112,7 +132,7 @@ namespace Ocelot.UnitTests.Request
private void ThenTheContexRequestIsMappedToADownstreamRequest()
{
_requestMapper.Verify(rm => rm.Map(_httpRequest.Object), Times.Once);
_requestMapper.Verify(rm => rm.Map(_httpRequest.Object, _downstreamContext.DownstreamReRoute), Times.Once);
}
private void ThenTheDownstreamRequestIsStored()

View File

@ -13,6 +13,8 @@
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using TestStack.BDDfy;
using Xunit;
@ -27,6 +29,8 @@
private List<KeyValuePair<string, StringValues>> _inputHeaders = null;
private DownstreamReRoute _downstreamReRoute;
public RequestMapperTests()
{
_httpContext = new DefaultHttpContext();
@ -47,6 +51,7 @@
.And(_ => GivenTheInputRequestHasHost(host))
.And(_ => GivenTheInputRequestHasPath(path))
.And(_ => GivenTheInputRequestHasQueryString(queryString))
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasUri(expectedUri))
@ -76,18 +81,35 @@
{
this.Given(_ => GivenTheInputRequestHasMethod(method))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasMethod(method))
.BDDfy();
}
[Theory]
[InlineData("", "GET")]
[InlineData(null, "GET")]
[InlineData("POST", "POST")]
public void Should_use_downstream_reroute_method_if_set(string input, string expected)
{
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheDownstreamReRouteMethodIs(input))
.And(_ => GivenTheInputRequestHasAValidUri())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasMethod(expected))
.BDDfy();
}
[Fact]
public void Should_map_all_headers()
{
this.Given(_ => GivenTheInputRequestHasHeaders())
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasEachHeader())
@ -100,6 +122,7 @@
this.Given(_ => GivenTheInputRequestHasNoHeaders())
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasNoHeaders())
@ -112,6 +135,7 @@
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasContent("This is my content"))
@ -124,6 +148,7 @@
this.Given(_ => GivenTheInputRequestHasNullContent())
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasNoContent())
@ -136,6 +161,7 @@
this.Given(_ => GivenTheInputRequestHasNoContentType())
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasNoContent())
@ -148,22 +174,13 @@
this.Given(_ => GivenTheInputRequestHasNoContentLength())
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasNoContent())
.BDDfy();
}
private void GivenTheInputRequestHasNoContentLength()
{
_inputRequest.ContentLength = null;
}
private void GivenTheInputRequestHasNoContentType()
{
_inputRequest.ContentType = null;
}
[Fact]
public void Should_map_content_headers()
{
@ -183,6 +200,7 @@
.And(_ => GivenTheContentMD5Is(md5bytes))
.And(_ => GivenTheInputRequestHasMethod("GET"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
@ -204,6 +222,7 @@
.And(_ => GivenTheContentTypeIs("application/json"))
.And(_ => GivenTheInputRequestHasMethod("POST"))
.And(_ => GivenTheInputRequestHasAValidUri())
.And(_ => GivenTheDownstreamReRoute())
.When(_ => WhenMapped())
.Then(_ => ThenNoErrorIsReturned())
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
@ -212,6 +231,30 @@
.BDDfy();
}
private void GivenTheDownstreamReRouteMethodIs(string input)
{
_downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownStreamHttpMethod(input)
.WithDownstreamHttpVersion(new Version("1.1")).Build();
}
private void GivenTheDownstreamReRoute()
{
_downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamHttpVersion(new Version("1.1")).Build();
}
private void GivenTheInputRequestHasNoContentLength()
{
_inputRequest.ContentLength = null;
}
private void GivenTheInputRequestHasNoContentType()
{
_inputRequest.ContentType = null;
}
private void ThenTheContentHeadersAreNotAddedToNonContentHeaders()
{
_mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Disposition");
@ -380,7 +423,7 @@
private async Task WhenMapped()
{
_mappedRequest = await _requestMapper.Map(_inputRequest);
_mappedRequest = await _requestMapper.Map(_inputRequest, _downstreamReRoute);
}
private void ThenNoErrorIsReturned()