Merge remote-tracking branch 'upstream/develop' into feature/AddStyleCopAnalyzers

# Conflicts:
#	test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj
#	test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj
This commit is contained in:
Philip Wood
2018-03-03 12:33:04 +00:00
161 changed files with 4612 additions and 2073 deletions

View File

@ -0,0 +1,372 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.AcceptanceTests
{
public class AggregateTests : IDisposable
{
private IWebHost _serviceOneBuilder;
private IWebHost _serviceTwoBuilder;
private readonly Steps _steps;
private string _downstreamPathOne;
private string _downstreamPathTwo;
public AggregateTests()
{
_steps = new Steps();
}
[Fact]
public void should_return_response_200_with_simple_url()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51885,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51886,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
var expected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51885", "/", 200, "{Hello from Laura}"))
.Given(x => x.GivenServiceTwoIsRunning("http://localhost:51886", "/", 200, "{Hello from Tom}"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe(expected))
.And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
.BDDfy();
}
[Fact]
public void should_return_response_200_with_simple_url_one_service_404()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51881,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51882,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
var expected = "{\"Laura\":,\"Tom\":{Hello from Tom}}";
this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51881", "/", 404, ""))
.Given(x => x.GivenServiceTwoIsRunning("http://localhost:51882", "/", 200, "{Hello from Tom}"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe(expected))
.And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
.BDDfy();
}
[Fact]
public void should_return_response_200_with_simple_url_both_service_404()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51883,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51884,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
var expected = "{\"Laura\":,\"Tom\":}";
this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51883", "/", 404, ""))
.Given(x => x.GivenServiceTwoIsRunning("http://localhost:51884", "/", 404, ""))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe(expected))
.And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
.BDDfy();
}
[Fact]
public void should_be_thread_safe()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51878", "/", 200, "{Hello from Laura}"))
.Given(x => x.GivenServiceTwoIsRunning("http://localhost:51880", "/", 200, "{Hello from Tom}"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIMakeLotsOfDifferentRequestsToTheApiGateway())
.And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
.BDDfy();
}
private void GivenServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
{
_serviceOneBuilder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
{
app.UsePathBase(basePath);
app.Run(async context =>
{
_downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
if(_downstreamPathOne != basePath)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync("downstream path didnt match base path");
}
else
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
}
});
})
.Build();
_serviceOneBuilder.Start();
}
private void GivenServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
{
_serviceOneBuilder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
{
app.UsePathBase(basePath);
app.Run(async context =>
{
_downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
if(_downstreamPathTwo != basePath)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync("downstream path didnt match base path");
}
else
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
}
});
})
.Build();
_serviceOneBuilder.Start();
}
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPathOne, string expectedDownstreamPath)
{
_downstreamPathOne.ShouldBe(expectedDownstreamPathOne);
_downstreamPathTwo.ShouldBe(expectedDownstreamPath);
}
public void Dispose()
{
_serviceOneBuilder?.Dispose();
_serviceTwoBuilder?.Dispose();
_steps.Dispose();
}
}
}

View File

@ -0,0 +1,225 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
using Butterfly.Client.AspNetCore;
using static Rafty.Infrastructure.Wait;
namespace Ocelot.AcceptanceTests
{
public class ButterflyTracingTests : IDisposable
{
private IWebHost _serviceOneBuilder;
private IWebHost _serviceTwoBuilder;
private IWebHost _fakeButterfly;
private readonly Steps _steps;
private string _downstreamPathOne;
private string _downstreamPathTwo;
private int _butterflyCalled;
public ButterflyTracingTests()
{
_steps = new Steps();
}
[Fact]
public void should_forward_tracing_information_from_ocelot_and_downstream_services()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/api/values",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51887,
}
},
UpstreamPathTemplate = "/api001/values",
UpstreamHttpMethod = new List<string> { "Get" },
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseTracing = true
},
QoSOptions = new FileQoSOptions
{
ExceptionsAllowedBeforeBreaking = 3,
DurationOfBreak = 10,
TimeoutValue = 5000
}
},
new FileReRoute
{
DownstreamPathTemplate = "/api/values",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51888,
}
},
UpstreamPathTemplate = "/api002/values",
UpstreamHttpMethod = new List<string> { "Get" },
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseTracing = true
},
QoSOptions = new FileQoSOptions
{
ExceptionsAllowedBeforeBreaking = 3,
DurationOfBreak = 10,
TimeoutValue = 5000
}
}
}
};
var butterflyUrl = "http://localhost:9618";
this.Given(x => GivenServiceOneIsRunning("http://localhost:51887", "/api/values", 200, "Hello from Laura", butterflyUrl))
.And(x => GivenServiceTwoIsRunning("http://localhost:51888", "/api/values", 200, "Hello from Tom", butterflyUrl))
.And(x => GivenFakeButterfly(butterflyUrl))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunningUsingButterfly(butterflyUrl))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/api001/values"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/api002/values"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Tom"))
.BDDfy();
var commandOnAllStateMachines = WaitFor(5000).Until(() => _butterflyCalled == 4);
commandOnAllStateMachines.ShouldBeTrue();
}
private void GivenServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody, string butterflyUrl)
{
_serviceOneBuilder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.ConfigureServices(services => {
services.AddButterfly(option =>
{
option.CollectorUrl = butterflyUrl;
option.Service = "Service One";
option.IgnoredRoutesRegexPatterns = new string[0];
});
})
.Configure(app =>
{
app.UsePathBase(basePath);
app.Run(async context =>
{
_downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
if(_downstreamPathOne != basePath)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync("downstream path didnt match base path");
}
else
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
}
});
})
.Build();
_serviceOneBuilder.Start();
}
private void GivenFakeButterfly(string baseUrl)
{
_fakeButterfly = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
{
app.Run(async context =>
{
_butterflyCalled++;
await context.Response.WriteAsync("OK...");
});
})
.Build();
_fakeButterfly.Start();
}
private void GivenServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody, string butterflyUrl)
{
_serviceTwoBuilder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.ConfigureServices(services => {
services.AddButterfly(option =>
{
option.CollectorUrl = butterflyUrl;
option.Service = "Service Two";
option.IgnoredRoutesRegexPatterns = new string[0];
});
})
.Configure(app =>
{
app.UsePathBase(basePath);
app.Run(async context =>
{
_downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
if(_downstreamPathTwo != basePath)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync("downstream path didnt match base path");
}
else
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
}
});
})
.Build();
_serviceTwoBuilder.Start();
}
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPathOne, string expectedDownstreamPath)
{
_downstreamPathOne.ShouldBe(expectedDownstreamPathOne);
_downstreamPathTwo.ShouldBe(expectedDownstreamPath);
}
public void Dispose()
{
_serviceOneBuilder?.Dispose();
_serviceTwoBuilder?.Dispose();
_fakeButterfly?.Dispose();
_steps.Dispose();
}
}
}

View File

@ -37,7 +37,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51899,
}
},
DownstreamScheme = "http",
@ -51,13 +51,13 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51879", 200, "Hello from Tom"))
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
@ -80,7 +80,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51899,
}
},
DownstreamScheme = "http",
@ -94,13 +94,13 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunningUsingJsonSerializedCache())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51879", 200, "Hello from Tom"))
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
@ -122,7 +122,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51899,
}
},
DownstreamScheme = "http",
@ -136,13 +136,13 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51879", 200, "Hello from Tom"))
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
.And(x => x.GivenTheCacheExpires())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))

View File

@ -36,7 +36,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51877,
}
},
DownstreamScheme = "http",
@ -46,7 +46,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
@ -69,7 +69,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51877,
}
},
DownstreamScheme = "http",
@ -80,7 +80,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
@ -103,7 +103,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51877,
}
},
DownstreamScheme = "http",
@ -114,7 +114,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
@ -137,7 +137,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51877,
}
},
DownstreamScheme = "http",
@ -148,7 +148,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
@ -171,7 +171,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51877,
}
},
DownstreamScheme = "http",
@ -182,7 +182,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
@ -205,7 +205,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51877,
}
},
DownstreamScheme = "http",
@ -216,7 +216,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))

View File

@ -48,7 +48,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51876,
}
},
DownstreamScheme = "http",
@ -81,7 +81,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/ClientRateLimit"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", "/api/ClientRateLimit"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
@ -109,7 +109,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51876,
}
},
DownstreamScheme = "http",
@ -140,7 +140,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/ClientRateLimit"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", "/api/ClientRateLimit"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))

View File

@ -4,13 +4,10 @@ using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
using TestStack.BDDfy;
using Xunit;
@ -275,7 +272,11 @@ namespace Ocelot.AcceptanceTests
private void GivenIWaitForTheConfigToReplicateToOcelot()
{
Thread.Sleep(10000);
var stopWatch = Stopwatch.StartNew();
while (stopWatch.ElapsedMilliseconds < 10000)
{
//do nothing!
}
}
private void GivenTheConsulConfigurationIs(FileConfiguration config)

View File

@ -32,7 +32,7 @@ namespace Ocelot.AcceptanceTests
[Fact]
public void should_call_pre_query_string_builder_middleware()
{
var configuration = new OcelotMiddlewareConfiguration
var configuration = new OcelotPipelineConfiguration
{
AuthorisationMiddleware = async (ctx, next) =>
{
@ -75,7 +75,7 @@ namespace Ocelot.AcceptanceTests
[Fact]
public void should_call_authorisation_middleware()
{
var configuration = new OcelotMiddlewareConfiguration
var configuration = new OcelotPipelineConfiguration
{
AuthorisationMiddleware = async (ctx, next) =>
{
@ -118,7 +118,7 @@ namespace Ocelot.AcceptanceTests
[Fact]
public void should_call_authentication_middleware()
{
var configuration = new OcelotMiddlewareConfiguration
var configuration = new OcelotPipelineConfiguration
{
AuthenticationMiddleware = async (ctx, next) =>
{
@ -161,7 +161,7 @@ namespace Ocelot.AcceptanceTests
[Fact]
public void should_call_pre_error_middleware()
{
var configuration = new OcelotMiddlewareConfiguration
var configuration = new OcelotPipelineConfiguration
{
PreErrorResponderMiddleware = async (ctx, next) =>
{
@ -204,7 +204,7 @@ namespace Ocelot.AcceptanceTests
[Fact]
public void should_call_pre_authorisation_middleware()
{
var configuration = new OcelotMiddlewareConfiguration
var configuration = new OcelotPipelineConfiguration
{
PreAuthorisationMiddleware = async (ctx, next) =>
{
@ -247,7 +247,7 @@ namespace Ocelot.AcceptanceTests
[Fact]
public void should_call_pre_http_authentication_middleware()
{
var configuration = new OcelotMiddlewareConfiguration
var configuration = new OcelotPipelineConfiguration
{
PreAuthenticationMiddleware = async (ctx, next) =>
{

View File

@ -41,7 +41,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51871,
}
},
UpstreamPathTemplate = "/",
@ -54,7 +54,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Laz"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51871", "/", 200, "Laz"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.And(x => _steps.GivenIAddAHeader("Laz", "D"))
@ -80,7 +80,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51871,
}
},
UpstreamPathTemplate = "/",
@ -93,7 +93,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Location", "http://www.bbc.co.uk/"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51871", "/", 200, "Location", "http://www.bbc.co.uk/"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))

View File

@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.0</TargetFramework>
@ -20,16 +19,13 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
<ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
@ -52,6 +48,6 @@
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="Consul" Version="0.7.2.3" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
</ItemGroup>
</Project>

View File

@ -41,7 +41,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51872,
}
},
UpstreamPathTemplate = "/",
@ -57,7 +57,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51879", "Hello from Laura"))
this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51872", "Hello from Laura"))
.Given(x => _steps.GivenThereIsAConfiguration(configuration))
.Given(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -92,7 +92,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51872,
}
},
UpstreamPathTemplate = "/",
@ -122,7 +122,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51879", "Hello from Laura"))
this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51872", "Hello from Laura"))
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", 200, "Hello from Tom"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())

View File

@ -39,7 +39,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51873,
}
},
DownstreamScheme = "http",
@ -50,7 +50,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51873"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -73,7 +73,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51873,
}
},
DownstreamScheme = "http",
@ -85,7 +85,7 @@ namespace Ocelot.AcceptanceTests
var requestId = Guid.NewGuid().ToString();
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51873"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", requestId))
@ -108,7 +108,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51873,
}
},
DownstreamScheme = "http",
@ -124,7 +124,7 @@ namespace Ocelot.AcceptanceTests
var requestId = Guid.NewGuid().ToString();
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51873"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", requestId))

View File

@ -298,7 +298,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51874,
}
},
UpstreamPathTemplate = "/vacancy/",
@ -315,7 +315,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51874,
}
},
UpstreamPathTemplate = "/vacancy/{vacancyId}",
@ -326,7 +326,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/v1/vacancy/1", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51874", "/api/v1/vacancy/1", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/vacancy/1"))

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
@ -24,6 +26,8 @@ using Ocelot.ServiceDiscovery;
using Shouldly;
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
using Ocelot.AcceptanceTests.Caching;
using Butterfly.Client.AspNetCore;
using Butterfly.Client.Tracing;
namespace Ocelot.AcceptanceTests
{
@ -103,6 +107,49 @@ namespace Ocelot.AcceptanceTests
_ocelotClient = _ocelotServer.CreateClient();
}
internal void GivenOcelotIsRunningUsingButterfly(string butterflyUrl)
{
_webHostBuilder = new WebHostBuilder();
_webHostBuilder
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
config.AddJsonFile("configuration.json");
config.AddEnvironmentVariables();
})
.ConfigureServices(s =>
{
s.AddOcelot()
.AddOpenTracing(option =>
{
//this is the url that the butterfly collector server is running on...
option.CollectorUrl = butterflyUrl;
option.Service = "Ocelot";
});
})
.Configure(app =>
{
app.Use(async (context, next) =>
{
await next.Invoke();
});
app.UseOcelot().Wait();
});
_ocelotServer = new TestServer(_webHostBuilder);
_ocelotClient = _ocelotServer.CreateClient();
}
/*
public void GivenIHaveAddedXForwardedForHeader(string value)
{
_ocelotClient.DefaultRequestHeaders.TryAddWithoutValidation("X-Forwarded-For", value);
}*/
public void GivenOcelotIsRunningWithMiddleareBeforePipeline<T>(Func<object, Task> callback)
{
_webHostBuilder = new WebHostBuilder();
@ -336,7 +383,7 @@ namespace Ocelot.AcceptanceTests
/// <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>
public void GivenOcelotIsRunning(OcelotMiddlewareConfiguration ocelotMiddlewareConfig)
public void GivenOcelotIsRunning(OcelotPipelineConfiguration ocelotPipelineConfig)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
@ -373,7 +420,7 @@ namespace Ocelot.AcceptanceTests
})
.Configure(a =>
{
a.UseOcelot(ocelotMiddlewareConfig).Wait();
a.UseOcelot(ocelotPipelineConfig).Wait();
}));
_ocelotClient = _ocelotServer.CreateClient();
@ -552,7 +599,6 @@ namespace Ocelot.AcceptanceTests
_response.StatusCode.ShouldBe(expectedHttpStatusCode);
}
public void ThenTheStatusCodeShouldBe(int expectedHttpStatusCode)
{
var responseStatusCode = (int)_response.StatusCode;
@ -579,5 +625,51 @@ namespace Ocelot.AcceptanceTests
{
_response.Content.Headers.ContentLength.ShouldBe(expected);
}
public void WhenIMakeLotsOfDifferentRequestsToTheApiGateway()
{
int numberOfRequests = 100;
var aggregateUrl = "/";
var aggregateExpected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
var tomUrl = "/tom";
var tomExpected = "{Hello from Tom}";
var lauraUrl = "/laura";
var lauraExpected = "{Hello from Laura}";
var random = new Random();
var aggregateTasks = new Task[numberOfRequests];
for (int i = 0; i < numberOfRequests; i++)
{
aggregateTasks[i] = Fire(aggregateUrl, aggregateExpected, random);
}
var tomTasks = new Task[numberOfRequests];
for (int i = 0; i < numberOfRequests; i++)
{
tomTasks[i] = Fire(tomUrl, tomExpected, random);
}
var lauraTasks = new Task[numberOfRequests];
for (int i = 0; i < numberOfRequests; i++)
{
lauraTasks[i] = Fire(lauraUrl, lauraExpected, random);
}
Task.WaitAll(lauraTasks);
Task.WaitAll(tomTasks);
Task.WaitAll(aggregateTasks);
}
private async Task Fire(string url, string expectedBody, Random random)
{
var request = new HttpRequestMessage(new HttpMethod("GET"), url);
await Task.Delay(random.Next(0, 2));
var response = await _ocelotClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
content.ShouldBe(expectedBody);
}
}
}

