Merge branch 'release/13.8.0'

This commit is contained in:
TomPallister
2019-10-28 07:34:56 +00:00
93 changed files with 1747 additions and 553 deletions

View File

@ -0,0 +1,201 @@
using Xunit;
namespace Ocelot.AcceptanceTests
{
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
using IdentityServer4.Test;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration.File;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using TestStack.BDDfy;
public class ClaimsToDownstreamPathTests : IDisposable
{
private IWebHost _servicebuilder;
private IWebHost _identityServerBuilder;
private readonly Steps _steps;
private Action<IdentityServerAuthenticationOptions> _options;
private string _identityServerRootUrl = "http://localhost:57888";
private string _downstreamFinalPath;
public ClaimsToDownstreamPathTests()
{
_steps = new Steps();
_options = o =>
{
o.Authority = _identityServerRootUrl;
o.ApiName = "api";
o.RequireHttpsMetadata = false;
o.SupportedTokens = SupportedTokens.Both;
o.ApiSecret = "secret";
};
}
[Fact]
public void should_return_200_and_change_downstream_path()
{
var user = new TestUser()
{
Username = "test",
Password = "test",
SubjectId = "registered|1231231",
};
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/users/{userId}",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 57876,
},
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/users",
UpstreamHttpMethod = new List<string> { "Get" },
AuthenticationOptions = new FileAuthenticationOptions
{
AuthenticationProviderKey = "Test",
AllowedScopes = new List<string>
{
"openid", "offline_access", "api",
},
},
ChangeDownstreamPathTemplate =
{
{"userId", "Claims[sub] > value[1] > |"},
},
},
},
};
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:57888", "api", AccessTokenType.Jwt, user))
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:57876", 200))
.And(x => _steps.GivenIHaveAToken("http://localhost:57888"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/users"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("UserId: 1231231"))
.And(x => _downstreamFinalPath.ShouldBe("/users/1231231"))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
{
_servicebuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
{
app.Run(async context =>
{
_downstreamFinalPath = context.Request.Path.Value;
string userId = _downstreamFinalPath.Replace("/users/", string.Empty);
var responseBody = $"UserId: {userId}";
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
});
})
.Build();
_servicebuilder.Start();
}
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, TestUser user)
{
_identityServerBuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.ConfigureServices(services =>
{
services.AddLogging();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(new List<ApiResource>
{
new ApiResource
{
Name = apiName,
Description = "My API",
Enabled = true,
DisplayName = "test",
Scopes = new List<Scope>()
{
new Scope("api"),
new Scope("openid"),
new Scope("offline_access")
},
ApiSecrets = new List<Secret>()
{
new Secret
{
Value = "secret".Sha256()
}
},
UserClaims = new List<string>()
{
"CustomerId", "LocationId", "UserType", "UserId"
}
}
})
.AddInMemoryClients(new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
AllowedScopes = new List<string> { apiName, "openid", "offline_access" },
AccessTokenType = tokenType,
Enabled = true,
RequireClientSecret = false
}
})
.AddTestUsers(new List<TestUser>
{
user
});
})
.Configure(app =>
{
app.UseIdentityServer();
})
.Build();
_identityServerBuilder.Start();
_steps.VerifyIdentiryServerStarted(url);
}
public void Dispose()
{
_servicebuilder?.Dispose();
_steps.Dispose();
_identityServerBuilder?.Dispose();
}
}
}

View File

@ -5,6 +5,7 @@ namespace Ocelot.AcceptanceTests
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -16,9 +17,9 @@ namespace Ocelot.AcceptanceTests
public class ConfigurationInConsulTests : IDisposable
{
private IWebHost _builder;
private IHost _builder;
private readonly Steps _steps;
private IWebHost _fakeConsulBuilder;
private IHost _fakeConsulBuilder;
private FileConfiguration _config;
private readonly List<ServiceEntry> _consulServices;
@ -75,8 +76,10 @@ namespace Ocelot.AcceptanceTests
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
{
_fakeConsulBuilder = new WebHostBuilder()
.UseUrls(url)
_fakeConsulBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
@ -103,7 +106,9 @@ namespace Ocelot.AcceptanceTests
{
var reader = new StreamReader(context.Request.Body);
var json = reader.ReadToEnd();
// Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
// var json = reader.ReadToEnd();
var json = await reader.ReadToEndAsync();
_config = JsonConvert.DeserializeObject<FileConfiguration>(json);
@ -122,8 +127,8 @@ namespace Ocelot.AcceptanceTests
await context.Response.WriteJsonAsync(_consulServices);
}
});
})
.Build();
});
}).Build();
_fakeConsulBuilder.Start();
}
@ -146,22 +151,24 @@ namespace Ocelot.AcceptanceTests
private void GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody)
{
_builder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
_builder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
app.UsePathBase(basePath);
app.Run(async context =>
webBuilder.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(url)
.Configure(app =>
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
});
})
app.UsePathBase(basePath);
app.Run(async context =>
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
});
});
})
.Build();
_builder.Start();

View File

@ -373,7 +373,9 @@
{
var reader = new StreamReader(context.Request.Body);
var json = reader.ReadToEnd();
// Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
// var json = reader.ReadToEnd();
var json = await reader.ReadToEndAsync();
_config = JsonConvert.DeserializeObject<FileConfiguration>(json);

View File

@ -181,7 +181,13 @@
}
else if (result.MessageType == WebSocketMessageType.Close)
{
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
if (client.State != WebSocketState.Closed)
{
// Last version, the client state is CloseReceived
// Valid states are: Open, CloseReceived, CloseSent
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
}
break;
}
}
@ -227,7 +233,13 @@
}
else if (result.MessageType == WebSocketMessageType.Close)
{
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
if (client.State != WebSocketState.Closed)
{
// Last version, the client state is CloseReceived
// Valid states are: Open, CloseReceived, CloseSent
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
}
break;
}
}

