public async Task ThrowsWhenBindingToIPv6AddressInUse()
        {
            IgnoredCriticalLogExceptions.Add(typeof(IOException));

            using (var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
                socket.Listen(0);
                var port = ((IPEndPoint)socket.LocalEndPoint).Port;

                var hostBuilder = TransportSelector.GetHostBuilder()
                                  .ConfigureWebHost(webHostBuilder =>
                {
                    webHostBuilder
                    .UseKestrel()
                    .UseUrls($"http://[::1]:{port}")
                    .Configure(ConfigureEchoAddress);
                })
                                  .ConfigureServices(AddTestLogging);

                using (var host = hostBuilder.Build())
                {
                    var exception = Assert.Throws <IOException>(() => host.Start());
                    Assert.Equal(CoreStrings.FormatEndpointAlreadyInUse($"http://[::1]:{port}"), exception.Message);

                    await host.StopAsync();
                }
            }
        }
        public async Task ThrowsForUnsupportedAddressFromHosting(string address)
        {
            IgnoredCriticalLogExceptions.Add(typeof(InvalidOperationException));

            var hostBuilder = TransportSelector.GetHostBuilder()
                              .ConfigureWebHost(webHostBuilder =>
            {
                webHostBuilder
                .UseKestrel()
                .UseUrls(address)
                .Configure(ConfigureEchoAddress);
            })
                              .ConfigureServices(AddTestLogging);

            using (var host = hostBuilder.Build())
            {
                Assert.Throws <InvalidOperationException>(() => host.Start());

                await host.StopAsync();
            }
        }
        public async Task ThrowsWhenBindingLocalhostToDynamicPort()
        {
            IgnoredCriticalLogExceptions.Add(typeof(InvalidOperationException));

            var hostBuilder = TransportSelector.GetHostBuilder()
                              .ConfigureWebHost(webHostBuilder =>
            {
                webHostBuilder
                .UseKestrel()
                .UseUrls("http://localhost:0")
                .Configure(ConfigureEchoAddress);
            })
                              .ConfigureServices(AddTestLogging);

            using (var host = hostBuilder.Build())
            {
                Assert.Throws <InvalidOperationException>(() => host.Start());

                await host.StopAsync();
            }
        }
        private void ThrowsWhenBindingLocalhostToAddressInUse(AddressFamily addressFamily)
        {
            IgnoredCriticalLogExceptions.Add(typeof(IOException));

            var addressInUseCount = 0;
            var wrongMessageCount = 0;

            var address            = addressFamily == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback;
            var otherAddressFamily = addressFamily == AddressFamily.InterNetwork ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork;

            while (addressInUseCount < 10 && wrongMessageCount < 10)
            {
                int port;

                using (var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
                {
                    // Bind first to IPv6Any to ensure both the IPv4 and IPv6 ports are available.
                    socket.Bind(new IPEndPoint(IPAddress.IPv6Any, 0));
                    socket.Listen(0);
                    port = ((IPEndPoint)socket.LocalEndPoint).Port;
                }

                using (var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp))
                {
                    try
                    {
                        socket.Bind(new IPEndPoint(address, port));
                        socket.Listen(0);
                    }
                    catch (SocketException)
                    {
                        addressInUseCount++;
                        continue;
                    }

                    var hostBuilder = TransportSelector.GetHostBuilder()
                                      .ConfigureWebHost(webHostBuilder =>
                    {
                        webHostBuilder
                        .UseKestrel()
                        .UseUrls($"http://localhost:{port}")
                        .Configure(ConfigureEchoAddress);
                    })
                                      .ConfigureServices(AddTestLogging);

                    using (var host = hostBuilder.Build())
                    {
                        var exception = Assert.Throws <IOException>(() => host.Start());

                        var thisAddressString  = $"http://{(addressFamily == AddressFamily.InterNetwork ? "127.0.0.1" : "[::1]")}:{port}";
                        var otherAddressString = $"http://{(addressFamily == AddressFamily.InterNetworkV6 ? "127.0.0.1" : "[::1]")}:{port}";

                        if (exception.Message == CoreStrings.FormatEndpointAlreadyInUse(otherAddressString))
                        {
                            // Don't fail immediately, because it's possible that something else really did bind to the
                            // same port for the other address family between the IPv6Any bind above and now.
                            wrongMessageCount++;
                            continue;
                        }

                        Assert.Equal(CoreStrings.FormatEndpointAlreadyInUse(thisAddressString), exception.Message);
                        break;
                    }
                }
            }

            if (addressInUseCount >= 10)
            {
                Assert.True(false, $"The corresponding {otherAddressFamily} address was already in use 10 times.");
            }

            if (wrongMessageCount >= 10)
            {
                Assert.True(false, $"An error for a conflict with {otherAddressFamily} was thrown 10 times.");
            }
        }