View File

@ -39,7 +39,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51875,
}
},
UpstreamPathTemplate = "/",
@ -49,7 +49,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -75,7 +75,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51875,
}
},
UpstreamPathTemplate = "/",
@ -101,7 +101,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -142,7 +142,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51875,
}
},
UpstreamPathTemplate = "/",
@ -152,7 +152,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -192,7 +192,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51875,
}
},
UpstreamPathTemplate = "/",
@ -202,7 +202,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -227,7 +227,7 @@ namespace Ocelot.AcceptanceTests
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
Port = 51875,
}
},
UpstreamPathTemplate = "/",
@ -237,7 +237,7 @@ namespace Ocelot.AcceptanceTests
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))

View File

@ -19,7 +19,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.9" />
<PackageReference Include="BenchmarkDotNet" Version="0.10.12" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@ -17,7 +17,7 @@ namespace Ocelot.Benchmarks
Add(StatisticColumn.AllStatistics);
}
[Setup]
[GlobalSetup]
public void SetUp()
{
_urlPathMatcher = new RegExUrlMatcher();
@ -37,4 +37,4 @@ namespace Ocelot.Benchmarks
_urlPathMatcher.Match(_downstreamUrlPath, _downstreamUrlPathTemplate);
}
}
}
}

View File

@ -59,7 +59,7 @@ namespace Ocelot.IntegrationTests
}
}
[Fact]
[Fact(Skip = "This tests is flakey at the moment so ignoring will be fixed long term see https://github.com/TomPallister/Ocelot/issues/245")]
public void should_persist_command_to_five_servers()
{
var configuration = new FileConfiguration
@ -118,7 +118,7 @@ namespace Ocelot.IntegrationTests
ThenTheCommandIsReplicatedToAllStateMachines(command);
}
[Fact]
[Fact(Skip = "This tests is flakey at the moment so ignoring will be fixed long term see https://github.com/TomPallister/Ocelot/issues/245")]
public void should_persist_command_to_five_servers_when_using_administration_api()
{
var configuration = new FileConfiguration

View File

@ -25,25 +25,24 @@ namespace Ocelot.ManualTest
.AddEnvironmentVariables();
})
.ConfigureServices(s => {
s.AddAuthentication()
s.AddAuthentication()
.AddJwtBearer("TestKey", x =>
{
x.Authority = "test";
x.Audience = "test";
});
s.AddOcelot()
.AddCacheManager(x =>
{
x.WithDictionaryHandle();
})
.AddOpenTracing(option =>
{
option.CollectorUrl = "http://localhost:9618";
option.Service = "Ocelot.ManualTest";
})
.AddAdministration("/administration", "secret");
s.AddOcelot()
.AddCacheManager(x =>
{
x.WithDictionaryHandle();
})
.AddOpenTracing(option =>
{
option.CollectorUrl = "http://localhost:9618";
option.Service = "Ocelot.ManualTest";
})
.AddAdministration("/administration", "secret");
})
.ConfigureLogging((hostingContext, logging) =>
{

View File

@ -8,7 +8,7 @@
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
"Port": 5007
}
],
"HttpHandlerOptions": {
@ -99,7 +99,7 @@
"HttpHandlerOptions": {
"AllowAutoRedirect": true,
"UseCookieContainer": true,
"UseTracing": true
"UseTracing": false
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
@ -121,7 +121,7 @@
"HttpHandlerOptions": {
"AllowAutoRedirect": true,
"UseCookieContainer": true,
"UseTracing": true
"UseTracing": false
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,

View File

@ -1,6 +1,11 @@
namespace Ocelot.UnitTests.Authentication
using Ocelot.Configuration;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Authentication
{
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
@ -8,6 +13,7 @@
using Ocelot.Authentication.Middleware;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Responses;
@ -15,56 +21,75 @@
using TestStack.BDDfy;
using Xunit;
public class AuthenticationMiddlewareTests : ServerHostedMiddlewareTest
public class AuthenticationMiddlewareTests
{
private OkResponse<DownstreamRoute> _downstreamRoute;
private AuthenticationMiddleware _middleware;
private Mock<IOcelotLoggerFactory> _factory;
private Mock<IOcelotLogger> _logger;
private OcelotRequestDelegate _next;
private DownstreamContext _downstreamContext;
public AuthenticationMiddlewareTests()
{
GivenTheTestServerIsConfigured();
_factory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_factory.Setup(x => x.CreateLogger<AuthenticationMiddleware>()).Returns(_logger.Object);
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
}
[Fact]
public void should_call_next_middleware_if_route_is_not_authenticated()
{
this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build())))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheUserIsAuthenticated())
this.Given(x => GivenTheDownStreamRouteIs(
new DownstreamReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build()))
.And(x => GivenTheTestServerPipelineIsConfigured())
.When(x => WhenICallTheMiddleware())
.Then(x => ThenTheUserIsAuthenticated())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(ScopedRepository.Object);
_next = async (context) => {
byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
MemoryStream stream = new MemoryStream(byteArray);
context.HttpContext.Response.Body = stream;
};
_middleware = new AuthenticationMiddleware(_next, _factory.Object);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
private void GivenTheTestServerPipelineIsConfigured()
{
app.UseAuthenticationMiddleware();
app.Run(async x =>
{
await x.Response.WriteAsync("The user is authenticated");
});
_next = async (context) => {
byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
MemoryStream stream = new MemoryStream(byteArray);
context.HttpContext.Response.Body = stream;
};
}
private void ThenTheUserIsAuthenticated()
{
var content = ResponseMessage.Content.ReadAsStringAsync().Result;
var content = _downstreamContext.HttpContext.Response.Body.AsString();
content.ShouldBe("The user is authenticated");
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
private void GivenTheDownStreamRouteIs(DownstreamReRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.DownstreamReRoute = downstreamRoute;
}
}
public static class StreamExtensions
{
public static string AsString(this Stream stream)
{
using(var reader = new StreamReader(stream))
{
string text = reader.ReadToEnd();
return text;
};
}
}
}

View File

@ -1,9 +1,9 @@
namespace Ocelot.UnitTests.Authorization
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Authorization
{
using System.Collections.Generic;
using System.Security.Claims;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Authorisation;
using Ocelot.Authorisation.Middleware;
@ -14,55 +14,57 @@
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
using Microsoft.AspNetCore.Http;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Configuration;
public class AuthorisationMiddlewareTests : ServerHostedMiddlewareTest
public class AuthorisationMiddlewareTests
{
private readonly Mock<IClaimsAuthoriser> _authService;
private readonly Mock<IScopesAuthoriser> _authScopesService;
private OkResponse<DownstreamRoute> _downstreamRoute;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly AuthorisationMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public AuthorisationMiddlewareTests()
{
_authService = new Mock<IClaimsAuthoriser>();
_authScopesService = new Mock<IScopesAuthoriser>();
GivenTheTestServerIsConfigured();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_middleware = new AuthorisationMiddleware(_next, _authService.Object, _authScopesService.Object, _loggerFactory.Object);
}
[Fact]
public void should_call_authorisation_service()
{
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
this.Given(x => x.GivenTheDownStreamRouteIs(new List<PlaceholderNameAndValue>(),
new DownstreamReRouteBuilder()
.WithIsAuthorised(true)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.Build()))
.And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheAuthServiceIsCalledCorrectly())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_authService.Object);
services.AddSingleton(_authScopesService.Object);
services.AddSingleton(ScopedRepository.Object);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
private void GivenTheDownStreamRouteIs(List<PlaceholderNameAndValue> templatePlaceholderNameAndValues, DownstreamReRoute downstreamReRoute)
{
app.UseAuthorisationMiddleware();
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = templatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamReRoute;
}
private void GivenTheAuthServiceReturns(Response<bool> expected)

View File

@ -1,4 +1,6 @@
using Ocelot.Infrastructure.RequestData;
using Ocelot.Errors;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Cache
{
@ -22,20 +24,37 @@ namespace Ocelot.UnitTests.Cache
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
using Ocelot.DownstreamRouteFinder.Middleware;
using Microsoft.AspNetCore.Http;
public class OutputCacheMiddlewareRealCacheTests : ServerHostedMiddlewareTest
public class OutputCacheMiddlewareRealCacheTests
{
private IOcelotCache<CachedResponse> _cacheManager;
private CachedResponse _response;
private IRequestScopedDataRepository _repo;
private OutputCacheMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private IRegionCreator _regionCreator;
private Mock<IOcelotLogger> _logger;
public OutputCacheMiddlewareRealCacheTests()
{
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
GivenTheTestServerIsConfigured();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
_regionCreator = new RegionCreator();
var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
{
x.WithDictionaryHandle();
});
_cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123");
_next = async context => {
//do nothing..
};
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager, _regionCreator);
}
[Fact]
@ -54,12 +73,16 @@ namespace Ocelot.UnitTests.Cache
this.Given(x => x.GivenResponseIsNotCached(response))
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereAreNoErrors())
.And(x => x.GivenThereIsADownstreamUrl())
.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");
@ -67,65 +90,25 @@ namespace Ocelot.UnitTests.Cache
header.First().ShouldBe("application/json");
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
{
x.WithDictionaryHandle();
});
_cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
services.AddSingleton<IOcelotCache<CachedResponse>>(_cacheManager);
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_cacheManager);
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IRegionCreator, RegionCreator>();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseOutputCacheMiddleware();
}
private void GivenResponseIsNotCached(HttpResponseMessage message)
{
ScopedRepository
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
.Returns(new OkResponse<HttpResponseMessage>(message));
_downstreamContext.DownstreamResponse = message;
}
private void GivenTheDownstreamRouteIs()
{
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
_downstreamContext.DownstreamReRoute = reRoute;
}
private void GivenThereAreNoErrors()
{
ScopedRepository
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
.Returns(new OkResponse<bool>(false));
}
private void GivenThereIsADownstreamUrl()
{
ScopedRepository
.Setup(x => x.Get<string>("DownstreamUrl"))
.Returns(new OkResponse<string>("anything"));
_downstreamContext.Errors = new List<Error>();
}
}
}

View File

