Use dynamic ports for all deployers

This commit is contained in:
Pavel Krymets 2016-01-13 13:48:38 -08:00
parent c747ce630d
commit 3c79b425f1
5 changed files with 61 additions and 30 deletions

View File

@ -0,0 +1,38 @@
// 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.Net;
using System.Net.Sockets;
namespace Microsoft.AspNet.Server.Testing.Common
{
public static class FreePortHelper
{
public static Uri FindFreeUrl(string urlHint)
{
var uriHint = new Uri(urlHint);
var builder = new UriBuilder(uriHint)
{
Port = FindFreePort(uriHint.Port)
};
return builder.Uri;
}
public static int FindFreePort(int initialPort)
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
try
{
socket.Bind(new IPEndPoint(IPAddress.Loopback, initialPort));
}
catch (SocketException)
{
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
}
return ((IPEndPoint)socket.LocalEndPoint).Port;
}
}
}
}

View File

@ -93,7 +93,7 @@ namespace Microsoft.AspNet.Server.Testing
protected void DnuPublish(string publishRoot = null)
{
DeploymentParameters.PublishedApplicationRootPath = Path.Combine(publishRoot ?? Path.GetTempPath(), Guid.NewGuid().ToString());
DeploymentParameters.PublishedApplicationRootPath = publishRoot ?? Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
var noSource = DeploymentParameters.PublishWithNoSource ? "--no-source" : string.Empty;
var command = DeploymentParameters.Command ?? "web";

View File

@ -8,6 +8,7 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.AspNet.Server.Testing.Common;
using Microsoft.Extensions.Logging;
using Microsoft.Web.Administration;
@ -45,10 +46,12 @@ namespace Microsoft.AspNet.Server.Testing
// Drop a json file instead of setting environment variable.
SetAspEnvironmentWithJson();
var uri = FreePortHelper.FindFreeUrl(DeploymentParameters.ApplicationBaseUriHint);
lock (_syncObject)
{
// To prevent modifying the IIS setup concurrently.
_application.Deploy();
_application.Deploy(uri);
}
// Warm up time for IIS setup.
@ -60,7 +63,7 @@ namespace Microsoft.AspNet.Server.Testing
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
// Accomodate the vdir name.
ApplicationBaseUri = new UriBuilder(Uri.UriSchemeHttp, "localhost", _application.Port).Uri.AbsoluteUri + "/",
ApplicationBaseUri = uri.ToString(),
HostShutdownToken = _hostShutdownToken.Token
};
}
@ -104,20 +107,16 @@ namespace Microsoft.AspNet.Server.Testing
{
_deploymentParameters = deploymentParameters;
_logger = logger;
WebSiteName = CreateTestSiteName();
Port = FindFreePort();
}
public int Port { get; }
public string WebSiteName { get; }
public string WebSiteRootFolder => $"{Environment.GetEnvironmentVariable("SystemDrive")}\\inetpub\\{WebSiteName}";
public void Deploy()
public void Deploy(Uri uri)
{
_serverManager.Sites.Add(WebSiteName, _deploymentParameters.ApplicationPath, Port);
_serverManager.Sites.Add(WebSiteName, _deploymentParameters.ApplicationPath, uri.Port);
_serverManager.CommitChanges();
}
@ -136,25 +135,15 @@ namespace Microsoft.AspNet.Server.Testing
_serverManager.CommitChanges();
}
}
private static int FindFreePort()
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)socket.LocalEndPoint).Port;
}
}
private string CreateTestSiteName()
{
if (!string.IsNullOrEmpty(_deploymentParameters.SiteName))
{
return $"{_deploymentParameters.SiteName}{DateTime.Now.ToString("yyyyMMddHHmmss")}";
return $"{_deploymentParameters.SiteName}{DateTime.Now.ToString("yyyyMMddHHmmss")}";
}
else
{
return $"testsite{DateTime.Now.ToString("yyyyMMddHHmmss")}";
return $"testsite{DateTime.Now.ToString("yyyyMMddHHmmss")}";
}
}
}

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.IO;
using System.Threading;
using Microsoft.Extensions.Logging;
using Microsoft.AspNet.Server.Testing.Common;
namespace Microsoft.AspNet.Server.Testing
{
@ -35,20 +36,21 @@ namespace Microsoft.AspNet.Server.Testing
DnuPublish();
}
var uri = FreePortHelper.FindFreeUrl(DeploymentParameters.ApplicationBaseUriHint);
// Launch the host process.
var hostExitToken = StartIISExpress();
var hostExitToken = StartIISExpress(uri);
return new DeploymentResult
{
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
// Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.
ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
ApplicationBaseUri = uri.ToString(),
HostShutdownToken = hostExitToken
};
}
private CancellationToken StartIISExpress()
private CancellationToken StartIISExpress(Uri uri)
{
if (!string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigTemplateContent))
{
@ -58,7 +60,7 @@ namespace Microsoft.AspNet.Server.Testing
DeploymentParameters.ApplicationHostConfigTemplateContent =
DeploymentParameters.ApplicationHostConfigTemplateContent
.Replace("[ApplicationPhysicalPath]", DeploymentParameters.ApplicationPath)
.Replace("[PORT]", new Uri(DeploymentParameters.ApplicationBaseUriHint).Port.ToString());
.Replace("[PORT]", uri.Port.ToString());
DeploymentParameters.ApplicationHostConfigLocation = Path.GetTempFileName();
@ -72,7 +74,7 @@ namespace Microsoft.AspNet.Server.Testing
}
var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigLocation) ?
string.Format("/port:{0} /path:\"{1}\" /trace:error", new Uri(DeploymentParameters.ApplicationBaseUriHint).Port, webroot) :
string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, webroot) :
string.Format("/site:{0} /config:{1} /trace:error", DeploymentParameters.SiteName, DeploymentParameters.ApplicationHostConfigLocation);
var iisExpressPath = GetIISExpressPath();

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.IO;
using System.Threading;
using Microsoft.Extensions.Logging;
using Microsoft.AspNet.Server.Testing.Common;
namespace Microsoft.AspNet.Server.Testing
{
@ -33,19 +34,20 @@ namespace Microsoft.AspNet.Server.Testing
DnuPublish();
}
var uri = FreePortHelper.FindFreeUrl(DeploymentParameters.ApplicationBaseUriHint);
// Launch the host process.
var hostExitToken = StartSelfHost();
var hostExitToken = StartSelfHost(uri);
return new DeploymentResult
{
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
ApplicationBaseUri = uri.ToString(),
HostShutdownToken = hostExitToken
};
}
private CancellationToken StartSelfHost()
private CancellationToken StartSelfHost(Uri uri)
{
var commandName = DeploymentParameters.Command;
if (string.IsNullOrEmpty(commandName))
@ -55,7 +57,7 @@ namespace Microsoft.AspNet.Server.Testing
var dnxPath = Path.Combine(TargetRuntimeBinPath, DnxCommandName);
var dnxArgs = $"-p \"{DeploymentParameters.ApplicationPath}\" {commandName} " +
$"--server.urls {DeploymentParameters.ApplicationBaseUriHint} " +
$"--server.urls {uri} " +
$"--server {(DeploymentParameters.ServerType == ServerType.WebListener ? "Microsoft.AspNet.Server.WebListener" : "Microsoft.AspNet.Server.Kestrel")}";
Logger.LogInformation($"Executing {dnxPath} {dnxArgs}");