View File

@ -55,7 +55,7 @@ namespace Ocelot.AcceptanceTests
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.And(x => ThenTheContentTypeShouldBeEmpty())
.And(x => ThenTheContentLengthShouldBeEmpty())
.And(x => ThenTheContentLengthShouldBeZero())
.BDDfy();
}
@ -139,9 +139,9 @@ namespace Ocelot.AcceptanceTests
_contentType.ShouldBe(expected);
}
private void ThenTheContentLengthShouldBeEmpty()
private void ThenTheContentLengthShouldBeZero()
{
_contentLength.ShouldBeNull();
_contentLength.ShouldBeEquivalentTo(0L);
}
private void ThenTheContentLengthIs(int expected)

View File

@ -73,7 +73,9 @@ namespace Ocelot.AcceptanceTests
{
using (var sr = new StreamReader(decompress))
{
text = sr.ReadToEnd();
// Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
// text = sr.ReadToEnd();
text = await sr.ReadToEndAsync();
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Ocelot.AcceptanceTests</PackageId>
@ -36,36 +36,39 @@
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4" Version="2.4.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4" Version="3.0.1" />
<PackageReference Include="Consul" Version="0.7.2.6" />
<PackageReference Include="Rafty" Version="0.4.4" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.2.0" />
<PackageReference Include="CacheManager.Serialization.Json" Version="1.2.0" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
<PackageReference Include="CacheManager.Serialization.Json" Version="2.0.0-beta-1629" />
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
</ItemGroup>
</Project>

View File

@ -37,7 +37,7 @@
using System.Threading.Tasks;
using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests;
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
using CookieHeaderValue = System.Net.Http.Headers.CookieHeaderValue;
using CookieHeaderValue = Microsoft.Net.Http.Headers.CookieHeaderValue;
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
public class Steps : IDisposable
@ -338,7 +338,7 @@
{
x.WithMicrosoftLogging(log =>
{
log.AddConsole(LogLevel.Debug);
//log.AddConsole(LogLevel.Debug);
})
.WithJsonSerializer()
.WithHandle(typeof(InMemoryJsonHandle<>));
@ -424,7 +424,7 @@
{
x.WithMicrosoftLogging(log =>
{
log.AddConsole(LogLevel.Debug);
//log.AddConsole(LogLevel.Debug);
})
.WithJsonSerializer()
.WithHandle(typeof(InMemoryJsonHandle<>));

View File

@ -164,7 +164,13 @@ namespace Ocelot.AcceptanceTests
}
else if (result.MessageType == WebSocketMessageType.Close)
{
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
if (client.State != WebSocketState.Closed)
{
// Last version, the client state is CloseReceived
// Valid states are: Open, CloseReceived, CloseSent
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
}
break;
}
}
@ -210,7 +216,13 @@ namespace Ocelot.AcceptanceTests
}
else if (result.MessageType == WebSocketMessageType.Close)
{
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
if (client.State != WebSocketState.Closed)
{
// Last version, the client state is CloseReceived
// Valid states are: Open, CloseReceived, CloseSent
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
}
break;
}
}
@ -273,13 +285,13 @@ namespace Ocelot.AcceptanceTests
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
catch (Exception e)

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Ocelot.Benchmarks</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Ocelot.Benchmarks</PackageId>
@ -19,8 +19,12 @@
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
</ItemGroup>
</Project>

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Ocelot.Administration;
using Ocelot.Cache;
@ -29,15 +30,15 @@ namespace Ocelot.IntegrationTests
private HttpClient _httpClient;
private readonly HttpClient _httpClientTwo;
private HttpResponseMessage _response;
private IWebHost _builder;
private IWebHostBuilder _webHostBuilder;
private IHost _builder;
private IHostBuilder _webHostBuilder;
private string _ocelotBaseUrl;
private BearerToken _token;
private IWebHostBuilder _webHostBuilderTwo;
private IWebHost _builderTwo;
private IWebHost _identityServerBuilder;
private IWebHost _fooServiceBuilder;
private IWebHost _barServiceBuilder;
private IHostBuilder _webHostBuilderTwo;
private IHost _builderTwo;
private IHost _identityServerBuilder;
private IHost _fooServiceBuilder;
private IHost _barServiceBuilder;
public AdministrationTests()
{
@ -220,7 +221,7 @@ namespace Ocelot.IntegrationTests
UpstreamHttpMethod = new List<string> { "get" },
UpstreamPathTemplate = "/test"
}
}
},
};
var updatedConfiguration = new FileConfiguration
@ -476,56 +477,59 @@ namespace Ocelot.IntegrationTests
private void GivenThereIsAnIdentityServerOn(string url, string apiName)
{
_identityServerBuilder = new WebHostBuilder()
.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureServices(services =>
_identityServerBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
services.AddLogging();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
webBuilder.UseUrls(url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureServices(services =>
{
services.AddLogging();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(new List<ApiResource>
{
new ApiResource
new ApiResource
{
Name = apiName,
Description = apiName,
Enabled = true,
DisplayName = apiName,
Scopes = new List<Scope>()
{
Name = apiName,
Description = apiName,
Enabled = true,
DisplayName = apiName,
Scopes = new List<Scope>()
{
new Scope(apiName)
}
}
new Scope(apiName),
},
},
})
.AddInMemoryClients(new List<Client>
{
new Client
{
ClientId = apiName,
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
AllowedScopes = new List<string> { apiName },
AccessTokenType = AccessTokenType.Jwt,
Enabled = true
}
new Client
{
ClientId = apiName,
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },
AllowedScopes = new List<string> { apiName },
AccessTokenType = AccessTokenType.Jwt,
Enabled = true
},
})
.AddTestUsers(new List<TestUser>
{
new TestUser
{
Username = "test",
Password = "test",
SubjectId = "1231231"
}
new TestUser
{
Username = "test",
Password = "test",
SubjectId = "1231231"
},
});
})
.Configure(app =>
{
app.UseIdentityServer();
})
.Build();
})
.Configure(app =>
{
app.UseIdentityServer();
}
);
}).Build();
_identityServerBuilder.Start();
@ -540,28 +544,32 @@ namespace Ocelot.IntegrationTests
{
_httpClientTwo.BaseAddress = new Uri(baseUrl);
_webHostBuilderTwo = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddOcelot()
_webHostBuilderTwo = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddMvc(option => option.EnableEndpointRouting = false);
x.AddOcelot()
.AddAdministration("/administration", "secret");
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
});
_builderTwo = _webHostBuilderTwo.Build();
@ -654,29 +662,33 @@ namespace Ocelot.IntegrationTests
private void GivenOcelotIsRunningWithIdentityServerSettings(Action<IdentityServerAuthenticationOptions> configOptions)
{
_webHostBuilder = new WebHostBuilder()
.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
_webHostBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
webBuilder.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddSingleton(_webHostBuilder);
x.AddOcelot()
.AddAdministration("/administration", configOptions);
})
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddMvc(option => option.EnableEndpointRouting = false);
x.AddSingleton(_webHostBuilder);
x.AddOcelot()
.AddAdministration("/administration", configOptions);
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
});
_builder = _webHostBuilder.Build();
@ -685,27 +697,31 @@ namespace Ocelot.IntegrationTests
private void GivenOcelotIsRunning()
{
_webHostBuilder = new WebHostBuilder()
.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
_webHostBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
webBuilder.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddOcelot()
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddMvc(s => s.EnableEndpointRouting = false);
x.AddOcelot()
.AddAdministration("/administration", "secret");
})
.Configure(app =>
{
app.UseOcelot().Wait();
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
});
_builder = _webHostBuilder.Build();
@ -715,30 +731,34 @@ namespace Ocelot.IntegrationTests
private void GivenOcelotIsRunningWithNoWebHostBuilder(string baseUrl)
{
_webHostBuilder = new WebHostBuilder()
.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
_webHostBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
webBuilder.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddSingleton(_webHostBuilder);
x.AddOcelot()
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(x =>
{
x.AddMvc(option => option.EnableEndpointRouting = false);
x.AddSingleton(_webHostBuilder);
x.AddOcelot()
.AddAdministration("/administration", "secret");
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
});
_builder = _webHostBuilder.Build();
_builder.Start();
@ -797,42 +817,46 @@ namespace Ocelot.IntegrationTests
private void GivenThereIsAFooServiceRunningOn(string baseUrl)
{
_fooServiceBuilder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
_fooServiceBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
app.UsePathBase("/foo");
app.Run(async context =>
webBuilder.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("foo");
app.UsePathBase("/foo");
app.Run(async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("foo");
});
});
})
.Build();
}).Build();
_fooServiceBuilder.Start();
}
private void GivenThereIsABarServiceRunningOn(string baseUrl)
{
_barServiceBuilder = new WebHostBuilder()
.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
_barServiceBuilder = Host.CreateDefaultBuilder()
.ConfigureWebHost(webBuilder =>
{
app.UsePathBase("/bar");
app.Run(async context =>
webBuilder.UseUrls(baseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.Configure(app =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("bar");
app.UsePathBase("/bar");
app.Run(async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("bar");
});
});
})
.Build();
}).Build();
_barServiceBuilder.Start();
}