@ -1,4 +1,6 @@
using System.Net;
using Ocelot.Errors;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Cache
{
@ -6,6 +8,7 @@ namespace Ocelot.UnitTests.Cache
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Cache;
@ -13,26 +16,37 @@ namespace Ocelot.UnitTests.Cache
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
public class OutputCacheMiddlewareTests : ServerHostedMiddlewareTest
public class OutputCacheMiddlewareTests
{
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private OutputCacheMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private CachedResponse _response;
private IRegionCreator _regionCreator;
public OutputCacheMiddlewareTests()
{
_cacheManager = new Mock<IOcelotCache<CachedResponse>>();
_regionCreator = new RegionCreator();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
GivenTheTestServerIsConfigured();
_downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123");
}
[Fact]
@ -41,7 +55,6 @@ namespace Ocelot.UnitTests.Cache
var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", new Dictionary<string, IEnumerable<string>>());
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
.BDDfy();
@ -53,24 +66,15 @@ namespace Ocelot.UnitTests.Cache
this.Given(x => x.GivenResponseIsNotCached())
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereAreNoErrors())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_cacheManager.Object);
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IRegionCreator, RegionCreator>();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseOutputCacheMiddleware();
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager.Object, _regionCreator);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenThereIsACachedResponse(CachedResponse response)
@ -83,38 +87,30 @@ namespace Ocelot.UnitTests.Cache
private void GivenResponseIsNotCached()
{
ScopedRepository
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
.Returns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage()));
_downstreamContext.DownstreamResponse = new HttpResponseMessage();
}
private void GivenTheDownstreamRouteIs()
{
var reRoute = new ReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void GivenThereAreNoErrors()
{
ScopedRepository
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
.Returns(new OkResponse<bool>(false));
}
_downstreamContext.Errors = new List<Error>();
private void GivenThereIsADownstreamUrl()
{
ScopedRepository
.Setup(x => x.Get<string>("DownstreamUrl"))
.Returns(new OkResponse<string>("anything"));
}
private void ThenTheCacheGetIsCalledCorrectly()

View File

@ -1,9 +1,9 @@
namespace Ocelot.UnitTests.Claims
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Claims
{
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Claims;
using Ocelot.Claims.Middleware;
@ -15,17 +15,29 @@
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
using Ocelot.DownstreamRouteFinder.Middleware;
public class ClaimsBuilderMiddlewareTests : ServerHostedMiddlewareTest
public class ClaimsBuilderMiddlewareTests
{
private readonly Mock<IAddClaimsToRequest> _addHeaders;
private Response<DownstreamRoute> _downstreamRoute;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly ClaimsBuilderMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public ClaimsBuilderMiddlewareTests()
{
_addHeaders = new Mock<IAddClaimsToRequest>();
GivenTheTestServerIsConfigured();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ClaimsBuilderMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_middleware = new ClaimsBuilderMiddleware(_next, _loggerFactory.Object, _addHeaders.Object);
}
[Fact]
@ -33,11 +45,14 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToClaims(new List<ClaimToThing>
{
new ClaimToThing("sub", "UserType", "|", 0)
})
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToClaims(new List<ClaimToThing>
{
new ClaimToThing("sub", "UserType", "|", 0)
})
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
@ -48,25 +63,16 @@
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_addHeaders.Object);
services.AddSingleton(ScopedRepository.Object);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseClaimsBuilderMiddleware();
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void GivenTheAddClaimsToRequestReturns()

View File

@ -20,7 +20,7 @@ namespace Ocelot.UnitTests.Configuration
private readonly IConfigurationValidator _configurationValidator;
private FileConfiguration _fileConfiguration;
private Response<ConfigurationValidationResult> _result;
private Mock<IAuthenticationSchemeProvider> _provider;
private readonly Mock<IAuthenticationSchemeProvider> _provider;
public ConfigurationFluentValidationTests()
{
@ -28,6 +28,373 @@ namespace Ocelot.UnitTests.Configuration
_configurationValidator = new FileConfigurationFluentValidator(_provider.Object);
}
[Fact]
public void configuration_is_valid_if_aggregates_are_valid()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
this.Given(x => x.GivenAConfiguration(configuration))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsValid())
.BDDfy();
}
[Fact]
public void configuration_is_invalid_if_aggregates_are_duplicate_of_re_routes()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom",
UpstreamHost = "localhost"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/tom",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
},
}
}
};
this.Given(x => x.GivenAConfiguration(configuration))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid())
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "reRoute /tom has duplicate aggregate"))
.BDDfy();
}
[Fact]
public void configuration_is_valid_if_aggregates_are_not_duplicate_of_re_routes()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Post" },
Key = "Tom",
UpstreamHost = "localhost"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/tom",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
},
}
}
};
this.Given(x => x.GivenAConfiguration(configuration))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsValid())
.BDDfy();
}
[Fact]
public void configuration_is_invalid_if_aggregates_are_duplicate_of_aggregates()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/lol",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/tom",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
},
new FileAggregateReRoute
{
UpstreamPathTemplate = "/tom",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
this.Given(x => x.GivenAConfiguration(configuration))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid())
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "aggregate /tom has duplicate aggregate"))
.BDDfy();
}
[Fact]
public void configuration_is_invalid_if_re_routes_dont_exist_for_aggregate()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
this.Given(x => x.GivenAConfiguration(configuration))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid())
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "ReRoutes for aggregateReRoute / either do not exist or do not have correct Key property"))
.BDDfy();
}
[Fact]
public void configuration_is_invalid_if_aggregate_has_re_routes_with_specific_request_id_keys()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
RequestIdKey = "should_fail",
Key = "Tom"
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
this.Given(x => x.GivenAConfiguration(configuration))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid())
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "aggregateReRoute / contains ReRoute with specific RequestIdKey, this is not possible with Aggregates"))
.BDDfy();
}
[Fact]
public void configuration_is_invalid_if_scheme_in_downstream_or_upstream_template()
{

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Castle.Components.DictionaryAdapter;
using Microsoft.Extensions.Options;
using Moq;
using Ocelot.Cache;
@ -81,6 +82,125 @@ namespace Ocelot.UnitTests.Configuration
_downstreamAddressesCreator.Object);
}
[Fact]
public void should_set_up_aggregate_re_route()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51878,
}
},
UpstreamPathTemplate = "/laura",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Laura",
UpstreamHost = "localhost"
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51880,
}
},
UpstreamPathTemplate = "/tom",
UpstreamHttpMethod = new List<string> { "Get" },
Key = "Tom",
UpstreamHost = "localhost",
}
},
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
UpstreamPathTemplate = "/",
UpstreamHost = "localhost",
ReRouteKeys = new List<string>
{
"Tom",
"Laura"
}
}
}
};
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
var expected = new List<ReRoute>();
var lauraDownstreamReRoute = new DownstreamReRouteBuilder()
.WithUpstreamHost("localhost")
.WithKey("Laura")
.WithDownstreamPathTemplate("/")
.WithDownstreamScheme("http")
.WithUpstreamHttpMethod(new List<string>() {"Get"})
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("localhost", 51878)})
.Build();
var lauraReRoute = new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string>() { "Get" })
.WithUpstreamHost("localhost")
.WithUpstreamPathTemplate("/laura")
.WithDownstreamReRoute(lauraDownstreamReRoute)
.Build();
expected.Add(lauraReRoute);
var tomDownstreamReRoute = new DownstreamReRouteBuilder()
.WithUpstreamHost("localhost")
.WithKey("Tom")
.WithDownstreamPathTemplate("/")
.WithDownstreamScheme("http")
.WithUpstreamHttpMethod(new List<string>() { "Get" })
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() { new DownstreamHostAndPort("localhost", 51878) })
.Build();
var tomReRoute = new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string>() { "Get" })
.WithUpstreamHost("localhost")
.WithUpstreamPathTemplate("/tom")
.WithDownstreamReRoute(tomDownstreamReRoute)
.Build();
expected.Add(tomReRoute);
var aggregateReReRoute = new ReRouteBuilder()
.WithUpstreamPathTemplate("/")
.WithUpstreamHost("localhost")
.WithDownstreamReRoute(lauraDownstreamReRoute)
.WithDownstreamReRoute(tomDownstreamReRoute)
.WithUpstreamHttpMethod(new List<string>() { "Get" })
.Build();
expected.Add(aggregateReReRoute);
this.Given(x => x.GivenTheConfigIs(configuration))
.And(x => x.GivenTheFollowingOptionsAreReturned(new ReRouteOptionsBuilder().Build()))
.And(x => x.GivenTheFollowingIsReturned(serviceProviderConfig))
.And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheServiceProviderCreatorIsCalledCorrectly())
.Then(x => x.ThenTheReRoutesAre(expected))
.BDDfy();
}
[Fact]
public void should_call_service_provider_config_creator()
{
@ -234,6 +354,13 @@ namespace Ocelot.UnitTests.Configuration
var reRouteOptions = new ReRouteOptionsBuilder()
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("127.0.0.1", 80)})
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
@ -261,8 +388,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamAddresses(new List<DownstreamHostAndPort>(){new DownstreamHostAndPort("127.0.0.1", 80) })
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()
@ -276,6 +402,13 @@ namespace Ocelot.UnitTests.Configuration
var reRouteOptions = new ReRouteOptionsBuilder()
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamScheme("https")
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
@ -297,8 +430,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamScheme("https")
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()
@ -312,6 +444,14 @@ namespace Ocelot.UnitTests.Configuration
var reRouteOptions = new ReRouteOptionsBuilder()
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUseServiceDiscovery(true)
.WithServiceName("ProductService")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
@ -341,11 +481,9 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUseServiceDiscovery(true)
.WithServiceName("ProductService")
.Build()
}))
.BDDfy();
@ -356,7 +494,15 @@ namespace Ocelot.UnitTests.Configuration
{
var reRouteOptions = new ReRouteOptionsBuilder()
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUseServiceDiscovery(false)
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
@ -378,10 +524,9 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUseServiceDiscovery(false)
.Build()
}))
.BDDfy();
@ -392,7 +537,15 @@ namespace Ocelot.UnitTests.Configuration
{
var reRouteOptions = new ReRouteOptionsBuilder()
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
@ -415,7 +568,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
@ -430,6 +583,13 @@ namespace Ocelot.UnitTests.Configuration
var reRouteOptions = new ReRouteOptionsBuilder()
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithRequestIdKey("blahhhh")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
@ -456,10 +616,9 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithRequestIdKey("blahhhh")
.Build()
}))
.And(x => x.ThenTheRequestIdKeyCreatorIsCalledCorrectly())
@ -514,17 +673,23 @@ namespace Ocelot.UnitTests.Configuration
.WithAllowedScopes(new List<string>())
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithAuthenticationOptions(authenticationOptions)
.WithClaimsToHeaders(new List<ClaimToThing>
{
new ClaimToThing("CustomerId", "CustomerId", "", 0),
})
.Build();
var expected = new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithAuthenticationOptions(authenticationOptions)
.WithClaimsToHeaders(new List<ClaimToThing>
{
new ClaimToThing("CustomerId", "CustomerId", "", 0),
})
.Build()
};
@ -554,13 +719,19 @@ namespace Ocelot.UnitTests.Configuration
.WithAllowedScopes(new List<string>())
.Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithAuthenticationOptions(authenticationOptions)
.Build();
var expected = new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithAuthenticationOptions(authenticationOptions)
.Build()
};
@ -643,14 +814,16 @@ namespace Ocelot.UnitTests.Configuration
var result = _config.Data.ReRoutes[i];
var expected = expectedReRoutes[i];
result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value);
result.DownstreamReRoute.Count.ShouldBe(expected.DownstreamReRoute.Count);
result.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamReRoute[0].DownstreamPathTemplate.Value);
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value);
result.UpstreamTemplatePattern?.Template.ShouldBe(expected.UpstreamTemplatePattern?.Template);
result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count);
result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count);
result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count);
result.RequestIdKey.ShouldBe(expected.RequestIdKey);
result.DownstreamReRoute[0].ClaimsToClaims.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToClaims.Count);
result.DownstreamReRoute[0].ClaimsToHeaders.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToHeaders.Count);
result.DownstreamReRoute[0].ClaimsToQueries.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToQueries.Count);
result.DownstreamReRoute[0].RequestIdKey.ShouldBe(expected.DownstreamReRoute[0].RequestIdKey);
}
}
@ -659,8 +832,8 @@ namespace Ocelot.UnitTests.Configuration
{
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
{
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
var expected = expectedReRoutes[i].AuthenticationOptions;
var result = _config.Data.ReRoutes[i].DownstreamReRoute[0].AuthenticationOptions;
var expected = expectedReRoutes[i].DownstreamReRoute[0].AuthenticationOptions;
result.AllowedScopes.ShouldBe(expected.AllowedScopes);
}
}
@ -714,10 +887,10 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheQosOptionsAre(QoSOptions qosOptions)
{
_config.Data.ReRoutes[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
_config.Data.ReRoutes[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
_config.Data.ReRoutes[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
}
private void ThenTheServiceProviderCreatorIsCalledCorrectly()

View File

@ -44,7 +44,7 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheConfigurationIsReturned()
{
_getResult.Data.ReRoutes[0].DownstreamPathTemplate.Value.ShouldBe("initial");
_getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
}
private void WhenIGetTheConfiguration()
@ -83,13 +83,24 @@ namespace Ocelot.UnitTests.Configuration
AdministrationPath = administrationPath;
}
public List<ReRoute> ReRoutes => new List<ReRoute>
public List<ReRoute> ReRoutes
{
new ReRouteBuilder()
.WithDownstreamPathTemplate(_downstreamTemplatePath)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()
};
get
{
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate(_downstreamTemplatePath)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
return new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build()
};
}
}
public string AdministrationPath {get;}

View File

