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) 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 noSource = DeploymentParameters.PublishWithNoSource ? "--no-source" : string.Empty;
var command = DeploymentParameters.Command ?? "web"; var command = DeploymentParameters.Command ?? "web";

View File

@ -8,6 +8,7 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using Microsoft.AspNet.Server.Testing.Common;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Web.Administration; using Microsoft.Web.Administration;
@ -45,10 +46,12 @@ namespace Microsoft.AspNet.Server.Testing
// Drop a json file instead of setting environment variable. // Drop a json file instead of setting environment variable.
SetAspEnvironmentWithJson(); SetAspEnvironmentWithJson();
var uri = FreePortHelper.FindFreeUrl(DeploymentParameters.ApplicationBaseUriHint);
lock (_syncObject) lock (_syncObject)
{ {
// To prevent modifying the IIS setup concurrently. // To prevent modifying the IIS setup concurrently.
_application.Deploy(); _application.Deploy(uri);
} }
// Warm up time for IIS setup. // Warm up time for IIS setup.
@ -60,7 +63,7 @@ namespace Microsoft.AspNet.Server.Testing
WebRootLocation = DeploymentParameters.ApplicationPath, WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters, DeploymentParameters = DeploymentParameters,
// Accomodate the vdir name. // Accomodate the vdir name.
ApplicationBaseUri = new UriBuilder(Uri.UriSchemeHttp, "localhost", _application.Port).Uri.AbsoluteUri + "/", ApplicationBaseUri = uri.ToString(),
HostShutdownToken = _hostShutdownToken.Token HostShutdownToken = _hostShutdownToken.Token
}; };
} }
@ -104,20 +107,16 @@ namespace Microsoft.AspNet.Server.Testing
{ {
_deploymentParameters = deploymentParameters; _deploymentParameters = deploymentParameters;
_logger = logger; _logger = logger;
WebSiteName = CreateTestSiteName(); WebSiteName = CreateTestSiteName();
Port = FindFreePort();
} }
public int Port { get; }
public string WebSiteName { get; } public string WebSiteName { get; }
public string WebSiteRootFolder => $"{Environment.GetEnvironmentVariable("SystemDrive")}\\inetpub\\{WebSiteName}"; 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(); _serverManager.CommitChanges();
} }
@ -136,25 +135,15 @@ namespace Microsoft.AspNet.Server.Testing
_serverManager.CommitChanges(); _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() private string CreateTestSiteName()
{ {
if (!string.IsNullOrEmpty(_deploymentParameters.SiteName)) if (!string.IsNullOrEmpty(_deploymentParameters.SiteName))
{ {
return $"{_deploymentParameters.SiteName}{DateTime.Now.ToString("yyyyMMddHHmmss")}"; return $"{_deploymentParameters.SiteName}{DateTime.Now.ToString("yyyyMMddHHmmss")}";
} }
else 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.IO;
using System.Threading; using System.Threading;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.AspNet.Server.Testing.Common;
namespace Microsoft.AspNet.Server.Testing namespace Microsoft.AspNet.Server.Testing
{ {
@ -35,20 +36,21 @@ namespace Microsoft.AspNet.Server.Testing
DnuPublish(); DnuPublish();
} }
var uri = FreePortHelper.FindFreeUrl(DeploymentParameters.ApplicationBaseUriHint);
// Launch the host process. // Launch the host process.
var hostExitToken = StartIISExpress(); var hostExitToken = StartIISExpress(uri);
return new DeploymentResult return new DeploymentResult
{ {
WebRootLocation = DeploymentParameters.ApplicationPath, WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters, DeploymentParameters = DeploymentParameters,
// Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath. // 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 HostShutdownToken = hostExitToken
}; };
} }
private CancellationToken StartIISExpress() private CancellationToken StartIISExpress(Uri uri)
{ {
if (!string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigTemplateContent)) if (!string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigTemplateContent))
{ {
@ -58,7 +60,7 @@ namespace Microsoft.AspNet.Server.Testing
DeploymentParameters.ApplicationHostConfigTemplateContent = DeploymentParameters.ApplicationHostConfigTemplateContent =
DeploymentParameters.ApplicationHostConfigTemplateContent DeploymentParameters.ApplicationHostConfigTemplateContent
.Replace("[ApplicationPhysicalPath]", DeploymentParameters.ApplicationPath) .Replace("[ApplicationPhysicalPath]", DeploymentParameters.ApplicationPath)
.Replace("[PORT]", new Uri(DeploymentParameters.ApplicationBaseUriHint).Port.ToString()); .Replace("[PORT]", uri.Port.ToString());
DeploymentParameters.ApplicationHostConfigLocation = Path.GetTempFileName(); DeploymentParameters.ApplicationHostConfigLocation = Path.GetTempFileName();
@ -72,7 +74,7 @@ namespace Microsoft.AspNet.Server.Testing
} }
var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigLocation) ? 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); string.Format("/site:{0} /config:{1} /trace:error", DeploymentParameters.SiteName, DeploymentParameters.ApplicationHostConfigLocation);
var iisExpressPath = GetIISExpressPath(); var iisExpressPath = GetIISExpressPath();

View File

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