View File

@ -5,6 +5,8 @@ namespace Ocelot.IntegrationTests
using global::CacheManager.Core;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Ocelot.Administration;
@ -25,15 +27,10 @@ namespace Ocelot.IntegrationTests
private HttpClient _httpClient;
private readonly HttpClient _httpClientTwo;
private HttpResponseMessage _response;
private IWebHost _builder;
private IWebHostBuilder _webHostBuilder;
private IHost _builder;
private IHostBuilder _webHostBuilder;
private string _ocelotBaseUrl;
private BearerToken _token;
private IWebHostBuilder _webHostBuilderTwo;
private IWebHost _builderTwo;
private IWebHost _identityServerBuilder;
private IWebHost _fooServiceBuilder;
private IWebHost _barServiceBuilder;
public CacheManagerTests()
{
@ -61,7 +58,7 @@ namespace Ocelot.IntegrationTests
{
Host = "localhost",
Port = 80,
}
},
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/",
@ -69,8 +66,8 @@ namespace Ocelot.IntegrationTests
UpstreamPathTemplate = "/",
FileCacheOptions = new FileCacheOptions
{
TtlSeconds = 10
}
TtlSeconds = 10,
},
},
new FileReRoute()
{
@ -80,7 +77,7 @@ namespace Ocelot.IntegrationTests
{
Host = "localhost",
Port = 80,
}
},
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/",
@ -88,10 +85,10 @@ namespace Ocelot.IntegrationTests
UpstreamPathTemplate = "/test",
FileCacheOptions = new FileCacheOptions
{
TtlSeconds = 10
}
}
}
TtlSeconds = 10,
},
},
},
};
var regionToClear = "gettest";
@ -118,7 +115,7 @@ namespace Ocelot.IntegrationTests
new KeyValuePair<string, string>("client_id", "admin"),
new KeyValuePair<string, string>("client_secret", "secret"),
new KeyValuePair<string, string>("scope", "admin"),
new KeyValuePair<string, string>("grant_type", "client_credentials")
new KeyValuePair<string, string>("grant_type", "client_credentials"),
};
var content = new FormUrlEncodedContent(formData);
@ -133,16 +130,13 @@ namespace Ocelot.IntegrationTests
private void GivenOcelotIsRunning()
{
_webHostBuilder = new WebHostBuilder()
.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
_webHostBuilder = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
@ -151,20 +145,26 @@ namespace Ocelot.IntegrationTests
Action<ConfigurationBuilderCachePart> settings = (s) =>
{
s.WithMicrosoftLogging(log =>
{
log.AddConsole(LogLevel.Debug);
})
.WithDictionaryHandle();
{
//log.AddConsole(LogLevel.Debug);
})
.WithDictionaryHandle();
};
x.AddMvc(option => option.EnableEndpointRouting = false);
x.AddOcelot()
.AddCacheManager(settings)
.AddAdministration("/administration", "secret");
})
.AddCacheManager(settings)
.AddAdministration("/administration", "secret");
})
.ConfigureWebHost(webBuilder =>
{
webBuilder.UseUrls(_ocelotBaseUrl)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.Configure(app =>
{
app.UseOcelot().Wait();
});
});
_builder = _webHostBuilder.Build();
@ -214,7 +214,7 @@ namespace Ocelot.IntegrationTests
Environment.SetEnvironmentVariable("OCELOT_CERTIFICATE_PASSWORD", "");
_builder?.Dispose();
_httpClient?.Dispose();
_identityServerBuilder?.Dispose();
//_identityServerBuilder?.Dispose();
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Ocelot.IntegrationTests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Ocelot.IntegrationTests</PackageId>
@ -29,30 +29,33 @@
<ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
<ProjectReference Include="..\..\src\Ocelot.Provider.Rafty\Ocelot.Provider.Rafty.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.Data.SQLite" Version="2.2.4" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="Microsoft.Data.SQLite" Version="3.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="Microsoft.Data.SQLite" Version="2.2.4" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4" Version="2.4.0" />
<PackageReference Include="Microsoft.Data.SQLite" Version="3.0.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4" Version="3.0.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
</ItemGroup>
</Project>

