Put hostname address registration into separate test

This commit is contained in:
Nate McMaster 2017-04-24 14:37:41 -07:00 committed by Nate McMaster
parent c22f8f5c59
commit 089ff49643
4 changed files with 94 additions and 48 deletions

View File

@ -23,13 +23,32 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Xunit; using Xunit;
using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{ {
public class AddressRegistrationTests public class AddressRegistrationTests
{ {
[ConditionalTheory, MemberData(nameof(AddressRegistrationDataIPv4))] private readonly ILoggerFactory _logger;
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Causing test failures")]
public AddressRegistrationTests(ITestOutputHelper output) => _logger = new LoggerFactory().AddXunit(output);
[ConditionalFact]
[DnsHostNameIsResolvable]
public async Task RegisterAddresses_HostName_Success()
{
var hostName = Dns.GetHostName();
string FixUrl(string url)
{
return url
.Replace("0.0.0.0", hostName)
.Replace("[::]", hostName);
}
await RegisterAddresses_Success($"http://{hostName}:0", a => a.Addresses.Select(FixUrl).ToArray());
}
[Theory, MemberData(nameof(AddressRegistrationDataIPv4))]
public async Task RegisterAddresses_IPv4_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls) public async Task RegisterAddresses_IPv4_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls)
{ {
await RegisterAddresses_Success(addressInput, testUrls); await RegisterAddresses_Success(addressInput, testUrls);
@ -101,6 +120,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{ {
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseKestrel() .UseKestrel()
.UseLoggerFactory(_logger)
.UseUrls(addressInput) .UseUrls(addressInput)
.Configure(ConfigureEchoAddress); .Configure(ConfigureEchoAddress);
@ -122,6 +142,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
private async Task RegisterIPEndPoint_Success(IPEndPoint endPoint, Func<IPEndPoint, string> testUrl) private async Task RegisterIPEndPoint_Success(IPEndPoint endPoint, Func<IPEndPoint, string> testUrl)
{ {
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseLoggerFactory(_logger)
.UseKestrel(options => .UseKestrel(options =>
{ {
options.Listen(endPoint, listenOptions => options.Listen(endPoint, listenOptions =>
@ -170,9 +191,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var testLogger = new TestApplicationErrorLogger(); var testLogger = new TestApplicationErrorLogger();
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseKestrel() .UseLoggerFactory(_logger)
.UseLoggerFactory(_ => new KestrelTestLoggerFactory(testLogger)) .UseKestrel()
.Configure(ConfigureEchoAddress); .UseLoggerFactory(_ => new KestrelTestLoggerFactory(testLogger))
.Configure(ConfigureEchoAddress);
using (var host = hostBuilder.Build()) using (var host = hostBuilder.Build())
{ {
@ -199,6 +221,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
socket.Bind(new IPEndPoint(IPAddress.Loopback, port)); socket.Bind(new IPEndPoint(IPAddress.Loopback, port));
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseLoggerFactory(_logger)
.UseKestrel() .UseKestrel()
.UseUrls($"http://127.0.0.1:{port}") .UseUrls($"http://127.0.0.1:{port}")
.Configure(ConfigureEchoAddress); .Configure(ConfigureEchoAddress);
@ -221,6 +244,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, port)); socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, port));
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseLoggerFactory(_logger)
.UseKestrel() .UseKestrel()
.UseUrls($"http://[::1]:{port}") .UseUrls($"http://[::1]:{port}")
.Configure(ConfigureEchoAddress); .Configure(ConfigureEchoAddress);
@ -271,10 +295,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var endPointAddress = $"http://localhost:{endPointPort}"; var endPointAddress = $"http://localhost:{endPointPort}";
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseKestrel(options => options.Listen(IPAddress.Loopback, endPointPort)) .UseLoggerFactory(_logger)
.UseUrls($"http://localhost:{useUrlsPort}") .UseKestrel(options => options.Listen(IPAddress.Loopback, endPointPort))
.PreferHostingUrls(false) .UseUrls($"http://localhost:{useUrlsPort}")
.Configure(ConfigureEchoAddress); .PreferHostingUrls(false)
.Configure(ConfigureEchoAddress);
using (var host = hostBuilder.Build()) using (var host = hostBuilder.Build())
{ {
@ -292,9 +317,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var endPointAddress = $"http://localhost:{endPointPort}"; var endPointAddress = $"http://localhost:{endPointPort}";
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseKestrel(options => options.Listen(IPAddress.Loopback, endPointPort)) .UseLoggerFactory(_logger)
.PreferHostingUrls(true) .UseKestrel(options => options.Listen(IPAddress.Loopback, endPointPort))
.Configure(ConfigureEchoAddress); .PreferHostingUrls(true)
.Configure(ConfigureEchoAddress);
using (var host = hostBuilder.Build()) using (var host = hostBuilder.Build())
{ {
@ -356,6 +382,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
socket.Bind(new IPEndPoint(address, port)); socket.Bind(new IPEndPoint(address, port));
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.UseLoggerFactory(_logger)
.UseKestrel() .UseKestrel()
.UseUrls($"http://localhost:{port}") .UseUrls($"http://localhost:{port}")
.Configure(ConfigureEchoAddress); .Configure(ConfigureEchoAddress);
@ -389,15 +416,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
dataset.Add($"http://*:{port}/", _ => new[] { $"http://127.0.0.1:{port}/" }); dataset.Add($"http://*:{port}/", _ => new[] { $"http://127.0.0.1:{port}/" });
dataset.Add($"http://+:{port}/", _ => new[] { $"http://127.0.0.1:{port}/" }); dataset.Add($"http://+:{port}/", _ => new[] { $"http://127.0.0.1:{port}/" });
// Dynamic port and non-loopback addresses // Dynamic port addresses
dataset.Add("http://127.0.0.1:0/", GetTestUrls); dataset.Add("http://127.0.0.1:0/", f => f.Addresses.ToArray());
dataset.Add($"http://{Dns.GetHostName()}:0/", GetTestUrls);
var ipv4Addresses = GetIPAddresses() var ipv4Addresses = GetIPAddresses()
.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork); .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork);
foreach (var ip in ipv4Addresses) foreach (var ip in ipv4Addresses)
{ {
dataset.Add($"http://{ip}:0/", GetTestUrls); dataset.Add($"http://{ip}:0/", f => f.Addresses.ToArray());
} }
return dataset; return dataset;
@ -425,8 +451,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
dataset.Add(new IPEndPoint(IPAddress.Loopback, port), _ => $"https://127.0.0.1:{port}/"); dataset.Add(new IPEndPoint(IPAddress.Loopback, port), _ => $"https://127.0.0.1:{port}/");
// IPv6 loopback // IPv6 loopback
dataset.Add(new IPEndPoint(IPAddress.IPv6Loopback, port), _ => FixTestUrl($"http://[::1]:{port}/")); dataset.Add(new IPEndPoint(IPAddress.IPv6Loopback, port), _ => $"http://[::1]:{port}/");
dataset.Add(new IPEndPoint(IPAddress.IPv6Loopback, port), _ => FixTestUrl($"https://[::1]:{port}/")); dataset.Add(new IPEndPoint(IPAddress.IPv6Loopback, port), _ => $"https://[::1]:{port}/");
// Any // Any
dataset.Add(new IPEndPoint(IPAddress.Any, port), _ => $"http://127.0.0.1:{port}/"); dataset.Add(new IPEndPoint(IPAddress.Any, port), _ => $"http://127.0.0.1:{port}/");
@ -434,9 +460,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
// IPv6 Any // IPv6 Any
dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => $"http://127.0.0.1:{port}/"); dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => $"http://127.0.0.1:{port}/");
dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => FixTestUrl($"http://[::1]:{port}/")); dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => $"http://[::1]:{port}/");
dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => $"https://127.0.0.1:{port}/"); dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => $"https://127.0.0.1:{port}/");
dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => FixTestUrl($"https://[::1]:{port}/")); dataset.Add(new IPEndPoint(IPAddress.IPv6Any, port), _ => $"https://[::1]:{port}/");
// Dynamic port // Dynamic port
dataset.Add(new IPEndPoint(IPAddress.Loopback, 0), endPoint => $"http://127.0.0.1:{endPoint.Port}/"); dataset.Add(new IPEndPoint(IPAddress.Loopback, 0), endPoint => $"http://127.0.0.1:{endPoint.Port}/");
@ -446,8 +472,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork); .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork);
foreach (var ip in ipv4Addresses) foreach (var ip in ipv4Addresses)
{ {
dataset.Add(new IPEndPoint(ip, 0), endPoint => FixTestUrl($"http://{endPoint}/")); dataset.Add(new IPEndPoint(ip, 0), endPoint => $"http://{endPoint}/");
dataset.Add(new IPEndPoint(ip, 0), endPoint => FixTestUrl($"https://{endPoint}/")); dataset.Add(new IPEndPoint(ip, 0), endPoint => $"https://{endPoint}/");
} }
return dataset; return dataset;
@ -476,9 +502,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var dataset = new TheoryData<IPEndPoint, Func<IPEndPoint, string>>(); var dataset = new TheoryData<IPEndPoint, Func<IPEndPoint, string>>();
dataset.Add(new IPEndPoint(IPAddress.Loopback, 443), _ => "https://127.0.0.1/"); dataset.Add(new IPEndPoint(IPAddress.Loopback, 443), _ => "https://127.0.0.1/");
dataset.Add(new IPEndPoint(IPAddress.IPv6Loopback, 443), _ => FixTestUrl("https://[::1]/")); dataset.Add(new IPEndPoint(IPAddress.IPv6Loopback, 443), _ => "https://[::1]/");
dataset.Add(new IPEndPoint(IPAddress.Any, 443), _ => "https://127.0.0.1/"); dataset.Add(new IPEndPoint(IPAddress.Any, 443), _ => "https://127.0.0.1/");
dataset.Add(new IPEndPoint(IPAddress.IPv6Any, 443), _ => FixTestUrl("https://[::1]/")); dataset.Add(new IPEndPoint(IPAddress.IPv6Any, 443), _ => "https://[::1]/");
return dataset; return dataset;
} }
@ -515,9 +541,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var ipv6Addresses = GetIPAddresses() var ipv6Addresses = GetIPAddresses()
.Where(ip => ip.AddressFamily == AddressFamily.InterNetworkV6) .Where(ip => ip.AddressFamily == AddressFamily.InterNetworkV6)
.Where(ip => ip.ScopeId == 0); .Where(ip => ip.ScopeId == 0);
foreach (var ip in ipv6Addresses) foreach (var ip in ipv6Addresses)
{ {
dataset.Add($"http://[{ip}]:0/", GetTestUrls); dataset.Add($"http://[{ip}]:0/", f => f.Addresses.ToArray());
} }
return dataset; return dataset;
@ -560,12 +587,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
foreach (var ip in ipv6Addresses) foreach (var ip in ipv6Addresses)
{ {
dataset.Add($"http://[{ip}]:0/", GetTestUrls); dataset.Add($"http://[{ip}]:0/", f => f.Addresses.ToArray());
} }
// There may be no addresses with scope IDs and we need at least one data item in the // There may be no addresses with scope IDs and we need at least one data item in the
// collection, otherwise xUnit fails the test run because a theory has no data. // collection, otherwise xUnit fails the test run because a theory has no data.
dataset.Add("http://[::1]:0", GetTestUrls); dataset.Add("http://[::1]:0", f => f.Addresses.ToArray());
return dataset; return dataset;
} }
@ -579,27 +606,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
.Select(a => a.Address); .Select(a => a.Address);
} }
private static string[] GetTestUrls(IServerAddressesFeature addressesFeature)
{
return addressesFeature.Addresses
.Select(FixTestUrl)
.ToArray();
}
private static string FixTestUrl(string url)
{
var fixedUrl = url.Replace("://+", "://localhost")
.Replace("0.0.0.0", Dns.GetHostName())
.Replace("[::]", Dns.GetHostName());
if (!fixedUrl.EndsWith("/"))
{
fixedUrl = fixedUrl + "/";
}
return fixedUrl;
}
private void ConfigureEchoAddress(IApplicationBuilder app) private void ConfigureEchoAddress(IApplicationBuilder app)
{ {
app.Run(context => app.Run(context =>

View File

@ -0,0 +1,40 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Net;
using Microsoft.AspNetCore.Testing.xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class DnsHostNameIsResolvableAttribute : Attribute, ITestCondition
{
private string _hostname;
public bool IsMet
{
get
{
try
{
_hostname = Dns.GetHostName();
var addresses = Dns.GetHostAddresses(_hostname);
if (addresses.Any(i => !IPAddress.IsLoopback(i)))
{
return true;
}
}
catch
{ }
return false;
}
}
public string SkipReason => _hostname != null
? $"Could not resolve any non-loopback IP address(es) for hostname '{_hostname}'"
: "Could not determine hostname for current test machine";
}
}