@ -1,7 +1,11 @@
namespace Ocelot.UnitTests.DownstreamRouteFinder
using Ocelot.Middleware;
using Ocelot.Middleware.Multiplexer;
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
@ -13,22 +17,36 @@
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class DownstreamRouteFinderMiddlewareTests : ServerHostedMiddlewareTest
public class DownstreamRouteFinderMiddlewareTests
{
private readonly Mock<IDownstreamRouteFinder> _downstreamRouteFinder;
private readonly Mock<IDownstreamRouteFinder> _finder;
private readonly Mock<IOcelotConfigurationProvider> _provider;
private Response<DownstreamRoute> _downstreamRoute;
private IOcelotConfiguration _config;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private DownstreamRouteFinderMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private readonly Mock<IMultiplexer> _multiplexer;
public DownstreamRouteFinderMiddlewareTests()
{
_provider = new Mock<IOcelotConfigurationProvider>();
_downstreamRouteFinder = new Mock<IDownstreamRouteFinder>();
GivenTheTestServerIsConfigured();
_finder = new Mock<IDownstreamRouteFinder>();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteFinderMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_multiplexer = new Mock<IMultiplexer>();
_middleware = new DownstreamRouteFinderMiddleware(_next, _loggerFactory.Object, _finder.Object, _provider.Object, _multiplexer.Object);
}
[Fact]
@ -36,11 +54,16 @@
{
var config = new OcelotConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(
new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.And(x => GivenTheFollowingConfig(config))
@ -49,6 +72,11 @@
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetType();
}
private void GivenTheFollowingConfig(IOcelotConfiguration config)
{
_config = config;
@ -57,35 +85,18 @@
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(_config));
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_downstreamRouteFinder.Object);
services.AddSingleton(_provider.Object);
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseDownstreamRouteFinderMiddleware();
}
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
_downstreamRouteFinder
_finder
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IOcelotConfiguration>(), It.IsAny<string>()))
.Returns(_downstreamRoute);
}
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
{
ScopedRepository
.Verify(x => x.Add("DownstreamRoute", _downstreamRoute.Data), Times.Once());
ScopedRepository
.Verify(x => x.Add("ServiceProviderConfiguration", _config.ServiceProviderConfiguration), Times.Once());
_downstreamContext.TemplatePlaceholderNameAndValues.ShouldBe(_downstreamRoute.Data.TemplatePlaceholderNameAndValues);
_downstreamContext.ServiceProviderConfiguration.ShouldBe(_config.ServiceProviderConfiguration);
}
}
}

View File

@ -47,13 +47,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
@ -64,7 +74,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.When(x => x.WhenICallTheFinder())
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
@ -84,13 +99,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
@ -101,7 +126,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.When(x => x.WhenICallTheFinder())
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.Build())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.Build()
@ -121,7 +150,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
@ -135,7 +169,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build()
@ -157,7 +195,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
@ -171,7 +214,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build()
@ -193,7 +240,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
@ -206,7 +258,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build()
@ -227,13 +283,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
@ -246,7 +312,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build()
@ -263,7 +333,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("somPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("somPath")
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
.Build())
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
@ -292,7 +367,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
@ -305,7 +385,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build()
@ -326,7 +410,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
@ -339,7 +428,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build()
@ -360,7 +453,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
@ -388,7 +486,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
@ -403,7 +507,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build()
@ -425,7 +533,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
@ -439,7 +552,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build()
@ -459,12 +576,17 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamHost("MATCH")
.Build()
}, string.Empty, serviceProviderConfig
))
@ -490,13 +612,24 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("THENULLPATH")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("THENULLPATH")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
@ -511,7 +644,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build()
@ -592,7 +729,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheFollowingIsReturned(DownstreamRoute expected)
{
_result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value);
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value);
_result.Data.ReRoute.UpstreamTemplatePattern.Priority.ShouldBe(expected.ReRoute.UpstreamTemplatePattern.Priority);
for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++)

View File

@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.DownstreamUrlCreator
using Ocelot.Middleware;
namespace Ocelot.UnitTests.DownstreamUrlCreator
{
using System;
using System.Collections.Generic;
@ -19,39 +21,49 @@
using TestStack.BDDfy;
using Xunit;
using Shouldly;
using Ocelot.DownstreamRouteFinder.Middleware;
using Microsoft.AspNetCore.Http;
public class DownstreamUrlCreatorMiddlewareTests : ServerHostedMiddlewareTest
public class DownstreamUrlCreatorMiddlewareTests
{
private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
private readonly Mock<IUrlBuilder> _urlBuilder;
private Response<DownstreamRoute> _downstreamRoute;
private OkResponse<DownstreamPath> _downstreamPath;
private HttpRequestMessage _downstreamRequest;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private DownstreamUrlCreatorMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public DownstreamUrlCreatorMiddlewareTests()
{
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<DownstreamUrlCreatorMiddleware>()).Returns(_logger.Object);
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
_urlBuilder = new Mock<IUrlBuilder>();
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
GivenTheTestServerIsConfigured();
_downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
_next = async context => {
//do nothing
};
}
[Fact]
public void should_replace_scheme_and_path()
{
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithDownstreamScheme("https")
.Build();
this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithDownstreamScheme("https")
.Build())))
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
@ -60,31 +72,21 @@
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object);
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton(_urlBuilder.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseDownstreamUrlCreatorMiddleware();
_middleware = new DownstreamUrlCreatorMiddleware(_next, _loggerFactory.Object, _downstreamUrlTemplateVariableReplacer.Object, _urlBuilder.Object);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void GivenTheDownstreamRequestUriIs(string uri)
{
_downstreamRequest.RequestUri = new Uri(uri);
_downstreamContext.DownstreamRequest.RequestUri = new Uri(uri);
}
private void GivenTheUrlReplacerWillReturn(string path)
@ -97,7 +99,7 @@
private void ThenTheDownstreamRequestUriIs(string expectedUri)
{
_downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
_downstreamContext.DownstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
}
}
}

View File

@ -29,6 +29,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -43,7 +46,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("/")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -56,7 +62,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("api")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("api")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -69,7 +78,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("api/")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("api/")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -82,7 +94,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("api/product/products/")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("api/product/products/")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -100,7 +115,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -118,7 +136,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -137,7 +158,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
@ -157,8 +181,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
@ -172,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
private void WhenIReplaceTheTemplateVariables()
{
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
}
private void ThenTheDownstreamUrlPathIsReturned(string expected)

View File

@ -1,10 +1,10 @@
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Errors
{
using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Errors.Middleware;
using Ocelot.Logging;
using Shouldly;
@ -14,18 +14,41 @@ namespace Ocelot.UnitTests.Errors
using Ocelot.Configuration.Provider;
using Moq;
using Ocelot.Configuration;
using Rafty.Concensus;
using Ocelot.Errors;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Infrastructure.RequestData;
public class ExceptionHandlerMiddlewareTests : ServerHostedMiddlewareTest
public class ExceptionHandlerMiddlewareTests
{
bool _shouldThrowAnException = false;
private Mock<IOcelotConfigurationProvider> _provider;
private Mock<IRequestScopedDataRepository> _repo;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private ExceptionHandlerMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public ExceptionHandlerMiddlewareTests()
{
_provider = new Mock<IOcelotConfigurationProvider>();
GivenTheTestServerIsConfigured();
_repo = new Mock<IRequestScopedDataRepository>();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ExceptionHandlerMiddleware>()).Returns(_logger.Object);
_next = async context => {
await Task.CompletedTask;
if (_shouldThrowAnException)
{
throw new Exception("BOOM");
}
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
};
_middleware = new ExceptionHandlerMiddleware(_next, _loggerFactory.Object, _provider.Object, _repo.Object);
}
[Fact]
@ -99,6 +122,17 @@ namespace Ocelot.UnitTests.Errors
.BDDfy();
}
private void WhenICallTheMiddlewareWithTheRequestIdKey(string key, string value)
{
_downstreamContext.HttpContext.Request.Headers.Add(key, value);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheConfigThrows()
{
var ex = new Exception("outer", new Exception("inner"));
@ -108,7 +142,7 @@ namespace Ocelot.UnitTests.Errors
private void ThenAnExceptionIsThrown()
{
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
_downstreamContext.HttpContext.Response.StatusCode.ShouldBe(500);
}
private void GivenTheConfigReturnsError()
@ -130,7 +164,7 @@ namespace Ocelot.UnitTests.Errors
private void TheRequestIdIsSet(string key, string value)
{
ScopedRepository.Verify(x => x.Add<string>(key, value), Times.Once);
_repo.Verify(x => x.Add<string>(key, value), Times.Once);
}
private void GivenTheConfigurationIs(IOcelotConfiguration config)
@ -140,31 +174,6 @@ namespace Ocelot.UnitTests.Errors
.Setup(x => x.Get()).ReturnsAsync(response);
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IOcelotConfigurationProvider>(_provider.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseExceptionHandlerMiddleware();
app.Run(DownstreamExceptionSimulator);
}
private async Task DownstreamExceptionSimulator(HttpContext context)
{
await Task.CompletedTask;
if (_shouldThrowAnException)
{
throw new Exception("BOOM");
}
context.Response.StatusCode = (int)HttpStatusCode.OK;
}
private void GivenAnExceptionWillNotBeThrownDownstream()
{
@ -178,17 +187,18 @@ namespace Ocelot.UnitTests.Errors
private void ThenTheResponseIsOk()
{
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.OK);
_downstreamContext.HttpContext.Response.StatusCode.ShouldBe(200);
}
private void ThenTheResponseIsError()
{
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
_downstreamContext.HttpContext.Response.StatusCode.ShouldBe(500);
}
private void TheRequestIdIsNotSet()
{
ScopedRepository.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
_repo.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
}
}
}
}

View File

@ -1,36 +1,43 @@
using Xunit;
using Shouldly;
using Ocelot.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Ocelot.Headers.Middleware;
using TestStack.BDDfy;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using Moq;
using Ocelot.Configuration;
using Ocelot.DownstreamRouteFinder;
using Ocelot.Responses;
using Ocelot.Configuration.Builder;
using Ocelot.Headers;
using System.Net.Http;
using Ocelot.Authorisation.Middleware;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Headers
{
public class HttpHeadersTransformationMiddlewareTests : ServerHostedMiddlewareTest
public class HttpHeadersTransformationMiddlewareTests
{
private Mock<IHttpContextRequestHeaderReplacer> _preReplacer;
private Mock<IHttpResponseHeaderReplacer> _postReplacer;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private HttpHeadersTransformationMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public HttpHeadersTransformationMiddlewareTests()
{
_preReplacer = new Mock<IHttpContextRequestHeaderReplacer>();
_postReplacer = new Mock<IHttpResponseHeaderReplacer>();
GivenTheTestServerIsConfigured();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_middleware = new HttpHeadersTransformationMiddleware(_next, _loggerFactory.Object, _preReplacer.Object, _postReplacer.Object);
}
[Fact]
@ -46,27 +53,34 @@ namespace Ocelot.UnitTests.Headers
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheDownstreamRequestIs()
{
var request = new HttpRequestMessage();
var response = new OkResponse<HttpRequestMessage>(request);
ScopedRepository.Setup(x => x.Get<HttpRequestMessage>("DownstreamRequest")).Returns(response);
_downstreamContext.DownstreamRequest = new HttpRequestMessage();
}
private void GivenTheHttpResponseMessageIs()
{
var httpResponseMessage = new HttpResponseMessage();
var response = new OkResponse<HttpResponseMessage>(httpResponseMessage);
ScopedRepository.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage")).Returns(response);
_downstreamContext.DownstreamResponse = new HttpResponseMessage();
}
private void GivenTheReRouteHasPreFindAndReplaceSetUp()
{
var fAndRs = new List<HeaderFindAndReplace>();
var reRoute = new ReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs).WithDownstreamHeaderFindAndReplace(fAndRs).Build();
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs)
.WithDownstreamHeaderFindAndReplace(fAndRs).Build())
.Build();
var dR = new DownstreamRoute(null, reRoute);
var response = new OkResponse<DownstreamRoute>(dR);
ScopedRepository.Setup(x => x.Get<DownstreamRoute>("DownstreamRoute")).Returns(response);
_downstreamContext.TemplatePlaceholderNameAndValues = dR.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = dR.ReRoute.DownstreamReRoute[0];
}
private void ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly()
@ -81,21 +95,7 @@ namespace Ocelot.UnitTests.Headers
private void GivenTheFollowingRequest()
{
Client.DefaultRequestHeaders.Add("test", "test");
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton(_preReplacer.Object);
services.AddSingleton(_postReplacer.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseHttpHeadersTransformationMiddleware();
_downstreamContext.HttpContext.Request.Headers.Add("test", "test");
}
}
}
}

View File

@ -1,13 +1,17 @@
namespace Ocelot.UnitTests.Headers
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Headers
{
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Headers;
using Ocelot.Headers.Middleware;
@ -16,22 +20,28 @@
using TestStack.BDDfy;
using Xunit;
public class HttpRequestHeadersBuilderMiddlewareTests : ServerHostedMiddlewareTest
public class HttpRequestHeadersBuilderMiddlewareTests
{
private readonly Mock<IAddHeadersToRequest> _addHeaders;
private readonly HttpRequestMessage _downstreamRequest;
private Response<DownstreamRoute> _downstreamRoute;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private HttpRequestHeadersBuilderMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public HttpRequestHeadersBuilderMiddlewareTests()
{
_addHeaders = new Mock<IAddHeadersToRequest>();
_downstreamRequest = new HttpRequestMessage();
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
GivenTheTestServerIsConfigured();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<HttpRequestHeadersBuilderMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_middleware = new HttpRequestHeadersBuilderMiddleware(_next, _loggerFactory.Object, _addHeaders.Object);
_downstreamContext.DownstreamRequest = new HttpRequestMessage();
}
[Fact]
@ -39,11 +49,14 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToHeaders(new List<ClaimToThing>
{
new ClaimToThing("UserId", "Subject", "", 0)
})
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToHeaders(new List<ClaimToThing>
{
new ClaimToThing("UserId", "Subject", "", 0)
})
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
@ -54,25 +67,16 @@
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_addHeaders.Object);
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseHttpRequestHeadersBuilderMiddleware();
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void GivenTheAddHeadersToDownstreamRequestReturnsOk()
@ -91,7 +95,7 @@
.Verify(x => x.SetHeadersOnDownstreamRequest(
It.IsAny<List<ClaimToThing>>(),
It.IsAny<IEnumerable<System.Security.Claims.Claim>>(),
_downstreamRequest), Times.Once);
_downstreamContext.DownstreamRequest), Times.Once);
}
}
}

View File