View File

@ -54,12 +54,12 @@ namespace Ocelot.IntegrationTests
{
Host = "localhost",
Port = 51879,
}
},
},
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
},
},
};
this.Given(x => GivenThereIsAConfiguration(configuration))

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>Ocelot.ManualTest</AssemblyName>
<OutputType>Exe</OutputType>
@ -28,16 +28,18 @@
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
</ItemGroup>
</Project>

View File

@ -32,12 +32,12 @@ namespace Ocelot.ManualTest
})
.ConfigureServices(s =>
{
s.AddAuthentication()
.AddJwtBearer("TestKey", x =>
{
x.Authority = "test";
x.Audience = "test";
});
s.AddAuthentication();
//.AddJwtBearer("TestKey", x =>
//{
// x.Authority = "test";
// x.Audience = "test";
//});
s.AddSingleton<QosDelegatingHandlerDelegate>((x, t) => new FakeHandler());
s.AddOcelot()

View File

@ -2,14 +2,15 @@ namespace Ocelot.UnitTests.Administration
{
using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Administration;
using Ocelot.DependencyInjection;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -25,9 +26,19 @@ namespace Ocelot.UnitTests.Administration
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotAdministrationBuilderTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
//keep
[Fact]

View File

@ -2,9 +2,10 @@
{
using global::CacheManager.Core;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting.Internal;
using Moq;
using Ocelot.Cache;
using Ocelot.Cache.CacheManager;
using Ocelot.Configuration;
@ -14,6 +15,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -30,11 +32,21 @@
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
_maxRetries = 100;
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_cache_manager()
{

View File

@ -15,7 +15,7 @@ namespace Ocelot.UnitTests.Configuration
public class DiskFileConfigurationRepositoryTests : IDisposable
{
private readonly Mock<IHostingEnvironment> _hostingEnvironment;
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
private IFileConfigurationRepository _repo;
private string _environmentSpecificPath;
private string _ocelotJsonPath;
@ -33,7 +33,7 @@ namespace Ocelot.UnitTests.Configuration
{
_semaphore = new SemaphoreSlim(1, 1);
_semaphore.Wait();
_hostingEnvironment = new Mock<IHostingEnvironment>();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
}

View File

@ -1,6 +1,7 @@
namespace Ocelot.UnitTests.Consul
{
using global::Consul;
using Microsoft.Extensions.Options;
using Moq;
using Newtonsoft.Json;
using Ocelot.Cache;
@ -23,8 +24,8 @@
public class ConsulFileConfigurationRepositoryTests
{
private ConsulFileConfigurationRepository _repo;
private Mock<IOptions<FileConfiguration>> _options;
private Mock<IOcelotCache<FileConfiguration>> _cache;
private Mock<IInternalConfigurationRepository> _internalRepo;
private Mock<IConsulClientFactory> _factory;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IConsulClient> _client;
@ -36,9 +37,9 @@
public ConsulFileConfigurationRepositoryTests()
{
_cache = new Mock<IOcelotCache<FileConfiguration>>();
_internalRepo = new Mock<IInternalConfigurationRepository>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_options = new Mock<IOptions<FileConfiguration>>();
_factory = new Mock<IConsulClientFactory>();
_client = new Mock<IConsulClient>();
_kvEndpoint = new Mock<IKVEndpoint>();
@ -51,11 +52,9 @@
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
.Returns(_client.Object);
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "", It.IsAny<LoadBalancerOptions>(), It.IsAny<string>(), It.IsAny<QoSOptions>(), It.IsAny<HttpHandlerOptions>())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
_options
.SetupGet(x => x.Value)
.Returns(() => _fileConfiguration);
}
[Fact]
@ -85,7 +84,10 @@
[Fact]
public void should_get_null_config()
{
this.Given(_ => GivenFetchFromConsulReturnsNull())
var config = FakeFileConfiguration();
this.Given(_ => GivenIHaveAConfiguration(config))
.Given(_ => GivenFetchFromConsulReturnsNull())
.When(_ => WhenIGetTheConfiguration())
.Then(_ => ThenTheConfigurationIsNull())
.BDDfy();
@ -136,14 +138,8 @@
private void GivenTheConfigKeyComesFromFileConfig(string key)
{
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "",
new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "",
new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(),
new HttpHandlerOptionsBuilder().Build())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
_fileConfiguration.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = key;
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
}
private void ThenTheConfigurationIsNull()
@ -221,6 +217,8 @@
private void GivenIHaveAConfiguration(FileConfiguration config)
{
_fileConfiguration = config;
_repo = new ConsulFileConfigurationRepository(_options.Object, _cache.Object, _factory.Object, _loggerFactory.Object);
}
private FileConfiguration FakeFileConfiguration()

View File

@ -1,14 +1,15 @@
namespace Ocelot.UnitTests.Consul
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DependencyInjection;
using Provider.Consul;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -24,10 +25,21 @@
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_consul()
{

View File

@ -15,7 +15,6 @@
public class PollingConsulServiceDiscoveryProviderTests
{
private readonly int _delay;
private PollConsul _provider;
private readonly List<Service> _services;
private readonly Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IOcelotLogger> _logger;
@ -56,27 +55,28 @@
private void WhenIGetTheServices(int expected)
{
_provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object);
var result = Wait.WaitFor(3000).Until(() =>
using (var provider = new PollConsul(_delay, _factory.Object, _consulServiceDiscoveryProvider.Object))
{
try
var result = Wait.WaitFor(3000).Until(() =>
{
_result = _provider.Get().GetAwaiter().GetResult();
if (_result.Count == expected)
try
{
return true;
_result = provider.Get().GetAwaiter().GetResult();
if (_result.Count == expected)
{
return true;
}
return false;
}
catch (Exception)
{
return false;
}
});
return false;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
result.ShouldBeTrue();
}
}
}
}

View File

@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.Consul
using Ocelot.Configuration.Builder;
namespace Ocelot.UnitTests.Consul
{
using Microsoft.Extensions.DependencyInjection;
using Moq;
@ -29,7 +31,11 @@
[Fact]
public void should_return_ConsulServiceDiscoveryProvider()
{
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), "");
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("")
.Build();
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("", "", 1, "", "", 1), reRoute);
provider.ShouldBeOfType<Consul>();
}
@ -37,8 +43,15 @@
public void should_return_PollingConsulServiceDiscoveryProvider()
{
var stopsPollerFromPolling = 10000;
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), "");
provider.ShouldBeOfType<PollConsul>();
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("")
.Build();
var provider = ConsulProviderFactory.Get(_provider, new ServiceProviderConfiguration("pollconsul", "", 1, "", "", stopsPollerFromPolling), reRoute);
var pollProvider = provider as PollConsul;
pollProvider.ShouldNotBeNull();
pollProvider.Dispose();
}
}
}

View File

@ -22,11 +22,11 @@
private FileConfiguration _reRouteB;
private FileConfiguration _aggregate;
private FileConfiguration _envSpecific;
private Mock<IHostingEnvironment> _hostingEnvironment;
private Mock<IWebHostEnvironment> _hostingEnvironment;
public ConfigurationBuilderExtensionsTests()
{
_hostingEnvironment = new Mock<IHostingEnvironment>();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
// Clean up config files before each test
var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");

View File

@ -1,11 +1,12 @@
namespace Ocelot.UnitTests.DependencyInjection
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration.Setter;
using Ocelot.DependencyInjection;
using Ocelot.Infrastructure;
using Ocelot.Middleware.Multiplexer;
using Ocelot.Requester;
using Ocelot.UnitTests.Requester;
@ -14,6 +15,7 @@ namespace Ocelot.UnitTests.DependencyInjection
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests;
@ -31,11 +33,21 @@ namespace Ocelot.UnitTests.DependencyInjection
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
_maxRetries = 100;
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_add_specific_delegating_handlers_transient()
{
@ -47,6 +59,17 @@ namespace Ocelot.UnitTests.DependencyInjection
.BDDfy();
}
[Fact]
public void should_add_type_specific_delegating_handlers_transient()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandler)))
.And(x => AddTypeSpecificTransientDelegatingHandler(typeof(FakeDelegatingHandlerTwo)))
.Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.And(x => ThenTheSpecificHandlersAreTransient())
.BDDfy();
}
[Fact]
public void should_add_global_delegating_handlers_transient()
{
@ -58,6 +81,17 @@ namespace Ocelot.UnitTests.DependencyInjection
.BDDfy();
}
[Fact]
public void should_add_global_type_delegating_handlers_transient()
{
this.Given(x => WhenISetUpOcelotServices())
.When(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandler>())
.And(x => AddTransientGlobalDelegatingHandler<FakeDelegatingHandlerTwo>())
.Then(x => ThenTheProviderIsRegisteredAndReturnsHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.And(x => ThenTheGlobalHandlersAreTransient())
.BDDfy();
}
[Fact]
public void should_set_up_services()
{
@ -114,6 +148,16 @@ namespace Ocelot.UnitTests.DependencyInjection
.BDDfy();
}
[Fact]
public void should_replace_iplaceholder()
{
this.Given(x => x.WhenISetUpOcelotServices())
.When(x => AddConfigPlaceholders())
.Then(x => ThenAnExceptionIsntThrown())
.And(x => ThenTheIPlaceholderInstanceIsReplaced())
.BDDfy();
}
private void AddSingletonDefinedAggregator<T>()
where T : class, IDefinedAggregator
{
@ -126,6 +170,11 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.AddTransientDefinedAggregator<T>();
}
private void AddConfigPlaceholders()
{
_ocelotBuilder.AddConfigPlaceholders();
}
private void ThenTheSpecificHandlersAreTransient()
{
var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
@ -156,6 +205,16 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.AddDelegatingHandler<T>();
}
private void AddTypeTransientGlobalDelegatingHandler(Type type)
{
_ocelotBuilder.AddDelegatingHandler(type, true);
}
private void AddTypeSpecificTransientDelegatingHandler(Type type)
{
_ocelotBuilder.AddDelegatingHandler(type);
}
private void ThenTheProviderIsRegisteredAndReturnsHandlers<TOne, TWo>()
{
_serviceProvider = _services.BuildServiceProvider();
@ -203,6 +262,13 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
}
private void ThenTheIPlaceholderInstanceIsReplaced()
{
_serviceProvider = _services.BuildServiceProvider();
var placeholders = _serviceProvider.GetService<IPlaceholders>();
placeholders.ShouldBeOfType<ConfigAwarePlaceholders>();
}
private void WhenISetUpOcelotServices()
{
try

View File

@ -0,0 +1,196 @@
using Moq;
using Ocelot.Configuration;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Errors;
using Ocelot.Infrastructure;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.PathManipulation;
using Ocelot.Responses;
using Ocelot.UnitTests.Responder;
using Ocelot.Values;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamPathManipulation
{
public class ChangeDownstreamPathTemplateTests
{
private readonly ChangeDownstreamPathTemplate _changeDownstreamPath;
private DownstreamPathTemplate _downstreamPathTemplate;
private readonly Mock<IClaimsParser> _parser;
private List<ClaimToThing> _configuration;
private List<Claim> _claims;
private Response _result;
private Response<string> _claimValue;
private List<PlaceholderNameAndValue> _placeholderValues;
public ChangeDownstreamPathTemplateTests()
{
_parser = new Mock<IClaimsParser>();
_changeDownstreamPath = new ChangeDownstreamPathTemplate(_parser.Object);
}
[Fact]
public void should_change_downstream_path_request()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>();
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsSuccess())
.And(x => x.ThenClaimDataIsContainedInPlaceHolder("{path-key}", "value"))
.BDDfy();
}
[Fact]
public void should_replace_existing_placeholder_value()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue ("{path-key}", "old_value"),
};
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsSuccess())
.And(x => x.ThenClaimDataIsContainedInPlaceHolder("{path-key}", "value"))
.BDDfy();
}
[Fact]
public void should_return_error_when_no_placeholder_in_downstream_path()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>();
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsCouldNotFindPlaceholderError())
.BDDfy();
}
[Fact]
private void should_return_error_when_claim_parser_returns_error()
{
var claims = new List<Claim>
{
new Claim("test", "data"),
};
var placeHolderValues = new List<PlaceholderNameAndValue>();
this.Given(
x => x.GivenAClaimToThing(new List<ClaimToThing>
{
new ClaimToThing("path-key", "", "", 0),
}))
.And(x => x.GivenClaims(claims))
.And(x => x.GivenDownstreamPathTemplate("/api/test/{path-key}"))
.And(x => x.GivenPlaceholderNameAndValues(placeHolderValues))
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
{
new AnyError(),
})))
.When(x => x.WhenIChangeDownstreamPath())
.Then(x => x.ThenTheResultIsError())
.BDDfy();
}
private void GivenAClaimToThing(List<ClaimToThing> configuration)
{
_configuration = configuration;
}
private void GivenClaims(List<Claim> claims)
{
_claims = claims;
}
private void GivenDownstreamPathTemplate(string template)
{
_downstreamPathTemplate = new DownstreamPathTemplate(template);
}
private void GivenPlaceholderNameAndValues(List<PlaceholderNameAndValue> placeholders)
{
_placeholderValues = placeholders;
}
private void GivenTheClaimParserReturns(Response<string> claimValue)
{
_claimValue = claimValue;
_parser
.Setup(
x =>
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<int>()))
.Returns(_claimValue);
}
private void WhenIChangeDownstreamPath()
{
_result = _changeDownstreamPath.ChangeDownstreamPath(_configuration, _claims,
_downstreamPathTemplate, _placeholderValues);
}
private void ThenTheResultIsSuccess()
{
_result.IsError.ShouldBe(false);
}
private void ThenTheResultIsCouldNotFindPlaceholderError()
{
_result.IsError.ShouldBe(true);
_result.Errors.Count.ShouldBe(1);
_result.Errors.First().ShouldBeOfType<CouldNotFindPlaceholderError>();
}
private void ThenTheResultIsError()
{
_result.IsError.ShouldBe(true);
}
private void ThenClaimDataIsContainedInPlaceHolder(string name, string value)
{
var placeHolder = _placeholderValues.FirstOrDefault(ph => ph.Name == name && ph.Value == value);
placeHolder.ShouldNotBeNull();
_placeholderValues.Count.ShouldBe(1);
}
}
}

View File

@ -0,0 +1,101 @@
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.PathManipulation;
using Ocelot.PathManipulation.Middleware;
using Ocelot.Request.Middleware;
using Ocelot.Responses;
using Ocelot.Values;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamPathManipulation
{
public class ClaimsToDownstreamPathMiddlewareTests
{
private readonly Mock<IChangeDownstreamPathTemplate> _changePath;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private ClaimsToDownstreamPathMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
public ClaimsToDownstreamPathMiddlewareTests()
{
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<ClaimsToDownstreamPathMiddleware>()).Returns(_logger.Object);
_next = context => Task.CompletedTask;
_changePath = new Mock<IChangeDownstreamPathTemplate>();
_downstreamContext.DownstreamRequest = new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com"));
_middleware = new ClaimsToDownstreamPathMiddleware(_next, _loggerFactory.Object, _changePath.Object);
}
[Fact]
public void should_call_add_queries_correctly()
{
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithClaimsToDownstreamPath(new List<ClaimToThing>
{
new ClaimToThing("UserId", "Subject", "", 0),
})
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => x.GivenTheChangeDownstreamPathReturnsOk())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenChangeDownstreamPathIsCalledCorrectly())
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenTheChangeDownstreamPathReturnsOk()
{
_changePath
.Setup(x => x.ChangeDownstreamPath(
It.IsAny<List<ClaimToThing>>(),
It.IsAny<IEnumerable<Claim>>(),
It.IsAny<DownstreamPathTemplate>(),
It.IsAny<List<PlaceholderNameAndValue>>()))
.Returns(new OkResponse());
}
private void ThenChangeDownstreamPathIsCalledCorrectly()
{
_changePath
.Verify(x => x.ChangeDownstreamPath(
It.IsAny<List<ClaimToThing>>(),
It.IsAny<IEnumerable<Claim>>(),
_downstreamContext.DownstreamReRoute.DownstreamPathTemplate,
_downstreamContext.TemplatePlaceholderNameAndValues), Times.Once);
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
{
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
}
}