@ -12,7 +12,7 @@ namespace Ocelot.UnitTests.LoadBalancer
{
public class LoadBalancerFactoryTests
{
private ReRoute _reRoute;
private DownstreamReRoute _reRoute;
private LoadBalancerFactory _factory;
private ILoadBalancer _result;
private Mock<IServiceDiscoveryProviderFactory> _serviceProviderFactory;
@ -29,7 +29,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_return_no_load_balancer()
{
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
@ -44,9 +44,9 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_return_round_robin_load_balancer()
{
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithLoadBalancer("RoundRobin")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -60,9 +60,9 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_return_round_least_connection_balancer()
{
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithLoadBalancer("LeastConnection")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -76,9 +76,9 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_call_service_provider()
{
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithLoadBalancer("RoundRobin")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -97,17 +97,17 @@ namespace Ocelot.UnitTests.LoadBalancer
private void GivenTheServiceProviderFactoryReturns()
{
_serviceProviderFactory
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()))
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()))
.Returns(_serviceProvider.Object);
}
private void ThenTheServiceProviderIsCalledCorrectly()
{
_serviceProviderFactory
.Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()), Times.Once);
.Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()), Times.Once);
}
private void GivenAReRoute(ReRoute reRoute)
private void GivenAReRoute(DownstreamReRoute reRoute)
{
_reRoute = reRoute;
}
@ -122,4 +122,4 @@ namespace Ocelot.UnitTests.LoadBalancer
_result.ShouldBeOfType<T>();
}
}
}
}

View File

@ -14,13 +14,13 @@ namespace Ocelot.UnitTests.LoadBalancer
{
public class LoadBalancerHouseTests
{
private ReRoute _reRoute;
private DownstreamReRoute _reRoute;
private ILoadBalancer _loadBalancer;
private readonly LoadBalancerHouse _loadBalancerHouse;
private Response _addResult;
private Response<ILoadBalancer> _getResult;
private string _key;
private Mock<ILoadBalancerFactory> _factory;
private readonly Mock<ILoadBalancerFactory> _factory;
private ServiceProviderConfiguration _serviceProviderConfig;
public LoadBalancerHouseTests()
@ -32,7 +32,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_store_load_balancer_on_first_request()
{
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
.Then(x => x.ThenItIsAdded())
@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_not_store_load_balancer_on_second_request()
{
var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
var reRoute = new DownstreamReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
@ -53,8 +53,8 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_store_load_balancers_by_key()
{
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testtwo").Build();
var reRoute = new DownstreamReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
var reRouteTwo = new DownstreamReRouteBuilder().WithLoadBalancer("FakeRoundRobinLoadBalancer").WithReRouteKey("testtwo").Build();
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
.And(x => x.GivenThereIsALoadBalancer(reRouteTwo, new FakeRoundRobinLoadBalancer()))
@ -68,7 +68,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_return_error_if_exception()
{
var reRoute = new ReRouteBuilder().Build();
var reRoute = new DownstreamReRouteBuilder().Build();
this.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
.Then(x => x.ThenAnErrorIsReturned())
@ -78,9 +78,9 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_get_new_load_balancer_if_reroute_load_balancer_has_changed()
{
var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
var reRoute = new DownstreamReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
var reRouteTwo = new ReRouteBuilder().WithLoadBalancer("LeastConnection").WithReRouteKey("test").Build();
var reRouteTwo = new DownstreamReRouteBuilder().WithLoadBalancer("LeastConnection").WithReRouteKey("test").Build();
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.LoadBalancer
.BDDfy();
}
private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(ReRoute reRoute)
private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(DownstreamReRoute reRoute)
{
_reRoute = reRoute;
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(new LeastConnection(null, null));
@ -117,7 +117,7 @@ namespace Ocelot.UnitTests.LoadBalancer
}
private void GivenThereIsALoadBalancer(ReRoute reRoute, ILoadBalancer loadBalancer)
private void GivenThereIsALoadBalancer(DownstreamReRoute reRoute, ILoadBalancer loadBalancer)
{
_reRoute = reRoute;
_loadBalancer = loadBalancer;
@ -125,7 +125,7 @@ namespace Ocelot.UnitTests.LoadBalancer
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
}
private void WhenWeGetTheLoadBalancer(ReRoute reRoute)
private void WhenWeGetTheLoadBalancer(DownstreamReRoute reRoute)
{
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
}

View File

@ -1,14 +1,18 @@
using Ocelot.Middleware;
namespace Ocelot.UnitTests.LoadBalancer
{
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Provider;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Errors;
using Ocelot.LoadBalancer.LoadBalancers;
using Ocelot.LoadBalancer.Middleware;
@ -19,7 +23,7 @@ namespace Ocelot.UnitTests.LoadBalancer
using TestStack.BDDfy;
using Xunit;
public class LoadBalancerMiddlewareTests : ServerHostedMiddlewareTest
public class LoadBalancerMiddlewareTests
{
private readonly Mock<ILoadBalancerHouse> _loadBalancerHouse;
private readonly Mock<ILoadBalancer> _loadBalancer;
@ -29,6 +33,11 @@ namespace Ocelot.UnitTests.LoadBalancer
private ErrorResponse<ServiceHostAndPort> _getHostAndPortError;
private HttpRequestMessage _downstreamRequest;
private ServiceProviderConfiguration _config;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private LoadBalancingMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public LoadBalancerMiddlewareTests()
{
@ -36,28 +45,29 @@ namespace Ocelot.UnitTests.LoadBalancer
_loadBalancer = new Mock<ILoadBalancer>();
_loadBalancerHouse = new Mock<ILoadBalancerHouse>();
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "");
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
GivenTheTestServerIsConfigured();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<LoadBalancingMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_downstreamContext.DownstreamRequest = _downstreamRequest;
}
[Fact]
public void should_call_scoped_data_repository_correctly()
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder()
var downstreamRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
.Build();
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
.And(x => x.GivenTheLoadBalancerHouseReturns())
.And(x => x.GivenTheLoadBalancerReturns())
.When(x => x.WhenICallTheMiddleware())
@ -68,17 +78,16 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_set_pipeline_error_if_cannot_get_load_balancer()
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder()
var downstreamRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
.Build();
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
.And(x => x.GivenTheLoadBalancerHouseReturnsAnError())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline())
@ -88,17 +97,16 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact]
public void should_set_pipeline_error_if_cannot_get_least()
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder()
var downstreamRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
.Build();
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
.And(x => x.GivenTheLoadBalancerHouseReturns())
.And(x => x.GivenTheLoadBalancerReturnsAnError())
.When(x => x.WhenICallTheMiddleware())
@ -106,24 +114,16 @@ namespace Ocelot.UnitTests.LoadBalancer
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware = new LoadBalancingMiddleware(_next, _loggerFactory.Object, _loadBalancerHouse.Object);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheConfigurationIs(ServiceProviderConfiguration config)
{
_config = config;
ScopedRepository
.Setup(x => x.Get<ServiceProviderConfiguration>("ServiceProviderConfiguration")).Returns(new OkResponse<ServiceProviderConfiguration>(config));
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_loadBalancerHouse.Object);
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseLoadBalancingMiddleware();
_downstreamContext.ServiceProviderConfiguration = config;
}
private void GivenTheDownStreamUrlIs(string downstreamUrl)
@ -147,18 +147,16 @@ namespace Ocelot.UnitTests.LoadBalancer
.ReturnsAsync(new OkResponse<ServiceHostAndPort>(_hostAndPort));
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
private void GivenTheDownStreamRouteIs(DownstreamReRoute downstreamRoute, List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue> placeholder)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = placeholder;
_downstreamContext.DownstreamReRoute = downstreamRoute;
}
private void GivenTheLoadBalancerHouseReturns()
{
_loadBalancerHouse
.Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
.ReturnsAsync(new OkResponse<ILoadBalancer>(_loadBalancer.Object));
}
@ -170,40 +168,32 @@ namespace Ocelot.UnitTests.LoadBalancer
});
_loadBalancerHouse
.Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
.ReturnsAsync(_getLoadBalancerHouseError);
}
private void ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline()
{
ScopedRepository
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
ScopedRepository
.Verify(x => x.Add("OcelotMiddlewareErrors", _getLoadBalancerHouseError.Errors), Times.Once);
_downstreamContext.IsError.ShouldBeTrue();
_downstreamContext.Errors.ShouldBe(_getLoadBalancerHouseError.Errors);
}
private void ThenAnErrorSayingReleaseFailedIsSetOnThePipeline()
{
ScopedRepository
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
ScopedRepository
.Verify(x => x.Add("OcelotMiddlewareErrors", It.IsAny<List<Error>>()), Times.Once);
_downstreamContext.IsError.ShouldBeTrue();
_downstreamContext.Errors.ShouldBe(It.IsAny<List<Error>>());
}
private void ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline()
{
ScopedRepository
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
_downstreamContext.IsError.ShouldBeTrue();
_downstreamContext.Errors.ShouldBe(_getHostAndPortError.Errors);
ScopedRepository
.Verify(x => x.Add("OcelotMiddlewareErrors", _getHostAndPortError.Errors), Times.Once);
}
private void ThenTheDownstreamUrlIsReplacedWith(string expectedUri)
{
_downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
_downstreamContext.DownstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
}
}
}

View File

@ -0,0 +1,69 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Middleware;
using Ocelot.Middleware.Multiplexer;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Middleware
{
public class MultiplexerTests
{
private readonly Multiplexer _multiplexer;
private readonly DownstreamContext _context;
private ReRoute _reRoute;
private readonly OcelotRequestDelegate _pipeline;
private int _count;
private Mock<IResponseAggregator> _aggregator;
public MultiplexerTests()
{
_aggregator = new Mock<IResponseAggregator>();
_context = new DownstreamContext(new DefaultHttpContext());
_pipeline = async context => { _count++; };
_multiplexer = new Multiplexer(_aggregator.Object);
}
[Fact]
public void should_multiplex()
{
var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
this.Given(x => GivenTheFollowing(reRoute))
.When(x => WhenIMultiplex())
.Then(x => ThePipelineIsCalled(2))
.BDDfy();
}
[Fact]
public void should_not_multiplex()
{
var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
this.Given(x => GivenTheFollowing(reRoute))
.When(x => WhenIMultiplex())
.Then(x => ThePipelineIsCalled(1))
.BDDfy();
}
private void GivenTheFollowing(ReRoute reRoute)
{
_reRoute = reRoute;
}
private void WhenIMultiplex()
{
_multiplexer.Multiplex(_context, _reRoute, _pipeline).GetAwaiter().GetResult();
}
private void ThePipelineIsCalled(int expected)
{
_count.ShouldBe(expected);
}
}
}

View File

@ -0,0 +1,87 @@
namespace Ocelot.UnitTests.Middleware
{
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Middleware.Pipeline;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class OcelotPiplineBuilderTests
{
private readonly IServiceCollection _services;
private IServiceProvider _serviceProvider;
private readonly IConfiguration _configRoot;
private IOcelotBuilder _ocelotBuilder;
private DownstreamContext _downstreamContext;
private int _counter;
public OcelotPiplineBuilderTests()
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IConfiguration>(_configRoot);
_services.AddOcelot();
}
[Fact]
public void should_build_generic()
{
this.When(x => WhenIUseAGeneric())
.Then(x => ThenTheGenericIsInThePipeline())
.BDDfy();
}
[Fact]
public void should_build_func()
{
this.When(x => WhenIUseAFunc())
.Then(x => ThenTheFuncIsInThePipeline())
.BDDfy();
}
private void WhenIUseAGeneric()
{
var provider = _services.BuildServiceProvider();
IOcelotPipelineBuilder builder = new OcelotPipelineBuilder(provider);
builder = builder.UseMiddleware<Ocelot.Errors.Middleware.ExceptionHandlerMiddleware>();
var del = builder.Build();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
del.Invoke(_downstreamContext);
}
private void ThenTheGenericIsInThePipeline()
{
_downstreamContext.HttpContext.Response.StatusCode.ShouldBe(500);
}
private void WhenIUseAFunc()
{
_counter = 0;
var provider = _services.BuildServiceProvider();
IOcelotPipelineBuilder builder = new OcelotPipelineBuilder(provider);
builder = builder.Use(async (ctx, next) =>
{
_counter++;
await next.Invoke();
});
var del = builder.Build();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
del.Invoke(_downstreamContext);
}
private void ThenTheFuncIsInThePipeline()
{
_counter.ShouldBe(1);
_downstreamContext.HttpContext.Response.StatusCode.ShouldBe(404);
}
}
}

View File