View File

@ -1,6 +1,6 @@
namespace Ocelot.UnitTests.Eureka
{
using Microsoft.AspNetCore.Builder.Internal;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;

View File

@ -27,7 +27,10 @@
var services = new ServiceCollection();
services.AddSingleton<IDiscoveryClient>(client.Object);
var sp = services.BuildServiceProvider();
var provider = EurekaProviderFactory.Get(sp, config, null);
var reRoute = new DownstreamReRouteBuilder()
.WithServiceName("")
.Build();
var provider = EurekaProviderFactory.Get(sp, config, reRoute);
provider.ShouldBeOfType<Eureka>();
}
}

View File

@ -0,0 +1,78 @@
namespace Ocelot.UnitTests.Infrastructure
{
using System;
using Moq;
using Ocelot.Infrastructure;
using Responses;
using Shouldly;
using Microsoft.Extensions.Configuration;
using Xunit;
public class ConfigAwarePlaceholdersTests
{
private readonly IPlaceholders _placeholders;
private readonly Mock<IPlaceholders> _basePlaceholders;
public ConfigAwarePlaceholdersTests()
{
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("appsettings.json");
var configuration = configurationBuilder.Build();
_basePlaceholders = new Mock<IPlaceholders>();
_placeholders = new ConfigAwarePlaceholders(configuration, _basePlaceholders.Object);
}
[Fact]
public void should_return_value_from_underlying_placeholders()
{
var baseUrl = "http://www.bbc.co.uk";
const string key = "{BaseUrl}";
_basePlaceholders.Setup(x => x.Get(key)).Returns(new OkResponse<string>(baseUrl));
var result = _placeholders.Get(key);
result.Data.ShouldBe(baseUrl);
}
[Fact]
public void should_return_value_from_config_with_same_name_as_placeholder_if_underlying_placeholder_not_found()
{
const string expected = "http://foo-bar.co.uk";
var baseUrl = "http://www.bbc.co.uk";
const string key = "{BaseUrl}";
_basePlaceholders.Setup(x => x.Get(key)).Returns(new ErrorResponse<string>(new FakeError()));
var result = _placeholders.Get(key);
result.Data.ShouldBe(expected);
}
[Theory]
[InlineData("{TestConfig}")]
[InlineData("{TestConfigNested:Child}")]
public void should_return_value_from_config(string key)
{
const string expected = "foo";
_basePlaceholders.Setup(x => x.Get(key)).Returns(new ErrorResponse<string>(new FakeError()));
var result = _placeholders.Get(key);
result.Data.ShouldBe(expected);
}
[Fact]
public void should_call_underyling_when_added()
{
const string key = "{Test}";
Func<Response<string>> func = () => new OkResponse<string>("test)");
_placeholders.Add(key, func);
_basePlaceholders.Verify(p => p.Add(key, func), Times.Once);
}
[Fact]
public void should_call_underyling_when_removed()
{
const string key = "{Test}";
_placeholders.Remove(key);
_basePlaceholders.Verify(p => p.Remove(key), Times.Once);
}
}
}