@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Errors;
using Ocelot.Middleware;
using Ocelot.Middleware.Multiplexer;
using Ocelot.UnitTests.Responder;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Middleware
{
public class SimpleJsonResponseAggregatorTests
{
private readonly SimpleJsonResponseAggregator _aggregator;
private List<DownstreamContext> _downstreamContexts;
private DownstreamContext _upstreamContext;
private ReRoute _reRoute;
public SimpleJsonResponseAggregatorTests()
{
_aggregator = new SimpleJsonResponseAggregator();
}
[Fact]
public void should_map_all_downstream_to_upstream_when_not_aggregate()
{
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
var downstreamReRoutes = new List<DownstreamReRoute>
{
billDownstreamReRoute,
};
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoutes(downstreamReRoutes)
.Build();
var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse =
new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Bill says hi") },
DownstreamReRoute = billDownstreamReRoute,
Errors = new List<Error> { new AnyError() },
DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.bbc.co.uk")),
};
var downstreamContexts = new List<DownstreamContext> { billDownstreamContext };
this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
.And(x => GivenTheReRoute(reRoute))
.And(x => GivenTheDownstreamContext(downstreamContexts))
.When(x => WhenIAggregate())
.Then(x => ThenTheContentIs("Bill says hi"))
.And(x => ThenTheUpstreamContextIsMappedForNonAggregate())
.BDDfy();
}
[Fact]
public void should_aggregate_n_responses_and_set_response_content_on_upstream_context()
{
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
var downstreamReRoutes = new List<DownstreamReRoute>
{
billDownstreamReRoute,
georgeDownstreamReRoute
};
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoutes(downstreamReRoutes)
.Build();
var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse =
new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("Bill says hi")},
DownstreamReRoute = billDownstreamReRoute
};
var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse =
new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("George says hi")},
DownstreamReRoute = georgeDownstreamReRoute
};
var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
var expected = "{\"Bill\":Bill says hi,\"George\":George says hi}";
this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
.And(x => GivenTheReRoute(reRoute))
.And(x => GivenTheDownstreamContext(downstreamContexts))
.When(x => WhenIAggregate())
.Then(x => ThenTheContentIs(expected))
.And(x => ThenTheContentTypeIs("application/json"))
.BDDfy();
}
[Fact]
public void should_return_error_if_any_downstreams_have_errored()
{
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
var downstreamReRoutes = new List<DownstreamReRoute>
{
billDownstreamReRoute,
georgeDownstreamReRoute
};
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoutes(downstreamReRoutes)
.Build();
var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse =
new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Bill says hi") },
DownstreamReRoute = billDownstreamReRoute
};
var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse =
new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Error") },
DownstreamReRoute = georgeDownstreamReRoute,
Errors = new List<Error>() { new AnyError() }
};
var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
var expected = "Error";
this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
.And(x => GivenTheReRoute(reRoute))
.And(x => GivenTheDownstreamContext(downstreamContexts))
.When(x => WhenIAggregate())
.Then(x => ThenTheContentIs(expected))
.And(x => ThenTheErrorIsMapped())
.BDDfy();
}
private void ThenTheErrorIsMapped()
{
_upstreamContext.Errors.ShouldBe(_downstreamContexts[1].Errors);
_upstreamContext.DownstreamResponse.ShouldBe(_downstreamContexts[1].DownstreamResponse);
}
private void GivenTheReRoute(ReRoute reRoute)
{
_reRoute = reRoute;
}
private void GivenTheUpstreamContext(DownstreamContext upstreamContext)
{
_upstreamContext = upstreamContext;
}
private void GivenTheDownstreamContext(List<DownstreamContext> downstreamContexts)
{
_downstreamContexts = downstreamContexts;
}
private void WhenIAggregate()
{
_aggregator.Aggregate(_reRoute, _upstreamContext, _downstreamContexts).GetAwaiter().GetResult();
}
private void ThenTheContentIs(string expected)
{
var content = _upstreamContext.DownstreamResponse.Content.ReadAsStringAsync()
.GetAwaiter()
.GetResult();
content.ShouldBe(expected);
}
private void ThenTheContentTypeIs(string expected)
{
_upstreamContext.DownstreamResponse.Content.Headers.ContentType.MediaType.ShouldBe(expected);
}
private void ThenTheUpstreamContextIsMappedForNonAggregate()
{
_upstreamContext.DownstreamRequest.ShouldBe(_downstreamContexts[0].DownstreamRequest);
_upstreamContext.DownstreamResponse.ShouldBe(_downstreamContexts[0].DownstreamResponse);
_upstreamContext.Errors.ShouldBe(_downstreamContexts[0].Errors);
}
}
}

View File

@ -54,6 +54,7 @@
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.QueryStrings
using Ocelot.Middleware;
namespace Ocelot.UnitTests.QueryStrings
{
using System.Collections.Generic;
using System.Net.Http;
@ -16,22 +18,30 @@
using Xunit;
using System.Security.Claims;
using Microsoft.AspNetCore.Builder;
using Ocelot.DownstreamRouteFinder.Middleware;
using Microsoft.AspNetCore.Http;
public class QueryStringBuilderMiddlewareTests : ServerHostedMiddlewareTest
public class QueryStringBuilderMiddlewareTests
{
private readonly Mock<IAddQueriesToRequest> _addQueries;
private readonly HttpRequestMessage _downstreamRequest;
private Response<DownstreamRoute> _downstreamRoute;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private QueryStringBuilderMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public QueryStringBuilderMiddlewareTests()
{
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<QueryStringBuilderMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_addQueries = new Mock<IAddQueriesToRequest>();
_downstreamRequest = new HttpRequestMessage();
ScopedRepository.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
GivenTheTestServerIsConfigured();
_downstreamContext.DownstreamRequest = new HttpRequestMessage();
_middleware = new QueryStringBuilderMiddleware(_next, _loggerFactory.Object, _addQueries.Object);
}
[Fact]
@ -39,11 +49,14 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToQueries(new List<ClaimToThing>
{
new ClaimToThing("UserId", "Subject", "", 0)
})
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToQueries(new List<ClaimToThing>
{
new ClaimToThing("UserId", "Subject", "", 0)
})
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
@ -54,17 +67,9 @@
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_addQueries.Object);
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseQueryStringBuilderMiddleware();
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheAddHeadersToRequestReturnsOk()
@ -83,15 +88,13 @@
.Verify(x => x.SetQueriesOnDownstreamRequest(
It.IsAny<List<ClaimToThing>>(),
It.IsAny<IEnumerable<Claim>>(),
_downstreamRequest), Times.Once);
_downstreamContext.DownstreamRequest), Times.Once);
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
}
}

View File

@ -1,11 +1,10 @@
namespace Ocelot.UnitTests.RateLimit
using Ocelot.Middleware;
namespace Ocelot.UnitTests.RateLimit
{
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
@ -13,27 +12,51 @@
using Ocelot.Logging;
using Ocelot.RateLimit;
using Ocelot.RateLimit.Middleware;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
using Ocelot.DownstreamRouteFinder.Middleware;
using Microsoft.Extensions.Caching.Memory;
using System.IO;
public class ClientRateLimitMiddlewareTests : ServerHostedMiddlewareTest
public class ClientRateLimitMiddlewareTests
{
private OkResponse<DownstreamRoute> _downstreamRoute;
private int responseStatusCode;
private int _responseStatusCode;
private IRateLimitCounterHandler _rateLimitCounterHandler;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly ClientRateLimitMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private readonly string _url;
public ClientRateLimitMiddlewareTests()
{
GivenTheTestServerIsConfigured();
_url = "http://localhost:51879";
var cacheEntryOptions = new MemoryCacheOptions();
_rateLimitCounterHandler = new MemoryCacheRateLimitCounterHandler(new MemoryCache(cacheEntryOptions));
var httpContext = new DefaultHttpContext();
_downstreamContext = new DownstreamContext(httpContext);
_downstreamContext.HttpContext.Response.Body = new FakeStream();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ClientRateLimitMiddleware>()).Returns(_logger.Object);
_next = async (context) => {
};
_middleware = new ClientRateLimitMiddleware(_next, _loggerFactory.Object, _rateLimitCounterHandler);
}
[Fact]
public void should_call_middleware_and_ratelimiting()
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429))
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
new RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
@ -49,8 +72,13 @@
public void should_call_middleware_withWhitelistClient()
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", 100,3),429))
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithEnableRateLimiting(true)
.WithRateLimitOptions(
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule("1s", 100, 3), 429))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
@ -60,31 +88,10 @@
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddMemoryCache();
services.AddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseRateLimiting();
app.Run(async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("This is ratelimit test");
});
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void WhenICallTheMiddlewareMultipleTime(int times)
@ -93,11 +100,12 @@
for (int i = 0; i < times; i++)
{
var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
request.Headers.Add("ClientId", clientId);
_downstreamContext.DownstreamRequest = request;
var response = Client.SendAsync(request);
responseStatusCode = (int)response.Result.StatusCode;
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
_responseStatusCode = (int)_downstreamContext.HttpContext.Response.StatusCode;
}
}
@ -107,22 +115,58 @@
for (int i = 0; i < 10; i++)
{
var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
request.Headers.Add("ClientId", clientId);
_downstreamContext.DownstreamRequest = request;
_downstreamContext.HttpContext.Request.Headers.TryAdd("ClientId", clientId);
var response = Client.SendAsync(request);
responseStatusCode = (int)response.Result.StatusCode;
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
_responseStatusCode = (int)_downstreamContext.HttpContext.Response.StatusCode;
}
}
private void ThenresponseStatusCodeIs429()
{
responseStatusCode.ShouldBe(429);
_responseStatusCode.ShouldBe(429);
}
private void ThenresponseStatusCodeIs200()
{
responseStatusCode.ShouldBe(200);
_responseStatusCode.ShouldBe(200);
}
}
class FakeStream : Stream
{
public override void Flush()
{
throw new System.NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new System.NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new System.NotImplementedException();
}
public override void SetLength(long value)
{
throw new System.NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
//do nothing
}
public override bool CanRead { get; }
public override bool CanSeek { get; }
public override bool CanWrite => true;
public override long Length { get; }
public override long Position { get; set; }
}
}

View File

@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.Request
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Request
{
using System.Net.Http;
using Microsoft.AspNetCore.Http;
@ -10,6 +12,8 @@
using TestStack.BDDfy;
using Xunit;
using Ocelot.Responses;
using Ocelot.DownstreamRouteFinder.Middleware;
using Shouldly;
public class DownstreamRequestInitialiserMiddlewareTests
{
@ -19,17 +23,16 @@
readonly Mock<HttpRequest> _httpRequest;
readonly Mock<RequestDelegate> _next;
readonly Mock<OcelotRequestDelegate> _next;
readonly Mock<IRequestMapper> _requestMapper;
readonly Mock<IRequestScopedDataRepository> _repo;
readonly Mock<IOcelotLoggerFactory> _loggerFactory;
readonly Mock<IOcelotLogger> _logger;
Response<HttpRequestMessage> _mappedRequest;
private DownstreamContext _downstreamContext;
public DownstreamRequestInitialiserMiddlewareTests()
{
@ -37,8 +40,7 @@
_httpContext = new Mock<HttpContext>();
_httpRequest = new Mock<HttpRequest>();
_requestMapper = new Mock<IRequestMapper>();
_repo = new Mock<IRequestScopedDataRepository>();
_next = new Mock<RequestDelegate>();
_next = new Mock<OcelotRequestDelegate>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
@ -49,8 +51,9 @@
_middleware = new DownstreamRequestInitialiserMiddleware(
_next.Object,
_loggerFactory.Object,
_repo.Object,
_requestMapper.Object);
_downstreamContext = new DownstreamContext(_httpContext.Object);
}
[Fact]
@ -104,7 +107,7 @@
private void WhenTheMiddlewareIsInvoked()
{
_middleware.Invoke(_httpContext.Object).GetAwaiter().GetResult();
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void ThenTheContexRequestIsMappedToADownstreamRequest()
@ -114,29 +117,28 @@
private void ThenTheDownstreamRequestIsStored()
{
_repo.Verify(r => r.Add("DownstreamRequest", _mappedRequest.Data), Times.Once);
_downstreamContext.DownstreamRequest.ShouldNotBeNull();
}
private void ThenTheDownstreamRequestIsNotStored()
{
_repo.Verify(r => r.Add("DownstreamRequest", It.IsAny<HttpRequestMessage>()), Times.Never);
_downstreamContext.DownstreamRequest.ShouldBeNull();
}
private void ThenAPipelineErrorIsStored()
{
_repo.Verify(r => r.Add("OcelotMiddlewareError", true), Times.Once);
_repo.Verify(r => r.Add("OcelotMiddlewareErrors", _mappedRequest.Errors), Times.Once);
_downstreamContext.IsError.ShouldBeTrue();
_downstreamContext.Errors.ShouldBe(_mappedRequest.Errors);
}
private void ThenTheNextMiddlewareIsInvoked()
{
_next.Verify(n => n(_httpContext.Object), Times.Once);
_next.Verify(n => n(_downstreamContext), Times.Once);
}
private void ThenTheNextMiddlewareIsNotInvoked()
{
_next.Verify(n => n(It.IsAny<HttpContext>()), Times.Never);
_next.Verify(n => n(It.IsAny<DownstreamContext>()), Times.Never);
}
}
}

View File

@ -1,152 +0,0 @@
namespace Ocelot.UnitTests.Request
{
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Request.Builder;
using Ocelot.Request.Middleware;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
using Ocelot.Requester.QoS;
using Ocelot.Configuration;
using Microsoft.AspNetCore.Builder;
using Ocelot.Errors;
public class HttpRequestBuilderMiddlewareTests : ServerHostedMiddlewareTest
{
private readonly Mock<IRequestCreator> _requestBuilder;
private readonly Mock<IRequestScopedDataRepository> _scopedRepository;
private readonly Mock<IQosProviderHouse> _qosProviderHouse;
private readonly HttpRequestMessage _downstreamRequest;
private OkResponse<Ocelot.Request.Request> _request;
private OkResponse<string> _downstreamUrl;
private OkResponse<DownstreamRoute> _downstreamRoute;
public HttpRequestBuilderMiddlewareTests()
{
_qosProviderHouse = new Mock<IQosProviderHouse>();
_requestBuilder = new Mock<IRequestCreator>();
_scopedRepository = new Mock<IRequestScopedDataRepository>();
_downstreamRequest = new HttpRequestMessage();
_scopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
GivenTheTestServerIsConfigured();
}
[Fact]
public void should_call_scoped_data_repository_correctly()
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true,false))
.Build());
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
.And(x => x.GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(new NoQoSProvider())))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, "", false)))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
.BDDfy();
}
[Fact]
public void should_call_scoped_data_repository_QosProviderError()
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true))
.Build());
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
.And(x => x.GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, "", false)))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedDataRepositoryQosProviderError())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_qosProviderHouse.Object);
services.AddSingleton(_requestBuilder.Object);
services.AddSingleton(_scopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseHttpRequestBuilderMiddleware();
}
private void GivenTheDownStreamUrlIs(string downstreamUrl)
{
_downstreamUrl = new OkResponse<string>(downstreamUrl);
_scopedRepository
.Setup(x => x.Get<string>(It.IsAny<string>()))
.Returns(_downstreamUrl);
}
private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
{
_qosProviderHouse
.Setup(x => x.Get(It.IsAny<ReRoute>()))
.Returns(qosProvider);
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
_scopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
}
private void GivenTheRequestBuilderReturns(Ocelot.Request.Request request)
{
_request = new OkResponse<Ocelot.Request.Request>(request);
_requestBuilder
.Setup(x => x.Build(It.IsAny<HttpRequestMessage>(),
It.IsAny<bool>(),
It.IsAny<IQoSProvider>(),
It.IsAny<bool>(),
It.IsAny<bool>(),
It.IsAny<string>(),
It.IsAny<bool>()))
.ReturnsAsync(_request);
}
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
{
_scopedRepository
.Verify(x => x.Add("Request", _request.Data), Times.Once());
}
private void ThenTheScopedDataRepositoryQosProviderError()
{
_scopedRepository
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once());
}
}
}

View File

@ -1,86 +0,0 @@
namespace Ocelot.UnitTests.Request
{
using System.Net.Http;
using Ocelot.Request.Builder;
using Ocelot.Requester.QoS;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class HttpRequestCreatorTests
{
private readonly IRequestCreator _requestCreator;
private readonly bool _isQos;
private readonly IQoSProvider _qoSProvider;
private readonly HttpRequestMessage _requestMessage;
private readonly bool _useCookieContainer;
private readonly bool _allowAutoRedirect;
private Response<Ocelot.Request.Request> _response;
private string _reRouteKey;
private readonly bool _useTracing;
public HttpRequestCreatorTests()
{
_requestCreator = new HttpRequestCreator();
_isQos = true;
_qoSProvider = new NoQoSProvider();
_useCookieContainer = false;
_allowAutoRedirect = false;
_requestMessage = new HttpRequestMessage();
}
[Fact]
public void ShouldBuildRequest()
{
this.When(x => x.WhenIBuildARequest())
.Then(x => x.ThenTheRequestContainsTheRequestMessage())
.Then(x => x.ThenTheRequestContainsTheIsQos())
.Then(x => x.ThenTheRequestContainsTheQosProvider())
.Then(x => x.ThenTheRequestContainsUseCookieContainer())
.Then(x => x.ThenTheRequestContainsUseTracing())
.Then(x => x.ThenTheRequestContainsAllowAutoRedirect())
.BDDfy();
}
private void WhenIBuildARequest()
{
_response = _requestCreator.Build(_requestMessage,
_isQos, _qoSProvider, _useCookieContainer, _allowAutoRedirect, _reRouteKey, _useTracing)
.GetAwaiter()
.GetResult();
}
private void ThenTheRequestContainsTheRequestMessage()
{
_response.Data.HttpRequestMessage.ShouldBe(_requestMessage);
}
private void ThenTheRequestContainsTheIsQos()
{
_response.Data.IsQos.ShouldBe(_isQos);
}
private void ThenTheRequestContainsTheQosProvider()
{
_response.Data.QosProvider.ShouldBe(_qoSProvider);
}
private void ThenTheRequestContainsUseCookieContainer()
{
_response.Data.UseCookieContainer.ShouldBe(_useCookieContainer);
}
private void ThenTheRequestContainsUseTracing()
{
_response.Data.IsTracing.ShouldBe(_useTracing);
}
private void ThenTheRequestContainsAllowAutoRedirect()
{
_response.Data.AllowAutoRedirect.ShouldBe(_allowAutoRedirect);
}
}
}

View File

@ -1,13 +1,15 @@
namespace Ocelot.UnitTests.RequestId
using Ocelot.Middleware;
namespace Ocelot.UnitTests.RequestId
{
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Infrastructure.RequestData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
@ -19,22 +21,32 @@
using TestStack.BDDfy;
using Xunit;
public class ReRouteRequestIdMiddlewareTests : ServerHostedMiddlewareTest
public class ReRouteRequestIdMiddlewareTests
{
private readonly HttpRequestMessage _downstreamRequest;
private Response<DownstreamRoute> _downstreamRoute;
private string _value;
private string _key;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly ReRouteRequestIdMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private readonly Mock<IRequestScopedDataRepository> _repo;
public ReRouteRequestIdMiddlewareTests()
{
_downstreamRequest = new HttpRequestMessage();
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
GivenTheTestServerIsConfigured();
_repo = new Mock<IRequestScopedDataRepository>();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ReRouteRequestIdMiddleware>()).Returns(_logger.Object);
_next = async context => {
context.HttpContext.Response.Headers.Add("LSRequestId", context.HttpContext.TraceIdentifier);
};
_middleware = new ReRouteRequestIdMiddleware(_next, _loggerFactory.Object, _repo.Object);
_downstreamContext.DownstreamRequest = _downstreamRequest;
}
[Fact]
@ -42,8 +54,11 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
@ -62,10 +77,13 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build())
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => GivenThereIsNoGlobalRequestId())
@ -79,10 +97,13 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build())
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build());
var requestId = Guid.NewGuid().ToString();
@ -100,10 +121,13 @@
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build())
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build());
var requestId = Guid.NewGuid().ToString();
@ -116,67 +140,57 @@
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenThereIsNoGlobalRequestId()
{
ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>(null));
_repo.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>(null));
}
private void GivenTheRequestIdWasSetGlobally()
{
ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>("alreadyset"));
_repo.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>("alreadyset"));
}
private void ThenTheRequestIdIsSaved()
{
ScopedRepository.Verify(x => x.Add<string>("RequestId", _value), Times.Once);
_repo.Verify(x => x.Add<string>("RequestId", _value), Times.Once);
}
private void ThenTheRequestIdIsUpdated()
{
ScopedRepository.Verify(x => x.Update<string>("RequestId", _value), Times.Once);
_repo.Verify(x => x.Update<string>("RequestId", _value), Times.Once);
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseRequestIdMiddleware();
app.Run(x =>
{
x.Response.Headers.Add("LSRequestId", x.TraceIdentifier);
return Task.CompletedTask;
});
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(_downstreamRoute);
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void GivenTheRequestIdIsAddedToTheRequest(string key, string value)
{
_key = key;
_value = value;
Client.DefaultRequestHeaders.TryAddWithoutValidation(_key, _value);
_downstreamContext.HttpContext.Request.Headers.TryAdd(_key, _value);
}
private void ThenTheTraceIdIsAnything()
{
ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldNotBeNullOrEmpty();
StringValues value;
_downstreamContext.HttpContext.Response.Headers.TryGetValue("LSRequestId", out value);
value.First().ShouldNotBeNullOrEmpty();
}
private void ThenTheTraceIdIs(string expected)
{
ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldBe(expected);
StringValues value;
_downstreamContext.HttpContext.Response.Headers.TryGetValue("LSRequestId", out value);
value.First().ShouldBe(expected);
}
}
}

View File

@ -1,6 +1,9 @@
using System;
using System.Net.Http;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Errors;
using Ocelot.Requester;
using Ocelot.Responses;
using Shouldly;
@ -14,7 +17,7 @@ namespace Ocelot.UnitTests.Requester
private readonly DelegatingHandlerHandlerHouse _house;
private Mock<IDelegatingHandlerHandlerProviderFactory> _factory;
private readonly Mock<IDelegatingHandlerHandlerProvider> _provider;
private Ocelot.Request.Request _request;
private DownstreamReRoute _request;
private Response<IDelegatingHandlerHandlerProvider> _result;
public DelegatingHandlerHandlerHouseTests()
@ -27,9 +30,10 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_create_and_store_provider()
{
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
this.Given(x => GivenTheRequest(request))
this.Given(x => GivenTheRequest(reRoute))
.And(x => GivenTheProviderReturns())
.When(x => WhenIGet())
.Then(x => ThenTheFactoryIsCalled(1))
@ -40,9 +44,10 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_get_provider()
{
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
this.Given(x => GivenTheRequest(request))
this.Given(x => GivenTheRequest(reRoute))
.And(x => GivenTheProviderReturns())
.And(x => WhenIGet())
.And(x => GivenTheFactoryIsCleared())
@ -55,15 +60,34 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_return_error()
{
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
this.Given(x => GivenTheRequest(request))
this.Given(x => GivenTheRequest(reRoute))
.And(x => GivenTheProviderThrows())
.When(x => WhenIGet())
.And(x => ThenAnErrorIsReturned())
.BDDfy();
}
[Fact]
public void should_return_error_if_factory_errors()
{
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
this.Given(x => GivenTheRequest(reRoute))
.And(x => GivenTheProviderReturnsError())
.When(x => WhenIGet())
.Then(x => ThenAnUnknownErrorIsReturned())
.BDDfy();
}
private void ThenAnUnknownErrorIsReturned()
{
_result.IsError.ShouldBeTrue();
}
private void ThenAnErrorIsReturned()
{
_result.IsError.ShouldBeTrue();
@ -72,7 +96,7 @@ namespace Ocelot.UnitTests.Requester
private void GivenTheProviderThrows()
{
_factory.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Throws<Exception>();
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Throws<Exception>();
}
private void GivenTheFactoryIsCleared()
@ -90,14 +114,19 @@ namespace Ocelot.UnitTests.Requester
_result = _house.Get(_request);
}
private void GivenTheRequest(Ocelot.Request.Request request)
private void GivenTheRequest(DownstreamReRoute request)
{
_request = request;
}
private void GivenTheProviderReturns()
{
_factory.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Returns(_provider.Object);
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
}
private void GivenTheProviderReturnsError()
{
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new ErrorResponse<IDelegatingHandlerHandlerProvider>(It.IsAny<Error>()));
}
private void ThenTheFactoryIsCalled(int times)

View File

@ -2,8 +2,13 @@ using System;
using System.Collections.Generic;
using System.Net.Http;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Errors;
using Ocelot.Logging;
using Ocelot.Requester;
using Ocelot.Requester.QoS;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
@ -14,17 +19,29 @@ namespace Ocelot.UnitTests.Requester
{
private readonly DelegatingHandlerHandlerProviderFactory _factory;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Ocelot.Request.Request _request;
private IDelegatingHandlerHandlerProvider _provider;
private DownstreamReRoute _request;
private Response<IDelegatingHandlerHandlerProvider> _provider;
private readonly Mock<IDelegatingHandlerHandlerProvider> _allRoutesProvider;
private readonly Mock<IQosProviderHouse> _qosProviderHouse;
private readonly Mock<ITracingHandlerFactory> _tracingFactory;
public DelegatingHandlerHandlerProviderFactoryTests()
{
_tracingFactory = new Mock<ITracingHandlerFactory>();
_qosProviderHouse = new Mock<IQosProviderHouse>();
_allRoutesProvider = new Mock<IDelegatingHandlerHandlerProvider>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_factory = new DelegatingHandlerHandlerProviderFactory(_loggerFactory.Object, _allRoutesProvider.Object, null);
_factory = new DelegatingHandlerHandlerProviderFactory(_loggerFactory.Object, _allRoutesProvider.Object, _tracingFactory.Object, _qosProviderHouse.Object);
}
private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
{
_qosProviderHouse
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
.Returns(qosProvider);
}
[Fact]
public void should_all_from_all_routes_provider_and_qos()
{
@ -34,9 +51,11 @@ namespace Ocelot.UnitTests.Requester
() => new FakeDelegatingHandler(1)
};
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
this.Given(x => GivenTheFollowingRequest(request))
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheAllRoutesProviderReturns(handlers))
.When(x => WhenIGet())
.Then(x => ThenThereIsDelegatesInProvider(3))
@ -48,9 +67,10 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_return_provider_with_no_delegates()
{
var request = new Ocelot.Request.Request(new HttpRequestMessage(), false, null, true, true, "", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
this.Given(x => GivenTheFollowingRequest(request))
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheAllRoutesProviderReturns())
.When(x => WhenIGet())
.Then(x => ThenNoDelegatesAreInTheProvider())
@ -60,9 +80,11 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_return_provider_with_qos_delegate()
{
var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
this.Given(x => GivenTheFollowingRequest(request))
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheAllRoutesProviderReturns())
.When(x => WhenIGet())
.Then(x => ThenThereIsDelegatesInProvider(1))
@ -70,9 +92,28 @@ namespace Ocelot.UnitTests.Requester
.BDDfy();
}
[Fact]
public void should_return_error()
{
var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
.And(x => GivenTheAllRoutesProviderReturns())
.When(x => WhenIGet())
.Then(x => ThenAnErrorIsReturned())
.BDDfy();
}
private void ThenAnErrorIsReturned()
{
_provider.IsError.ShouldBeTrue();
}
private void ThenTheDelegatesAreAddedCorrectly()
{
var delegates = _provider.Get();
var delegates = _provider.Data.Get();
var del = delegates[0].Invoke();
var handler = (FakeDelegatingHandler) del;
handler.Order.ShouldBe(0);
@ -94,7 +135,7 @@ namespace Ocelot.UnitTests.Requester
private void ThenItIsPolly(int i)
{
var delegates = _provider.Get();
var delegates = _provider.Data.Get();
var del = delegates[i].Invoke();
del.ShouldBeOfType<PollyCircuitBreakingDelegatingHandler>();
}
@ -102,10 +143,10 @@ namespace Ocelot.UnitTests.Requester
private void ThenThereIsDelegatesInProvider(int count)
{
_provider.ShouldNotBeNull();
_provider.Get().Count.ShouldBe(count);
_provider.Data.Get().Count.ShouldBe(count);
}
private void GivenTheFollowingRequest(Ocelot.Request.Request request)
private void GivenTheFollowingRequest(DownstreamReRoute request)
{
_request = request;
}
@ -118,7 +159,7 @@ namespace Ocelot.UnitTests.Requester
private void ThenNoDelegatesAreInTheProvider()
{
_provider.ShouldNotBeNull();
_provider.Get().Count.ShouldBe(0);
_provider.Data.Get().Count.ShouldBe(0);
}
}
}