View File

@ -1,12 +1,13 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DependencyInjection;
using Ocelot.Provider.Kubernetes;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -24,10 +25,20 @@ namespace Ocelot.UnitTests.Kubernetes
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_kubernetes()
{

View File

@ -10,8 +10,8 @@ namespace Ocelot.UnitTests.Logging
public class AspDotNetLoggerTests
{
private readonly Mock<ILogger<object>> _coreLogger;
private readonly Mock<IRequestScopedDataRepository> _repo;
private readonly AspDotNetLogger _logger;
private Mock<IRequestScopedDataRepository> _repo;
private readonly string _b;
private readonly string _a;
private readonly Exception _ex;
@ -55,7 +55,7 @@ namespace Ocelot.UnitTests.Logging
{
_logger.LogError($"a message from {_a} to {_b}", _ex);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Error);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura", LogLevel.Error, _ex);
}
[Fact]
@ -63,18 +63,18 @@ namespace Ocelot.UnitTests.Logging
{
_logger.LogCritical($"a message from {_a} to {_b}", _ex);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Critical);
ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura", LogLevel.Critical, _ex);
}
private void ThenLevelIsLogged(string expected, LogLevel expectedLogLevel)
private void ThenLevelIsLogged(string expected, LogLevel expectedLogLevel, Exception ex = null)
{
_coreLogger.Verify(
x => x.Log(
expectedLogLevel,
It.IsAny<EventId>(),
It.Is<object>(o => o.ToString() == expected),
It.IsAny<Exception>(),
It.IsAny<Func<object, Exception, string>>()), Times.Once);
default(EventId),
expected,
ex,
It.IsAny<Func<string, Exception, string>>()), Times.Once);
}
}
}