View File

@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.Net.Http;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Requester;
using Ocelot.Responses;
using Shouldly;
@ -18,7 +20,7 @@ namespace Ocelot.UnitTests.Requester
private IHttpClientBuilder _builderResult;
private IHttpClient _httpClient;
private HttpResponseMessage _response;
private Ocelot.Request.Request _request;
private DownstreamReRoute _request;
public HttpClientBuilderTests()
{
@ -62,13 +64,16 @@ namespace Ocelot.UnitTests.Requester
private void GivenARequest()
{
_request = new Ocelot.Request.Request(null, false, null, false, false, "", false);
var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false)).WithReRouteKey("").Build();
_request = reRoute;
}
private void GivenTheHouseReturns()
{
_house
.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>()))
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
.Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
}

View File

@ -1,13 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Moq;
using Ocelot.Logging;
using Ocelot.Requester;
using Ocelot.Requester.QoS;
using Ocelot.Responses;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Middleware;
using TestStack.BDDfy;
using Xunit;
using Shouldly;
@ -21,7 +22,7 @@ namespace Ocelot.UnitTests.Requester
private Mock<IDelegatingHandlerHandlerProvider> _provider;
private Response<HttpResponseMessage> _response;
private readonly HttpClientHttpRequester _httpClientRequester;
private Ocelot.Request.Request _request;
private DownstreamContext _request;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
@ -30,7 +31,7 @@ namespace Ocelot.UnitTests.Requester
_provider = new Mock<IDelegatingHandlerHandlerProvider>();
_provider.Setup(x => x.Get()).Returns(new List<Func<DelegatingHandler>>());
_house = new Mock<IDelegatingHandlerHandlerHouse>();
_house.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
_house.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
_logger = new Mock<IOcelotLogger>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_loggerFactory
@ -43,7 +44,16 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_call_request_correctly()
{
this.Given(x=>x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") }, false, new NoQoSProvider(), false, false, "", false)))
var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false)).WithReRouteKey("").Build();
var context = new DownstreamContext(new DefaultHttpContext())
{
DownstreamReRoute = reRoute,
DownstreamRequest = new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") },
};
this.Given(x=>x.GivenTheRequestIs(context))
.When(x=>x.WhenIGetResponse())
.Then(x => x.ThenTheResponseIsCalledCorrectly())
.BDDfy();
@ -52,13 +62,22 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_call_request_unable_to_complete_request()
{
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }, false, new NoQoSProvider(), false, false, "", false)))
var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false)).WithReRouteKey("").Build();
var context = new DownstreamContext(new DefaultHttpContext())
{
DownstreamReRoute = reRoute,
DownstreamRequest = new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") },
};
this.Given(x => x.GivenTheRequestIs(context))
.When(x => x.WhenIGetResponse())
.Then(x => x.ThenTheResponseIsCalledError())
.BDDfy();
}
private void GivenTheRequestIs(Ocelot.Request.Request request)
private void GivenTheRequestIs(DownstreamContext request)
{
_request = request;
}

View File

@ -1,81 +1,73 @@
using Ocelot.Configuration.Builder;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Requester
{
using Microsoft.AspNetCore.Http;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Logging;
using Ocelot.Requester;
using Ocelot.Requester.Middleware;
using Ocelot.Requester.QoS;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
using Shouldly;
public class HttpRequesterMiddlewareTests : ServerHostedMiddlewareTest
public class HttpRequesterMiddlewareTests
{
private readonly Mock<IHttpRequester> _requester;
private OkResponse<HttpResponseMessage> _response;
private OkResponse<Ocelot.Request.Request> _request;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly HttpRequesterMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public HttpRequesterMiddlewareTests()
{
_requester = new Mock<IHttpRequester>();
GivenTheTestServerIsConfigured();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<HttpRequesterMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_middleware = new HttpRequesterMiddleware(_next, _loggerFactory.Object, _requester.Object);
}
[Fact]
public void should_call_scoped_data_repository_correctly()
public void should_call_services_correctly()
{
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false, "", false)))
this.Given(x => x.GivenTheRequestIs())
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
.And(x => x.GivenTheScopedRepoReturns())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedRepoIsCalledCorrectly())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_requester.Object);
services.AddSingleton(ScopedRepository.Object);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
private void GivenTheRequestIs()
{
app.UseHttpRequesterMiddleware();
}
private void GivenTheRequestIs(Ocelot.Request.Request request)
{
_request = new OkResponse<Ocelot.Request.Request>(request);
ScopedRepository
.Setup(x => x.Get<Ocelot.Request.Request>(It.IsAny<string>()))
.Returns(_request);
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_downstreamContext.DownstreamReRoute = new DownstreamReRouteBuilder().Build();
}
private void GivenTheRequesterReturns(HttpResponseMessage response)
{
_response = new OkResponse<HttpResponseMessage>(response);
_requester
.Setup(x => x.GetResponse(It.IsAny<Ocelot.Request.Request>()))
.Setup(x => x.GetResponse(It.IsAny<DownstreamContext>()))
.ReturnsAsync(_response);
}
private void GivenTheScopedRepoReturns()
{
ScopedRepository
.Setup(x => x.Add(It.IsAny<string>(), _response.Data))
.Returns(new OkResponse());
}
private void ThenTheScopedRepoIsCalledCorrectly()
{
ScopedRepository
.Verify(x => x.Add("HttpResponseMessage", _response.Data), Times.Once());
_downstreamContext.DownstreamResponse.ShouldBe(_response.Data);
}
}
}

View File

@ -13,7 +13,7 @@ namespace Ocelot.UnitTests.Requester
public class QoSProviderFactoryTests
{
private readonly IQoSProviderFactory _factory;
private ReRoute _reRoute;
private DownstreamReRoute _reRoute;
private IQoSProvider _result;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
@ -31,7 +31,7 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_return_no_qos_provider()
{
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "get" })
.WithIsQos(false)
.Build();
@ -51,7 +51,7 @@ namespace Ocelot.UnitTests.Requester
.WithExceptionsAllowedBeforeBreaking(100)
.Build();
var reRoute = new ReRouteBuilder()
var reRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "get" })
.WithIsQos(true)
.WithQosOptions(qosOptions)
@ -63,7 +63,7 @@ namespace Ocelot.UnitTests.Requester
.BDDfy();
}
private void GivenAReRoute(ReRoute reRoute)
private void GivenAReRoute(DownstreamReRoute reRoute)
{
_reRoute = reRoute;
}

View File

@ -15,7 +15,7 @@ namespace Ocelot.UnitTests.Requester
private readonly QosProviderHouse _qosProviderHouse;
private Response _addResult;
private Response<IQoSProvider> _getResult;
private ReRoute _reRoute;
private DownstreamReRoute _reRoute;
private readonly Mock<IQoSProviderFactory> _factory;
public QosProviderHouseTests()
@ -27,7 +27,7 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_store_qos_provider_on_first_request()
{
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
.Then(x => x.ThenItIsAdded())
@ -37,7 +37,7 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_not_store_qos_provider_on_first_request()
{
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
@ -48,8 +48,8 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_store_qos_providers_by_key()
{
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testTwo").Build();
var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
var reRouteTwo = new DownstreamReRouteBuilder().WithReRouteKey("testTwo").Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
.And(x => x.GivenThereIsAQoSProvider(reRouteTwo, new FakePollyQoSProvider()))
@ -63,7 +63,7 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_return_error_if_no_qos_provider_with_key()
{
var reRoute = new ReRouteBuilder().Build();
var reRoute = new DownstreamReRouteBuilder().Build();
this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
.Then(x => x.ThenAnErrorIsReturned())
@ -73,9 +73,9 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_get_new_qos_provider_if_reroute_qos_provider_has_changed()
{
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("test").WithIsQos(true).Build();
var reRouteTwo = new DownstreamReRouteBuilder().WithReRouteKey("test").WithIsQos(true).Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
@ -85,7 +85,7 @@ namespace Ocelot.UnitTests.Requester
.BDDfy();
}
private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(ReRoute reRoute)
private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(DownstreamReRoute reRoute)
{
_reRoute = reRoute;
_factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider());
@ -112,7 +112,7 @@ namespace Ocelot.UnitTests.Requester
}
private void GivenThereIsAQoSProvider(ReRoute reRoute, IQoSProvider qoSProvider)
private void GivenThereIsAQoSProvider(DownstreamReRoute reRoute, IQoSProvider qoSProvider)
{
_reRoute = reRoute;
_qoSProvider = qoSProvider;
@ -120,7 +120,7 @@ namespace Ocelot.UnitTests.Requester
_getResult = _qosProviderHouse.Get(reRoute);
}
private void WhenWeGetTheQoSProvider(ReRoute reRoute)
private void WhenWeGetTheQoSProvider(DownstreamReRoute reRoute)
{
_getResult = _qosProviderHouse.Get(reRoute);
}

View File

@ -0,0 +1,27 @@
using Butterfly.Client.Tracing;
using Moq;
using Ocelot.Requester;
using Shouldly;
using Xunit;
namespace Ocelot.UnitTests.Requester
{
public class TracingHandlerFactoryTests
{
private TracingHandlerFactory _factory;
private Mock<IServiceTracer> _tracer;
public TracingHandlerFactoryTests()
{
_tracer = new Mock<IServiceTracer>();
_factory = new TracingHandlerFactory(_tracer.Object);
}
[Fact]
public void should_return()
{
var handler = _factory.Get();
handler.ShouldBeOfType<OcelotHttpTracingHandler>();
}
}
}

View File

@ -1,32 +1,45 @@
namespace Ocelot.UnitTests.Responder
using System.Collections.Generic;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Responder
{
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Ocelot.DownstreamRouteFinder.Middleware;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DownstreamRouteFinder.Finder;
using Ocelot.Errors;
using Ocelot.Logging;
using Ocelot.Requester;
using Ocelot.Responder;
using Ocelot.Responder.Middleware;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
public class ResponderMiddlewareTests : ServerHostedMiddlewareTest
public class ResponderMiddlewareTests
{
private readonly Mock<IHttpResponder> _responder;
private readonly Mock<IErrorsToHttpStatusCodeMapper> _codeMapper;
private OkResponse<HttpResponseMessage> _response;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private readonly ResponderMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public ResponderMiddlewareTests()
{
_responder = new Mock<IHttpResponder>();
_codeMapper = new Mock<IErrorsToHttpStatusCodeMapper>();
GivenTheTestServerIsConfigured();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ResponderMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
_middleware = new ResponderMiddleware(_next, _responder.Object, _loggerFactory.Object, _codeMapper.Object);
}
[Fact]
@ -39,7 +52,6 @@
.BDDfy();
}
[Fact]
public void should_return_any_errors()
{
@ -50,33 +62,19 @@
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_codeMapper.Object);
services.AddSingleton(_responder.Object);
services.AddSingleton(ScopedRepository.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseResponderMiddleware();
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheHttpResponseMessageIs(HttpResponseMessage response)
{
_response = new OkResponse<HttpResponseMessage>(response);
ScopedRepository
.Setup(x => x.Get<HttpResponseMessage>(It.IsAny<string>()))
.Returns(_response);
_downstreamContext.DownstreamResponse = response;
}
private void GivenThereAreNoPipelineErrors()
{
ScopedRepository
.Setup(x => x.Get<bool>(It.IsAny<string>()))
.Returns(new OkResponse<bool>(false));
_downstreamContext.Errors = new List<Error>();
}
private void ThenThereAreNoErrors()
@ -86,11 +84,7 @@
private void GivenThereArePipelineErrors(Error error)
{
ScopedRepository
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
.Returns(new OkResponse<bool>(true));
ScopedRepository.Setup(x => x.Get<List<Error>>("OcelotMiddlewareErrors"))
.Returns(new OkResponse<List<Error>>(new List<Error>() { error }));
_downstreamContext.Errors = new List<Error>(){error};
}
}
}

View File

@ -16,7 +16,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
private ServiceProviderConfiguration _serviceConfig;
private IServiceDiscoveryProvider _result;
private readonly ServiceDiscoveryProviderFactory _factory;
private ReRoute _reRoute;
private DownstreamReRoute _reRoute;
private Mock<IOcelotLoggerFactory> _loggerFactory;
public ServiceProviderFactoryTests()
@ -31,7 +31,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
var serviceConfig = new ServiceProviderConfigurationBuilder()
.Build();
var reRoute = new ReRouteBuilder().Build();
var reRoute = new DownstreamReRouteBuilder().Build();
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
.When(x => x.WhenIGetTheServiceProvider())
@ -51,7 +51,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
new DownstreamHostAndPort("abc.com", 80)
};
var reRoute = new ReRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
var reRoute = new DownstreamReRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
.When(x => x.WhenIGetTheServiceProvider())
@ -60,6 +60,23 @@ namespace Ocelot.UnitTests.ServiceDiscovery
.BDDfy();
}
[Fact]
public void should_return_consul_service_provider()
{
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("product")
.WithUseServiceDiscovery(true)
.Build();
var serviceConfig = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
.When(x => x.WhenIGetTheServiceProvider())
.Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>())
.BDDfy();
}
private void ThenTheFollowingServicesAreReturned(List<DownstreamHostAndPort> downstreamAddresses)
{
var result = (ConfigurationServiceProvider)_result;
@ -75,24 +92,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
}
}
[Fact]
public void should_return_consul_service_provider()
{
var reRoute = new ReRouteBuilder()
.WithServiceName("product")
.WithUseServiceDiscovery(true)
.Build();
var serviceConfig = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
.When(x => x.WhenIGetTheServiceProvider())
.Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>())
.BDDfy();
}
private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, ReRoute reRoute)
private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
{
_serviceConfig = serviceConfig;
_reRoute = reRoute;