View File

@ -4,16 +4,17 @@ using System.Threading.Tasks;
namespace Ocelot.UnitTests.Middleware
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.DependencyInjection;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.Middleware.Pipeline;
using Shouldly;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -28,11 +29,22 @@ namespace Ocelot.UnitTests.Middleware
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton<IConfiguration>(_configRoot);
_services.AddOcelot();
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotPiplineBuilderTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_build_generic()
{

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Ocelot.UnitTests</AssemblyName>
<PackageId>Ocelot.UnitTests</PackageId>
<OutputType>Exe</OutputType>
@ -46,13 +46,13 @@
<None Update="idsrv3test.pfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
@ -60,30 +60,38 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="Moq" Version="4.10.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
<PackageReference Include="Moq" Version="4.13.0" />
<PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4" Version="2.4.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4" Version="3.0.1" />
<PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
<PackageReference Include="Consul" Version="0.7.2.6" />
<PackageReference Include="CacheManager.Core" Version="1.2.0" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.2.0" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.2.0" />
<PackageReference Include="Polly" Version="7.1.0" />
<PackageReference Include="CacheManager.Core" Version="2.0.0-beta-1629" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="2.0.0-beta-1629" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
<PackageReference Include="Polly" Version="7.1.1" />
<PackageReference Include="Rafty" Version="0.4.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="WebSockets\" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" />
<PackageReference Include="coverlet.collector" Version="1.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -1,15 +1,16 @@
namespace Ocelot.UnitTests.Rafty
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Administration;
using Ocelot.DependencyInjection;
using Provider.Rafty;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Reflection;
using TestStack.BDDfy;
using Xunit;
@ -25,10 +26,20 @@
{
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
_services = new ServiceCollection();
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
_services.AddSingleton<IWebHostEnvironment>(GetHostingEnvironment());
_services.AddSingleton(_configRoot);
}
private IWebHostEnvironment GetHostingEnvironment()
{
var environment = new Mock<IWebHostEnvironment>();
environment
.Setup(e => e.ApplicationName)
.Returns(typeof(OcelotAdministrationBuilderExtensionsTests).GetTypeInfo().Assembly.GetName().Name);
return environment.Object;
}
[Fact]
public void should_set_up_rafty()
{

View File

@ -69,7 +69,7 @@ namespace Ocelot.UnitTests.RateLimit
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
.Then(x => x.ThenresponseStatusCodeIs200())
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
.When(x => x.WhenICallTheMiddlewareMultipleTime(3))
.Then(x => x.ThenresponseStatusCodeIs429())
.BDDfy();
}
@ -145,8 +145,9 @@ namespace Ocelot.UnitTests.RateLimit
internal class FakeStream : Stream
{
public override void Flush()
{
throw new System.NotImplementedException();
{
//do nothing
//throw new System.NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)

View File

@ -1,7 +1,6 @@
namespace Ocelot.UnitTests.Request.Mapper
{
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.Extensions.Primitives;
using Ocelot.Request.Mapper;
using Ocelot.Responses;
@ -19,6 +18,7 @@
public class RequestMapperTests
{
private readonly HttpContext _httpContext;
private readonly HttpRequest _inputRequest;
private readonly RequestMapper _requestMapper;
@ -29,8 +29,8 @@
public RequestMapperTests()
{
_inputRequest = new DefaultHttpRequest(new DefaultHttpContext());
_httpContext = new DefaultHttpContext();
_inputRequest = _httpContext.Request;
_requestMapper = new RequestMapper();
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat code coverage">
<Configuration>
<Format>opencover</Format>
<SingleHit>false</SingleHit>
<UseSourceLink>true</UseSourceLink>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
<!-- This is a workaround for an issue with Coverlet.Collector > 1.0.0 (see https://github.com/microsoft/vstest/issues/2205)-->
<InProcDataCollectionRunSettings>
<InProcDataCollectors>
<InProcDataCollector assemblyQualifiedName="Coverlet.Collector.DataCollection.CoverletInProcDataCollector, coverlet.collector, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null"
friendlyName="XPlat Code Coverage"
enabled="True"
codebase="coverlet.collector.dll" />
</InProcDataCollectors>
</InProcDataCollectionRunSettings>
</RunSettings>

View File

@ -20,5 +20,10 @@
"port": 5000,
"hostName": "localhost"
}
},
"BaseUrl": "http://foo-bar.co.uk",
"TestConfig": "foo",
"TestConfigNested":{
"Child": "foo"
}
}