From b783d504ffe1c4df75c2f0f722fdcd9d8815d86b Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Mon, 16 Apr 2018 16:57:19 -0700 Subject: [PATCH 01/70] Update version number to 2.2.0 --- version.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.props b/version.props index 40c54ac327..b656503324 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - 2.1.0 - preview3 + 2.2.0 + preview1 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 From 0cc416f1f9b1df8a1c566a324dda928745775563 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Tue, 17 Apr 2018 14:01:33 -0700 Subject: [PATCH 02/70] Change SelfHostDeployer to use dynamic ports by default (#1383) * Should significantly reduce flaky test failures due to AddressInUse exceptions * Addresses https://github.com/aspnet/Hosting/issues/1296 --- .../Common/TestUriHelper.cs | 47 ++++++++++++++++--- .../Deployers/SelfHostDeployer.cs | 5 +- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index 9fff9f1c59..7ebcb30367 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -11,39 +11,72 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common { public static Uri BuildTestUri() { - return new UriBuilder("http", "localhost", GetNextPort()).Uri; + return BuildTestUri(null); } public static Uri BuildTestUri(string hint) + { + // If this method is called directly, there is no way to know the server type or whether status messages + // are enabled. It's safest to assume the server is WebListener (which doesn't support binding to dynamic + // port "0") and status messages are not enabled (so the assigned port cannot be scraped from console output). + return BuildTestUri(hint, serverType: ServerType.WebListener, statusMessagesEnabled: false); + } + + internal static Uri BuildTestUri(string hint, ServerType serverType, bool statusMessagesEnabled) { if (string.IsNullOrEmpty(hint)) { - return BuildTestUri(); + if (serverType == ServerType.Kestrel && statusMessagesEnabled) + { + // Most functional tests use this codepath and should directly bind to dynamic port "0" and scrape + // the assigned port from the status message, which should be 100% reliable since the port is bound + // once and never released. Binding to dynamic port "0" on "localhost" (both IPv4 and IPv6) is not + // supported, so the port is only bound on "127.0.0.1" (IPv4). If a test explicitly requires IPv6, + // it should provide a hint URL with "localhost" (IPv4 and IPv6) or "[::1]" (IPv6-only). + return new UriBuilder("http", "127.0.0.1", 0).Uri; + } + else + { + // If the server type is not Kestrel, or status messages are disabled, there is no status message + // from which to scrape the assigned port, so the less reliable GetNextPort() must be used. The + // port is bound on "localhost" (both IPv4 and IPv6), since this is supported when using a specific + // (non-zero) port. + return new UriBuilder("http", "localhost", GetNextPort()).Uri; + } } else { var uriHint = new Uri(hint); if (uriHint.Port == 0) { + // Only a few tests use this codepath, so it's fine to use the less reliable GetNextPort() for simplicity. + // The tests using this codepath will be reviewed to see if they can be changed to directly bind to dynamic + // port "0" on "127.0.0.1" and scrape the assigned port from the status message (the default codepath). return new UriBuilder(uriHint) { Port = GetNextPort() }.Uri; } else { + // If the hint contains a specific port, return it unchanged. return uriHint; } } } // Copied from https://github.com/aspnet/KestrelHttpServer/blob/47f1db20e063c2da75d9d89653fad4eafe24446c/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs#L508 + // + // This method is an attempt to safely get a free port from the OS. Most of the time, + // when binding to dynamic port "0" the OS increments the assigned port, so it's safe + // to re-use the assigned port in another process. However, occasionally the OS will reuse + // a recently assigned port instead of incrementing, which causes flaky tests with AddressInUse + // exceptions. This method should only be used when the application itself cannot use + // dynamic port "0" (e.g. IISExpress). Most functional tests using raw Kestrel + // (with status messages enabled) should directly bind to dynamic port "0" and scrape + // the assigned port from the status message, which should be 100% reliable since the port + // is bound once and never released. public static int GetNextPort() { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { - // Let the OS assign the next available port. Unless we cycle through all ports - // on a test run, the OS will always increment the port number when making these calls. - // This prevents races in parallel test runs where a test is already bound to - // a given port, and a new test is able to bind to the same port due to port - // reuse being enabled by default by the OS. socket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); return ((IPEndPoint)socket.LocalEndPoint).Port; } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index 2bf3c731f5..2fcb391f72 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -41,7 +41,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting DotnetPublish(); } - var hintUrl = TestUriHelper.BuildTestUri(DeploymentParameters.ApplicationBaseUriHint); + var hintUrl = TestUriHelper.BuildTestUri( + DeploymentParameters.ApplicationBaseUriHint, + DeploymentParameters.ServerType, + DeploymentParameters.StatusMessagesEnabled); // Launch the host process. var (actualUrl, hostExitToken) = await StartSelfHostAsync(hintUrl); From 1cdd9bab0e8ab5738a495c66b9579b736c260b1f Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 17 Apr 2018 15:31:53 -0700 Subject: [PATCH 03/70] Fixup feature branch version calculation --- version.props | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/version.props b/version.props index b656503324..177fb295e3 100644 --- a/version.props +++ b/version.props @@ -2,17 +2,19 @@ 2.2.0 preview1 + + 0.5.0 + preview3 + $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final + $(ExperimentalVersionPrefix)-$(ExperimentalVersionSuffix)-final t000 + a- $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) $(VersionSuffix)-$(BuildNumber) - - 0.5.0 - preview2 - $(ExperimentalVersionPrefix) - $(ExperimentalVersionPrefix)-$(ExperimentalVersionSuffix)-final + $(FeatureBranchVersionPrefix)$(ExperimentalVersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) $(ExperimentalVersionSuffix)-$(BuildNumber) From 970bc8a30d66dd6894f8f662e5fdab9e68d57777 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Wed, 18 Apr 2018 14:04:16 -0700 Subject: [PATCH 04/70] Add TestUrlHelper class and GetAddress() extension method (#1387) --- .../Common/IWebHostExtensions.cs | 13 +++++++++++++ .../Common/TestUriHelper.cs | 18 ++++++++---------- .../Common/TestUrlHelper.cs | 11 +++++++++++ .../Deployers/IISExpressDeployer.cs | 2 +- .../Deployers/NginxDeployer.cs | 4 ++-- .../Deployers/SelfHostDeployer.cs | 2 +- ...AspNetCore.Server.IntegrationTesting.csproj | 4 ++++ 7 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/IWebHostExtensions.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUrlHelper.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/IWebHostExtensions.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/IWebHostExtensions.cs new file mode 100644 index 0000000000..732a598ab8 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/IWebHostExtensions.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Hosting.Server.Features; +using System.Linq; + +namespace Microsoft.AspNetCore.Hosting +{ + public static class IWebHostExtensions + { + public static string GetAddress(this IWebHost host) + { + return host.ServerFeatures.Get().Addresses.First(); + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index 7ebcb30367..c1feec8c6d 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -7,22 +7,20 @@ using System.Net.Sockets; namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common { - public static class TestUriHelper + internal static class TestUriHelper { - public static Uri BuildTestUri() + internal static Uri BuildTestUri(ServerType serverType) { - return BuildTestUri(null); + return BuildTestUri(serverType, hint: null); } - public static Uri BuildTestUri(string hint) + internal static Uri BuildTestUri(ServerType serverType, string hint) { - // If this method is called directly, there is no way to know the server type or whether status messages - // are enabled. It's safest to assume the server is WebListener (which doesn't support binding to dynamic - // port "0") and status messages are not enabled (so the assigned port cannot be scraped from console output). - return BuildTestUri(hint, serverType: ServerType.WebListener, statusMessagesEnabled: false); + // Assume status messages are enabled for Kestrel and disabled for all other servers. + return BuildTestUri(serverType, hint, statusMessagesEnabled: serverType == ServerType.Kestrel); } - internal static Uri BuildTestUri(string hint, ServerType serverType, bool statusMessagesEnabled) + internal static Uri BuildTestUri(ServerType serverType, string hint, bool statusMessagesEnabled) { if (string.IsNullOrEmpty(hint)) { @@ -73,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common // (with status messages enabled) should directly bind to dynamic port "0" and scrape // the assigned port from the status message, which should be 100% reliable since the port // is bound once and never released. - public static int GetNextPort() + internal static int GetNextPort() { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUrlHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUrlHelper.cs new file mode 100644 index 0000000000..f03321eba6 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUrlHelper.cs @@ -0,0 +1,11 @@ +namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common +{ + // Public for use in other test projects + public static class TestUrlHelper + { + public static string GetTestUrl(ServerType serverType) + { + return TestUriHelper.BuildTestUri(serverType).ToString(); + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index bc7aecb700..85ca880094 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting var contentRoot = DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath; - var testUri = TestUriHelper.BuildTestUri(DeploymentParameters.ApplicationBaseUriHint); + var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint); // Launch the host process. var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs index 1bc6c4b766..7341624d41 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs @@ -30,10 +30,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { _configFile = Path.GetTempFileName(); var uri = string.IsNullOrEmpty(DeploymentParameters.ApplicationBaseUriHint) ? - TestUriHelper.BuildTestUri() : + TestUriHelper.BuildTestUri(ServerType.Nginx) : new Uri(DeploymentParameters.ApplicationBaseUriHint); - var redirectUri = TestUriHelper.BuildTestUri(); + var redirectUri = TestUriHelper.BuildTestUri(ServerType.Nginx); if (DeploymentParameters.PublishApplicationBeforeDeployment) { diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index 2fcb391f72..4204d7415a 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -42,8 +42,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } var hintUrl = TestUriHelper.BuildTestUri( - DeploymentParameters.ApplicationBaseUriHint, DeploymentParameters.ServerType, + DeploymentParameters.ApplicationBaseUriHint, DeploymentParameters.StatusMessagesEnabled); // Launch the host process. diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj index c38a2ded59..02c01e1003 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj @@ -29,4 +29,8 @@ + + + + From 55feeeab15d9c00115ba1982f7638e0752e499a1 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Wed, 18 Apr 2018 15:18:59 -0700 Subject: [PATCH 05/70] Add DeploymentParameters.Scheme property (#1388) - Allows tests to use HTTPS with dynamic port "0" --- .../Common/DeploymentParameters.cs | 5 +++++ .../Common/TestUriHelper.cs | 10 ++++++---- .../Deployers/SelfHostDeployer.cs | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index 02b9c10cfa..b22f5e54ce 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -60,6 +60,11 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting /// public string ApplicationBaseUriHint { get; set; } + /// + /// Scheme used by the deployed application if is empty. + /// + public string Scheme { get; set; } = Uri.UriSchemeHttp; + public string EnvironmentName { get; set; } public string ServerConfigTemplateContent { get; set; } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index c1feec8c6d..012105a8ff 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -17,10 +17,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common internal static Uri BuildTestUri(ServerType serverType, string hint) { // Assume status messages are enabled for Kestrel and disabled for all other servers. - return BuildTestUri(serverType, hint, statusMessagesEnabled: serverType == ServerType.Kestrel); + var statusMessagesEnabled = (serverType == ServerType.Kestrel); + + return BuildTestUri(serverType, Uri.UriSchemeHttp, hint, statusMessagesEnabled); } - internal static Uri BuildTestUri(ServerType serverType, string hint, bool statusMessagesEnabled) + internal static Uri BuildTestUri(ServerType serverType, string scheme, string hint, bool statusMessagesEnabled) { if (string.IsNullOrEmpty(hint)) { @@ -31,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common // once and never released. Binding to dynamic port "0" on "localhost" (both IPv4 and IPv6) is not // supported, so the port is only bound on "127.0.0.1" (IPv4). If a test explicitly requires IPv6, // it should provide a hint URL with "localhost" (IPv4 and IPv6) or "[::1]" (IPv6-only). - return new UriBuilder("http", "127.0.0.1", 0).Uri; + return new UriBuilder(scheme, "127.0.0.1", 0).Uri; } else { @@ -39,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common // from which to scrape the assigned port, so the less reliable GetNextPort() must be used. The // port is bound on "localhost" (both IPv4 and IPv6), since this is supported when using a specific // (non-zero) port. - return new UriBuilder("http", "localhost", GetNextPort()).Uri; + return new UriBuilder(scheme, "localhost", GetNextPort()).Uri; } } else diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index 4204d7415a..35a06c8a9f 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting var hintUrl = TestUriHelper.BuildTestUri( DeploymentParameters.ServerType, + DeploymentParameters.Scheme, DeploymentParameters.ApplicationBaseUriHint, DeploymentParameters.StatusMessagesEnabled); From d69798d2c116e54b2f4962aebd60742f1a20aa99 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Tue, 10 Apr 2018 12:46:04 -0700 Subject: [PATCH 06/70] Clean up pipes usage in TestHost --- .../ResponseStream.cs | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.AspNetCore.TestHost/ResponseStream.cs b/src/Microsoft.AspNetCore.TestHost/ResponseStream.cs index 0cd3459a80..b2ababa182 100644 --- a/src/Microsoft.AspNetCore.TestHost/ResponseStream.cs +++ b/src/Microsoft.AspNetCore.TestHost/ResponseStream.cs @@ -109,34 +109,20 @@ namespace Microsoft.AspNetCore.TestHost var registration = cancellationToken.Register(Cancel); try { - // TODO: Usability issue. dotnet/corefx#27732 Flush or zero byte write causes ReadAsync to complete without data so I have to call ReadAsync in a loop. - while (true) + var result = await _pipe.Reader.ReadAsync(cancellationToken); + + if (result.Buffer.IsEmpty && result.IsCompleted) { - var result = await _pipe.Reader.ReadAsync(cancellationToken); - - var readableBuffer = result.Buffer; - if (!readableBuffer.IsEmpty) - { - var actual = Math.Min(readableBuffer.Length, count); - readableBuffer = readableBuffer.Slice(0, actual); - readableBuffer.CopyTo(new Span(buffer, offset, count)); - _pipe.Reader.AdvanceTo(readableBuffer.End, readableBuffer.End); - return (int)actual; - } - - if (result.IsCompleted) - { - _pipe.Reader.AdvanceTo(readableBuffer.End, readableBuffer.End); // TODO: Remove after https://github.com/dotnet/corefx/pull/27596 - _pipe.Reader.Complete(); - return 0; - } - - cancellationToken.ThrowIfCancellationRequested(); - Debug.Assert(!result.IsCanceled); // It should only be canceled by cancellationToken. - - // Try again. TODO: dotnet/corefx#27732 I shouldn't need to do this, there wasn't any data. - _pipe.Reader.AdvanceTo(readableBuffer.End, readableBuffer.End); + _pipe.Reader.Complete(); + return 0; } + + var readableBuffer = result.Buffer; + var actual = Math.Min(readableBuffer.Length, count); + readableBuffer = readableBuffer.Slice(0, actual); + readableBuffer.CopyTo(new Span(buffer, offset, count)); + _pipe.Reader.AdvanceTo(readableBuffer.End, readableBuffer.End); + return (int)actual; } finally { From 8c3b83c047c4c2dea9aa9cb7e3c8bb537bc0889e Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 20 Apr 2018 10:30:39 -0700 Subject: [PATCH 07/70] Fix ClientCancellationAborts test #1379 --- .../ClientHandlerTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs b/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs index 73f1c86d29..aeed94a6a8 100644 --- a/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs +++ b/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -210,8 +211,8 @@ namespace Microsoft.AspNetCore.TestHost Task readTask = responseStream.ReadAsync(new byte[100], 0, 100); Assert.False(readTask.IsCompleted); responseStream.Dispose(); - Assert.True(readTask.Wait(TimeSpan.FromSeconds(10)), "Finished"); - Assert.Equal(0, readTask.Result); + var result = await readTask.TimeoutAfter(TimeSpan.FromSeconds(10)); + Assert.Equal(0, result); block.Set(); } @@ -235,8 +236,7 @@ namespace Microsoft.AspNetCore.TestHost Task readTask = responseStream.ReadAsync(new byte[100], 0, 100, cts.Token); Assert.False(readTask.IsCompleted, "Not Completed"); cts.Cancel(); - var ex = Assert.Throws(() => readTask.Wait(TimeSpan.FromSeconds(10))); - Assert.IsAssignableFrom(ex.GetBaseException()); + await Assert.ThrowsAsync(() => readTask.TimeoutAfter(TimeSpan.FromSeconds(10))); block.Set(); } From b16de498078188cb77dbda44cd05cb005ee252b8 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Mon, 23 Apr 2018 12:08:24 -0700 Subject: [PATCH 08/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 68 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 6650548cd6..6e404c3bc0 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,47 +3,47 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.1.0-rc1-15774 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 - 2.1.0-rc1-30613 + 2.2.0-preview1-17037 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 + 2.2.0-preview1-34029 2.0.0 - 2.1.0-rc1-26419-02 + 2.1.0-preview3-26413-05 1.0.1 15.6.1 4.7.49 2.0.1 1.4.0 3.2.0 - 4.5.0-rc1-26419-03 - 4.5.0-rc1-26419-03 - 1.6.0-rc1-26419-03 - 4.5.0-rc1-26419-03 + 4.5.0-preview3-26413-02 + 4.5.0-preview3-26413-02 + 1.6.0-preview3-26413-02 + 4.5.0-preview3-26413-02 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index ce2f277c53..790ae84e6d 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.1.0-preview3-17018 -commithash:af264ca131f212b5ba8aafbc5110fc0fc510a2be +version:2.2.0-preview1-17037 +commithash:557055a86cbdc359c97d4fb1c2d23a3dc7ae731e From 9d82942a1a4650da9682b358262de5635a537f3f Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Tue, 24 Apr 2018 11:15:00 -0700 Subject: [PATCH 09/70] Run self-host tests with no-build. #1399 --- .../Common/DeploymentParameters.cs | 7 +++++++ .../Deployers/SelfHostDeployer.cs | 4 +--- .../IStartupInjectionAssemblyName/Program.cs | 11 +++++++---- .../IStartupInjectionAssemblyName/Startup.cs | 5 ----- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index b22f5e54ce..bf4decf481 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; namespace Microsoft.AspNetCore.Server.IntegrationTesting { @@ -45,6 +46,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting ServerType = serverType; RuntimeFlavor = runtimeFlavor; EnvironmentVariables["ASPNETCORE_DETAILEDERRORS"] = "true"; + + var configAttribute = Assembly.GetCallingAssembly().GetCustomAttribute(); + if (configAttribute != null && !string.IsNullOrEmpty(configAttribute.Configuration)) + { + Configuration = configAttribute.Configuration; + } } public ServerType ServerType { get; } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index 513c68bd75..f68fb7fbd6 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -97,9 +97,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0"); executableName = DotnetCommandName; - // Set VerifyMatchingImplicitPackageVersion to disable errors when Microsoft.NETCore.App's version is overridden externally - // This verification doesn't matter if we are skipping restore during tests. - executableArgs = $"run --no-restore --framework {targetFramework} /p:VerifyMatchingImplicitPackageVersion=false {DotnetArgumentSeparator}"; + executableArgs = $"run --no-build -c {DeploymentParameters.Configuration} --framework {targetFramework} {DotnetArgumentSeparator}"; } executableArgs += $" --server.urls {hintUrl} " diff --git a/test/TestAssets/IStartupInjectionAssemblyName/Program.cs b/test/TestAssets/IStartupInjectionAssemblyName/Program.cs index 15e8f4205c..405ec1fba0 100644 --- a/test/TestAssets/IStartupInjectionAssemblyName/Program.cs +++ b/test/TestAssets/IStartupInjectionAssemblyName/Program.cs @@ -13,13 +13,16 @@ namespace IStartupInjectionAssemblyName { public static void Main(string[] args) { - var server = new TestServer(CreateWebHostBuilder(args)); - - Task.Run(async () => Console.WriteLine(await server.CreateClient().GetStringAsync(""))).GetAwaiter().GetResult(); + var webHost = CreateWebHostBuilder(args).Build(); + var applicationName = webHost.Services.GetRequiredService().ApplicationName; + Console.WriteLine(applicationName); + Console.ReadKey(); } // Do not change the signature of this method. It's used for tests. private static IWebHostBuilder CreateWebHostBuilder(string [] args) => - new WebHostBuilder().SuppressStatusMessages(true).ConfigureServices(services => services.AddSingleton()); + new WebHostBuilder() + .SuppressStatusMessages(true) + .ConfigureServices(services => services.AddSingleton()); } } diff --git a/test/TestAssets/IStartupInjectionAssemblyName/Startup.cs b/test/TestAssets/IStartupInjectionAssemblyName/Startup.cs index c34254fba8..9f4e27223c 100644 --- a/test/TestAssets/IStartupInjectionAssemblyName/Startup.cs +++ b/test/TestAssets/IStartupInjectionAssemblyName/Startup.cs @@ -11,11 +11,6 @@ namespace IStartupInjectionAssemblyName { public void Configure(IApplicationBuilder app) { - var applicationName = app.ApplicationServices.GetRequiredService().ApplicationName; - app.Run(context => - { - return context.Response.WriteAsync(applicationName); - }); } public IServiceProvider ConfigureServices(IServiceCollection services) From efcb8d4a447c1bc4f44c7e7ba91035cad7aafb5a Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 29 Apr 2018 12:15:57 -0700 Subject: [PATCH 10/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 70 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 6e404c3bc0..0dde6de284 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,47 +3,47 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17037 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 - 2.2.0-preview1-34029 + 2.2.0-preview1-17042 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 + 2.2.0-preview1-34066 2.0.0 - 2.1.0-preview3-26413-05 + 2.2.0-preview1-26424-04 1.0.1 15.6.1 4.7.49 - 2.0.1 + 2.0.3 1.4.0 3.2.0 - 4.5.0-preview3-26413-02 - 4.5.0-preview3-26413-02 - 1.6.0-preview3-26413-02 - 4.5.0-preview3-26413-02 + 4.5.0-preview3-26423-04 + 4.5.0-preview3-26423-04 + 1.6.0-preview3-26423-04 + 4.5.0-preview3-26423-04 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 790ae84e6d..5a9689541e 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17037 -commithash:557055a86cbdc359c97d4fb1c2d23a3dc7ae731e +version:2.2.0-preview1-17042 +commithash:edf0705d014293c260de763543784330514db9a3 From e9b84a298aa8db641295dc977e05430a3ded3bf8 Mon Sep 17 00:00:00 2001 From: Marcin Polewski Date: Mon, 30 Apr 2018 13:08:20 -0500 Subject: [PATCH 11/70] Sample generic host using MSMQ (#1381) --- Hosting.sln | 15 ++++ samples/SampleMsmqHost/MsmqConnection.cs | 80 ++++++++++++++++++ samples/SampleMsmqHost/MsmqOptions.cs | 15 ++++ samples/SampleMsmqHost/MsmqProcessor.cs | 37 +++++++++ samples/SampleMsmqHost/MsmqService.cs | 44 ++++++++++ samples/SampleMsmqHost/Program.cs | 86 ++++++++++++++++++++ samples/SampleMsmqHost/SampleMsmqHost.csproj | 25 ++++++ 7 files changed, 302 insertions(+) create mode 100644 samples/SampleMsmqHost/MsmqConnection.cs create mode 100644 samples/SampleMsmqHost/MsmqOptions.cs create mode 100644 samples/SampleMsmqHost/MsmqProcessor.cs create mode 100644 samples/SampleMsmqHost/MsmqService.cs create mode 100644 samples/SampleMsmqHost/Program.cs create mode 100644 samples/SampleMsmqHost/SampleMsmqHost.csproj diff --git a/Hosting.sln b/Hosting.sln index 3ec084ca0b..7c15df66f9 100644 --- a/Hosting.sln +++ b/Hosting.sln @@ -76,6 +76,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateWebHostBuilderInvalid EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildWebHostInvalidSignature", "test\TestAssets\BuildWebHostInvalidSignature\BuildWebHostInvalidSignature.csproj", "{79D0E344-71C4-4D63-9632-01CC041C8788}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleMsmqHost", "samples\SampleMsmqHost\SampleMsmqHost.csproj", "{C082BF14-2F9A-4D48-8539-AEF3A1B2043C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -342,6 +344,18 @@ Global {79D0E344-71C4-4D63-9632-01CC041C8788}.Release|Mixed Platforms.Build.0 = Release|Any CPU {79D0E344-71C4-4D63-9632-01CC041C8788}.Release|x86.ActiveCfg = Release|Any CPU {79D0E344-71C4-4D63-9632-01CC041C8788}.Release|x86.Build.0 = Release|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Debug|x86.ActiveCfg = Debug|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Debug|x86.Build.0 = Debug|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Release|Any CPU.Build.0 = Release|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Release|x86.ActiveCfg = Release|Any CPU + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -371,6 +385,7 @@ Global {F9074486-EAE4-4171-BC9E-1557C2A56DDE} = {A7270417-6BC6-4E3F-A96A-79193D16BB82} {ACB63E80-375C-4A8F-9210-8FD509148F31} = {FA7D2012-C1B4-4AF7-9ADD-381B2004EA16} {79D0E344-71C4-4D63-9632-01CC041C8788} = {FA7D2012-C1B4-4AF7-9ADD-381B2004EA16} + {C082BF14-2F9A-4D48-8539-AEF3A1B2043C} = {9C7520A0-F2EB-411C-8BB2-80B39C937217} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AABD536D-E05F-409B-A716-535E0C478076} diff --git a/samples/SampleMsmqHost/MsmqConnection.cs b/samples/SampleMsmqHost/MsmqConnection.cs new file mode 100644 index 0000000000..d959c1a272 --- /dev/null +++ b/samples/SampleMsmqHost/MsmqConnection.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Messaging; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace SampleMsmqHost +{ + public interface IMsmqConnection + { + void SendText(string text); + + Task ReceiveAsync(CancellationToken cancellationToken); + } + + public class MsmqConnection : IMsmqConnection, IDisposable + { + private readonly MessageQueue _queue; + + public MsmqOptions Options { get; } + + public ILogger Logger { get; } + + public MsmqConnection(IOptions options, ILogger logger) + { + Options = options?.Value ?? throw new ArgumentNullException(nameof(options)); + Logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + _queue = OpenQueue(); + } + + private MessageQueue OpenQueue() + { + Logger.LogInformation("Opening Queue: Path={0}; AccessMode={1};", Options.Path, Options.AccessMode); + + return new MessageQueue(Options.Path, Options.SharedModeDenyReceive, Options.EnableCache, Options.AccessMode); + } + + public void Dispose() + { + Logger.LogInformation("Closing Queue"); + + _queue?.Dispose(); + } + + public void SendText(string text) + { + // send the text message as UTF7 + using (var stream = new MemoryStream()) + using (var writer = new StreamWriter(stream, Encoding.UTF7)) + using (var message = new Message()) + { + writer.Write(text); + writer.Flush(); + + message.BodyStream = stream; + + _queue.Send(message); + } + } + + public async Task ReceiveAsync(CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + using (cancellationToken.Register(obj => ((TaskCompletionSource)obj).TrySetCanceled(), tcs)) + { + // wait for a message to arrive or cancellation + var receiveTask = Task.Factory.FromAsync(_queue.BeginReceive(), _queue.EndReceive); + if (receiveTask != await Task.WhenAny(receiveTask, tcs.Task)) + throw new OperationCanceledException(cancellationToken); + + return receiveTask.Result; + } + } + + } +} \ No newline at end of file diff --git a/samples/SampleMsmqHost/MsmqOptions.cs b/samples/SampleMsmqHost/MsmqOptions.cs new file mode 100644 index 0000000000..f34fefb986 --- /dev/null +++ b/samples/SampleMsmqHost/MsmqOptions.cs @@ -0,0 +1,15 @@ +using System.Messaging; + +namespace SampleMsmqHost +{ + public class MsmqOptions + { + public string Path { get; set; } + + public bool SharedModeDenyReceive { get; set; } = false; + + public bool EnableCache { get; set; } = false; + + public QueueAccessMode AccessMode { get; set; } = QueueAccessMode.SendAndReceive; + } +} \ No newline at end of file diff --git a/samples/SampleMsmqHost/MsmqProcessor.cs b/samples/SampleMsmqHost/MsmqProcessor.cs new file mode 100644 index 0000000000..f99c2b8757 --- /dev/null +++ b/samples/SampleMsmqHost/MsmqProcessor.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; +using System.Messaging; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace SampleMsmqHost +{ + public interface IMsmqProcessor + { + Task ProcessMessageAsync(Message message, CancellationToken cancellationToken); + } + + public class MsmqProcessor : IMsmqProcessor + { + private readonly ILogger _logger; + + public MsmqProcessor(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public async Task ProcessMessageAsync(Message message, CancellationToken cancellationToken) + { + // we assume the message contains text encoded as UTF7 + using (var reader = new StreamReader(message.BodyStream, Encoding.UTF7)) + { + var text = await reader.ReadToEndAsync(); + + _logger.LogInformation("Received Message: {0}", text); + } + } + + } +} \ No newline at end of file diff --git a/samples/SampleMsmqHost/MsmqService.cs b/samples/SampleMsmqHost/MsmqService.cs new file mode 100644 index 0000000000..6c5c86a444 --- /dev/null +++ b/samples/SampleMsmqHost/MsmqService.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace SampleMsmqHost +{ + public class MsmqService : BackgroundService + { + public ILogger Logger { get; } + + public IMsmqConnection Connection { get; } + + public IMsmqProcessor Processor { get; } + + public MsmqService(ILogger logger, IMsmqConnection connection, IMsmqProcessor processor) + { + Logger = logger ?? throw new ArgumentNullException(nameof(logger)); + Connection = connection ?? throw new ArgumentNullException(nameof(connection)); + Processor = processor ?? throw new ArgumentNullException(nameof(processor)); + } + + protected override async Task ExecuteAsync(CancellationToken cancellationToken) + { + Logger.LogInformation("Begin Receive Loop"); + try + { + while (!cancellationToken.IsCancellationRequested) + { + using (var message = await Connection.ReceiveAsync(cancellationToken)) + { + await Processor.ProcessMessageAsync(message, cancellationToken); + } + } + } + finally + { + Logger.LogInformation("End Receive Loop"); + } + } + + } +} \ No newline at end of file diff --git a/samples/SampleMsmqHost/Program.cs b/samples/SampleMsmqHost/Program.cs new file mode 100644 index 0000000000..2c6989be26 --- /dev/null +++ b/samples/SampleMsmqHost/Program.cs @@ -0,0 +1,86 @@ +using System; +using System.Messaging; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace SampleMsmqHost +{ + public static class Program + { + // Before running this program, please make sure to install MSMQ + // and create the ".\private$\SampleQueue" queue on your local machine. + + public static async Task Main(string[] args) + { + var host = new HostBuilder() + .ConfigureAppConfiguration(config => + { + config.AddEnvironmentVariables(); + config.AddJsonFile("appsettings.json", optional: true); + config.AddCommandLine(args); + }) + .ConfigureLogging(factory => + { + factory.AddConsole(); + }) + .ConfigureServices(services => + { + services.AddOptions(); + + services.Configure(options => + { + options.Path = @".\private$\SampleQueue"; + options.AccessMode = QueueAccessMode.SendAndReceive; + }); + + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + }) + .Build(); + + using (host) + { + // start the MSMQ host + await host.StartAsync(); + + // read and dispatch messages to the MSMQ queue + StartReadLoop(host); + + // wait for the MSMQ host to shutdown + await host.WaitForShutdownAsync(); + } + } + + private static void StartReadLoop(IHost host) + { + var connection = host.Services.GetRequiredService(); + var applicationLifetime = host.Services.GetRequiredService(); + + // run the read loop in a background thread so that it can be stopped with CTRL+C + Task.Run(() => ReadLoop(connection, applicationLifetime.ApplicationStopping)); + } + + private static void ReadLoop(IMsmqConnection connection, CancellationToken cancellationToken) + { + Console.WriteLine("Enter your text message and press ENTER..."); + + while (!cancellationToken.IsCancellationRequested) + { + // read a text message from the user + cancellationToken.ThrowIfCancellationRequested(); + var text = Console.ReadLine(); + + // send the text message to the queue + cancellationToken.ThrowIfCancellationRequested(); + if (!string.IsNullOrEmpty(text)) + connection.SendText(text); + } + } + + } +} \ No newline at end of file diff --git a/samples/SampleMsmqHost/SampleMsmqHost.csproj b/samples/SampleMsmqHost/SampleMsmqHost.csproj new file mode 100644 index 0000000000..108db8d554 --- /dev/null +++ b/samples/SampleMsmqHost/SampleMsmqHost.csproj @@ -0,0 +1,25 @@ + + + + Exe + + net461 + latest + + + + + + + + + + + + + + + + + + From c72df2865c784446d41b98fc5d6cb8e46c995c4d Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 1 May 2018 10:05:07 -0700 Subject: [PATCH 12/70] Check existence of ANCMV2 Path (#1397) --- .../Deployers/IISExpressDeployer.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 85ca880094..286e05859d 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -119,11 +119,25 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); } - Logger.LogDebug("Writing ANCMPath '{ancmPath}' to config", ancmFile); + Logger.LogDebug("Writing ANCMPath '{ancmFile}' to config", ancmFile); serverConfig = serverConfig.Replace("[ANCMPath]", ancmFile); } + if (serverConfig.Contains("[ANCMV2Path]")) + { + var ancmFile = Path.Combine(contentRoot, Is64BitHost ? @"x64\aspnetcorev2.dll" : @"x86\aspnetcorev2.dll"); + + if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) + { + throw new FileNotFoundException("AspNetCoreModuleV2 could not be found.", ancmFile); + } + + Logger.LogDebug("Writing ANCMV2Path '{ancmFile}' to config", ancmFile); + serverConfig = + serverConfig.Replace("[ANCMV2Path]", ancmFile); + } + Logger.LogDebug("Writing ApplicationPhysicalPath '{applicationPhysicalPath}' to config", contentRoot); Logger.LogDebug("Writing Port '{port}' to config", port); serverConfig = From 52802d1afa85da289dea047efe90291287d129dc Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 2 May 2018 09:13:32 -0700 Subject: [PATCH 13/70] Make Deployers handle ANCM V1 and V2 (#1407) --- .../Common/ANCMVersion.cs | 11 +++++++++++ .../Common/DeploymentParameters.cs | 6 ++++++ .../Deployers/IISExpressDeployer.cs | 8 ++++---- 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs new file mode 100644 index 0000000000..5345c2dd19 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs @@ -0,0 +1,11 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public enum ANCMVersion + { + AspNetCoreModule, + AspNetCoreModuleV2 + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index bf4decf481..3cd6e3067b 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -120,6 +120,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public HostingModel HostingModel { get; set; } + /// + /// When using the IISExpressDeployer, determines whether to use the older or newer version + /// of ANCM. + /// + public ANCMVersion ANCMVersion { get; set; } = ANCMVersion.AspNetCoreModule; + /// /// Environment variables to be set before starting the host. /// Not applicable for IIS Scenarios. diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 286e05859d..cc27f9d6c4 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -106,7 +106,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. - if (serverConfig.Contains("[ANCMPath]")) { // We need to pick the bitness based the OS / IIS Express, not the application. @@ -166,8 +165,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting if (DeploymentParameters.HostingModel == HostingModel.InProcess) { - ModifyWebConfigToInProcess(); + ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", value: "inprocess"); } + ModifyAspNetCoreSectionInWebConfig(key: "modules", value: DeploymentParameters.ANCMVersion.ToString()); var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ? string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : @@ -319,12 +319,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Transforms the web.config file to include the hostingModel="inprocess" element // and adds the server type = Microsoft.AspNetServer.IIS such that Kestrel isn't added again in ServerTests - private void ModifyWebConfigToInProcess() + private void ModifyAspNetCoreSectionInWebConfig(string key, string value) { var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; var config = XDocument.Load(webConfigFile); var element = config.Descendants("aspNetCore").FirstOrDefault(); - element.SetAttributeValue("hostingModel", "inprocess"); + element.SetAttributeValue(key, value); config.Save(webConfigFile); } } From 10a4b84061a35c7339830d8883a058fd083295a0 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 2 May 2018 14:58:53 -0700 Subject: [PATCH 14/70] Revert "Make Deployers handle ANCM V1 and V2 (#1407)" This reverts commit 52802d1afa85da289dea047efe90291287d129dc. --- .../Common/ANCMVersion.cs | 11 ----------- .../Common/DeploymentParameters.cs | 6 ------ .../Deployers/IISExpressDeployer.cs | 8 ++++---- 3 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs deleted file mode 100644 index 5345c2dd19..0000000000 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs +++ /dev/null @@ -1,11 +0,0 @@ -// 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. - -namespace Microsoft.AspNetCore.Server.IntegrationTesting -{ - public enum ANCMVersion - { - AspNetCoreModule, - AspNetCoreModuleV2 - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index 3cd6e3067b..bf4decf481 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -120,12 +120,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public HostingModel HostingModel { get; set; } - /// - /// When using the IISExpressDeployer, determines whether to use the older or newer version - /// of ANCM. - /// - public ANCMVersion ANCMVersion { get; set; } = ANCMVersion.AspNetCoreModule; - /// /// Environment variables to be set before starting the host. /// Not applicable for IIS Scenarios. diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index cc27f9d6c4..286e05859d 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -106,6 +106,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. + if (serverConfig.Contains("[ANCMPath]")) { // We need to pick the bitness based the OS / IIS Express, not the application. @@ -165,9 +166,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting if (DeploymentParameters.HostingModel == HostingModel.InProcess) { - ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", value: "inprocess"); + ModifyWebConfigToInProcess(); } - ModifyAspNetCoreSectionInWebConfig(key: "modules", value: DeploymentParameters.ANCMVersion.ToString()); var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ? string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : @@ -319,12 +319,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Transforms the web.config file to include the hostingModel="inprocess" element // and adds the server type = Microsoft.AspNetServer.IIS such that Kestrel isn't added again in ServerTests - private void ModifyAspNetCoreSectionInWebConfig(string key, string value) + private void ModifyWebConfigToInProcess() { var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; var config = XDocument.Load(webConfigFile); var element = config.Descendants("aspNetCore").FirstOrDefault(); - element.SetAttributeValue(key, value); + element.SetAttributeValue("hostingModel", "inprocess"); config.Save(webConfigFile); } } From fb08967c9f3687802324ea42b328cc26362aa9fc Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Thu, 3 May 2018 13:49:21 -0700 Subject: [PATCH 15/70] Make Deployers handle ANCM V1 and V2 (#1407) (#1409) --- .../Common/ANCMVersion.cs | 11 +++++++++++ .../Common/DeploymentParameters.cs | 6 ++++++ .../Deployers/IISExpressDeployer.cs | 18 ++++++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs new file mode 100644 index 0000000000..5345c2dd19 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs @@ -0,0 +1,11 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public enum ANCMVersion + { + AspNetCoreModule, + AspNetCoreModuleV2 + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index bf4decf481..3cd6e3067b 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -120,6 +120,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public HostingModel HostingModel { get; set; } + /// + /// When using the IISExpressDeployer, determines whether to use the older or newer version + /// of ANCM. + /// + public ANCMVersion ANCMVersion { get; set; } = ANCMVersion.AspNetCoreModule; + /// /// Environment variables to be set before starting the host. /// Not applicable for IIS Scenarios. diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 286e05859d..fc9d9dd506 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -106,7 +106,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. - if (serverConfig.Contains("[ANCMPath]")) { // We need to pick the bitness based the OS / IIS Express, not the application. @@ -166,8 +165,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting if (DeploymentParameters.HostingModel == HostingModel.InProcess) { - ModifyWebConfigToInProcess(); + ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", value: "inprocess"); } + + ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.ANCMVersion.ToString()); var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ? string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : @@ -319,13 +320,22 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Transforms the web.config file to include the hostingModel="inprocess" element // and adds the server type = Microsoft.AspNetServer.IIS such that Kestrel isn't added again in ServerTests - private void ModifyWebConfigToInProcess() + private void ModifyAspNetCoreSectionInWebConfig(string key, string value) { var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; var config = XDocument.Load(webConfigFile); var element = config.Descendants("aspNetCore").FirstOrDefault(); - element.SetAttributeValue("hostingModel", "inprocess"); + element.SetAttributeValue(key, value); config.Save(webConfigFile); } + + private void ModifyHandlerSectionInWebConfig(string key, string value) + { + var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; + var config = XDocument.Load(webConfigFile); + var element = config.Descendants("handlers").FirstOrDefault().Descendants("add").FirstOrDefault(); + element.SetAttributeValue(key, value); + config.Save(webConfigFile); + } } } From 19d120a2bea8138cced776a687660043755833e0 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 6 May 2018 12:15:11 -0700 Subject: [PATCH 16/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 0dde6de284..51207ba0d1 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17042 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 - 2.2.0-preview1-34066 + 2.2.0-preview1-17047 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 + 2.2.0-preview1-34135 2.0.0 2.2.0-preview1-26424-04 1.0.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 5a9689541e..18df6940ae 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17042 -commithash:edf0705d014293c260de763543784330514db9a3 +version:2.2.0-preview1-17047 +commithash:e1957b52ddc8b62bd39c5c400322fccb5364624c From 38f691c09e3aae4f34be139c39ae1fb264803fd0 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Tue, 8 May 2018 11:02:12 -0700 Subject: [PATCH 17/70] Upgrade to netcoreapp22 (#1410) --- Directory.Build.targets | 5 +- build/dependencies.props | 61 ++++++++++--------- build/repo.props | 3 +- korebuild-lock.txt | 4 +- .../GenericHostSample.csproj | 2 +- samples/GenericWebHost/GenericWebHost.csproj | 2 +- samples/SampleStartups/SampleStartups.csproj | 4 +- .../Deployers/SelfHostDeployer.cs | 2 +- test/Directory.Build.props | 4 +- ....AspNetCore.Hosting.FunctionalTests.csproj | 2 +- .../ShutdownTests.cs | 2 +- .../WebHostBuilderTests.cs | 2 +- .../ClientHandlerTests.cs | 4 +- test/TestAssets/Directory.Build.props | 6 +- .../TestStartupAssembly1.csproj | 4 +- 15 files changed, 56 insertions(+), 51 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 53b3f6e1da..78626b773e 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,7 +1,10 @@ - + $(MicrosoftNETCoreApp20PackageVersion) $(MicrosoftNETCoreApp21PackageVersion) + $(MicrosoftNETCoreApp22PackageVersion) $(NETStandardLibrary20PackageVersion) + + 99.9 diff --git a/build/dependencies.props b/build/dependencies.props index 51207ba0d1..e79ed8b193 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,39 +1,40 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17047 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 - 2.2.0-preview1-34135 + 2.2.0-preview1-17048 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 + 2.2.0-preview1-34140 2.0.0 2.2.0-preview1-26424-04 + 2.2.0-preview1-26502-01 1.0.1 15.6.1 4.7.49 diff --git a/build/repo.props b/build/repo.props index 97e8f78223..d115087735 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,4 +1,4 @@ - + @@ -14,5 +14,6 @@ + diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 18df6940ae..da5dcd1202 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17047 -commithash:e1957b52ddc8b62bd39c5c400322fccb5364624c +version:2.2.0-preview1-17048 +commithash:de14a0ee5fb48508ee8a29c14280a2928f8dabf8 diff --git a/samples/GenericHostSample/GenericHostSample.csproj b/samples/GenericHostSample/GenericHostSample.csproj index 83a4ea2fc7..122533cc8d 100644 --- a/samples/GenericHostSample/GenericHostSample.csproj +++ b/samples/GenericHostSample/GenericHostSample.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1;net461 + netcoreapp2.2;net461 GenericHostSample.ProgramHelloWorld Exe latest diff --git a/samples/GenericWebHost/GenericWebHost.csproj b/samples/GenericWebHost/GenericWebHost.csproj index 34abb4e990..3f301ed6e3 100644 --- a/samples/GenericWebHost/GenericWebHost.csproj +++ b/samples/GenericWebHost/GenericWebHost.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1;net461 + netcoreapp2.2;net461 latest true diff --git a/samples/SampleStartups/SampleStartups.csproj b/samples/SampleStartups/SampleStartups.csproj index 52a90cdc3c..2a606543c5 100644 --- a/samples/SampleStartups/SampleStartups.csproj +++ b/samples/SampleStartups/SampleStartups.csproj @@ -1,7 +1,7 @@ - + - netcoreapp2.1;net461 + netcoreapp2.2;net461 SampleStartups.StartupInjection exe diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index f68fb7fbd6..dcb34788f6 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting else { workingDirectory = DeploymentParameters.ApplicationPath; - var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0"); + var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.2"); executableName = DotnetCommandName; executableArgs = $"run --no-build -c {DeploymentParameters.Configuration} --framework {targetFramework} {DotnetArgumentSeparator}"; diff --git a/test/Directory.Build.props b/test/Directory.Build.props index ffda45d379..558c29ae38 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -2,9 +2,9 @@ - netcoreapp2.1 + netcoreapp2.2 $(DeveloperBuildTestTfms) - $(StandardTestTfms);netcoreapp2.0 + $(StandardTestTfms) $(StandardTestTfms);net461 diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj index 8abf2de680..da0734c750 100644 --- a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj +++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.0 + netcoreapp2.2 diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs index 1c229e96b8..b54b923a89 100644 --- a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs @@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests RuntimeArchitecture.x64) { EnvironmentName = "Shutdown", - TargetFramework = "netcoreapp2.0", + TargetFramework = "netcoreapp2.2", ApplicationType = ApplicationType.Portable, PublishApplicationBeforeDeployment = true, StatusMessagesEnabled = false diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs index 4a56c432be..ec5dd12651 100644 --- a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests runtimeFlavor, RuntimeArchitecture.x64) { - TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.0", + TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.2", ApplicationType = ApplicationType.Portable, StatusMessagesEnabled = false }; diff --git a/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs b/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs index aeed94a6a8..e90a79e97b 100644 --- a/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs +++ b/test/Microsoft.AspNetCore.TestHost.Tests/ClientHandlerTests.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.TestHost var handler = new ClientHandler(new PathString("/A/Path/"), new DummyApplication(context => { // TODO: Assert.True(context.RequestAborted.CanBeCanceled); -#if NETCOREAPP2_1 +#if NETCOREAPP2_2 Assert.Equal("HTTP/2.0", context.Request.Protocol); #elif NET461 || NETCOREAPP2_0 Assert.Equal("HTTP/1.1", context.Request.Protocol); @@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.TestHost var handler = new ClientHandler(new PathString("/A/Path/"), new InspectingApplication(features => { // TODO: Assert.True(context.RequestAborted.CanBeCanceled); -#if NETCOREAPP2_1 +#if NETCOREAPP2_2 Assert.Equal("HTTP/2.0", features.Get().Protocol); #elif NET461 || NETCOREAPP2_0 Assert.Equal("HTTP/1.1", features.Get().Protocol); diff --git a/test/TestAssets/Directory.Build.props b/test/TestAssets/Directory.Build.props index 754b616d8b..6b3e58155c 100644 --- a/test/TestAssets/Directory.Build.props +++ b/test/TestAssets/Directory.Build.props @@ -1,11 +1,11 @@ - + - netcoreapp2.1 + netcoreapp2.2 $(DeveloperBuildTestAssetTfms) - $(StandardTestAssetTfms);netcoreapp2.0 + $(StandardTestAssetTfms) $(StandardTestAssetTfms);net461 diff --git a/test/TestAssets/TestStartupAssembly1/TestStartupAssembly1.csproj b/test/TestAssets/TestStartupAssembly1/TestStartupAssembly1.csproj index 5cf442c4ac..fffa97ef87 100644 --- a/test/TestAssets/TestStartupAssembly1/TestStartupAssembly1.csproj +++ b/test/TestAssets/TestStartupAssembly1/TestStartupAssembly1.csproj @@ -1,7 +1,7 @@ - + - netcoreapp2.0;net461 + netcoreapp2.2;net461 From 2575ebfcfe3f7019bd157fdbab8daaa1d8c45fdb Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 13 May 2018 14:08:25 -0700 Subject: [PATCH 18/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 72 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index e79ed8b193..7dde71cb55 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,50 +1,50 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17048 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 - 2.2.0-preview1-34140 + 2.2.0-preview1-17051 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 + 2.2.0-preview1-34184 2.0.0 - 2.2.0-preview1-26424-04 - 2.2.0-preview1-26502-01 + 2.1.0-rc1 + 2.2.0-preview1-26509-06 1.0.1 15.6.1 4.7.49 2.0.3 1.4.0 3.2.0 - 4.5.0-preview3-26423-04 - 4.5.0-preview3-26423-04 - 1.6.0-preview3-26423-04 - 4.5.0-preview3-26423-04 + 4.6.0-preview1-26508-04 + 4.6.0-preview1-26508-04 + 1.7.0-preview1-26508-04 + 4.6.0-preview1-26508-04 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index da5dcd1202..56263a26fc 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17048 -commithash:de14a0ee5fb48508ee8a29c14280a2928f8dabf8 +version:2.2.0-preview1-17051 +commithash:253c3a480063bc3abaa5cde42f6e27b58457ef9b From 5227de9a313f4b118914351b66db936551a69dbc Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Tue, 15 May 2018 18:11:12 -0700 Subject: [PATCH 19/70] Always check if ANCM is in the base output folder. (#1420) --- .../Deployers/IISExpressDeployer.cs | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index fc9d9dd506..029ddfa22e 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -106,36 +106,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. - if (serverConfig.Contains("[ANCMPath]")) - { - // We need to pick the bitness based the OS / IIS Express, not the application. - // We'll eventually add support for choosing which IIS Express bitness to run: https://github.com/aspnet/Hosting/issues/880 - var ancmFile = Path.Combine(contentRoot, Is64BitHost ? @"x64\aspnetcore.dll" : @"x86\aspnetcore.dll"); - // Bin deployed by Microsoft.AspNetCore.AspNetCoreModule.nupkg + serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, contentRoot); - if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) - { - throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); - } - - Logger.LogDebug("Writing ANCMPath '{ancmFile}' to config", ancmFile); - serverConfig = - serverConfig.Replace("[ANCMPath]", ancmFile); - } - - if (serverConfig.Contains("[ANCMV2Path]")) - { - var ancmFile = Path.Combine(contentRoot, Is64BitHost ? @"x64\aspnetcorev2.dll" : @"x86\aspnetcorev2.dll"); - - if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) - { - throw new FileNotFoundException("AspNetCoreModuleV2 could not be found.", ancmFile); - } - - Logger.LogDebug("Writing ANCMV2Path '{ancmFile}' to config", ancmFile); - serverConfig = - serverConfig.Replace("[ANCMV2Path]", ancmFile); - } + serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, contentRoot); Logger.LogDebug("Writing ApplicationPhysicalPath '{applicationPhysicalPath}' to config", contentRoot); Logger.LogDebug("Writing Port '{port}' to config", port); @@ -265,6 +238,26 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } + private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string contentRoot) + { + if (serverConfig.Contains(replaceFlag)) + { + var ancmFile = Path.Combine(contentRoot, Is64BitHost ? $@"x64\{dllName}" : $@"x86\{dllName}"); + if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) + { + ancmFile = Path.Combine(contentRoot, dllName); + if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) + { + throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); + } + } + + Logger.LogDebug($"Writing '{replaceFlag}' '{ancmFile}' to config"); + return serverConfig.Replace(replaceFlag, ancmFile); + } + return serverConfig; + } + private string GetIISExpressPath() { // Get path to program files From 0b6dbab37ab102ed77615a9bd8aca7f0cdeda161 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 16 May 2018 09:26:55 -0500 Subject: [PATCH 20/70] Using block in the externally controlled example (#1422) --- samples/SampleStartups/StartupExternallyControlled.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/SampleStartups/StartupExternallyControlled.cs b/samples/SampleStartups/StartupExternallyControlled.cs index 68ec11c9b0..ba45235a6a 100644 --- a/samples/SampleStartups/StartupExternallyControlled.cs +++ b/samples/SampleStartups/StartupExternallyControlled.cs @@ -38,8 +38,10 @@ namespace SampleStartups public async Task StopAsync() { - await _host.StopAsync(TimeSpan.FromSeconds(5)); - _host.Dispose(); + using (_host) + { + await _host.StopAsync(TimeSpan.FromSeconds(5)); + } } public void AddUrl(string url) From 3b5b40884f36d29a844c2e30d2bc215719af23b8 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Tue, 8 May 2018 11:04:13 -0700 Subject: [PATCH 21/70] Refactor integration testing for test matrix generation. --- build/dependencies.props | 56 +-- .../Common/ANCMVersion.cs | 3 +- .../Common/ApplicationType.cs | 7 + .../Common/DeploymentParameters.cs | 39 +- .../Common/HostingModel.cs | 4 + .../Common/RuntimeFlavor.cs | 5 +- .../Common/ServerType.cs | 3 +- .../Common/Tfm.cs | 20 ++ .../Deployers/ApplicationDeployer.cs | 62 +++- .../Deployers/ApplicationDeployerFactory.cs | 4 +- .../Deployers/IApplicationDeployer.cs | 20 -- .../Deployers/IISExpressDeployer.cs | 20 +- .../RemoteWindowsDeployer.cs | 4 +- .../Deployers/SelfHostDeployer.cs | 14 +- .../TestMatrix.cs | 336 ++++++++++++++++++ .../TestVariant.cs | 49 +++ .../xunit/IISExpressAncmSchema.cs | 55 +++ ...SExpressSchemaMissingInProcessAttribute.cs | 16 + .../ShutdownTests.cs | 2 +- .../WebHostBuilderTests.cs | 24 +- 20 files changed, 622 insertions(+), 121 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs delete mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IApplicationDeployer.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/IISExpressAncmSchema.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipIfIISExpressSchemaMissingInProcessAttribute.cs diff --git a/build/dependencies.props b/build/dependencies.props index 7dde71cb55..c06cdb96ea 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,34 +4,34 @@ 2.2.0-preview1-17051 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 - 2.2.0-preview1-34184 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 + 2.2.0-preview1-34216 2.0.0 2.1.0-rc1 2.2.0-preview1-26509-06 diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs index 5345c2dd19..38cf93ffcd 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ANCMVersion.cs @@ -3,8 +3,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { - public enum ANCMVersion + public enum AncmVersion { + None, AspNetCoreModule, AspNetCoreModuleV2 } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ApplicationType.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ApplicationType.cs index 02d8715984..3a8afeb94d 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ApplicationType.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ApplicationType.cs @@ -5,7 +5,14 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { public enum ApplicationType { + /// + /// Does not target a specific platform. Requires the matching runtime to be installed. + /// Portable, + + /// + /// All dlls are published with the app for x-copy deploy. Net461 requires this because ASP.NET Core is not in the GAC. + /// Standalone } } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index 3cd6e3067b..538cd5ffe3 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -13,6 +13,35 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting /// public class DeploymentParameters { + public DeploymentParameters() + { + EnvironmentVariables["ASPNETCORE_DETAILEDERRORS"] = "true"; + + var configAttribute = Assembly.GetCallingAssembly().GetCustomAttribute(); + if (configAttribute != null && !string.IsNullOrEmpty(configAttribute.Configuration)) + { + Configuration = configAttribute.Configuration; + } + } + + public DeploymentParameters(TestVariant variant) + { + EnvironmentVariables["ASPNETCORE_DETAILEDERRORS"] = "true"; + + var configAttribute = Assembly.GetCallingAssembly().GetCustomAttribute(); + if (configAttribute != null && !string.IsNullOrEmpty(configAttribute.Configuration)) + { + Configuration = configAttribute.Configuration; + } + + ServerType = variant.Server; + TargetFramework = variant.Tfm; + ApplicationType = variant.ApplicationType; + RuntimeArchitecture = variant.Architecture; + HostingModel = variant.HostingModel; + AncmVersion = variant.AncmVersion; + } + /// /// Creates an instance of . /// @@ -54,11 +83,11 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } - public ServerType ServerType { get; } + public ServerType ServerType { get; set; } - public RuntimeFlavor RuntimeFlavor { get; } + public RuntimeFlavor RuntimeFlavor { get; set; } - public RuntimeArchitecture RuntimeArchitecture { get; } = RuntimeArchitecture.x64; + public RuntimeArchitecture RuntimeArchitecture { get; set; } = RuntimeArchitecture.x64; /// /// Suggested base url for the deployed application. The final deployed url could be @@ -80,7 +109,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public string SiteName { get; set; } - public string ApplicationPath { get; } + public string ApplicationPath { get; set; } /// /// Gets or sets the name of the application. This is used to execute the application when deployed. @@ -124,7 +153,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting /// When using the IISExpressDeployer, determines whether to use the older or newer version /// of ANCM. /// - public ANCMVersion ANCMVersion { get; set; } = ANCMVersion.AspNetCoreModule; + public AncmVersion AncmVersion { get; set; } = AncmVersion.AspNetCoreModule; /// /// Environment variables to be set before starting the host. diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/HostingModel.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/HostingModel.cs index 1eb1aea8c0..5eea2b8ce3 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/HostingModel.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/HostingModel.cs @@ -3,8 +3,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { + /// + /// For ANCM + /// public enum HostingModel { + None, OutOfProcess, InProcess } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/RuntimeFlavor.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/RuntimeFlavor.cs index 510c713f59..3d65f0eaca 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/RuntimeFlavor.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/RuntimeFlavor.cs @@ -5,7 +5,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { public enum RuntimeFlavor { - Clr, - CoreClr + None, + CoreClr, + Clr } } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ServerType.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ServerType.cs index 060c8ed0ca..ac84d0225f 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ServerType.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/ServerType.cs @@ -5,9 +5,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { public enum ServerType { + None, IISExpress, IIS, - WebListener, + HttpSys, Kestrel, Nginx } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs new file mode 100644 index 0000000000..56715d3c08 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/Tfm.cs @@ -0,0 +1,20 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public static class Tfm + { + public const string Net461 = "net461"; + public const string NetCoreApp20 = "netcoreapp2.0"; + public const string NetCoreApp21 = "netcoreapp2.1"; + public const string NetCoreApp22 = "netcoreapp2.2"; + + public static bool Matches(string tfm1, string tfm2) + { + return string.Equals(tfm1, tfm2, StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs index 3c81f32902..f475c65d81 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting /// /// Abstract base class of all deployers with implementation of some of the common helpers. /// - public abstract class ApplicationDeployer : IApplicationDeployer + public abstract class ApplicationDeployer : IDisposable { public static readonly string DotnetCommandName = "dotnet"; @@ -31,11 +31,56 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting DeploymentParameters = deploymentParameters; LoggerFactory = loggerFactory; Logger = LoggerFactory.CreateLogger(GetType().FullName); + + ValidateParameters(); + } + + private void ValidateParameters() + { + if (DeploymentParameters.ServerType == ServerType.None) + { + throw new ArgumentException($"Invalid ServerType '{DeploymentParameters.ServerType}'."); + } + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.None && !string.IsNullOrEmpty(DeploymentParameters.TargetFramework)) + { + DeploymentParameters.RuntimeFlavor = GetRuntimeFlavor(DeploymentParameters.TargetFramework); + } + + if (DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86 && DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr) + { + throw new NotSupportedException("32 bit deployment is not yet supported for CoreCLR. Don't remove the tests, just disable them for now."); + } + + if (string.IsNullOrEmpty(DeploymentParameters.ApplicationPath)) + { + throw new ArgumentException("ApplicationPath cannot be null."); + } + + if (!Directory.Exists(DeploymentParameters.ApplicationPath)) + { + throw new DirectoryNotFoundException(string.Format("Application path {0} does not exist.", DeploymentParameters.ApplicationPath)); + } + + if (string.IsNullOrEmpty(DeploymentParameters.ApplicationName)) + { + DeploymentParameters.ApplicationName = new DirectoryInfo(DeploymentParameters.ApplicationPath).Name; + } + } + + private RuntimeFlavor GetRuntimeFlavor(string tfm) + { + if (Tfm.Matches(Tfm.Net461, tfm)) + { + return RuntimeFlavor.Clr; + } + return RuntimeFlavor.CoreClr; } protected DeploymentParameters DeploymentParameters { get; } protected ILoggerFactory LoggerFactory { get; } + protected ILogger Logger { get; } public abstract Task DeployAsync(); @@ -217,7 +262,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting private string GetRuntimeIdentifier() { - var architecture = GetArchitecture(); + var architecture = DeploymentParameters.RuntimeArchitecture; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return "win7-" + architecture; @@ -235,18 +280,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting throw new InvalidOperationException("Unrecognized operation system platform"); } } - - private string GetArchitecture() - { - switch (RuntimeInformation.OSArchitecture) - { - case Architecture.X86: - return "x86"; - case Architecture.X64: - return "x64"; - default: - throw new NotSupportedException($"Unsupported architecture: {RuntimeInformation.OSArchitecture}"); - } - } } } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs index eb66761807..76f3588dd9 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting /// /// /// - public static IApplicationDeployer Create(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) + public static ApplicationDeployer Create(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) { if (deploymentParameters == null) { @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return new IISExpressDeployer(deploymentParameters, loggerFactory); case ServerType.IIS: throw new NotSupportedException("The IIS deployer is no longer supported"); - case ServerType.WebListener: + case ServerType.HttpSys: case ServerType.Kestrel: return new SelfHostDeployer(deploymentParameters, loggerFactory); case ServerType.Nginx: diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IApplicationDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IApplicationDeployer.cs deleted file mode 100644 index 400ae978ed..0000000000 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IApplicationDeployer.cs +++ /dev/null @@ -1,20 +0,0 @@ -// 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.Threading.Tasks; - -namespace Microsoft.AspNetCore.Server.IntegrationTesting -{ - /// - /// Common operations on an application deployer. - /// - public interface IApplicationDeployer : IDisposable - { - /// - /// Deploys the application to the target with specified . - /// - /// - Task DeployAsync(); - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 029ddfa22e..8a7439809e 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -35,16 +35,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { } - public bool IsWin8OrLater - { - get - { - var win8Version = new Version(6, 2); - - return (Environment.OSVersion.Version >= win8Version); - } - } - public bool Is64BitHost { get @@ -61,13 +51,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting StartTimer(); // For now we always auto-publish. Otherwise we'll have to write our own local web.config for the HttpPlatformHandler - DeploymentParameters.PublishApplicationBeforeDeployment = true; - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - DotnetPublish(); - } + DotnetPublish(); - var contentRoot = DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath; + var contentRoot = DeploymentParameters.PublishedApplicationRootPath; var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint); @@ -141,7 +127,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", value: "inprocess"); } - ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.ANCMVersion.ToString()); + ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ? string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs index a102cd02da..dc764bf98a 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs @@ -33,10 +33,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting if (_deploymentParameters.ServerType != ServerType.IIS && _deploymentParameters.ServerType != ServerType.Kestrel - && _deploymentParameters.ServerType != ServerType.WebListener) + && _deploymentParameters.ServerType != ServerType.HttpSys) { throw new InvalidOperationException($"Server type {_deploymentParameters.ServerType} is not supported for remote deployment." + - $" Supported server types are {nameof(ServerType.Kestrel)}, {nameof(ServerType.IIS)} and {nameof(ServerType.WebListener)}"); + $" Supported server types are {nameof(ServerType.Kestrel)}, {nameof(ServerType.IIS)} and {nameof(ServerType.HttpSys)}"); } if (string.IsNullOrWhiteSpace(_deploymentParameters.ServerName)) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index dcb34788f6..e9ee52ac3d 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -76,12 +76,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ""; var executable = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, DeploymentParameters.ApplicationName + executableExtension); - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - executableName = "mono"; - executableArgs = executable; - } - else if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) { executableName = "dotnet"; executableArgs = executable; @@ -94,14 +89,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting else { workingDirectory = DeploymentParameters.ApplicationPath; - var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.2"); - + var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? Tfm.Net461 : Tfm.NetCoreApp22); executableName = DotnetCommandName; executableArgs = $"run --no-build -c {DeploymentParameters.Configuration} --framework {targetFramework} {DotnetArgumentSeparator}"; } - executableArgs += $" --server.urls {hintUrl} " - + $" --server {(DeploymentParameters.ServerType == ServerType.WebListener ? "Microsoft.AspNetCore.Server.HttpSys" : "Microsoft.AspNetCore.Server.Kestrel")}"; + executableArgs += $" --urls {hintUrl} " + + $" --server {(DeploymentParameters.ServerType == ServerType.HttpSys ? "Microsoft.AspNetCore.Server.HttpSys" : "Microsoft.AspNetCore.Server.Kestrel")}"; Logger.LogInformation($"Executing {executableName} {executableArgs}"); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs new file mode 100644 index 0000000000..857bb143d9 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs @@ -0,0 +1,336 @@ +// 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.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class TestMatrix : IEnumerable + { + public IList Servers { get; set; } = new List(); + public IList Tfms { get; set; } = new List(); + public IList ApplicationTypes { get; set; } = new List(); + public IList Architectures { get; set; } = new List(); + + // ANCM specific... + public IList HostingModels { get; set; } = new List(); + public IList AncmVersions { get; set; } = new List(); + + private IList, string>> Skips { get; } = new List, string>>(); + + public static TestMatrix ForServers(params ServerType[] types) + { + return new TestMatrix() + { + Servers = types + }; + } + + public TestMatrix WithTfms(params string[] tfms) + { + Tfms = tfms; + return this; + } + + public TestMatrix WithApplicationTypes(params ApplicationType[] types) + { + ApplicationTypes = types; + return this; + } + + public TestMatrix WithAllApplicationTypes() + { + ApplicationTypes.Add(ApplicationType.Portable); + ApplicationTypes.Add(ApplicationType.Standalone); + return this; + } + public TestMatrix WithArchitectures(params RuntimeArchitecture[] archs) + { + Architectures = archs; + return this; + } + + public TestMatrix WithAllArchitectures() + { + Architectures.Add(RuntimeArchitecture.x64); + Architectures.Add(RuntimeArchitecture.x86); + return this; + } + + public TestMatrix WithHostingModels(params HostingModel[] models) + { + HostingModels = models; + return this; + } + + public TestMatrix WithAllHostingModels() + { + HostingModels.Add(HostingModel.OutOfProcess); + HostingModels.Add(HostingModel.InProcess); + return this; + } + + public TestMatrix WithAncmVersions(params AncmVersion[] versions) + { + AncmVersions = versions; + return this; + } + + public TestMatrix WithAllAncmVersions() + { + AncmVersions.Add(AncmVersion.AspNetCoreModule); + AncmVersions.Add(AncmVersion.AspNetCoreModuleV2); + return this; + } + + /// + /// V2 + InProc + /// + /// + public TestMatrix WithAncmV2InProcess() => WithAncmVersions(AncmVersion.AspNetCoreModuleV2).WithHostingModels(HostingModel.InProcess); + + public TestMatrix Skip(string message, Func check) + { + Skips.Add(new Tuple, string>(check, message)); + return this; + } + + private IEnumerable Build() + { + if (!Servers.Any()) + { + throw new ArgumentException("No servers were specified."); + } + + // TFMs. + if (!Tfms.Any()) + { + throw new ArgumentException("No TFMs were specified."); + } + + ResolveDefaultArchitecture(); + + if (!ApplicationTypes.Any()) + { + ApplicationTypes.Add(ApplicationType.Portable); + } + + if (!AncmVersions.Any()) + { + AncmVersions.Add(AncmVersion.AspNetCoreModule); + } + + if (!HostingModels.Any()) + { + HostingModels.Add(HostingModel.OutOfProcess); + } + + var variants = new List(); + VaryByServer(variants); + + CheckForSkips(variants); + + return variants; + } + + private void ResolveDefaultArchitecture() + { + if (!Architectures.Any()) + { + switch (RuntimeInformation.OSArchitecture) + { + case Architecture.X86: + Architectures.Add(RuntimeArchitecture.x86); + break; + case Architecture.X64: + Architectures.Add(RuntimeArchitecture.x64); + break; + default: + throw new ArgumentException(RuntimeInformation.OSArchitecture.ToString()); + } + } + } + + private void VaryByServer(List variants) + { + foreach (var server in Servers) + { + var skip = SkipIfServerIsNotSupportedOnThisOS(server); + + VaryByTfm(variants, server, skip); + } + } + + private static string SkipIfServerIsNotSupportedOnThisOS(ServerType server) + { + var skip = false; + switch (server) + { + case ServerType.IIS: + case ServerType.IISExpress: + case ServerType.HttpSys: + skip = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + break; + case ServerType.Kestrel: + break; + case ServerType.Nginx: + // Technically it's possible but we don't test it. + skip = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + break; + default: + throw new ArgumentException(server.ToString()); + } + + return skip ? "This server is not supported on this operating system." : null; + } + + private void VaryByTfm(List variants, ServerType server, string skip) + { + foreach (var tfm in Tfms) + { + if (!CheckTfmIsSupportedForServer(tfm, server)) + { + // Don't generate net461 variations for nginx server. + continue; + } + + var skipTfm = skip ?? SkipIfTfmIsNotSupportedOnThisOS(tfm); + + VaryByApplicationType(variants, server, tfm, skipTfm); + } + } + + private bool CheckTfmIsSupportedForServer(string tfm, ServerType server) + { + // Not a combination we test + return !(Tfm.Matches(Tfm.Net461, tfm) && ServerType.Nginx == server); + } + + private static string SkipIfTfmIsNotSupportedOnThisOS(string tfm) + { + if (Tfm.Matches(Tfm.Net461, tfm) && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return "This TFM is not supported on this operating system."; + } + + return null; + } + + private void VaryByApplicationType(List variants, ServerType server, string tfm, string skip) + { + foreach (var t in ApplicationTypes) + { + var type = t; + if (Tfm.Matches(Tfm.Net461, tfm) && type == ApplicationType.Portable) + { + if (ApplicationTypes.Count == 1) + { + // Override the default + type = ApplicationType.Standalone; + } + else + { + continue; + } + } + + VaryByArchitecture(variants, server, tfm, skip, type); + } + } + + private void VaryByArchitecture(List variants, ServerType server, string tfm, string skip, ApplicationType type) + { + foreach (var arch in Architectures) + { + if (server == ServerType.IISExpress) + { + VaryByAncmVersion(variants, server, tfm, type, arch, skip); + } + else + { + variants.Add(new TestVariant() + { + Server = server, + Tfm = tfm, + ApplicationType = type, + Architecture = arch, + Skip = skip, + }); + } + } + } + + private void VaryByAncmVersion(IList variants, ServerType server, string tfm, ApplicationType type, RuntimeArchitecture arch, string skip) + { + foreach (var version in AncmVersions) + { + VaryByAncmHostingModel(variants, server, tfm, type, arch, skip, version); + } + } + + private void VaryByAncmHostingModel(IList variants, ServerType server, string tfm, ApplicationType type, RuntimeArchitecture arch, string skip, AncmVersion version) + { + foreach (var hostingModel in HostingModels) + { + var skipAncm = skip; + if (hostingModel == HostingModel.InProcess) + { + // Not supported + if (Tfm.Matches(Tfm.Net461, tfm) || version == AncmVersion.AspNetCoreModule) + { + continue; + } + + if (!IISExpressAncmSchema.SupportsInProcessHosting) + { + skipAncm = skipAncm ?? IISExpressAncmSchema.SkipReason; + } + } + + variants.Add(new TestVariant() + { + Server = server, + Tfm = tfm, + ApplicationType = type, + Architecture = arch, + AncmVersion = version, + HostingModel = hostingModel, + Skip = skipAncm, + }); + } + } + + private void CheckForSkips(List variants) + { + foreach (var variant in variants) + { + foreach (var skipPair in Skips) + { + if (skipPair.Item1(variant)) + { + variant.Skip = skipPair.Item2; + break; + } + } + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)this).GetEnumerator(); + } + + // This is what Xunit MemberData expects + public IEnumerator GetEnumerator() + { + foreach (var v in Build()) + { + yield return new[] { v }; + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs new file mode 100644 index 0000000000..e9b9cda607 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs @@ -0,0 +1,49 @@ +// 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 Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class TestVariant : IXunitSerializable + { + public ServerType Server { get; set; } + public string Tfm { get; set; } + public ApplicationType ApplicationType { get; set; } + public RuntimeArchitecture Architecture { get; set; } + + public string Skip { get; set; } + + // ANCM specifics... + public HostingModel HostingModel { get; set; } + public AncmVersion AncmVersion { get; set; } + + public override string ToString() + { + // For debug and test explorer view + return $"Server: {Server}, TFM: {Tfm}, Type: {ApplicationType}, Host: {HostingModel}, ANCM: {AncmVersion}, Arch: {Architecture}"; + } + + public void Serialize(IXunitSerializationInfo info) + { + info.AddValue(nameof(Skip), Skip, typeof(string)); + info.AddValue(nameof(Server), Server, typeof(ServerType)); + info.AddValue(nameof(Tfm), Tfm, typeof(string)); + info.AddValue(nameof(ApplicationType), ApplicationType, typeof(ApplicationType)); + info.AddValue(nameof(Architecture), Architecture, typeof(RuntimeArchitecture)); + info.AddValue(nameof(HostingModel), HostingModel, typeof(HostingModel)); + info.AddValue(nameof(AncmVersion), AncmVersion, typeof(AncmVersion)); + } + + public void Deserialize(IXunitSerializationInfo info) + { + Skip = info.GetValue(nameof(Skip)); + Server = info.GetValue(nameof(Server)); + Tfm = info.GetValue(nameof(Tfm)); + ApplicationType = info.GetValue(nameof(ApplicationType)); + Architecture = info.GetValue(nameof(Architecture)); + HostingModel = info.GetValue(nameof(HostingModel)); + AncmVersion = info.GetValue(nameof(AncmVersion)); + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/IISExpressAncmSchema.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/IISExpressAncmSchema.cs new file mode 100644 index 0000000000..53ea67ddd2 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/IISExpressAncmSchema.cs @@ -0,0 +1,55 @@ +// 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.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Xml.Linq; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class IISExpressAncmSchema + { + public static bool SupportsInProcessHosting { get; } + public static string SkipReason { get; } + + static IISExpressAncmSchema() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + SkipReason = "IIS Express tests can only be run on Windows"; + return; + } + + var ancmConfigPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + "IIS Express", "config", "schema", "aspnetcore_schema.xml"); + + if (!File.Exists(ancmConfigPath)) + { + SkipReason = "IIS Express is not installed."; + return; + } + + XDocument ancmConfig; + + try + { + ancmConfig = XDocument.Load(ancmConfigPath); + } + catch + { + SkipReason = "Could not read ANCM schema configuration"; + return; + } + + SupportsInProcessHosting = ancmConfig + .Root + .Descendants("attribute") + .Any(n => "hostingModel".Equals(n.Attribute("name")?.Value, StringComparison.Ordinal)); + + SkipReason = SupportsInProcessHosting ? null : "IIS Express must be upgraded to support in-process hosting."; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipIfIISExpressSchemaMissingInProcessAttribute.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipIfIISExpressSchemaMissingInProcessAttribute.cs new file mode 100644 index 0000000000..ecadf4522a --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipIfIISExpressSchemaMissingInProcessAttribute.cs @@ -0,0 +1,16 @@ +// 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 Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Assembly | AttributeTargets.Class)] + public sealed partial class SkipIfIISExpressSchemaMissingInProcessAttribute : Attribute, ITestCondition + { + public bool IsMet => IISExpressAncmSchema.SupportsInProcessHosting; + + public string SkipReason => IISExpressAncmSchema.SkipReason; + } +} diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs index b54b923a89..4249627f56 100644 --- a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs @@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests RuntimeArchitecture.x64) { EnvironmentName = "Shutdown", - TargetFramework = "netcoreapp2.2", + TargetFramework = Tfm.NetCoreApp22, ApplicationType = ApplicationType.Portable, PublishApplicationBeforeDeployment = true, StatusMessagesEnabled = false diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs index ec5dd12651..f594af25b0 100644 --- a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/WebHostBuilderTests.cs @@ -17,17 +17,12 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests { public WebHostBuilderTests(ITestOutputHelper output) : base(output) { } - [Fact] - public async Task InjectedStartup_DefaultApplicationNameIsEntryAssembly_CoreClr() - => await InjectedStartup_DefaultApplicationNameIsEntryAssembly(RuntimeFlavor.CoreClr); + public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.Kestrel) + .WithTfms(Tfm.Net461, Tfm.NetCoreApp22); - [ConditionalFact] - [OSSkipCondition(OperatingSystems.MacOSX)] - [OSSkipCondition(OperatingSystems.Linux)] - public async Task InjectedStartup_DefaultApplicationNameIsEntryAssembly_Clr() - => await InjectedStartup_DefaultApplicationNameIsEntryAssembly(RuntimeFlavor.Clr); - - private async Task InjectedStartup_DefaultApplicationNameIsEntryAssembly(RuntimeFlavor runtimeFlavor) + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task InjectedStartup_DefaultApplicationNameIsEntryAssembly(TestVariant variant) { using (StartLog(out var loggerFactory)) { @@ -35,14 +30,9 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests var applicationPath = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("Hosting"), "test", "TestAssets", "IStartupInjectionAssemblyName"); - var deploymentParameters = new DeploymentParameters( - applicationPath, - ServerType.Kestrel, - runtimeFlavor, - RuntimeArchitecture.x64) + var deploymentParameters = new DeploymentParameters(variant) { - TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.2", - ApplicationType = ApplicationType.Portable, + ApplicationPath = applicationPath, StatusMessagesEnabled = false }; From eda6940350c264dc31688070b6bc91418a65c9b0 Mon Sep 17 00:00:00 2001 From: John Luo Date: Thu, 17 May 2018 13:05:49 -0700 Subject: [PATCH 22/70] Fix integration testing after logging change --- .../Microsoft.AspNetCore.Server.IntegrationTesting.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj index 02c01e1003..76b5ed9fb2 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj @@ -22,7 +22,7 @@ - + From 5906740cdbdc6224b29ce0617d5e1daa8cae6abe Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 20 May 2018 19:31:33 +0000 Subject: [PATCH 23/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index c06cdb96ea..9a0848da88 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17051 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 - 2.2.0-preview1-34216 + 2.2.0-preview1-17060 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 + 2.2.0-preview1-34255 2.0.0 2.1.0-rc1 2.2.0-preview1-26509-06 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 56263a26fc..06fc8a13e4 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17051 -commithash:253c3a480063bc3abaa5cde42f6e27b58457ef9b +version:2.2.0-preview1-17060 +commithash:25b4b134d6f8f7b461928f0d495cfc695ccabb5b From 09d3b32fe570e330c1bd91b297e7cf9aad17b239 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 18 May 2018 16:39:14 -0700 Subject: [PATCH 24/70] Enable x86 testing #949 --- .../Common/DeploymentParameters.cs | 5 -- .../Common/DotNetCommands.cs | 71 ++++++++++++++++ .../Deployers/ApplicationDeployer.cs | 5 -- .../Deployers/IISExpressDeployer.cs | 40 ++++++--- .../Deployers/NginxDeployer.cs | 7 ++ .../Deployers/SelfHostDeployer.cs | 81 +++++++++++++------ .../TestMatrix.cs | 29 ++++++- .../TestVariant.cs | 8 +- .../xunit/SkipOn32BitOSAttribute.cs | 23 ++---- 9 files changed, 204 insertions(+), 65 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index 538cd5ffe3..a687a542b3 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -65,11 +65,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting throw new DirectoryNotFoundException(string.Format("Application path {0} does not exist.", applicationPath)); } - if (runtimeArchitecture == RuntimeArchitecture.x86 && runtimeFlavor == RuntimeFlavor.CoreClr) - { - throw new NotSupportedException("32 bit deployment is not yet supported for CoreCLR. Don't remove the tests, just disable them for now."); - } - ApplicationPath = applicationPath; ApplicationName = new DirectoryInfo(ApplicationPath).Name; ServerType = serverType; diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs new file mode 100644 index 0000000000..38f84d5044 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs @@ -0,0 +1,71 @@ +// 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.IO; +using System.Runtime.InteropServices; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common +{ + internal static class DotNetCommands + { + private const string _dotnetFolderName = ".dotnet"; + + internal static string DotNetHome { get; } = GetDotNetHome(); + + // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76 + private static string GetDotNetHome() + { + var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME"); + var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); + var home = Environment.GetEnvironmentVariable("HOME"); + + var result = Path.Combine(Directory.GetCurrentDirectory(), _dotnetFolderName); + if (!string.IsNullOrEmpty(dotnetHome)) + { + result = dotnetHome; + } + else if (!string.IsNullOrEmpty(userProfile)) + { + result = Path.Combine(userProfile, _dotnetFolderName); + } + else if (!string.IsNullOrEmpty(home)) + { + result = home; + } + + return result; + } + + internal static string GetDotNetInstallDir(RuntimeArchitecture arch) + { + var dotnetDir = DotNetHome; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + dotnetDir = Path.Combine(dotnetDir, arch.ToString()); + } + + return dotnetDir; + } + + internal static string GetDotNetExecutable(RuntimeArchitecture arch) + { + var dotnetDir = GetDotNetInstallDir(arch); + + var dotnetFile = "dotnet"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + dotnetFile += ".exe"; + } + + return Path.Combine(dotnetDir, dotnetFile); + } + + internal static bool IsRunningX86OnX64(RuntimeArchitecture arch) + { + return (RuntimeInformation.OSArchitecture == Architecture.X64 || RuntimeInformation.OSArchitecture == Architecture.Arm64) + && arch == RuntimeArchitecture.x86; + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs index f475c65d81..ddaac89711 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs @@ -47,11 +47,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting DeploymentParameters.RuntimeFlavor = GetRuntimeFlavor(DeploymentParameters.TargetFramework); } - if (DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86 && DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr) - { - throw new NotSupportedException("32 bit deployment is not yet supported for CoreCLR. Don't remove the tests, just disable them for now."); - } - if (string.IsNullOrEmpty(DeploymentParameters.ApplicationPath)) { throw new ArgumentException("ApplicationPath cannot be null."); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 8a7439809e..bdb70d4287 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -35,14 +35,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { } - public bool Is64BitHost - { - get - { - return Environment.Is64BitOperatingSystem; - } - } - public override async Task DeployAsync() { using (Logger.BeginScope("Deployment")) @@ -128,6 +120,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); + ModifyDotNetExePathInWebConfig(); var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ? string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : @@ -228,7 +221,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { if (serverConfig.Contains(replaceFlag)) { - var ancmFile = Path.Combine(contentRoot, Is64BitHost ? $@"x64\{dllName}" : $@"x86\{dllName}"); + var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}"; + var ancmFile = Path.Combine(contentRoot, arch); if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) { ancmFile = Path.Combine(contentRoot, dllName); @@ -246,8 +240,14 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting private string GetIISExpressPath() { + var programFiles = "Program Files"; + if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) + { + programFiles = "Program Files (x86)"; + } + // Get path to program files - var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", "Program Files", "IIS Express", "iisexpress.exe"); + var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", programFiles, "IIS Express", "iisexpress.exe"); if (!File.Exists(iisExpressPath)) { @@ -297,8 +297,24 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } - // Transforms the web.config file to include the hostingModel="inprocess" element - // and adds the server type = Microsoft.AspNetServer.IIS such that Kestrel isn't added again in ServerTests + private void ModifyDotNetExePathInWebConfig() + { + // We assume the x64 dotnet.exe is on the path so we need to provide an absolute path for x86 scenarios. + // Only do it for scenarios that rely on dotnet.exe (Core, portable, etc.). + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr + && DeploymentParameters.ApplicationType == ApplicationType.Portable + && DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) + { + var executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); + if (!File.Exists(executableName)) + { + throw new Exception($"Unable to find '{executableName}'.'"); + } + ModifyAspNetCoreSectionInWebConfig("processPath", executableName); + } + } + + // Transforms the web.config file to set attributes like hostingModel="inprocess" element private void ModifyAspNetCoreSectionInWebConfig(string key, string value) { var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs index 7341624d41..655630f08a 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs @@ -35,6 +35,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting var redirectUri = TestUriHelper.BuildTestUri(ServerType.Nginx); + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr + && DeploymentParameters.ApplicationType == ApplicationType.Standalone) + { + // Publish is required to get the correct files in the output directory + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + if (DeploymentParameters.PublishApplicationBeforeDeployment) { DotnetPublish(); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index e9ee52ac3d..8a9f6d6a4e 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -36,6 +36,20 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Start timer StartTimer(); + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr + && DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) + { + // Publish is required to rebuild for the right bitness + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr + && DeploymentParameters.ApplicationType == ApplicationType.Standalone) + { + // Publish is required to get the correct files in the output directory + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + if (DeploymentParameters.PublishApplicationBeforeDeployment) { DotnetPublish(); @@ -65,37 +79,42 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { using (Logger.BeginScope("StartSelfHost")) { - string executableName; - string executableArgs = string.Empty; - string workingDirectory = string.Empty; + var executableName = string.Empty; + var executableArgs = string.Empty; + var workingDirectory = string.Empty; + var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" + : (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""); + if (DeploymentParameters.PublishApplicationBeforeDeployment) { workingDirectory = DeploymentParameters.PublishedApplicationRootPath; - var executableExtension = - DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? ".exe" : - DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ""; - var executable = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, DeploymentParameters.ApplicationName + executableExtension); - - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) - { - executableName = "dotnet"; - executableArgs = executable; - } - else - { - executableName = executable; - } } else { - workingDirectory = DeploymentParameters.ApplicationPath; - var targetFramework = DeploymentParameters.TargetFramework ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? Tfm.Net461 : Tfm.NetCoreApp22); - executableName = DotnetCommandName; - executableArgs = $"run --no-build -c {DeploymentParameters.Configuration} --framework {targetFramework} {DotnetArgumentSeparator}"; + // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable. + // Run from the pre-built bin/{config}/{tfm} directory. + var targetFramework = DeploymentParameters.TargetFramework + ?? (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr ? Tfm.Net461 : Tfm.NetCoreApp22); + workingDirectory = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework); + // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead. + DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath; } - executableArgs += $" --urls {hintUrl} " - + $" --server {(DeploymentParameters.ServerType == ServerType.HttpSys ? "Microsoft.AspNetCore.Server.HttpSys" : "Microsoft.AspNetCore.Server.Kestrel")}"; + var executable = Path.Combine(workingDirectory, DeploymentParameters.ApplicationName + executableExtension); + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) + { + executableName = GetDotNetExeForArchitecture(); + executableArgs = executable; + } + else + { + executableName = executable; + } + + var server = DeploymentParameters.ServerType == ServerType.HttpSys + ? "Microsoft.AspNetCore.Server.HttpSys" : "Microsoft.AspNetCore.Server.Kestrel"; + executableArgs += $" --urls {hintUrl} --server {server}"; Logger.LogInformation($"Executing {executableName} {executableArgs}"); @@ -175,6 +194,22 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } + private string GetDotNetExeForArchitecture() + { + var executableName = DotnetCommandName; + // We expect x64 dotnet.exe to be on the path but we have to go searching for the x86 version. + if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) + { + executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); + if (!File.Exists(executableName)) + { + throw new Exception($"Unable to find '{executableName}'.'"); + } + } + + return executableName; + } + public override void Dispose() { using (Logger.BeginScope("SelfHost.Dispose")) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs index 857bb143d9..76785d20c7 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs @@ -246,9 +246,15 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { foreach (var arch in Architectures) { + if (!IsArchitectureSupportedOnServer(arch, server)) + { + continue; + } + var archSkip = skip ?? SkipIfArchitectureNotSupportedOnCurrentSystem(arch); + if (server == ServerType.IISExpress) { - VaryByAncmVersion(variants, server, tfm, type, arch, skip); + VaryByAncmVersion(variants, server, tfm, type, arch, archSkip); } else { @@ -258,12 +264,31 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting Tfm = tfm, ApplicationType = type, Architecture = arch, - Skip = skip, + Skip = archSkip, }); } } } + private string SkipIfArchitectureNotSupportedOnCurrentSystem(RuntimeArchitecture arch) + { + if (arch == RuntimeArchitecture.x64) + { + // Can't run x64 on a x86 OS. + return (RuntimeInformation.OSArchitecture == Architecture.Arm || RuntimeInformation.OSArchitecture == Architecture.X86) + ? $"Cannot run {arch} on your current system." : null; + } + + // No x86 runtimes available on MacOS or Linux. + return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? null : $"No {arch} available for non-Windows systems."; + } + + private bool IsArchitectureSupportedOnServer(RuntimeArchitecture arch, ServerType server) + { + // No x86 Mac/Linux runtime, don't generate a test variation that will always be skipped. + return !(arch == RuntimeArchitecture.x86 && ServerType.Nginx == server); + } + private void VaryByAncmVersion(IList variants, ServerType server, string tfm, ApplicationType type, RuntimeArchitecture arch, string skip) { foreach (var version in AncmVersions) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs index e9b9cda607..76220d7fef 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs @@ -21,7 +21,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public override string ToString() { // For debug and test explorer view - return $"Server: {Server}, TFM: {Tfm}, Type: {ApplicationType}, Host: {HostingModel}, ANCM: {AncmVersion}, Arch: {Architecture}"; + var description = $"Server: {Server}, TFM: {Tfm}, Type: {ApplicationType}, Arch: {Architecture}"; + if (Server == ServerType.IISExpress) + { + var version = AncmVersion == AncmVersion.AspNetCoreModule ? "V1" : "V2"; + description += $", ANCM: {version}, Host: {HostingModel}"; + } + return description; } public void Serialize(IXunitSerializationInfo info) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipOn32BitOSAttribute.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipOn32BitOSAttribute.cs index 554cc63eda..066eb729c6 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipOn32BitOSAttribute.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/SkipOn32BitOSAttribute.cs @@ -2,32 +2,21 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.IO; +using System.Runtime.InteropServices; using Microsoft.AspNetCore.Testing.xunit; namespace Microsoft.AspNetCore.Server.IntegrationTesting { /// - /// Skips a 64 bit test if the current Windows OS is 32-bit. + /// Skips a 64 bit test if the current OS is 32-bit. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class SkipOn32BitOSAttribute : Attribute, ITestCondition { - public bool IsMet - { - get - { - // Directory found only on 64-bit OS. - return Directory.Exists(Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "SysWOW64")); - } - } + public bool IsMet => + RuntimeInformation.OSArchitecture == Architecture.Arm64 + || RuntimeInformation.OSArchitecture == Architecture.X64; - public string SkipReason - { - get - { - return "Skipping the x64 test since Windows is 32-bit"; - } - } + public string SkipReason => "Skipping the x64 test since Windows is 32-bit"; } } \ No newline at end of file From a3300a6a605dd66d79fabc297e8d8abdb8b8edf6 Mon Sep 17 00:00:00 2001 From: Rutger Storm Date: Fri, 25 May 2018 18:21:26 +0200 Subject: [PATCH 25/70] Add try..finally around RunAsync and WaitForTokenShutdownAsync #1194 The try..finally ensures that the ManualResetEventSlim which AttachCtrlcSigtermShutdown uses is set even when an exception occurs in these two methods. --- .../WebHostExtensions.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs index 06a3e00cf8..e73399c419 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostExtensions.cs @@ -45,8 +45,14 @@ namespace Microsoft.AspNetCore.Hosting { AttachCtrlcSigtermShutdown(cts, done, shutdownMessage: string.Empty); - await host.WaitForTokenShutdownAsync(cts.Token); - done.Set(); + try + { + await host.WaitForTokenShutdownAsync(cts.Token); + } + finally + { + done.Set(); + } } } @@ -80,8 +86,14 @@ namespace Microsoft.AspNetCore.Hosting var shutdownMessage = host.Services.GetRequiredService().SuppressStatusMessages ? string.Empty : "Application is shutting down..."; AttachCtrlcSigtermShutdown(cts, done, shutdownMessage: shutdownMessage); - await host.RunAsync(cts.Token, "Application started. Press Ctrl+C to shut down."); - done.Set(); + try + { + await host.RunAsync(cts.Token, "Application started. Press Ctrl+C to shut down."); + } + finally + { + done.Set(); + } } } @@ -92,7 +104,6 @@ namespace Microsoft.AspNetCore.Hosting await host.StartAsync(token); var hostingEnvironment = host.Services.GetService(); - var applicationLifetime = host.Services.GetService(); var options = host.Services.GetRequiredService(); if (!options.SuppressStatusMessages) From ad5d0505801e8d870e1247f39ec63b3a6aade19b Mon Sep 17 00:00:00 2001 From: "Nate McMaster (automated)" Date: Fri, 25 May 2018 16:14:11 -0700 Subject: [PATCH 26/70] Update bootstrapper scripts (automated commit) [ci skip] --- run.ps1 | 25 +++++++++++++++++++------ run.sh | 33 +++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/run.ps1 b/run.ps1 index 27dcf848f8..3b27382468 100644 --- a/run.ps1 +++ b/run.ps1 @@ -26,12 +26,18 @@ The base url where build tools can be downloaded. Overrides the value from the c .PARAMETER Update Updates KoreBuild to the latest version even if a lock file is present. +.PARAMETER Reinstall +Re-installs KoreBuild + .PARAMETER ConfigFile The path to the configuration file that stores values. Defaults to korebuild.json. .PARAMETER ToolsSourceSuffix The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores. +.PARAMETER CI +Sets up CI specific settings and variables. + .PARAMETER Arguments Arguments to be passed to the command @@ -65,8 +71,10 @@ param( [string]$ToolsSource, [Alias('u')] [switch]$Update, - [string]$ConfigFile, + [switch]$Reinstall, [string]$ToolsSourceSuffix, + [string]$ConfigFile = $null, + [switch]$CI, [Parameter(ValueFromRemainingArguments = $true)] [string[]]$Arguments ) @@ -93,6 +101,10 @@ function Get-KoreBuild { $version = $version.TrimStart('version:').Trim() $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version) + if ($Reinstall -and (Test-Path $korebuildPath)) { + Remove-Item -Force -Recurse $korebuildPath + } + if (!(Test-Path $korebuildPath)) { Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version" New-Item -ItemType Directory -Path $korebuildPath | Out-Null @@ -101,9 +113,9 @@ function Get-KoreBuild { try { $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix - if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) { + if (Get-Command -Name 'Microsoft.PowerShell.Archive\Expand-Archive' -ErrorAction Ignore) { # Use built-in commands where possible as they are cross-plat compatible - Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath + Microsoft.PowerShell.Archive\Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath } else { # Fallback to old approach for old installations of PowerShell @@ -167,8 +179,9 @@ if (Test-Path $ConfigFile) { } } catch { - Write-Warning "$ConfigFile could not be read. Its settings will be ignored." - Write-Warning $Error[0] + Write-Host -ForegroundColor Red $Error[0] + Write-Error "$ConfigFile contains invalid JSON." + exit 1 } } @@ -188,7 +201,7 @@ $korebuildPath = Get-KoreBuild Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') try { - Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile + Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI Invoke-KoreBuildCommand $Command @Arguments } finally { diff --git a/run.sh b/run.sh index 834961fc3a..02aac15874 100755 --- a/run.sh +++ b/run.sh @@ -14,10 +14,12 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" [ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" verbose=false update=false +reinstall=false repo_path="$DIR" channel='' tools_source='' tools_source_suffix='' +ci=false # # Functions @@ -38,6 +40,8 @@ __usage() { echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings." echo " -u|--update Update to the latest KoreBuild even if the lock file is present." + echo " --reinstall Reinstall KoreBuild." + echo " --ci Apply CI specific settings and environment variables." echo "" echo "Description:" echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." @@ -62,6 +66,10 @@ get_korebuild() { version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" + if [ "$reinstall" = true ] && [ -d "$korebuild_path" ]; then + rm -rf "$korebuild_path" + fi + { if [ ! -d "$korebuild_path" ]; then mkdir -p "$korebuild_path" @@ -175,6 +183,12 @@ while [[ $# -gt 0 ]]; do -u|--update|-Update) update=true ;; + --reinstall|-[Rr]einstall) + reinstall=true + ;; + --ci|-[Cc][Ii]) + ci=true + ;; --verbose|-Verbose) verbose=true ;; @@ -206,17 +220,28 @@ if [ -f "$config_file" ]; then config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" else - __warn "$config_file is invalid JSON. Its settings will be ignored." + _error "$config_file contains invalid JSON." + exit 1 fi elif __machine_has python ; then if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" else - __warn "$config_file is invalid JSON. Its settings will be ignored." + _error "$config_file contains invalid JSON." + exit 1 + fi + elif __machine_has python3 ; then + if python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then + config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" + config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" + else + _error "$config_file contains invalid JSON." + exit 1 fi else - __warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.' + _error 'Missing required command: jq or python. Could not parse the JSON file.' + exit 1 fi [ ! -z "${config_channel:-}" ] && channel="$config_channel" @@ -227,5 +252,5 @@ fi [ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' get_korebuild -set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" +set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" "$ci" invoke_korebuild_command "$command" "$@" From 7acd373e27cdd58c2687c871dc3973d1739751a4 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 27 May 2018 19:14:16 +0000 Subject: [PATCH 27/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 68 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9a0848da88..ff9fac2495 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,48 +3,48 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17060 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 - 2.2.0-preview1-34255 + 2.2.0-preview1-17064 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 + 2.2.0-preview1-34326 2.0.0 2.1.0-rc1 - 2.2.0-preview1-26509-06 + 2.2.0-preview1-26526-03 1.0.1 15.6.1 4.7.49 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26508-04 - 4.6.0-preview1-26508-04 - 1.7.0-preview1-26508-04 - 4.6.0-preview1-26508-04 + 4.6.0-preview1-26525-01 + 4.6.0-preview1-26525-01 + 1.7.0-preview1-26525-01 + 4.6.0-preview1-26525-01 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 06fc8a13e4..de5df64434 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17060 -commithash:25b4b134d6f8f7b461928f0d495cfc695ccabb5b +version:2.2.0-preview1-17064 +commithash:5380a2461b135b261646f31d1c919ab0a7b577a8 From 23e3ab6555acf68715672f930b01b9a6a8b8134b Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 30 May 2018 13:55:46 -0700 Subject: [PATCH 28/70] Add TestPortHelper class for tests (#1438) * Add TestPortHelper class for tests * Remove copy * Update IISExpressDeployer --- .../Common/TestPortHelper.cs | 60 +++++++++++++++++++ .../Common/TestUriHelper.cs | 24 +------- .../Deployers/IISExpressDeployer.cs | 2 +- 3 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestPortHelper.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestPortHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestPortHelper.cs new file mode 100644 index 0000000000..05c6080cd5 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestPortHelper.cs @@ -0,0 +1,60 @@ +// 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.AspNetCore.Server.IntegrationTesting.Common +{ + public static class TestPortHelper + { + // Copied from https://github.com/aspnet/KestrelHttpServer/blob/47f1db20e063c2da75d9d89653fad4eafe24446c/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs#L508 + // + // This method is an attempt to safely get a free port from the OS. Most of the time, + // when binding to dynamic port "0" the OS increments the assigned port, so it's safe + // to re-use the assigned port in another process. However, occasionally the OS will reuse + // a recently assigned port instead of incrementing, which causes flaky tests with AddressInUse + // exceptions. This method should only be used when the application itself cannot use + // dynamic port "0" (e.g. IISExpress). Most functional tests using raw Kestrel + // (with status messages enabled) should directly bind to dynamic port "0" and scrape + // the assigned port from the status message, which should be 100% reliable since the port + // is bound once and never released. + public static int GetNextPort() + { + using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + socket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); + return ((IPEndPoint)socket.LocalEndPoint).Port; + } + } + + // IIS Express preregisteres 44300-44399 ports with SSL bindings. + // So some tests always have to use ports in this range, and we can't rely on OS-allocated ports without a whole lot of ceremony around + // creating self-signed certificates and registering SSL bindings with HTTP.sys + public static int GetNextSSLPort() + { + var next = 44300; + using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + while (true) + { + try + { + var port = next++; + socket.Bind(new IPEndPoint(IPAddress.Loopback, port)); + return port; + } + catch (SocketException) + { + // Retry unless exhausted + if (next > 44399) + { + throw; + } + } + } + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index 012105a8ff..1c09b08dfa 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common // from which to scrape the assigned port, so the less reliable GetNextPort() must be used. The // port is bound on "localhost" (both IPv4 and IPv6), since this is supported when using a specific // (non-zero) port. - return new UriBuilder(scheme, "localhost", GetNextPort()).Uri; + return new UriBuilder(scheme, "localhost", TestPortHelper.GetNextPort()).Uri; } } else @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common // Only a few tests use this codepath, so it's fine to use the less reliable GetNextPort() for simplicity. // The tests using this codepath will be reviewed to see if they can be changed to directly bind to dynamic // port "0" on "127.0.0.1" and scrape the assigned port from the status message (the default codepath). - return new UriBuilder(uriHint) { Port = GetNextPort() }.Uri; + return new UriBuilder(uriHint) { Port = TestPortHelper.GetNextPort() }.Uri; } else { @@ -61,25 +61,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common } } } - - // Copied from https://github.com/aspnet/KestrelHttpServer/blob/47f1db20e063c2da75d9d89653fad4eafe24446c/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs#L508 - // - // This method is an attempt to safely get a free port from the OS. Most of the time, - // when binding to dynamic port "0" the OS increments the assigned port, so it's safe - // to re-use the assigned port in another process. However, occasionally the OS will reuse - // a recently assigned port instead of incrementing, which causes flaky tests with AddressInUse - // exceptions. This method should only be used when the application itself cannot use - // dynamic port "0" (e.g. IISExpress). Most functional tests using raw Kestrel - // (with status messages enabled) should directly bind to dynamic port "0" and scrape - // the assigned port from the status message, which should be 100% reliable since the port - // is bound once and never released. - internal static int GetNextPort() - { - using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) - { - socket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); - return ((IPEndPoint)socket.LocalEndPoint).Port; - } - } } } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index bdb70d4287..91c9c7eae3 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting var port = uri.Port; if (port == 0) { - port = TestUriHelper.GetNextPort(); + port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort(); } for (var attempt = 0; attempt < MaximumAttempts; attempt++) From 8d55a447d480bb826cf0088718bbea200b2537bb Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 25 May 2018 15:19:25 -0700 Subject: [PATCH 29/70] Allow running some IIS Express variants without publishing #1431 --- .../Common/DeploymentParameters.cs | 2 +- .../Common/DotNetCommands.cs | 2 +- .../Deployers/ApplicationDeployer.cs | 16 + .../Deployers/IISExpressDeployer.cs | 232 ++-- .../RemoteWindowsDeployer.cs | 12 +- .../Deployers/SelfHostDeployer.cs | 16 - .../Http.config | 1034 +++++++++++++++++ ...spNetCore.Server.IntegrationTesting.csproj | 4 + .../TestMatrix.cs | 2 +- 9 files changed, 1229 insertions(+), 91 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Http.config diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index a687a542b3..968647edba 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public string ServerConfigLocation { get; set; } - public string SiteName { get; set; } + public string SiteName { get; set; } = "HttpTestSite"; public string ApplicationPath { get; set; } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs index 38f84d5044..d9f5577056 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs @@ -5,7 +5,7 @@ using System; using System.IO; using System.Runtime.InteropServices; -namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common +namespace Microsoft.AspNetCore.Server.IntegrationTesting { internal static class DotNetCommands { diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs index ddaac89711..a9212b0d54 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs @@ -161,6 +161,22 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } + protected string GetDotNetExeForArchitecture() + { + var executableName = DotnetCommandName; + // We expect x64 dotnet.exe to be on the path but we have to go searching for the x86 version. + if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) + { + executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); + if (!File.Exists(executableName)) + { + throw new Exception($"Unable to find '{executableName}'.'"); + } + } + + return executableName; + } + protected void ShutDownIfAnyHostProcess(Process hostProcess) { if (hostProcess != null && !hostProcess.HasExited) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 91c9c7eae3..1bdc58ec8a 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -3,9 +3,9 @@ using System; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -42,15 +42,52 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Start timer StartTimer(); - // For now we always auto-publish. Otherwise we'll have to write our own local web.config for the HttpPlatformHandler - DotnetPublish(); + // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/net461/ + // and contentRoot points to the project directory so you get things like static assets. + // For a published app both point to the publish directory. + var dllRoot = CheckIfPublishIsRequired(); + var contentRoot = string.Empty; + if (DeploymentParameters.PublishApplicationBeforeDeployment) + { + DotnetPublish(); + contentRoot = DeploymentParameters.PublishedApplicationRootPath; + dllRoot = contentRoot; + } + else + { + // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable. + // Update processPath and arguments for our current scenario + contentRoot = DeploymentParameters.ApplicationPath; - var contentRoot = DeploymentParameters.PublishedApplicationRootPath; + var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ".exe"; + var entryPoint = Path.Combine(dllRoot, DeploymentParameters.ApplicationName + executableExtension); + + var executableName = string.Empty; + var executableArgs = string.Empty; + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) + { + executableName = GetDotNetExeForArchitecture(); + executableArgs = entryPoint; + } + else + { + executableName = entryPoint; + } + + Logger.LogInformation("Executing: {exe} {args}", executableName, executableArgs); + DeploymentParameters.EnvironmentVariables["LAUNCHER_PATH"] = executableName; + DeploymentParameters.EnvironmentVariables["LAUNCHER_ARGS"] = executableArgs; + + // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead. + Logger.LogInformation("ContentRoot: {path}", DeploymentParameters.ApplicationPath); + DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath; + } var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint); // Launch the host process. - var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot); + var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot, dllRoot); Logger.LogInformation("Application ready at URL: {appUrl}", actualUri); @@ -64,7 +101,43 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } - private async Task<(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot) + private string CheckIfPublishIsRequired() + { + var targetFramework = DeploymentParameters.TargetFramework; + + // IISIntegration uses this layout + var dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.RuntimeArchitecture.ToString(), + DeploymentParameters.Configuration, targetFramework); + + if (!Directory.Exists(dllRoot)) + { + // Most repos use this layout + dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework); + + if (!Directory.Exists(dllRoot)) + { + // The bits we need weren't pre-compiled, compile on publish + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + else if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr + && DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) + { + // x64 is the default. Publish to rebuild for the right bitness + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + } + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr + && DeploymentParameters.ApplicationType == ApplicationType.Standalone) + { + // Publish is always required to get the correct standalone files in the output directory + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + + return dllRoot; + } + + private async Task<(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot, string dllRoot) { using (Logger.BeginScope("StartIISExpress")) { @@ -74,60 +147,17 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort(); } + Logger.LogInformation("Attempting to start IIS Express on port: {port}", port); + PrepareConfig(contentRoot, dllRoot, port); + + var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ? + string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : + string.Format("/site:{0} /config:{1} /trace:error", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); + + var iisExpressPath = GetIISExpressPath(); + for (var attempt = 0; attempt < MaximumAttempts; attempt++) { - Logger.LogInformation("Attempting to start IIS Express on port: {port}", port); - - if (!string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigTemplateContent)) - { - var serverConfig = DeploymentParameters.ServerConfigTemplateContent; - - // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config - // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. - serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, contentRoot); - - serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, contentRoot); - - Logger.LogDebug("Writing ApplicationPhysicalPath '{applicationPhysicalPath}' to config", contentRoot); - Logger.LogDebug("Writing Port '{port}' to config", port); - serverConfig = - serverConfig - .Replace("[ApplicationPhysicalPath]", contentRoot) - .Replace("[PORT]", port.ToString()); - - DeploymentParameters.ServerConfigLocation = Path.GetTempFileName(); - - if (serverConfig.Contains("[HostingModel]")) - { - var hostingModel = DeploymentParameters.HostingModel.ToString(); - serverConfig.Replace("[HostingModel]", hostingModel); - Logger.LogDebug("Writing HostingModel '{hostingModel}' to config", hostingModel); - } - - Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation); - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace($"Config File Content:{Environment.NewLine}===START CONFIG==={Environment.NewLine}{{configContent}}{Environment.NewLine}===END CONFIG===", serverConfig); - } - - File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig); - } - - if (DeploymentParameters.HostingModel == HostingModel.InProcess) - { - ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", value: "inprocess"); - } - - ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); - ModifyDotNetExePathInWebConfig(); - - var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ? - string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : - string.Format("/site:{0} /config:{1} /trace:error", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); - - var iisExpressPath = GetIISExpressPath(); - Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters); var startInfo = new ProcessStartInfo @@ -197,7 +227,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // just in case we missed one -anurse if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10))) { - Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", _hostProcess.Id, port); + Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port); // Wait for the process to exit and try again process.WaitForExit(30 * 1000); @@ -217,15 +247,69 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } - private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string contentRoot) + private void PrepareConfig(string contentRoot, string dllRoot, int port) + { + // Config is required. If not present then fall back to one we carry with us. + if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent)) + { + using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.AspNetCore.Server.IntegrationTesting.Http.config")) + using (var reader = new StreamReader(stream)) + { + DeploymentParameters.ServerConfigTemplateContent = reader.ReadToEnd(); + } + } + + var serverConfig = DeploymentParameters.ServerConfigTemplateContent; + + // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config + // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. + serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, dllRoot); + serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, dllRoot); + + serverConfig = ReplacePlaceholder(serverConfig, "[PORT]", port.ToString(CultureInfo.InvariantCulture)); + serverConfig = ReplacePlaceholder(serverConfig, "[ApplicationPhysicalPath]", contentRoot); + + if (DeploymentParameters.PublishApplicationBeforeDeployment) + { + // For published apps, prefer the content in the web.config, but update it. + ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", + value: DeploymentParameters.HostingModel == HostingModel.InProcess ? "inprocess" : ""); + ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); + ModifyDotNetExePathInWebConfig(); + serverConfig = RemoveRedundantElements(serverConfig); + } + else + { + // The elements normally in the web.config are in the applicationhost.config for unpublished apps. + serverConfig = ReplacePlaceholder(serverConfig, "[HostingModel]", DeploymentParameters.HostingModel.ToString()); + serverConfig = ReplacePlaceholder(serverConfig, "[AspNetCoreModule]", DeploymentParameters.AncmVersion.ToString()); + } + + DeploymentParameters.ServerConfigLocation = Path.GetTempFileName(); + Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation); + + File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig); + } + + private string ReplacePlaceholder(string content, string field, string value) + { + if (content.Contains(field)) + { + content = content.Replace(field, value); + Logger.LogDebug("Writing {field} '{value}' to config", field, value); + } + return content; + } + + private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string dllRoot) { if (serverConfig.Contains(replaceFlag)) { var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}"; - var ancmFile = Path.Combine(contentRoot, arch); + var ancmFile = Path.Combine(dllRoot, arch); if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) { - ancmFile = Path.Combine(contentRoot, dllName); + ancmFile = Path.Combine(dllRoot, dllName); if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) { throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); @@ -263,7 +347,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { ShutDownIfAnyHostProcess(_hostProcess); - if (!string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) + if (!string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) && File.Exists(DeploymentParameters.ServerConfigLocation)) { // Delete the temp applicationHostConfig that we created. @@ -317,7 +401,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Transforms the web.config file to set attributes like hostingModel="inprocess" element private void ModifyAspNetCoreSectionInWebConfig(string key, string value) { - var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; + var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); var config = XDocument.Load(webConfigFile); var element = config.Descendants("aspNetCore").FirstOrDefault(); element.SetAttributeValue(key, value); @@ -326,11 +410,27 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting private void ModifyHandlerSectionInWebConfig(string key, string value) { - var webConfigFile = $"{DeploymentParameters.PublishedApplicationRootPath}/web.config"; + var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); var config = XDocument.Load(webConfigFile); var element = config.Descendants("handlers").FirstOrDefault().Descendants("add").FirstOrDefault(); element.SetAttributeValue(key, value); - config.Save(webConfigFile); + config.Save(webConfigFile); + } + + // These elements are duplicated in the web.config if you publish. Remove them from the host.config. + private string RemoveRedundantElements(string serverConfig) + { + var hostConfig = XDocument.Parse(serverConfig); + + var coreElement = hostConfig.Descendants("aspNetCore").FirstOrDefault(); + coreElement?.Remove(); + + var handlersElement = hostConfig.Descendants("handlers").First(); + var handlerElement = handlersElement.Descendants("add") + .Where(x => x.Attribute("name").Value == "aspNetCore").FirstOrDefault(); + handlerElement?.Remove(); + + return hostConfig.ToString(); } } } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs index dc764bf98a..f33b285d63 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/RemoteWindowsDeployer/RemoteWindowsDeployer.cs @@ -39,37 +39,37 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting $" Supported server types are {nameof(ServerType.Kestrel)}, {nameof(ServerType.IIS)} and {nameof(ServerType.HttpSys)}"); } - if (string.IsNullOrWhiteSpace(_deploymentParameters.ServerName)) + if (string.IsNullOrEmpty(_deploymentParameters.ServerName)) { throw new ArgumentException($"Invalid value '{_deploymentParameters.ServerName}' for {nameof(RemoteWindowsDeploymentParameters.ServerName)}"); } - if (string.IsNullOrWhiteSpace(_deploymentParameters.ServerAccountName)) + if (string.IsNullOrEmpty(_deploymentParameters.ServerAccountName)) { throw new ArgumentException($"Invalid value '{_deploymentParameters.ServerAccountName}' for {nameof(RemoteWindowsDeploymentParameters.ServerAccountName)}." + " Account credentials are required to enable creating a powershell session to the remote server."); } - if (string.IsNullOrWhiteSpace(_deploymentParameters.ServerAccountPassword)) + if (string.IsNullOrEmpty(_deploymentParameters.ServerAccountPassword)) { throw new ArgumentException($"Invalid value '{_deploymentParameters.ServerAccountPassword}' for {nameof(RemoteWindowsDeploymentParameters.ServerAccountPassword)}." + " Account credentials are required to enable creating a powershell session to the remote server."); } if (_deploymentParameters.ApplicationType == ApplicationType.Portable - && string.IsNullOrWhiteSpace(_deploymentParameters.DotnetRuntimePath)) + && string.IsNullOrEmpty(_deploymentParameters.DotnetRuntimePath)) { throw new ArgumentException($"Invalid value '{_deploymentParameters.DotnetRuntimePath}' for {nameof(RemoteWindowsDeploymentParameters.DotnetRuntimePath)}. " + "It must be non-empty for portable apps."); } - if (string.IsNullOrWhiteSpace(_deploymentParameters.RemoteServerFileSharePath)) + if (string.IsNullOrEmpty(_deploymentParameters.RemoteServerFileSharePath)) { throw new ArgumentException($"Invalid value for {nameof(RemoteWindowsDeploymentParameters.RemoteServerFileSharePath)}." + " . A file share is required to copy the application's published output."); } - if (string.IsNullOrWhiteSpace(_deploymentParameters.ApplicationBaseUriHint)) + if (string.IsNullOrEmpty(_deploymentParameters.ApplicationBaseUriHint)) { throw new ArgumentException($"Invalid value for {nameof(RemoteWindowsDeploymentParameters.ApplicationBaseUriHint)}."); } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs index 8a9f6d6a4e..ae6a7a08af 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs @@ -194,22 +194,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } - private string GetDotNetExeForArchitecture() - { - var executableName = DotnetCommandName; - // We expect x64 dotnet.exe to be on the path but we have to go searching for the x86 version. - if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) - { - executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); - if (!File.Exists(executableName)) - { - throw new Exception($"Unable to find '{executableName}'.'"); - } - } - - return executableName; - } - public override void Dispose() { using (Logger.BeginScope("SelfHost.Dispose")) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Http.config b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Http.config new file mode 100644 index 0000000000..4508dea843 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Http.config @@ -0,0 +1,1034 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj index 76b5ed9fb2..9e304fde5e 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Microsoft.AspNetCore.Server.IntegrationTesting.csproj @@ -13,6 +13,10 @@ false + + + + diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs index 76785d20c7..d577e25dc7 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs @@ -305,7 +305,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting if (hostingModel == HostingModel.InProcess) { // Not supported - if (Tfm.Matches(Tfm.Net461, tfm) || version == AncmVersion.AspNetCoreModule) + if (Tfm.Matches(Tfm.Net461, tfm) || Tfm.Matches(Tfm.NetCoreApp20, tfm) || version == AncmVersion.AspNetCoreModule) { continue; } From ec51afd9d0a973c2a00b37a4c4e529b48ce816bf Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 3 Jun 2018 19:14:10 +0000 Subject: [PATCH 30/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 70 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ff9fac2495..4566a170ed 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,48 +3,48 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17064 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 - 2.2.0-preview1-34326 + 2.2.0-preview1-17067 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 + 2.2.0-preview1-34373 2.0.0 - 2.1.0-rc1 - 2.2.0-preview1-26526-03 + 2.1.0 + 2.2.0-preview1-26531-03 1.0.1 15.6.1 4.7.49 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26525-01 - 4.6.0-preview1-26525-01 - 1.7.0-preview1-26525-01 - 4.6.0-preview1-26525-01 + 4.6.0-preview1-26531-03 + 4.6.0-preview1-26531-03 + 1.7.0-preview1-26531-03 + 4.6.0-preview1-26531-03 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index de5df64434..34bf7eb808 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17064 -commithash:5380a2461b135b261646f31d1c919ab0a7b577a8 +version:2.2.0-preview1-17067 +commithash:2af0e2e3d02329b4f0290061ab9bd8c7ca1aa26f From de49ba74db0c4c536ce56306e5169a15e94f67dd Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 5 Jun 2018 22:32:02 -0700 Subject: [PATCH 31/70] Add certificate names for code signing --- Directory.Build.props | 2 ++ korebuild-lock.txt | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index fbb0c081f2..cffe01b760 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,6 +14,8 @@ $(MSBuildThisFileDirectory) $(MSBuildThisFileDirectory)build\Key.snk true + Microsoft + MicrosoftNuGet true true diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 34bf7eb808..2dedb9dd4c 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17067 -commithash:2af0e2e3d02329b4f0290061ab9bd8c7ca1aa26f +version:2.2.0-preview1-17075 +commithash:d9f07c7f313a0af1d49f003f5424b4dbbdd3e09f From ba88bdfd5e334907e36174a2aa247ed5c31cdac9 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Wed, 6 Jun 2018 17:25:31 -0500 Subject: [PATCH 32/70] Move AddCommandLine in SampleStartups (#1449) --- samples/SampleStartups/StartupFullControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/SampleStartups/StartupFullControl.cs b/samples/SampleStartups/StartupFullControl.cs index 272e747446..a7986d9e0c 100644 --- a/samples/SampleStartups/StartupFullControl.cs +++ b/samples/SampleStartups/StartupFullControl.cs @@ -15,9 +15,9 @@ namespace SampleStartups public static void Main(string[] args) { var config = new ConfigurationBuilder() - .AddCommandLine(args) .AddEnvironmentVariables(prefix: "ASPNETCORE_") .AddJsonFile("hosting.json", optional: true) + .AddCommandLine(args) .Build(); var host = new WebHostBuilder() From 5ca023fa1a464cf7a455f4d879cd528be250bdbd Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 7 Jun 2018 19:34:54 +0000 Subject: [PATCH 33/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 68 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 4566a170ed..b1220cd824 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,48 +3,48 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17067 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 - 2.2.0-preview1-34373 + 2.2.0-preview1-17081 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 + 2.2.0-preview1-34411 2.0.0 2.1.0 - 2.2.0-preview1-26531-03 + 2.2.0-preview1-26606-01 1.0.1 15.6.1 4.7.49 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26531-03 - 4.6.0-preview1-26531-03 - 1.7.0-preview1-26531-03 - 4.6.0-preview1-26531-03 + 4.6.0-preview1-26605-01 + 4.6.0-preview1-26605-01 + 1.7.0-preview1-26605-01 + 4.6.0-preview1-26605-01 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 2dedb9dd4c..9592880b2a 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17075 -commithash:d9f07c7f313a0af1d49f003f5424b4dbbdd3e09f +version:2.2.0-preview1-17081 +commithash:73f09c256e2a54270951562ecc0ef4a953926c36 From 9983831ef5c3a9e5ed93d78cebe27bc9d14340a8 Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Thu, 7 Jun 2018 15:44:53 -0700 Subject: [PATCH 34/70] Adding VSTS file --- .vsts-pipelines/builds/ci-internal.yml | 13 +++++++++++++ .vsts-pipelines/builds/ci-public.yml | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .vsts-pipelines/builds/ci-internal.yml create mode 100644 .vsts-pipelines/builds/ci-public.yml diff --git a/.vsts-pipelines/builds/ci-internal.yml b/.vsts-pipelines/builds/ci-internal.yml new file mode 100644 index 0000000000..d7ceb76378 --- /dev/null +++ b/.vsts-pipelines/builds/ci-internal.yml @@ -0,0 +1,13 @@ +trigger: +- dev +- release/* + +resources: + repositories: + - repository: buildtools + type: git + name: aspnet-BuildTools + ref: refs/heads/dev + +phases: +- template: .vsts-pipelines/templates/project-ci.yml@buildtools diff --git a/.vsts-pipelines/builds/ci-public.yml b/.vsts-pipelines/builds/ci-public.yml new file mode 100644 index 0000000000..b7f25723f8 --- /dev/null +++ b/.vsts-pipelines/builds/ci-public.yml @@ -0,0 +1,15 @@ +trigger: +- dev +- release/* + +# See https://github.com/aspnet/BuildTools +resources: + repositories: + - repository: buildtools + type: github + endpoint: DotNet-Bot GitHub Connection + name: aspnet/BuildTools + ref: refs/heads/dev + +phases: +- template: .vsts-pipelines/templates/project-ci.yml@buildtools From c5de0e1892748302ade3e902a04b456857b0e61a Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Mon, 11 Jun 2018 15:09:58 -0700 Subject: [PATCH 35/70] Pass timeout to WaitForExit() on "dotnet publish" (#1453) * Addresses https://github.com/aspnet/Hosting/issues/1451 --- .../Deployers/ApplicationDeployer.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs index a9212b0d54..999b9c788c 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs @@ -127,11 +127,27 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting hostProcess.StartAndCaptureOutAndErrToLogger("dotnet-publish", Logger); - hostProcess.WaitForExit(); - - if (hostProcess.ExitCode != 0) + // A timeout is passed to Process.WaitForExit() for two reasons: + // + // 1. When process output is read asynchronously, WaitForExit() without a timeout blocks until child processes + // are killed, which can cause hangs due to MSBuild NodeReuse child processes started by dotnet.exe. + // With a timeout, WaitForExit() returns when the parent process is killed and ignores child processes. + // https://stackoverflow.com/a/37983587/102052 + // + // 2. If "dotnet publish" does hang indefinitely for some reason, tests should fail fast with an error message. + const int timeoutMinutes = 5; + if (hostProcess.WaitForExit(milliseconds: timeoutMinutes * 60 * 1000)) { - var message = $"{DotnetCommandName} publish exited with exit code : {hostProcess.ExitCode}"; + if (hostProcess.ExitCode != 0) + { + var message = $"{DotnetCommandName} publish exited with exit code : {hostProcess.ExitCode}"; + Logger.LogError(message); + throw new Exception(message); + } + } + else + { + var message = $"{DotnetCommandName} publish failed to exit after {timeoutMinutes} minutes"; Logger.LogError(message); throw new Exception(message); } From 8672b1b04a9abc44377a5eac2b89d2fdeb7f0004 Mon Sep 17 00:00:00 2001 From: Henk Mollema Date: Sat, 16 Jun 2018 12:18:48 +0200 Subject: [PATCH 36/70] Inherit web IHostingEnvironment and IApplicationEnvironment from the Generic Host one (#1461) --- .../IApplicationLifetime.cs | 25 +------------------ .../IHostingEnvironment.cs | 24 +----------------- .../Internal/ApplicationLifetime.cs | 2 +- .../Internal/HostingEnvironment.cs | 2 +- 4 files changed, 4 insertions(+), 49 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs b/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs index f4613dd7d9..cba94f40fe 100644 --- a/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs +++ b/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs @@ -8,30 +8,7 @@ namespace Microsoft.AspNetCore.Hosting /// /// Allows consumers to perform cleanup during a graceful shutdown. /// - public interface IApplicationLifetime + public interface IApplicationLifetime : Extensions.Hosting.IApplicationLifetime { - /// - /// Triggered when the application host has fully started and is about to wait - /// for a graceful shutdown. - /// - CancellationToken ApplicationStarted { get; } - - /// - /// Triggered when the application host is performing a graceful shutdown. - /// Requests may still be in flight. Shutdown will block until this event completes. - /// - CancellationToken ApplicationStopping { get; } - - /// - /// Triggered when the application host is performing a graceful shutdown. - /// All requests should be complete at this point. Shutdown will block - /// until this event completes. - /// - CancellationToken ApplicationStopped { get; } - - /// - /// Requests termination of the current application. - /// - void StopApplication(); } } diff --git a/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs b/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs index 5feeb38eb7..8278ba9f85 100644 --- a/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs +++ b/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs @@ -8,20 +8,8 @@ namespace Microsoft.AspNetCore.Hosting /// /// Provides information about the web hosting environment an application is running in. /// - public interface IHostingEnvironment + public interface IHostingEnvironment : Extensions.Hosting.IHostingEnvironment { - /// - /// Gets or sets the name of the environment. The host automatically sets this property to the value - /// of the "ASPNETCORE_ENVIRONMENT" environment variable, or "environment" as specified in any other configuration source. - /// - string EnvironmentName { get; set; } - - /// - /// Gets or sets the name of the application. This property is automatically set by the host to the assembly containing - /// the application entry point. - /// - string ApplicationName { get; set; } - /// /// Gets or sets the absolute path to the directory that contains the web-servable application content files. /// @@ -31,15 +19,5 @@ namespace Microsoft.AspNetCore.Hosting /// Gets or sets an pointing at . ///
IFileProvider WebRootFileProvider { get; set; } - - /// - /// Gets or sets the absolute path to the directory that contains the application content files. - /// - string ContentRootPath { get; set; } - - /// - /// Gets or sets an pointing at . - /// - IFileProvider ContentRootFileProvider { get; set; } } } diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs b/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs index 958f8b5dcc..47d16e9654 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal /// /// Allows consumers to perform cleanup during a graceful shutdown. /// - public class ApplicationLifetime : IApplicationLifetime, Extensions.Hosting.IApplicationLifetime + public class ApplicationLifetime : IApplicationLifetime { private readonly CancellationTokenSource _startedSource = new CancellationTokenSource(); private readonly CancellationTokenSource _stoppingSource = new CancellationTokenSource(); diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs b/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs index 1f8d1887d7..34924ab365 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.FileProviders; namespace Microsoft.AspNetCore.Hosting.Internal { - public class HostingEnvironment : IHostingEnvironment, Extensions.Hosting.IHostingEnvironment + public class HostingEnvironment : IHostingEnvironment { public string EnvironmentName { get; set; } = Hosting.EnvironmentName.Production; From cfab182399e2a22f3e6d87a8875396fced6078c8 Mon Sep 17 00:00:00 2001 From: Henk Mollema Date: Mon, 18 Jun 2018 19:47:17 +0200 Subject: [PATCH 37/70] Revert "Inherit web IHostingEnvironment and IApplicationEnvironment from the Generic Host one (#1461)" (#1467) This reverts commit 8672b1b04a9abc44377a5eac2b89d2fdeb7f0004. --- .../IApplicationLifetime.cs | 25 ++++++++++++++++++- .../IHostingEnvironment.cs | 24 +++++++++++++++++- .../Internal/ApplicationLifetime.cs | 2 +- .../Internal/HostingEnvironment.cs | 2 +- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs b/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs index cba94f40fe..f4613dd7d9 100644 --- a/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs +++ b/src/Microsoft.AspNetCore.Hosting.Abstractions/IApplicationLifetime.cs @@ -8,7 +8,30 @@ namespace Microsoft.AspNetCore.Hosting /// /// Allows consumers to perform cleanup during a graceful shutdown. /// - public interface IApplicationLifetime : Extensions.Hosting.IApplicationLifetime + public interface IApplicationLifetime { + /// + /// Triggered when the application host has fully started and is about to wait + /// for a graceful shutdown. + /// + CancellationToken ApplicationStarted { get; } + + /// + /// Triggered when the application host is performing a graceful shutdown. + /// Requests may still be in flight. Shutdown will block until this event completes. + /// + CancellationToken ApplicationStopping { get; } + + /// + /// Triggered when the application host is performing a graceful shutdown. + /// All requests should be complete at this point. Shutdown will block + /// until this event completes. + /// + CancellationToken ApplicationStopped { get; } + + /// + /// Requests termination of the current application. + /// + void StopApplication(); } } diff --git a/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs b/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs index 8278ba9f85..5feeb38eb7 100644 --- a/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs +++ b/src/Microsoft.AspNetCore.Hosting.Abstractions/IHostingEnvironment.cs @@ -8,8 +8,20 @@ namespace Microsoft.AspNetCore.Hosting /// /// Provides information about the web hosting environment an application is running in. /// - public interface IHostingEnvironment : Extensions.Hosting.IHostingEnvironment + public interface IHostingEnvironment { + /// + /// Gets or sets the name of the environment. The host automatically sets this property to the value + /// of the "ASPNETCORE_ENVIRONMENT" environment variable, or "environment" as specified in any other configuration source. + /// + string EnvironmentName { get; set; } + + /// + /// Gets or sets the name of the application. This property is automatically set by the host to the assembly containing + /// the application entry point. + /// + string ApplicationName { get; set; } + /// /// Gets or sets the absolute path to the directory that contains the web-servable application content files. /// @@ -19,5 +31,15 @@ namespace Microsoft.AspNetCore.Hosting /// Gets or sets an pointing at . ///
IFileProvider WebRootFileProvider { get; set; } + + /// + /// Gets or sets the absolute path to the directory that contains the application content files. + /// + string ContentRootPath { get; set; } + + /// + /// Gets or sets an pointing at . + /// + IFileProvider ContentRootFileProvider { get; set; } } } diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs b/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs index 47d16e9654..958f8b5dcc 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/ApplicationLifetime.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal /// /// Allows consumers to perform cleanup during a graceful shutdown. /// - public class ApplicationLifetime : IApplicationLifetime + public class ApplicationLifetime : IApplicationLifetime, Extensions.Hosting.IApplicationLifetime { private readonly CancellationTokenSource _startedSource = new CancellationTokenSource(); private readonly CancellationTokenSource _stoppingSource = new CancellationTokenSource(); diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs b/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs index 34924ab365..1f8d1887d7 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/HostingEnvironment.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.FileProviders; namespace Microsoft.AspNetCore.Hosting.Internal { - public class HostingEnvironment : IHostingEnvironment + public class HostingEnvironment : IHostingEnvironment, Extensions.Hosting.IHostingEnvironment { public string EnvironmentName { get; set; } = Hosting.EnvironmentName.Production; From 2a98db6a73512b8e36f55a1e6678461c34f4cc4d Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Mon, 25 Jun 2018 11:14:55 -0700 Subject: [PATCH 38/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 68 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index b1220cd824..b78e93abea 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,48 +3,48 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17081 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 - 2.2.0-preview1-34411 + 2.2.0-preview1-17090 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 + 2.2.0-preview1-34530 2.0.0 2.1.0 - 2.2.0-preview1-26606-01 + 2.2.0-preview1-26618-02 1.0.1 15.6.1 4.7.49 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26605-01 - 4.6.0-preview1-26605-01 - 1.7.0-preview1-26605-01 - 4.6.0-preview1-26605-01 + 4.6.0-preview1-26617-01 + 4.6.0-preview1-26617-01 + 1.7.0-preview1-26617-01 + 4.6.0-preview1-26617-01 2.3.1 2.4.0-beta.1.build3945 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 9592880b2a..3e694b2ed8 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17081 -commithash:73f09c256e2a54270951562ecc0ef4a953926c36 +version:2.2.0-preview1-17090 +commithash:b19e903e946579cd9482089bce7d917e8bacd765 From 5fd60d68b6fb30b9de9a639ae07fa9ac42babd22 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 28 Jun 2018 16:19:48 -0700 Subject: [PATCH 39/70] Update infrastructure for the 2.2 release --- .vsts-pipelines/builds/ci-internal.yml | 4 ++-- .vsts-pipelines/builds/ci-public.yml | 6 +++--- build/repo.props | 1 + korebuild.json | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.vsts-pipelines/builds/ci-internal.yml b/.vsts-pipelines/builds/ci-internal.yml index d7ceb76378..dc7b8a3cb9 100644 --- a/.vsts-pipelines/builds/ci-internal.yml +++ b/.vsts-pipelines/builds/ci-internal.yml @@ -1,5 +1,5 @@ trigger: -- dev +- master - release/* resources: @@ -7,7 +7,7 @@ resources: - repository: buildtools type: git name: aspnet-BuildTools - ref: refs/heads/dev + ref: refs/heads/release/2.2 phases: - template: .vsts-pipelines/templates/project-ci.yml@buildtools diff --git a/.vsts-pipelines/builds/ci-public.yml b/.vsts-pipelines/builds/ci-public.yml index b7f25723f8..f5087d9c30 100644 --- a/.vsts-pipelines/builds/ci-public.yml +++ b/.vsts-pipelines/builds/ci-public.yml @@ -1,5 +1,5 @@ trigger: -- dev +- master - release/* # See https://github.com/aspnet/BuildTools @@ -9,7 +9,7 @@ resources: type: github endpoint: DotNet-Bot GitHub Connection name: aspnet/BuildTools - ref: refs/heads/dev - + ref: refs/heads/release/2.2 + phases: - template: .vsts-pipelines/templates/project-ci.yml@buildtools diff --git a/build/repo.props b/build/repo.props index d115087735..d6a2be7fc5 100644 --- a/build/repo.props +++ b/build/repo.props @@ -8,6 +8,7 @@ Internal.AspNetCore.Universe.Lineup + 2.2.0-* https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json diff --git a/korebuild.json b/korebuild.json index bd5d51a51b..d217d06e3e 100644 --- a/korebuild.json +++ b/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.2/tools/korebuild.schema.json", + "channel": "release/2.2" } From 68dc961abbf6f24e75dfe9a16b8541f671967326 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 8 Jul 2018 12:13:44 -0700 Subject: [PATCH 40/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 64 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index b78e93abea..2f4eb5da86 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,37 +3,37 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17090 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.2.0-preview1-34530 - 2.0.0 - 2.1.0 + 2.2.0-preview1-17099 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.2.0-preview1-34640 + 2.0.7 + 2.1.1 2.2.0-preview1-26618-02 1.0.1 15.6.1 @@ -46,7 +46,7 @@ 1.7.0-preview1-26617-01 4.6.0-preview1-26617-01 2.3.1 - 2.4.0-beta.1.build3945 + 2.4.0-rc.1.build4038 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 3e694b2ed8..8b9d17825f 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17090 -commithash:b19e903e946579cd9482089bce7d917e8bacd765 +version:2.2.0-preview1-17099 +commithash:263ed1db9866b6b419b1f5d5189a712aa218acb3 From 51c94337d7755dc4970da77f2ee12285da176d86 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 10 Jul 2018 11:29:39 -0700 Subject: [PATCH 41/70] /systray:false (#1486) --- .../Deployers/IISExpressDeployer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs index 1bdc58ec8a..8a2cc6cf1d 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -151,8 +151,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting PrepareConfig(contentRoot, dllRoot, port); var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ? - string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) : - string.Format("/site:{0} /config:{1} /trace:error", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); + string.Format("/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) : + string.Format("/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); var iisExpressPath = GetIISExpressPath(); From 9149f5e4cfe309711ec61b5c6cc5dd5940d5b287 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 15 Jul 2018 12:13:31 -0700 Subject: [PATCH 42/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 2f4eb5da86..e4f620952e 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,36 +4,36 @@ 2.2.0-preview1-17099 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.2.0-preview1-34640 - 2.0.7 - 2.1.1 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.2.0-preview1-34694 + 2.0.9 + 2.1.2 2.2.0-preview1-26618-02 1.0.1 15.6.1 @@ -41,10 +41,10 @@ 2.0.3 1.4.0 3.2.0 - 4.6.0-preview1-26617-01 - 4.6.0-preview1-26617-01 - 1.7.0-preview1-26617-01 - 4.6.0-preview1-26617-01 + 4.5.0 + 4.5.0 + 1.6.0 + 4.5.0 2.3.1 2.4.0-rc.1.build4038 From ec0b7ab2cd6c351199ba7956fbc3a93d9f70923f Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 17 Jul 2018 10:16:50 -0700 Subject: [PATCH 43/70] Remove IISExpress deployer (#1493) --- .../Common/DotNetCommands.cs | 8 +- .../Common/TestUriHelper.cs | 9 +- .../Deployers/ApplicationDeployerFactory.cs | 3 +- .../Deployers/IISExpressDeployer.cs | 436 ------------------ 4 files changed, 8 insertions(+), 448 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs index d9f5577056..51414544c0 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs @@ -7,14 +7,14 @@ using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Server.IntegrationTesting { - internal static class DotNetCommands + public static class DotNetCommands { private const string _dotnetFolderName = ".dotnet"; internal static string DotNetHome { get; } = GetDotNetHome(); // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76 - private static string GetDotNetHome() + public static string GetDotNetHome() { var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME"); var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return result; } - internal static string GetDotNetInstallDir(RuntimeArchitecture arch) + public static string GetDotNetInstallDir(RuntimeArchitecture arch) { var dotnetDir = DotNetHome; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return dotnetDir; } - internal static string GetDotNetExecutable(RuntimeArchitecture arch) + public static string GetDotNetExecutable(RuntimeArchitecture arch) { var dotnetDir = GetDotNetInstallDir(arch); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index 1c09b08dfa..5a79a31cef 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -2,19 +2,16 @@ // 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.AspNetCore.Server.IntegrationTesting.Common { - internal static class TestUriHelper + public static class TestUriHelper { - internal static Uri BuildTestUri(ServerType serverType) + public static Uri BuildTestUri(ServerType serverType) { return BuildTestUri(serverType, hint: null); } - internal static Uri BuildTestUri(ServerType serverType, string hint) + public static Uri BuildTestUri(ServerType serverType, string hint) { // Assume status messages are enabled for Kestrel and disabled for all other servers. var statusMessagesEnabled = (serverType == ServerType.Kestrel); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs index 76f3588dd9..959f4ffeed 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs @@ -32,9 +32,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting switch (deploymentParameters.ServerType) { case ServerType.IISExpress: - return new IISExpressDeployer(deploymentParameters, loggerFactory); case ServerType.IIS: - throw new NotSupportedException("The IIS deployer is no longer supported"); + throw new NotSupportedException("Use Microsoft.AspNetCore.Server.IntegrationTesting.IIS package and IISApplicationDeployerFactory for IIS support."); case ServerType.HttpSys: case ServerType.Kestrel: return new SelfHostDeployer(deploymentParameters, loggerFactory); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs deleted file mode 100644 index 8a2cc6cf1d..0000000000 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ /dev/null @@ -1,436 +0,0 @@ -// 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.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.AspNetCore.Server.IntegrationTesting.Common; -using Microsoft.AspNetCore.Testing; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Server.IntegrationTesting -{ - /// - /// Deployment helper for IISExpress. - /// - public class IISExpressDeployer : ApplicationDeployer - { - private const string IISExpressRunningMessage = "IIS Express is running."; - private const string FailedToInitializeBindingsMessage = "Failed to initialize site bindings"; - private const string UnableToStartIISExpressMessage = "Unable to start iisexpress."; - private const int MaximumAttempts = 5; - - private static readonly Regex UrlDetectorRegex = new Regex(@"^\s*Successfully registered URL ""(?[^""]+)"" for site.*$"); - - private Process _hostProcess; - - public IISExpressDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) - : base(deploymentParameters, loggerFactory) - { - } - - public override async Task DeployAsync() - { - using (Logger.BeginScope("Deployment")) - { - // Start timer - StartTimer(); - - // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/net461/ - // and contentRoot points to the project directory so you get things like static assets. - // For a published app both point to the publish directory. - var dllRoot = CheckIfPublishIsRequired(); - var contentRoot = string.Empty; - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - DotnetPublish(); - contentRoot = DeploymentParameters.PublishedApplicationRootPath; - dllRoot = contentRoot; - } - else - { - // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable. - // Update processPath and arguments for our current scenario - contentRoot = DeploymentParameters.ApplicationPath; - - var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ".exe"; - var entryPoint = Path.Combine(dllRoot, DeploymentParameters.ApplicationName + executableExtension); - - var executableName = string.Empty; - var executableArgs = string.Empty; - - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) - { - executableName = GetDotNetExeForArchitecture(); - executableArgs = entryPoint; - } - else - { - executableName = entryPoint; - } - - Logger.LogInformation("Executing: {exe} {args}", executableName, executableArgs); - DeploymentParameters.EnvironmentVariables["LAUNCHER_PATH"] = executableName; - DeploymentParameters.EnvironmentVariables["LAUNCHER_ARGS"] = executableArgs; - - // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead. - Logger.LogInformation("ContentRoot: {path}", DeploymentParameters.ApplicationPath); - DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath; - } - - var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint); - - // Launch the host process. - var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot, dllRoot); - - Logger.LogInformation("Application ready at URL: {appUrl}", actualUri); - - // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath. - return new DeploymentResult( - LoggerFactory, - DeploymentParameters, - applicationBaseUri: actualUri.ToString(), - contentRoot: contentRoot, - hostShutdownToken: hostExitToken); - } - } - - private string CheckIfPublishIsRequired() - { - var targetFramework = DeploymentParameters.TargetFramework; - - // IISIntegration uses this layout - var dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.RuntimeArchitecture.ToString(), - DeploymentParameters.Configuration, targetFramework); - - if (!Directory.Exists(dllRoot)) - { - // Most repos use this layout - dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework); - - if (!Directory.Exists(dllRoot)) - { - // The bits we need weren't pre-compiled, compile on publish - DeploymentParameters.PublishApplicationBeforeDeployment = true; - } - else if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr - && DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) - { - // x64 is the default. Publish to rebuild for the right bitness - DeploymentParameters.PublishApplicationBeforeDeployment = true; - } - } - - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr - && DeploymentParameters.ApplicationType == ApplicationType.Standalone) - { - // Publish is always required to get the correct standalone files in the output directory - DeploymentParameters.PublishApplicationBeforeDeployment = true; - } - - return dllRoot; - } - - private async Task<(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot, string dllRoot) - { - using (Logger.BeginScope("StartIISExpress")) - { - var port = uri.Port; - if (port == 0) - { - port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort(); - } - - Logger.LogInformation("Attempting to start IIS Express on port: {port}", port); - PrepareConfig(contentRoot, dllRoot, port); - - var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ? - string.Format("/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) : - string.Format("/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); - - var iisExpressPath = GetIISExpressPath(); - - for (var attempt = 0; attempt < MaximumAttempts; attempt++) - { - Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters); - - var startInfo = new ProcessStartInfo - { - FileName = iisExpressPath, - Arguments = parameters, - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardError = true, - RedirectStandardOutput = true - }; - - AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables); - - Uri url = null; - var started = new TaskCompletionSource(); - - var process = new Process() { StartInfo = startInfo }; - process.OutputDataReceived += (sender, dataArgs) => - { - if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage)) - { - // We completely failed to start and we don't really know why - started.TrySetException(new InvalidOperationException("Failed to start IIS Express")); - } - else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage)) - { - started.TrySetResult(false); - } - else if (string.Equals(dataArgs.Data, IISExpressRunningMessage)) - { - started.TrySetResult(true); - } - else if (!string.IsNullOrEmpty(dataArgs.Data)) - { - var m = UrlDetectorRegex.Match(dataArgs.Data); - if (m.Success) - { - url = new Uri(m.Groups["url"].Value); - } - } - }; - - process.EnableRaisingEvents = true; - var hostExitTokenSource = new CancellationTokenSource(); - process.Exited += (sender, e) => - { - Logger.LogInformation("iisexpress Process {pid} shut down", process.Id); - - // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want - started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}")); - - TriggerHostShutdown(hostExitTokenSource); - }; - process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger); - Logger.LogInformation("iisexpress Process {pid} started", process.Id); - - if (process.HasExited) - { - Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode); - throw new Exception("Failed to start host"); - } - - // Wait for the app to start - // The timeout here is large, because we don't know how long the test could need - // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build - // just in case we missed one -anurse - if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10))) - { - Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port); - - // Wait for the process to exit and try again - process.WaitForExit(30 * 1000); - await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up - } - else - { - _hostProcess = process; - Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port); - return (url: url, hostExitToken: hostExitTokenSource.Token); - } - } - - var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port"; - Logger.LogError(message); - throw new TimeoutException(message); - } - } - - private void PrepareConfig(string contentRoot, string dllRoot, int port) - { - // Config is required. If not present then fall back to one we carry with us. - if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent)) - { - using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.AspNetCore.Server.IntegrationTesting.Http.config")) - using (var reader = new StreamReader(stream)) - { - DeploymentParameters.ServerConfigTemplateContent = reader.ReadToEnd(); - } - } - - var serverConfig = DeploymentParameters.ServerConfigTemplateContent; - - // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config - // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. - serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, dllRoot); - serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, dllRoot); - - serverConfig = ReplacePlaceholder(serverConfig, "[PORT]", port.ToString(CultureInfo.InvariantCulture)); - serverConfig = ReplacePlaceholder(serverConfig, "[ApplicationPhysicalPath]", contentRoot); - - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - // For published apps, prefer the content in the web.config, but update it. - ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", - value: DeploymentParameters.HostingModel == HostingModel.InProcess ? "inprocess" : ""); - ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); - ModifyDotNetExePathInWebConfig(); - serverConfig = RemoveRedundantElements(serverConfig); - } - else - { - // The elements normally in the web.config are in the applicationhost.config for unpublished apps. - serverConfig = ReplacePlaceholder(serverConfig, "[HostingModel]", DeploymentParameters.HostingModel.ToString()); - serverConfig = ReplacePlaceholder(serverConfig, "[AspNetCoreModule]", DeploymentParameters.AncmVersion.ToString()); - } - - DeploymentParameters.ServerConfigLocation = Path.GetTempFileName(); - Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation); - - File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig); - } - - private string ReplacePlaceholder(string content, string field, string value) - { - if (content.Contains(field)) - { - content = content.Replace(field, value); - Logger.LogDebug("Writing {field} '{value}' to config", field, value); - } - return content; - } - - private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string dllRoot) - { - if (serverConfig.Contains(replaceFlag)) - { - var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}"; - var ancmFile = Path.Combine(dllRoot, arch); - if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) - { - ancmFile = Path.Combine(dllRoot, dllName); - if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) - { - throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); - } - } - - Logger.LogDebug($"Writing '{replaceFlag}' '{ancmFile}' to config"); - return serverConfig.Replace(replaceFlag, ancmFile); - } - return serverConfig; - } - - private string GetIISExpressPath() - { - var programFiles = "Program Files"; - if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) - { - programFiles = "Program Files (x86)"; - } - - // Get path to program files - var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", programFiles, "IIS Express", "iisexpress.exe"); - - if (!File.Exists(iisExpressPath)) - { - throw new Exception("Unable to find IISExpress on the machine: " + iisExpressPath); - } - - return iisExpressPath; - } - - public override void Dispose() - { - using (Logger.BeginScope("Dispose")) - { - ShutDownIfAnyHostProcess(_hostProcess); - - if (!string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) - && File.Exists(DeploymentParameters.ServerConfigLocation)) - { - // Delete the temp applicationHostConfig that we created. - Logger.LogDebug("Deleting applicationHost.config file from {configLocation}", DeploymentParameters.ServerConfigLocation); - try - { - File.Delete(DeploymentParameters.ServerConfigLocation); - } - catch (Exception exception) - { - // Ignore delete failures - just write a log. - Logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", DeploymentParameters.ServerConfigLocation, exception.Message); - } - } - - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - CleanPublishedOutput(); - } - - InvokeUserApplicationCleanup(); - - StopTimer(); - } - - // If by this point, the host process is still running (somehow), throw an error. - // A test failure is better than a silent hang and unknown failure later on - if (_hostProcess != null && !_hostProcess.HasExited) - { - throw new Exception($"iisexpress Process {_hostProcess.Id} failed to shutdown"); - } - } - - private void ModifyDotNetExePathInWebConfig() - { - // We assume the x64 dotnet.exe is on the path so we need to provide an absolute path for x86 scenarios. - // Only do it for scenarios that rely on dotnet.exe (Core, portable, etc.). - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr - && DeploymentParameters.ApplicationType == ApplicationType.Portable - && DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) - { - var executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); - if (!File.Exists(executableName)) - { - throw new Exception($"Unable to find '{executableName}'.'"); - } - ModifyAspNetCoreSectionInWebConfig("processPath", executableName); - } - } - - // Transforms the web.config file to set attributes like hostingModel="inprocess" element - private void ModifyAspNetCoreSectionInWebConfig(string key, string value) - { - var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); - var config = XDocument.Load(webConfigFile); - var element = config.Descendants("aspNetCore").FirstOrDefault(); - element.SetAttributeValue(key, value); - config.Save(webConfigFile); - } - - private void ModifyHandlerSectionInWebConfig(string key, string value) - { - var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); - var config = XDocument.Load(webConfigFile); - var element = config.Descendants("handlers").FirstOrDefault().Descendants("add").FirstOrDefault(); - element.SetAttributeValue(key, value); - config.Save(webConfigFile); - } - - // These elements are duplicated in the web.config if you publish. Remove them from the host.config. - private string RemoveRedundantElements(string serverConfig) - { - var hostConfig = XDocument.Parse(serverConfig); - - var coreElement = hostConfig.Descendants("aspNetCore").FirstOrDefault(); - coreElement?.Remove(); - - var handlersElement = hostConfig.Descendants("handlers").First(); - var handlerElement = handlersElement.Descendants("add") - .Where(x => x.Attribute("name").Value == "aspNetCore").FirstOrDefault(); - handlerElement?.Remove(); - - return hostConfig.ToString(); - } - } -} From 65f8cfc55b3591ed52ecf6342e919c9443b9d835 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 17 Jul 2018 12:07:42 -0700 Subject: [PATCH 44/70] Revert "Remove IISExpress deployer (#1493)" This reverts commit ec0b7ab2cd6c351199ba7956fbc3a93d9f70923f. --- .../Common/DotNetCommands.cs | 8 +- .../Common/TestUriHelper.cs | 9 +- .../Deployers/ApplicationDeployerFactory.cs | 3 +- .../Deployers/IISExpressDeployer.cs | 436 ++++++++++++++++++ 4 files changed, 448 insertions(+), 8 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs index 51414544c0..d9f5577056 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs @@ -7,14 +7,14 @@ using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Server.IntegrationTesting { - public static class DotNetCommands + internal static class DotNetCommands { private const string _dotnetFolderName = ".dotnet"; internal static string DotNetHome { get; } = GetDotNetHome(); // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76 - public static string GetDotNetHome() + private static string GetDotNetHome() { var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME"); var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return result; } - public static string GetDotNetInstallDir(RuntimeArchitecture arch) + internal static string GetDotNetInstallDir(RuntimeArchitecture arch) { var dotnetDir = DotNetHome; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return dotnetDir; } - public static string GetDotNetExecutable(RuntimeArchitecture arch) + internal static string GetDotNetExecutable(RuntimeArchitecture arch) { var dotnetDir = GetDotNetInstallDir(arch); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index 5a79a31cef..1c09b08dfa 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -2,16 +2,19 @@ // 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.AspNetCore.Server.IntegrationTesting.Common { - public static class TestUriHelper + internal static class TestUriHelper { - public static Uri BuildTestUri(ServerType serverType) + internal static Uri BuildTestUri(ServerType serverType) { return BuildTestUri(serverType, hint: null); } - public static Uri BuildTestUri(ServerType serverType, string hint) + internal static Uri BuildTestUri(ServerType serverType, string hint) { // Assume status messages are enabled for Kestrel and disabled for all other servers. var statusMessagesEnabled = (serverType == ServerType.Kestrel); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs index 959f4ffeed..76f3588dd9 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs @@ -32,8 +32,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting switch (deploymentParameters.ServerType) { case ServerType.IISExpress: + return new IISExpressDeployer(deploymentParameters, loggerFactory); case ServerType.IIS: - throw new NotSupportedException("Use Microsoft.AspNetCore.Server.IntegrationTesting.IIS package and IISApplicationDeployerFactory for IIS support."); + throw new NotSupportedException("The IIS deployer is no longer supported"); case ServerType.HttpSys: case ServerType.Kestrel: return new SelfHostDeployer(deploymentParameters, loggerFactory); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs new file mode 100644 index 0000000000..8a2cc6cf1d --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs @@ -0,0 +1,436 @@ +// 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.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IntegrationTesting.Common; +using Microsoft.AspNetCore.Testing; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + /// + /// Deployment helper for IISExpress. + /// + public class IISExpressDeployer : ApplicationDeployer + { + private const string IISExpressRunningMessage = "IIS Express is running."; + private const string FailedToInitializeBindingsMessage = "Failed to initialize site bindings"; + private const string UnableToStartIISExpressMessage = "Unable to start iisexpress."; + private const int MaximumAttempts = 5; + + private static readonly Regex UrlDetectorRegex = new Regex(@"^\s*Successfully registered URL ""(?[^""]+)"" for site.*$"); + + private Process _hostProcess; + + public IISExpressDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) + : base(deploymentParameters, loggerFactory) + { + } + + public override async Task DeployAsync() + { + using (Logger.BeginScope("Deployment")) + { + // Start timer + StartTimer(); + + // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/net461/ + // and contentRoot points to the project directory so you get things like static assets. + // For a published app both point to the publish directory. + var dllRoot = CheckIfPublishIsRequired(); + var contentRoot = string.Empty; + if (DeploymentParameters.PublishApplicationBeforeDeployment) + { + DotnetPublish(); + contentRoot = DeploymentParameters.PublishedApplicationRootPath; + dllRoot = contentRoot; + } + else + { + // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable. + // Update processPath and arguments for our current scenario + contentRoot = DeploymentParameters.ApplicationPath; + + var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ".exe"; + var entryPoint = Path.Combine(dllRoot, DeploymentParameters.ApplicationName + executableExtension); + + var executableName = string.Empty; + var executableArgs = string.Empty; + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) + { + executableName = GetDotNetExeForArchitecture(); + executableArgs = entryPoint; + } + else + { + executableName = entryPoint; + } + + Logger.LogInformation("Executing: {exe} {args}", executableName, executableArgs); + DeploymentParameters.EnvironmentVariables["LAUNCHER_PATH"] = executableName; + DeploymentParameters.EnvironmentVariables["LAUNCHER_ARGS"] = executableArgs; + + // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead. + Logger.LogInformation("ContentRoot: {path}", DeploymentParameters.ApplicationPath); + DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath; + } + + var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint); + + // Launch the host process. + var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot, dllRoot); + + Logger.LogInformation("Application ready at URL: {appUrl}", actualUri); + + // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath. + return new DeploymentResult( + LoggerFactory, + DeploymentParameters, + applicationBaseUri: actualUri.ToString(), + contentRoot: contentRoot, + hostShutdownToken: hostExitToken); + } + } + + private string CheckIfPublishIsRequired() + { + var targetFramework = DeploymentParameters.TargetFramework; + + // IISIntegration uses this layout + var dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.RuntimeArchitecture.ToString(), + DeploymentParameters.Configuration, targetFramework); + + if (!Directory.Exists(dllRoot)) + { + // Most repos use this layout + dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework); + + if (!Directory.Exists(dllRoot)) + { + // The bits we need weren't pre-compiled, compile on publish + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + else if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr + && DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) + { + // x64 is the default. Publish to rebuild for the right bitness + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + } + + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr + && DeploymentParameters.ApplicationType == ApplicationType.Standalone) + { + // Publish is always required to get the correct standalone files in the output directory + DeploymentParameters.PublishApplicationBeforeDeployment = true; + } + + return dllRoot; + } + + private async Task<(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot, string dllRoot) + { + using (Logger.BeginScope("StartIISExpress")) + { + var port = uri.Port; + if (port == 0) + { + port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort(); + } + + Logger.LogInformation("Attempting to start IIS Express on port: {port}", port); + PrepareConfig(contentRoot, dllRoot, port); + + var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ? + string.Format("/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) : + string.Format("/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); + + var iisExpressPath = GetIISExpressPath(); + + for (var attempt = 0; attempt < MaximumAttempts; attempt++) + { + Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters); + + var startInfo = new ProcessStartInfo + { + FileName = iisExpressPath, + Arguments = parameters, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardError = true, + RedirectStandardOutput = true + }; + + AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables); + + Uri url = null; + var started = new TaskCompletionSource(); + + var process = new Process() { StartInfo = startInfo }; + process.OutputDataReceived += (sender, dataArgs) => + { + if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage)) + { + // We completely failed to start and we don't really know why + started.TrySetException(new InvalidOperationException("Failed to start IIS Express")); + } + else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage)) + { + started.TrySetResult(false); + } + else if (string.Equals(dataArgs.Data, IISExpressRunningMessage)) + { + started.TrySetResult(true); + } + else if (!string.IsNullOrEmpty(dataArgs.Data)) + { + var m = UrlDetectorRegex.Match(dataArgs.Data); + if (m.Success) + { + url = new Uri(m.Groups["url"].Value); + } + } + }; + + process.EnableRaisingEvents = true; + var hostExitTokenSource = new CancellationTokenSource(); + process.Exited += (sender, e) => + { + Logger.LogInformation("iisexpress Process {pid} shut down", process.Id); + + // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want + started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}")); + + TriggerHostShutdown(hostExitTokenSource); + }; + process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger); + Logger.LogInformation("iisexpress Process {pid} started", process.Id); + + if (process.HasExited) + { + Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode); + throw new Exception("Failed to start host"); + } + + // Wait for the app to start + // The timeout here is large, because we don't know how long the test could need + // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build + // just in case we missed one -anurse + if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10))) + { + Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port); + + // Wait for the process to exit and try again + process.WaitForExit(30 * 1000); + await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up + } + else + { + _hostProcess = process; + Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port); + return (url: url, hostExitToken: hostExitTokenSource.Token); + } + } + + var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port"; + Logger.LogError(message); + throw new TimeoutException(message); + } + } + + private void PrepareConfig(string contentRoot, string dllRoot, int port) + { + // Config is required. If not present then fall back to one we carry with us. + if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent)) + { + using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.AspNetCore.Server.IntegrationTesting.Http.config")) + using (var reader = new StreamReader(stream)) + { + DeploymentParameters.ServerConfigTemplateContent = reader.ReadToEnd(); + } + } + + var serverConfig = DeploymentParameters.ServerConfigTemplateContent; + + // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config + // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. + serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, dllRoot); + serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, dllRoot); + + serverConfig = ReplacePlaceholder(serverConfig, "[PORT]", port.ToString(CultureInfo.InvariantCulture)); + serverConfig = ReplacePlaceholder(serverConfig, "[ApplicationPhysicalPath]", contentRoot); + + if (DeploymentParameters.PublishApplicationBeforeDeployment) + { + // For published apps, prefer the content in the web.config, but update it. + ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", + value: DeploymentParameters.HostingModel == HostingModel.InProcess ? "inprocess" : ""); + ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); + ModifyDotNetExePathInWebConfig(); + serverConfig = RemoveRedundantElements(serverConfig); + } + else + { + // The elements normally in the web.config are in the applicationhost.config for unpublished apps. + serverConfig = ReplacePlaceholder(serverConfig, "[HostingModel]", DeploymentParameters.HostingModel.ToString()); + serverConfig = ReplacePlaceholder(serverConfig, "[AspNetCoreModule]", DeploymentParameters.AncmVersion.ToString()); + } + + DeploymentParameters.ServerConfigLocation = Path.GetTempFileName(); + Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation); + + File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig); + } + + private string ReplacePlaceholder(string content, string field, string value) + { + if (content.Contains(field)) + { + content = content.Replace(field, value); + Logger.LogDebug("Writing {field} '{value}' to config", field, value); + } + return content; + } + + private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string dllRoot) + { + if (serverConfig.Contains(replaceFlag)) + { + var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}"; + var ancmFile = Path.Combine(dllRoot, arch); + if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) + { + ancmFile = Path.Combine(dllRoot, dllName); + if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) + { + throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); + } + } + + Logger.LogDebug($"Writing '{replaceFlag}' '{ancmFile}' to config"); + return serverConfig.Replace(replaceFlag, ancmFile); + } + return serverConfig; + } + + private string GetIISExpressPath() + { + var programFiles = "Program Files"; + if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) + { + programFiles = "Program Files (x86)"; + } + + // Get path to program files + var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", programFiles, "IIS Express", "iisexpress.exe"); + + if (!File.Exists(iisExpressPath)) + { + throw new Exception("Unable to find IISExpress on the machine: " + iisExpressPath); + } + + return iisExpressPath; + } + + public override void Dispose() + { + using (Logger.BeginScope("Dispose")) + { + ShutDownIfAnyHostProcess(_hostProcess); + + if (!string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) + && File.Exists(DeploymentParameters.ServerConfigLocation)) + { + // Delete the temp applicationHostConfig that we created. + Logger.LogDebug("Deleting applicationHost.config file from {configLocation}", DeploymentParameters.ServerConfigLocation); + try + { + File.Delete(DeploymentParameters.ServerConfigLocation); + } + catch (Exception exception) + { + // Ignore delete failures - just write a log. + Logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", DeploymentParameters.ServerConfigLocation, exception.Message); + } + } + + if (DeploymentParameters.PublishApplicationBeforeDeployment) + { + CleanPublishedOutput(); + } + + InvokeUserApplicationCleanup(); + + StopTimer(); + } + + // If by this point, the host process is still running (somehow), throw an error. + // A test failure is better than a silent hang and unknown failure later on + if (_hostProcess != null && !_hostProcess.HasExited) + { + throw new Exception($"iisexpress Process {_hostProcess.Id} failed to shutdown"); + } + } + + private void ModifyDotNetExePathInWebConfig() + { + // We assume the x64 dotnet.exe is on the path so we need to provide an absolute path for x86 scenarios. + // Only do it for scenarios that rely on dotnet.exe (Core, portable, etc.). + if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr + && DeploymentParameters.ApplicationType == ApplicationType.Portable + && DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) + { + var executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); + if (!File.Exists(executableName)) + { + throw new Exception($"Unable to find '{executableName}'.'"); + } + ModifyAspNetCoreSectionInWebConfig("processPath", executableName); + } + } + + // Transforms the web.config file to set attributes like hostingModel="inprocess" element + private void ModifyAspNetCoreSectionInWebConfig(string key, string value) + { + var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); + var config = XDocument.Load(webConfigFile); + var element = config.Descendants("aspNetCore").FirstOrDefault(); + element.SetAttributeValue(key, value); + config.Save(webConfigFile); + } + + private void ModifyHandlerSectionInWebConfig(string key, string value) + { + var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); + var config = XDocument.Load(webConfigFile); + var element = config.Descendants("handlers").FirstOrDefault().Descendants("add").FirstOrDefault(); + element.SetAttributeValue(key, value); + config.Save(webConfigFile); + } + + // These elements are duplicated in the web.config if you publish. Remove them from the host.config. + private string RemoveRedundantElements(string serverConfig) + { + var hostConfig = XDocument.Parse(serverConfig); + + var coreElement = hostConfig.Descendants("aspNetCore").FirstOrDefault(); + coreElement?.Remove(); + + var handlersElement = hostConfig.Descendants("handlers").First(); + var handlerElement = handlersElement.Descendants("add") + .Where(x => x.Attribute("name").Value == "aspNetCore").FirstOrDefault(); + handlerElement?.Remove(); + + return hostConfig.ToString(); + } + } +} From 19839ed3085dfde64fc93675efdcdfb8fbe87b11 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 17 Jul 2018 21:05:59 -0700 Subject: [PATCH 45/70] Revert "Merge pull request #1494 from aspnet/revert-1493-pakrym/useiis" (#1496) This reverts commit 7a0a1ee50bb426323d4209707df98bf77fbabfa1, reversing changes made to ec0b7ab2cd6c351199ba7956fbc3a93d9f70923f. --- .../Common/DotNetCommands.cs | 10 +- .../Common/TestUriHelper.cs | 9 +- .../Deployers/ApplicationDeployerFactory.cs | 3 +- .../Deployers/IISExpressDeployer.cs | 436 ------------------ 4 files changed, 9 insertions(+), 449 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs index d9f5577056..e30e9defc5 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DotNetCommands.cs @@ -7,14 +7,14 @@ using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Server.IntegrationTesting { - internal static class DotNetCommands + public static class DotNetCommands { private const string _dotnetFolderName = ".dotnet"; internal static string DotNetHome { get; } = GetDotNetHome(); // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76 - private static string GetDotNetHome() + public static string GetDotNetHome() { var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME"); var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return result; } - internal static string GetDotNetInstallDir(RuntimeArchitecture arch) + public static string GetDotNetInstallDir(RuntimeArchitecture arch) { var dotnetDir = DotNetHome; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return dotnetDir; } - internal static string GetDotNetExecutable(RuntimeArchitecture arch) + public static string GetDotNetExecutable(RuntimeArchitecture arch) { var dotnetDir = GetDotNetInstallDir(arch); @@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting return Path.Combine(dotnetDir, dotnetFile); } - internal static bool IsRunningX86OnX64(RuntimeArchitecture arch) + public static bool IsRunningX86OnX64(RuntimeArchitecture arch) { return (RuntimeInformation.OSArchitecture == Architecture.X64 || RuntimeInformation.OSArchitecture == Architecture.Arm64) && arch == RuntimeArchitecture.x86; diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs index 1c09b08dfa..5a79a31cef 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs @@ -2,19 +2,16 @@ // 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.AspNetCore.Server.IntegrationTesting.Common { - internal static class TestUriHelper + public static class TestUriHelper { - internal static Uri BuildTestUri(ServerType serverType) + public static Uri BuildTestUri(ServerType serverType) { return BuildTestUri(serverType, hint: null); } - internal static Uri BuildTestUri(ServerType serverType, string hint) + public static Uri BuildTestUri(ServerType serverType, string hint) { // Assume status messages are enabled for Kestrel and disabled for all other servers. var statusMessagesEnabled = (serverType == ServerType.Kestrel); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs index 76f3588dd9..959f4ffeed 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployerFactory.cs @@ -32,9 +32,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting switch (deploymentParameters.ServerType) { case ServerType.IISExpress: - return new IISExpressDeployer(deploymentParameters, loggerFactory); case ServerType.IIS: - throw new NotSupportedException("The IIS deployer is no longer supported"); + throw new NotSupportedException("Use Microsoft.AspNetCore.Server.IntegrationTesting.IIS package and IISApplicationDeployerFactory for IIS support."); case ServerType.HttpSys: case ServerType.Kestrel: return new SelfHostDeployer(deploymentParameters, loggerFactory); diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs deleted file mode 100644 index 8a2cc6cf1d..0000000000 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/IISExpressDeployer.cs +++ /dev/null @@ -1,436 +0,0 @@ -// 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.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.AspNetCore.Server.IntegrationTesting.Common; -using Microsoft.AspNetCore.Testing; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Server.IntegrationTesting -{ - /// - /// Deployment helper for IISExpress. - /// - public class IISExpressDeployer : ApplicationDeployer - { - private const string IISExpressRunningMessage = "IIS Express is running."; - private const string FailedToInitializeBindingsMessage = "Failed to initialize site bindings"; - private const string UnableToStartIISExpressMessage = "Unable to start iisexpress."; - private const int MaximumAttempts = 5; - - private static readonly Regex UrlDetectorRegex = new Regex(@"^\s*Successfully registered URL ""(?[^""]+)"" for site.*$"); - - private Process _hostProcess; - - public IISExpressDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) - : base(deploymentParameters, loggerFactory) - { - } - - public override async Task DeployAsync() - { - using (Logger.BeginScope("Deployment")) - { - // Start timer - StartTimer(); - - // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/net461/ - // and contentRoot points to the project directory so you get things like static assets. - // For a published app both point to the publish directory. - var dllRoot = CheckIfPublishIsRequired(); - var contentRoot = string.Empty; - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - DotnetPublish(); - contentRoot = DeploymentParameters.PublishedApplicationRootPath; - dllRoot = contentRoot; - } - else - { - // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable. - // Update processPath and arguments for our current scenario - contentRoot = DeploymentParameters.ApplicationPath; - - var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ".exe"; - var entryPoint = Path.Combine(dllRoot, DeploymentParameters.ApplicationName + executableExtension); - - var executableName = string.Empty; - var executableArgs = string.Empty; - - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable) - { - executableName = GetDotNetExeForArchitecture(); - executableArgs = entryPoint; - } - else - { - executableName = entryPoint; - } - - Logger.LogInformation("Executing: {exe} {args}", executableName, executableArgs); - DeploymentParameters.EnvironmentVariables["LAUNCHER_PATH"] = executableName; - DeploymentParameters.EnvironmentVariables["LAUNCHER_ARGS"] = executableArgs; - - // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead. - Logger.LogInformation("ContentRoot: {path}", DeploymentParameters.ApplicationPath); - DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath; - } - - var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint); - - // Launch the host process. - var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot, dllRoot); - - Logger.LogInformation("Application ready at URL: {appUrl}", actualUri); - - // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath. - return new DeploymentResult( - LoggerFactory, - DeploymentParameters, - applicationBaseUri: actualUri.ToString(), - contentRoot: contentRoot, - hostShutdownToken: hostExitToken); - } - } - - private string CheckIfPublishIsRequired() - { - var targetFramework = DeploymentParameters.TargetFramework; - - // IISIntegration uses this layout - var dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.RuntimeArchitecture.ToString(), - DeploymentParameters.Configuration, targetFramework); - - if (!Directory.Exists(dllRoot)) - { - // Most repos use this layout - dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework); - - if (!Directory.Exists(dllRoot)) - { - // The bits we need weren't pre-compiled, compile on publish - DeploymentParameters.PublishApplicationBeforeDeployment = true; - } - else if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr - && DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) - { - // x64 is the default. Publish to rebuild for the right bitness - DeploymentParameters.PublishApplicationBeforeDeployment = true; - } - } - - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr - && DeploymentParameters.ApplicationType == ApplicationType.Standalone) - { - // Publish is always required to get the correct standalone files in the output directory - DeploymentParameters.PublishApplicationBeforeDeployment = true; - } - - return dllRoot; - } - - private async Task<(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot, string dllRoot) - { - using (Logger.BeginScope("StartIISExpress")) - { - var port = uri.Port; - if (port == 0) - { - port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort(); - } - - Logger.LogInformation("Attempting to start IIS Express on port: {port}", port); - PrepareConfig(contentRoot, dllRoot, port); - - var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ? - string.Format("/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) : - string.Format("/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation); - - var iisExpressPath = GetIISExpressPath(); - - for (var attempt = 0; attempt < MaximumAttempts; attempt++) - { - Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters); - - var startInfo = new ProcessStartInfo - { - FileName = iisExpressPath, - Arguments = parameters, - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardError = true, - RedirectStandardOutput = true - }; - - AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables); - - Uri url = null; - var started = new TaskCompletionSource(); - - var process = new Process() { StartInfo = startInfo }; - process.OutputDataReceived += (sender, dataArgs) => - { - if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage)) - { - // We completely failed to start and we don't really know why - started.TrySetException(new InvalidOperationException("Failed to start IIS Express")); - } - else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage)) - { - started.TrySetResult(false); - } - else if (string.Equals(dataArgs.Data, IISExpressRunningMessage)) - { - started.TrySetResult(true); - } - else if (!string.IsNullOrEmpty(dataArgs.Data)) - { - var m = UrlDetectorRegex.Match(dataArgs.Data); - if (m.Success) - { - url = new Uri(m.Groups["url"].Value); - } - } - }; - - process.EnableRaisingEvents = true; - var hostExitTokenSource = new CancellationTokenSource(); - process.Exited += (sender, e) => - { - Logger.LogInformation("iisexpress Process {pid} shut down", process.Id); - - // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want - started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}")); - - TriggerHostShutdown(hostExitTokenSource); - }; - process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger); - Logger.LogInformation("iisexpress Process {pid} started", process.Id); - - if (process.HasExited) - { - Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode); - throw new Exception("Failed to start host"); - } - - // Wait for the app to start - // The timeout here is large, because we don't know how long the test could need - // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build - // just in case we missed one -anurse - if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10))) - { - Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port); - - // Wait for the process to exit and try again - process.WaitForExit(30 * 1000); - await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up - } - else - { - _hostProcess = process; - Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port); - return (url: url, hostExitToken: hostExitTokenSource.Token); - } - } - - var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port"; - Logger.LogError(message); - throw new TimeoutException(message); - } - } - - private void PrepareConfig(string contentRoot, string dllRoot, int port) - { - // Config is required. If not present then fall back to one we carry with us. - if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent)) - { - using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.AspNetCore.Server.IntegrationTesting.Http.config")) - using (var reader = new StreamReader(stream)) - { - DeploymentParameters.ServerConfigTemplateContent = reader.ReadToEnd(); - } - } - - var serverConfig = DeploymentParameters.ServerConfigTemplateContent; - - // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config - // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo. - serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, dllRoot); - serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, dllRoot); - - serverConfig = ReplacePlaceholder(serverConfig, "[PORT]", port.ToString(CultureInfo.InvariantCulture)); - serverConfig = ReplacePlaceholder(serverConfig, "[ApplicationPhysicalPath]", contentRoot); - - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - // For published apps, prefer the content in the web.config, but update it. - ModifyAspNetCoreSectionInWebConfig(key: "hostingModel", - value: DeploymentParameters.HostingModel == HostingModel.InProcess ? "inprocess" : ""); - ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString()); - ModifyDotNetExePathInWebConfig(); - serverConfig = RemoveRedundantElements(serverConfig); - } - else - { - // The elements normally in the web.config are in the applicationhost.config for unpublished apps. - serverConfig = ReplacePlaceholder(serverConfig, "[HostingModel]", DeploymentParameters.HostingModel.ToString()); - serverConfig = ReplacePlaceholder(serverConfig, "[AspNetCoreModule]", DeploymentParameters.AncmVersion.ToString()); - } - - DeploymentParameters.ServerConfigLocation = Path.GetTempFileName(); - Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation); - - File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig); - } - - private string ReplacePlaceholder(string content, string field, string value) - { - if (content.Contains(field)) - { - content = content.Replace(field, value); - Logger.LogDebug("Writing {field} '{value}' to config", field, value); - } - return content; - } - - private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string dllRoot) - { - if (serverConfig.Contains(replaceFlag)) - { - var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}"; - var ancmFile = Path.Combine(dllRoot, arch); - if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) - { - ancmFile = Path.Combine(dllRoot, dllName); - if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) - { - throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); - } - } - - Logger.LogDebug($"Writing '{replaceFlag}' '{ancmFile}' to config"); - return serverConfig.Replace(replaceFlag, ancmFile); - } - return serverConfig; - } - - private string GetIISExpressPath() - { - var programFiles = "Program Files"; - if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) - { - programFiles = "Program Files (x86)"; - } - - // Get path to program files - var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", programFiles, "IIS Express", "iisexpress.exe"); - - if (!File.Exists(iisExpressPath)) - { - throw new Exception("Unable to find IISExpress on the machine: " + iisExpressPath); - } - - return iisExpressPath; - } - - public override void Dispose() - { - using (Logger.BeginScope("Dispose")) - { - ShutDownIfAnyHostProcess(_hostProcess); - - if (!string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) - && File.Exists(DeploymentParameters.ServerConfigLocation)) - { - // Delete the temp applicationHostConfig that we created. - Logger.LogDebug("Deleting applicationHost.config file from {configLocation}", DeploymentParameters.ServerConfigLocation); - try - { - File.Delete(DeploymentParameters.ServerConfigLocation); - } - catch (Exception exception) - { - // Ignore delete failures - just write a log. - Logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", DeploymentParameters.ServerConfigLocation, exception.Message); - } - } - - if (DeploymentParameters.PublishApplicationBeforeDeployment) - { - CleanPublishedOutput(); - } - - InvokeUserApplicationCleanup(); - - StopTimer(); - } - - // If by this point, the host process is still running (somehow), throw an error. - // A test failure is better than a silent hang and unknown failure later on - if (_hostProcess != null && !_hostProcess.HasExited) - { - throw new Exception($"iisexpress Process {_hostProcess.Id} failed to shutdown"); - } - } - - private void ModifyDotNetExePathInWebConfig() - { - // We assume the x64 dotnet.exe is on the path so we need to provide an absolute path for x86 scenarios. - // Only do it for scenarios that rely on dotnet.exe (Core, portable, etc.). - if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr - && DeploymentParameters.ApplicationType == ApplicationType.Portable - && DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture)) - { - var executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture); - if (!File.Exists(executableName)) - { - throw new Exception($"Unable to find '{executableName}'.'"); - } - ModifyAspNetCoreSectionInWebConfig("processPath", executableName); - } - } - - // Transforms the web.config file to set attributes like hostingModel="inprocess" element - private void ModifyAspNetCoreSectionInWebConfig(string key, string value) - { - var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); - var config = XDocument.Load(webConfigFile); - var element = config.Descendants("aspNetCore").FirstOrDefault(); - element.SetAttributeValue(key, value); - config.Save(webConfigFile); - } - - private void ModifyHandlerSectionInWebConfig(string key, string value) - { - var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"); - var config = XDocument.Load(webConfigFile); - var element = config.Descendants("handlers").FirstOrDefault().Descendants("add").FirstOrDefault(); - element.SetAttributeValue(key, value); - config.Save(webConfigFile); - } - - // These elements are duplicated in the web.config if you publish. Remove them from the host.config. - private string RemoveRedundantElements(string serverConfig) - { - var hostConfig = XDocument.Parse(serverConfig); - - var coreElement = hostConfig.Descendants("aspNetCore").FirstOrDefault(); - coreElement?.Remove(); - - var handlersElement = hostConfig.Descendants("handlers").First(); - var handlerElement = handlersElement.Descendants("add") - .Where(x => x.Attribute("name").Value == "aspNetCore").FirstOrDefault(); - handlerElement?.Remove(); - - return hostConfig.ToString(); - } - } -} From 21d9ec64f054038407e22c9f100896d8a5a6ff03 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 18 Jul 2018 14:28:48 -0700 Subject: [PATCH 46/70] Add copy constructor to deployment parameters (#1497) --- .../Common/DeploymentParameters.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index 968647edba..a5f9460c5b 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -78,6 +78,27 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } + public DeploymentParameters(DeploymentParameters parameters) + { + foreach (var propertyInfo in typeof(DeploymentParameters).GetProperties()) + { + if (propertyInfo.CanWrite) + { + propertyInfo.SetValue(this, propertyInfo.GetValue(parameters)); + } + } + + foreach (var kvp in parameters.EnvironmentVariables) + { + EnvironmentVariables.Add(kvp); + } + + foreach (var kvp in parameters.PublishEnvironmentVariables) + { + PublishEnvironmentVariables.Add(kvp); + } + } + public ServerType ServerType { get; set; } public RuntimeFlavor RuntimeFlavor { get; set; } From f73008537f228a59e22461d16bd270b8dbc0c77d Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 22 Jul 2018 12:13:04 -0700 Subject: [PATCH 47/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 56 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index e4f620952e..7ddfd08ad4 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,34 +4,34 @@ 2.2.0-preview1-17099 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 - 2.2.0-preview1-34694 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 + 2.2.0-preview1-34755 2.0.9 2.1.2 2.2.0-preview1-26618-02 From c4e8dd3664d1860985bc7d98f74d3dc355b2df7e Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 25 Jul 2018 16:44:20 -0700 Subject: [PATCH 48/70] Rename WebHostBuilderFactory (#1505) --- NuGetPackageVerifier.json | 2 +- .../FactoryResolutionResult.cs | 0 .../FactoryResolutionResultKind.cs | 0 .../WebHostFactoryResolver.cs | 0 .../Microsoft.AspNetCore.TestHost.csproj | 6 +++--- ...ft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename shared/{Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources => Internal.WebHostBuilderFactory.Sources}/FactoryResolutionResult.cs (100%) rename shared/{Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources => Internal.WebHostBuilderFactory.Sources}/FactoryResolutionResultKind.cs (100%) rename shared/{Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources => Internal.WebHostBuilderFactory.Sources}/WebHostFactoryResolver.cs (100%) diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index 7e6fb60925..0d0532ab07 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -4,7 +4,7 @@ // Don't run any rules for packages that don't ship. ], "packages": { - "Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources": {}, + "Internal.WebHostBuilderFactory.Sources": {}, "Microsoft.AspNetCore.Server.IntegrationTesting": {} } }, diff --git a/shared/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources/FactoryResolutionResult.cs b/shared/Internal.WebHostBuilderFactory.Sources/FactoryResolutionResult.cs similarity index 100% rename from shared/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources/FactoryResolutionResult.cs rename to shared/Internal.WebHostBuilderFactory.Sources/FactoryResolutionResult.cs diff --git a/shared/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources/FactoryResolutionResultKind.cs b/shared/Internal.WebHostBuilderFactory.Sources/FactoryResolutionResultKind.cs similarity index 100% rename from shared/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources/FactoryResolutionResultKind.cs rename to shared/Internal.WebHostBuilderFactory.Sources/FactoryResolutionResultKind.cs diff --git a/shared/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources/WebHostFactoryResolver.cs b/shared/Internal.WebHostBuilderFactory.Sources/WebHostFactoryResolver.cs similarity index 100% rename from shared/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Sources/WebHostFactoryResolver.cs rename to shared/Internal.WebHostBuilderFactory.Sources/WebHostFactoryResolver.cs diff --git a/src/Microsoft.AspNetCore.TestHost/Microsoft.AspNetCore.TestHost.csproj b/src/Microsoft.AspNetCore.TestHost/Microsoft.AspNetCore.TestHost.csproj index 92a0795d05..ba05df4468 100644 --- a/src/Microsoft.AspNetCore.TestHost/Microsoft.AspNetCore.TestHost.csproj +++ b/src/Microsoft.AspNetCore.TestHost/Microsoft.AspNetCore.TestHost.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/test/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj b/test/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj index af6ea3865b..f7c7d6a88e 100644 --- a/test/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj +++ b/test/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests/Microsoft.AspNetCore.Hosting.WebHostBuilderFactory.Tests.csproj @@ -5,7 +5,7 @@ - + From fed2eb1cdfef598b5315da045f741403fad89e05 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Thu, 26 Jul 2018 17:07:24 -0700 Subject: [PATCH 49/70] More robust username discovery on Linux in NginxDeployer (#1508) VSTS does not have the LOGNAME env var set. This adds some fallbacks (USER and USERNAME) and `whoami` if they are not present. --- .../Deployers/NginxDeployer.cs | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs index 655630f08a..30451f9e88 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.IO; using System.Net.Http; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IntegrationTesting.Common; using Microsoft.Extensions.Logging; @@ -77,16 +78,48 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } + private string GetUserName() + { + var retVal = Environment.GetEnvironmentVariable("LOGNAME") + ?? Environment.GetEnvironmentVariable("USER") + ?? Environment.GetEnvironmentVariable("USERNAME"); + + if (!string.IsNullOrEmpty(retVal)) + { + return retVal; + } + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + using (var process = new Process + { + StartInfo = + { + FileName = "whoami", + RedirectStandardOutput = true, + } + }) + { + process.Start(); + process.WaitForExit(10_000); + return process.StandardOutput.ReadToEnd(); + } + } + + return null; + } + private void SetupNginx(string redirectUri, Uri originalUri) { using (Logger.BeginScope("SetupNginx")) { + var userName = GetUserName() ?? throw new InvalidOperationException("Could not identify the current username"); // copy nginx.conf template and replace pertinent information var pidFile = Path.Combine(DeploymentParameters.ApplicationPath, $"{Guid.NewGuid()}.nginx.pid"); var errorLog = Path.Combine(DeploymentParameters.ApplicationPath, "nginx.error.log"); var accessLog = Path.Combine(DeploymentParameters.ApplicationPath, "nginx.access.log"); DeploymentParameters.ServerConfigTemplateContent = DeploymentParameters.ServerConfigTemplateContent - .Replace("[user]", Environment.GetEnvironmentVariable("LOGNAME")) + .Replace("[user]", userName) .Replace("[errorlog]", errorLog) .Replace("[accesslog]", accessLog) .Replace("[listenPort]", originalUri.Port.ToString()) @@ -117,13 +150,14 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { runNginx.StartAndCaptureOutAndErrToLogger("nginx start", Logger); runNginx.WaitForExit(_waitTime); + if (runNginx.ExitCode != 0) { - throw new Exception("Failed to start nginx"); + throw new InvalidOperationException("Failed to start nginx"); } // Read the PID file - if(!File.Exists(pidFile)) + if (!File.Exists(pidFile)) { Logger.LogWarning("Unable to find nginx PID file: {pidFile}", pidFile); } From 6efdf78fb584646838de2ab1bc5385a86e2380d9 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 27 Jul 2018 11:48:57 -0700 Subject: [PATCH 50/70] IIS ANCM support in test matrix (#1509) --- .../TestMatrix.cs | 2 +- .../TestVariant.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs index d577e25dc7..4353627fc5 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestMatrix.cs @@ -252,7 +252,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } var archSkip = skip ?? SkipIfArchitectureNotSupportedOnCurrentSystem(arch); - if (server == ServerType.IISExpress) + if (server == ServerType.IISExpress || server == ServerType.IIS) { VaryByAncmVersion(variants, server, tfm, type, arch, archSkip); } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs index 76220d7fef..adf25b0dfa 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/TestVariant.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { // For debug and test explorer view var description = $"Server: {Server}, TFM: {Tfm}, Type: {ApplicationType}, Arch: {Architecture}"; - if (Server == ServerType.IISExpress) + if (Server == ServerType.IISExpress || Server == ServerType.IIS) { var version = AncmVersion == AncmVersion.AspNetCoreModule ? "V1" : "V2"; description += $", ANCM: {version}, Host: {HostingModel}"; From 446b64c199f6a0dc5b905c6e8a367db60ca67c6e Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 29 Jul 2018 12:12:44 -0700 Subject: [PATCH 51/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 61 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 7ddfd08ad4..f17eac0179 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17099 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 - 2.2.0-preview1-34755 + 2.2.0-preview1-17102 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 + 2.2.0-preview1-34823 2.0.9 2.1.2 2.2.0-preview1-26618-02 @@ -46,7 +46,8 @@ 1.6.0 4.5.0 2.3.1 - 2.4.0-rc.1.build4038 + 2.4.0 + diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 8b9d17825f..28cd6a5b03 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17099 -commithash:263ed1db9866b6b419b1f5d5189a712aa218acb3 +version:2.2.0-preview1-17102 +commithash:e7e2b5a97ca92cfc6acc4def534cb0901a6d1eb9 From 658906bf7c760f6523b0d0acaa6723411ee5be29 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 31 Jul 2018 16:36:31 -0700 Subject: [PATCH 52/70] Add TestApplication to allow publish output caching (#1511) --- build/dependencies.props | 56 ++++---- .../ApplicationPublisher.cs | 127 +++++++++++++++++ .../CachingApplicationPublisher.cs | 101 ++++++++++++++ .../Common/DeploymentParameters.cs | 2 + .../Deployers/ApplicationDeployer.cs | 130 ++---------------- .../ProcessHelpers.cs | 36 +++++ .../PublishedApplication.cs | 31 +++++ 7 files changed, 333 insertions(+), 150 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/ProcessHelpers.cs create mode 100644 src/Microsoft.AspNetCore.Server.IntegrationTesting/PublishedApplication.cs diff --git a/build/dependencies.props b/build/dependencies.props index f17eac0179..9a9e6c7622 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,34 +4,34 @@ 2.2.0-preview1-17102 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 - 2.2.0-preview1-34823 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 + 2.2.0-preview1-34825 2.0.9 2.1.2 2.2.0-preview1-26618-02 diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs new file mode 100644 index 0000000000..1af71c3ae9 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs @@ -0,0 +1,127 @@ +// 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.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class ApplicationPublisher + { + public string ApplicationPath { get; } + + public ApplicationPublisher(string applicationPath) + { + ApplicationPath = applicationPath; + } + + public static readonly string DotnetCommandName = "dotnet"; + + public virtual Task Publish(DeploymentParameters deploymentParameters, ILogger logger) + { + var publishDirectory = CreateTempDirectory(); + using (logger.BeginScope("dotnet-publish")) + { + if (string.IsNullOrEmpty(deploymentParameters.TargetFramework)) + { + throw new Exception($"A target framework must be specified in the deployment parameters for applications that require publishing before deployment"); + } + + var parameters = $"publish " + + $" --output \"{publishDirectory.FullName}\"" + + $" --framework {deploymentParameters.TargetFramework}" + + $" --configuration {deploymentParameters.Configuration}" + + (deploymentParameters.RestoreOnPublish + ? string.Empty + : " --no-restore -p:VerifyMatchingImplicitPackageVersion=false"); + // Set VerifyMatchingImplicitPackageVersion to disable errors when Microsoft.NETCore.App's version is overridden externally + // This verification doesn't matter if we are skipping restore during tests. + + if (deploymentParameters.ApplicationType == ApplicationType.Standalone) + { + parameters += $" --runtime {GetRuntimeIdentifier(deploymentParameters)}"; + } + + parameters += $" {deploymentParameters.AdditionalPublishParameters}"; + + var startInfo = new ProcessStartInfo + { + FileName = DotnetCommandName, + Arguments = parameters, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardError = true, + RedirectStandardOutput = true, + WorkingDirectory = deploymentParameters.ApplicationPath, + }; + + ProcessHelpers.AddEnvironmentVariablesToProcess(startInfo, deploymentParameters.PublishEnvironmentVariables, logger); + + var hostProcess = new Process() { StartInfo = startInfo }; + + logger.LogInformation($"Executing command {DotnetCommandName} {parameters}"); + + hostProcess.StartAndCaptureOutAndErrToLogger("dotnet-publish", logger); + + // A timeout is passed to Process.WaitForExit() for two reasons: + // + // 1. When process output is read asynchronously, WaitForExit() without a timeout blocks until child processes + // are killed, which can cause hangs due to MSBuild NodeReuse child processes started by dotnet.exe. + // With a timeout, WaitForExit() returns when the parent process is killed and ignores child processes. + // https://stackoverflow.com/a/37983587/102052 + // + // 2. If "dotnet publish" does hang indefinitely for some reason, tests should fail fast with an error message. + const int timeoutMinutes = 5; + if (hostProcess.WaitForExit(milliseconds: timeoutMinutes * 60 * 1000)) + { + if (hostProcess.ExitCode != 0) + { + var message = $"{DotnetCommandName} publish exited with exit code : {hostProcess.ExitCode}"; + logger.LogError(message); + throw new Exception(message); + } + } + else + { + var message = $"{DotnetCommandName} publish failed to exit after {timeoutMinutes} minutes"; + logger.LogError(message); + throw new Exception(message); + } + + logger.LogInformation($"{DotnetCommandName} publish finished with exit code : {hostProcess.ExitCode}"); + } + + return Task.FromResult(new PublishedApplication(publishDirectory.FullName, logger)); + } + + private static string GetRuntimeIdentifier(DeploymentParameters deploymentParameters) + { + var architecture = deploymentParameters.RuntimeArchitecture; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return "win7-" + architecture; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return "linux-" + architecture; + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return "osx-" + architecture; + } + throw new InvalidOperationException("Unrecognized operation system platform"); + } + + protected static DirectoryInfo CreateTempDirectory() + { + var tempPath = Path.GetTempPath() + Guid.NewGuid().ToString("N"); + var target = new DirectoryInfo(tempPath); + target.Create(); + return target; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs new file mode 100644 index 0000000000..582297ccc7 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs @@ -0,0 +1,101 @@ +// 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.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class CachingApplicationPublisher: ApplicationPublisher, IDisposable + { + private readonly Dictionary _publishCache = new Dictionary(); + + public CachingApplicationPublisher(string applicationPath) : base(applicationPath) + { + } + + public override async Task Publish(DeploymentParameters deploymentParameters, ILogger logger) + { + if (ApplicationPath != deploymentParameters.ApplicationPath) + { + throw new InvalidOperationException("ApplicationPath mismatch"); + } + + if (deploymentParameters.PublishEnvironmentVariables.Any()) + { + throw new InvalidOperationException("DeploymentParameters.PublishEnvironmentVariables not supported"); + } + + if (!string.IsNullOrEmpty(deploymentParameters.PublishedApplicationRootPath)) + { + throw new InvalidOperationException("DeploymentParameters.PublishedApplicationRootPath not supported"); + } + + if (deploymentParameters.RestoreOnPublish) + { + throw new InvalidOperationException("DeploymentParameters.RestoreOnPublish not supported"); + } + + var dotnetPublishParameters = new DotnetPublishParameters + { + TargetFramework = deploymentParameters.TargetFramework, + Configuration = deploymentParameters.Configuration, + ApplicationType = deploymentParameters.ApplicationType, + RuntimeArchitecture = deploymentParameters.RuntimeArchitecture + }; + + if (!_publishCache.TryGetValue(dotnetPublishParameters, out var publishedApplication)) + { + publishedApplication = await base.Publish(deploymentParameters, logger); + _publishCache.Add(dotnetPublishParameters, publishedApplication); + } + + return new PublishedApplication(CopyPublishedOutput(publishedApplication, logger), logger); + } + + private string CopyPublishedOutput(PublishedApplication application, ILogger logger) + { + var target = CreateTempDirectory(); + + var source = new DirectoryInfo(application.Path); + CopyFiles(source, target, logger); + return target.FullName; + } + + public static void CopyFiles(DirectoryInfo source, DirectoryInfo target, ILogger logger) + { + foreach (DirectoryInfo directoryInfo in source.GetDirectories()) + { + CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name), logger); + } + + logger.LogDebug($"Processing {target.FullName}"); + foreach (FileInfo fileInfo in source.GetFiles()) + { + logger.LogDebug($" Copying {fileInfo.Name}"); + var destFileName = Path.Combine(target.FullName, fileInfo.Name); + fileInfo.CopyTo(destFileName); + } + } + + public void Dispose() + { + foreach (var publishedApp in _publishCache.Values) + { + publishedApp.Dispose(); + } + } + + private struct DotnetPublishParameters + { + public string TargetFramework { get; set; } + public string Configuration { get; set; } + public ApplicationType ApplicationType { get; set; } + public RuntimeArchitecture RuntimeArchitecture { get; set; } + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index a5f9460c5b..4b94657743 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -99,6 +99,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } } + public ApplicationPublisher ApplicationPublisher { get; set; } + public ServerType ServerType { get; set; } public RuntimeFlavor RuntimeFlavor { get; set; } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs index 999b9c788c..5e1457e70f 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/ApplicationDeployer.cs @@ -20,12 +20,10 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { public static readonly string DotnetCommandName = "dotnet"; - // This is the argument that separates the dotnet arguments for the args being passed to the - // app being run when running dotnet run - public static readonly string DotnetArgumentSeparator = "--"; - private readonly Stopwatch _stopwatch = new Stopwatch(); + private PublishedApplication _publishedApplication; + public ApplicationDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) { DeploymentParameters = deploymentParameters; @@ -82,78 +80,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting protected void DotnetPublish(string publishRoot = null) { - using (Logger.BeginScope("dotnet-publish")) - { - if (string.IsNullOrEmpty(DeploymentParameters.TargetFramework)) - { - throw new Exception($"A target framework must be specified in the deployment parameters for applications that require publishing before deployment"); - } - - DeploymentParameters.PublishedApplicationRootPath = publishRoot ?? Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - - var parameters = $"publish " - + $" --output \"{DeploymentParameters.PublishedApplicationRootPath}\"" - + $" --framework {DeploymentParameters.TargetFramework}" - + $" --configuration {DeploymentParameters.Configuration}" - + (DeploymentParameters.RestoreOnPublish - ? string.Empty - : " --no-restore -p:VerifyMatchingImplicitPackageVersion=false"); - // Set VerifyMatchingImplicitPackageVersion to disable errors when Microsoft.NETCore.App's version is overridden externally - // This verification doesn't matter if we are skipping restore during tests. - - if (DeploymentParameters.ApplicationType == ApplicationType.Standalone) - { - parameters += $" --runtime {GetRuntimeIdentifier()}"; - } - - parameters += $" {DeploymentParameters.AdditionalPublishParameters}"; - - var startInfo = new ProcessStartInfo - { - FileName = DotnetCommandName, - Arguments = parameters, - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardError = true, - RedirectStandardOutput = true, - WorkingDirectory = DeploymentParameters.ApplicationPath, - }; - - AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.PublishEnvironmentVariables); - - var hostProcess = new Process() { StartInfo = startInfo }; - - Logger.LogInformation($"Executing command {DotnetCommandName} {parameters}"); - - hostProcess.StartAndCaptureOutAndErrToLogger("dotnet-publish", Logger); - - // A timeout is passed to Process.WaitForExit() for two reasons: - // - // 1. When process output is read asynchronously, WaitForExit() without a timeout blocks until child processes - // are killed, which can cause hangs due to MSBuild NodeReuse child processes started by dotnet.exe. - // With a timeout, WaitForExit() returns when the parent process is killed and ignores child processes. - // https://stackoverflow.com/a/37983587/102052 - // - // 2. If "dotnet publish" does hang indefinitely for some reason, tests should fail fast with an error message. - const int timeoutMinutes = 5; - if (hostProcess.WaitForExit(milliseconds: timeoutMinutes * 60 * 1000)) - { - if (hostProcess.ExitCode != 0) - { - var message = $"{DotnetCommandName} publish exited with exit code : {hostProcess.ExitCode}"; - Logger.LogError(message); - throw new Exception(message); - } - } - else - { - var message = $"{DotnetCommandName} publish failed to exit after {timeoutMinutes} minutes"; - Logger.LogError(message); - throw new Exception(message); - } - - Logger.LogInformation($"{DotnetCommandName} publish finished with exit code : {hostProcess.ExitCode}"); - } + var publisher = DeploymentParameters.ApplicationPublisher ?? new ApplicationPublisher(DeploymentParameters.ApplicationPath); + _publishedApplication = publisher.Publish(DeploymentParameters, Logger).GetAwaiter().GetResult(); + DeploymentParameters.PublishedApplicationRootPath = _publishedApplication.Path; } protected void CleanPublishedOutput() @@ -168,11 +97,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } else { - RetryHelper.RetryOperation( - () => Directory.Delete(DeploymentParameters.PublishedApplicationRootPath, true), - e => Logger.LogWarning($"Failed to delete directory : {e.Message}"), - retryCount: 3, - retryDelayMilliseconds: 100); + _publishedApplication.Dispose(); } } } @@ -219,26 +144,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting protected void AddEnvironmentVariablesToProcess(ProcessStartInfo startInfo, IDictionary environmentVariables) { var environment = startInfo.Environment; - SetEnvironmentVariable(environment, "ASPNETCORE_ENVIRONMENT", DeploymentParameters.EnvironmentName); - - foreach (var environmentVariable in environmentVariables) - { - SetEnvironmentVariable(environment, environmentVariable.Key, environmentVariable.Value); - } - } - - protected void SetEnvironmentVariable(IDictionary environment, string name, string value) - { - if (value == null) - { - Logger.LogInformation("Removing environment variable {name}", name); - environment.Remove(name); - } - else - { - Logger.LogInformation("SET {name}={value}", name, value); - environment[name] = value; - } + ProcessHelpers.SetEnvironmentVariable(environment, "ASPNETCORE_ENVIRONMENT", DeploymentParameters.EnvironmentName, Logger); + ProcessHelpers.AddEnvironmentVariablesToProcess(startInfo, environmentVariables, Logger); } protected void InvokeUserApplicationCleanup() @@ -286,26 +193,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting } public abstract void Dispose(); - - private string GetRuntimeIdentifier() - { - var architecture = DeploymentParameters.RuntimeArchitecture; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return "win7-" + architecture; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return "linux-" + architecture; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return "osx-" + architecture; - } - else - { - throw new InvalidOperationException("Unrecognized operation system platform"); - } - } } } diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/ProcessHelpers.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/ProcessHelpers.cs new file mode 100644 index 0000000000..c00b6c2b4c --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/ProcessHelpers.cs @@ -0,0 +1,36 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + internal class ProcessHelpers + { + public static void AddEnvironmentVariablesToProcess(ProcessStartInfo startInfo, IDictionary environmentVariables, ILogger logger) + { + var environment = startInfo.Environment; + + foreach (var environmentVariable in environmentVariables) + { + SetEnvironmentVariable(environment, environmentVariable.Key, environmentVariable.Value, logger); + } + } + + public static void SetEnvironmentVariable(IDictionary environment, string name, string value, ILogger logger) + { + if (value == null) + { + logger.LogInformation("Removing environment variable {name}", name); + environment.Remove(name); + } + else + { + logger.LogInformation("SET {name}={value}", name, value); + environment[name] = value; + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/PublishedApplication.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/PublishedApplication.cs new file mode 100644 index 0000000000..3913a7e908 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/PublishedApplication.cs @@ -0,0 +1,31 @@ +// 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.IO; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class PublishedApplication: IDisposable + { + private readonly ILogger _logger; + + public string Path { get; } + + public PublishedApplication(string path, ILogger logger) + { + _logger = logger; + Path = path; + } + + public void Dispose() + { + RetryHelper.RetryOperation( + () => Directory.Delete(Path, true), + e => _logger.LogWarning($"Failed to delete directory : {e.Message}"), + retryCount: 3, + retryDelayMilliseconds: 100); + } + } +} \ No newline at end of file From fd9485410dd3cbea5f86ccf7a257df90e8260d36 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 5 Aug 2018 19:14:15 +0000 Subject: [PATCH 53/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9a9e6c7622..66bc055526 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-17102 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 - 2.2.0-preview1-34825 + 2.2.0-preview1-20180731.1 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 + 2.2.0-preview1-34882 2.0.9 2.1.2 2.2.0-preview1-26618-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 28cd6a5b03..b6efc7cfcb 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-17102 -commithash:e7e2b5a97ca92cfc6acc4def534cb0901a6d1eb9 +version:2.2.0-preview1-20180731.1 +commithash:29fde58465439f4bb9df40830635ed758e063daf From ea4623aae06c4a000e1b1445c418b342ddf505ac Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Mon, 6 Aug 2018 20:36:33 +0000 Subject: [PATCH 54/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 56 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 66bc055526..f5c8e9e658 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,34 +4,34 @@ 2.2.0-preview1-20180731.1 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 - 2.2.0-preview1-34882 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 + 2.2.0-preview1-34896 2.0.9 2.1.2 2.2.0-preview1-26618-02 From b078521f171727735ab4a33709b2cc88bb091fb2 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Wed, 8 Aug 2018 16:34:04 -0700 Subject: [PATCH 55/70] Hold open the nginx dynamic port --- .../Deployers/NginxDeployer.cs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs index 30451f9e88..262ff80ce8 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/NginxDeployer.cs @@ -4,7 +4,9 @@ using System; using System.Diagnostics; using System.IO; +using System.Net; using System.Net.Http; +using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IntegrationTesting.Common; @@ -19,6 +21,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { private string _configFile; private readonly int _waitTime = (int)TimeSpan.FromSeconds(30).TotalMilliseconds; + private Socket _portSelector; public NginxDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) : base(deploymentParameters, loggerFactory) @@ -30,10 +33,29 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting using (Logger.BeginScope("Deploy")) { _configFile = Path.GetTempFileName(); + var uri = string.IsNullOrEmpty(DeploymentParameters.ApplicationBaseUriHint) ? - TestUriHelper.BuildTestUri(ServerType.Nginx) : + new Uri("http://localhost:0") : new Uri(DeploymentParameters.ApplicationBaseUriHint); + if (uri.Port == 0) + { + var builder = new UriBuilder(uri); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + // This works with nginx 1.9.1 and later using the reuseport flag, available on Ubuntu 16.04. + // Keep it open so nobody else claims the port + _portSelector = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + _portSelector.Bind(new IPEndPoint(IPAddress.Loopback, 0)); + builder.Port = ((IPEndPoint)_portSelector.LocalEndPoint).Port; + } + else + { + builder.Port = TestPortHelper.GetNextPort(); + } + uri = builder.Uri; + } + var redirectUri = TestUriHelper.BuildTestUri(ServerType.Nginx); if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr @@ -122,7 +144,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting .Replace("[user]", userName) .Replace("[errorlog]", errorLog) .Replace("[accesslog]", accessLog) - .Replace("[listenPort]", originalUri.Port.ToString()) + .Replace("[listenPort]", originalUri.Port.ToString() + (_portSelector != null ? " reuseport" : "")) .Replace("[redirectUri]", redirectUri) .Replace("[pidFile]", pidFile); Logger.LogDebug("Using PID file: {pidFile}", pidFile); @@ -199,6 +221,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting File.Delete(_configFile); } + _portSelector?.Dispose(); + base.Dispose(); } } From 687a99438a1a596a11b7dbd0bf9da5035b3b74eb Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 12 Aug 2018 19:13:25 +0000 Subject: [PATCH 56/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index f5c8e9e658..50d69a9a80 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180731.1 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 - 2.2.0-preview1-34896 + 2.2.0-preview1-20180807.2 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 + 2.2.0-preview1-34967 2.0.9 2.1.2 2.2.0-preview1-26618-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index b6efc7cfcb..29a57027f1 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180731.1 -commithash:29fde58465439f4bb9df40830635ed758e063daf +version:2.2.0-preview1-20180807.2 +commithash:11495dbd236104434e08cb1152fcb58cf2a20923 From ef465439af5c706f6a11b0aa9dadf569943eea03 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Tue, 21 Aug 2018 13:33:50 -0700 Subject: [PATCH 57/70] Update package branding for 2.2.0-preview2 --- build/dependencies.props | 2 +- version.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 50d69a9a80..1f202fed2d 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -48,6 +48,6 @@ 2.3.1 2.4.0 - + diff --git a/version.props b/version.props index 84d0ba366d..4ad31df891 100644 --- a/version.props +++ b/version.props @@ -1,10 +1,10 @@ 2.2.0 - preview1 + preview2 0.6.0 - preview1 + preview2 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final From 04b365a22f130af93298aa5388e2fba441c44dca Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 27 Aug 2018 11:59:56 -0700 Subject: [PATCH 58/70] Don't hold onto the HttpContext in the HostingLogScope (#1531) - Multiple things capture the ExecutionContext, reduce the changes of improperly rooting the HttpContext when we only need a few properties from the request. --- .../Internal/HostingLoggerExtensions.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/HostingLoggerExtensions.cs b/src/Microsoft.AspNetCore.Hosting/Internal/HostingLoggerExtensions.cs index a0579880a0..ce333f232c 100644 --- a/src/Microsoft.AspNetCore.Hosting/Internal/HostingLoggerExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/Internal/HostingLoggerExtensions.cs @@ -94,7 +94,8 @@ namespace Microsoft.AspNetCore.Hosting.Internal private class HostingLogScope : IReadOnlyList> { - private readonly HttpContext _httpContext; + private readonly string _path; + private readonly string _traceIdentifier; private readonly string _correlationId; private string _cachedToString; @@ -113,11 +114,11 @@ namespace Microsoft.AspNetCore.Hosting.Internal { if (index == 0) { - return new KeyValuePair("RequestId", _httpContext.TraceIdentifier); + return new KeyValuePair("RequestId", _traceIdentifier); } else if (index == 1) { - return new KeyValuePair("RequestPath", _httpContext.Request.Path.ToString()); + return new KeyValuePair("RequestPath", _path); } else if (index == 2) { @@ -130,7 +131,8 @@ namespace Microsoft.AspNetCore.Hosting.Internal public HostingLogScope(HttpContext httpContext, string correlationId) { - _httpContext = httpContext; + _traceIdentifier = httpContext.TraceIdentifier; + _path = httpContext.Request.Path.ToString(); _correlationId = correlationId; } @@ -141,8 +143,8 @@ namespace Microsoft.AspNetCore.Hosting.Internal _cachedToString = string.Format( CultureInfo.InvariantCulture, "RequestId:{0} RequestPath:{1}", - _httpContext.TraceIdentifier, - _httpContext.Request.Path); + _traceIdentifier, + _path); } return _cachedToString; From c3edce8e8a19a1e2e58fd21a986271b88071e6ba Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 2 Sep 2018 12:12:42 -0700 Subject: [PATCH 59/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 1f202fed2d..af8937cb80 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180807.2 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 + 2.2.0-preview1-20180821.1 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 + 2.2.0-preview2-35143 2.0.9 2.1.2 2.2.0-preview1-26618-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 29a57027f1..524a2323d0 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180807.2 -commithash:11495dbd236104434e08cb1152fcb58cf2a20923 +version:2.2.0-preview1-20180821.1 +commithash:c8d0cc52cd1abb697be24e288ffd54f8fae8bf17 From 795a2238eb146e733a337afb2ded7b88f49fa635 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Wed, 5 Sep 2018 16:34:22 -0700 Subject: [PATCH 60/70] Update branding to 2.2.0-preview3 --- version.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.props b/version.props index 4ad31df891..b07397dad4 100644 --- a/version.props +++ b/version.props @@ -1,10 +1,10 @@ 2.2.0 - preview2 + preview3 0.6.0 - preview2 + preview3 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final From 857df2f864fb97153e65947c3496b2d4839bbafb Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 9 Sep 2018 12:13:34 -0700 Subject: [PATCH 61/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 62 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index af8937cb80..466bda21cf 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,38 +3,38 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180821.1 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 - 2.2.0-preview2-35143 + 2.2.0-preview1-20180907.8 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 + 2.2.0-preview3-35202 2.0.9 - 2.1.2 - 2.2.0-preview1-26618-02 + 2.1.3 + 2.2.0-preview2-26905-02 1.0.1 15.6.1 4.7.49 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 524a2323d0..552300b0ce 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180821.1 -commithash:c8d0cc52cd1abb697be24e288ffd54f8fae8bf17 +version:2.2.0-preview1-20180907.8 +commithash:078918eb5c1f176ee1da351c584fb4a4d7491aa0 From b195e36cc35fbae20842440b47baafe1f5270886 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 16 Sep 2018 12:12:17 -0700 Subject: [PATCH 62/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 466bda21cf..53c0a095c2 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180907.8 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 - 2.2.0-preview3-35202 + 2.2.0-preview1-20180911.1 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 + 2.2.0-preview3-35252 2.0.9 2.1.3 2.2.0-preview2-26905-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 552300b0ce..1090ad6a92 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180907.8 -commithash:078918eb5c1f176ee1da351c584fb4a4d7491aa0 +version:2.2.0-preview1-20180911.1 +commithash:ddfecdfc6e8e4859db5a0daea578070b862aac65 From ef69aa833b291946c608a4bf24d36ea7fb1538dc Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 23 Sep 2018 19:14:22 +0000 Subject: [PATCH 63/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 58 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 53c0a095c2..97c99b8a98 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,35 +3,35 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180911.1 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 - 2.2.0-preview3-35252 + 2.2.0-preview1-20180918.1 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 + 2.2.0-preview3-35301 2.0.9 2.1.3 2.2.0-preview2-26905-02 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 1090ad6a92..8491de70e6 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180911.1 -commithash:ddfecdfc6e8e4859db5a0daea578070b862aac65 +version:2.2.0-preview1-20180918.1 +commithash:ad5e3fc53442741a0dd49bce437d2ac72f4b5800 From f17142b2ec901e29e0fe2c8cd38ad383171fcf23 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 24 Sep 2018 10:41:30 -0700 Subject: [PATCH 64/70] Delay resolution until after application services are built (#1553) - Resolve the logger from the right service provider to log duplicate hosting startup assemblies. - Don't create a 3rd IServiceProvider if we resolved the default implementation. --- .../WebHostBuilder.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs index 423b898cec..2238bd3b9b 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs @@ -174,13 +174,6 @@ namespace Microsoft.AspNetCore.Hosting } } - var logger = hostingServiceProvider.GetRequiredService>(); - // Warn about duplicate HostingStartupAssemblies - foreach (var assemblyName in _options.GetFinalHostingStartupAssemblies().GroupBy(a => a, StringComparer.OrdinalIgnoreCase).Where(g => g.Count() > 1)) - { - logger.LogWarning($"The assembly {assemblyName} was specified multiple times. Hosting startup assemblies should only be specified once."); - } - AddApplicationServices(applicationServices, hostingServiceProvider); var host = new WebHost( @@ -193,6 +186,14 @@ namespace Microsoft.AspNetCore.Hosting { host.Initialize(); + var logger = host.Services.GetRequiredService>(); + + // Warn about duplicate HostingStartupAssemblies + foreach (var assemblyName in _options.GetFinalHostingStartupAssemblies().GroupBy(a => a, StringComparer.OrdinalIgnoreCase).Where(g => g.Count() > 1)) + { + logger.LogWarning($"The assembly {assemblyName} was specified multiple times. Hosting startup assemblies should only be specified once."); + } + return host; } catch @@ -208,7 +209,7 @@ namespace Microsoft.AspNetCore.Hosting var provider = collection.BuildServiceProvider(); var factory = provider.GetService>(); - if (factory != null) + if (factory != null && !(factory is DefaultServiceProviderFactory)) { using (provider) { From 2e0e32319939c67137ae3a89df5c49f751320987 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 28 Sep 2018 17:10:33 -0700 Subject: [PATCH 65/70] automated: bulk infrastructure updates. Update bootstrapper scripts and remove unnecessary signing properties --- Directory.Build.props | 3 --- run.ps1 | 6 +++--- run.sh | 10 +++++----- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index cffe01b760..d913619aa9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,9 +14,6 @@ $(MSBuildThisFileDirectory) $(MSBuildThisFileDirectory)build\Key.snk true - Microsoft - MicrosoftNuGet - true true false diff --git a/run.ps1 b/run.ps1 index 3b27382468..34604c7175 100644 --- a/run.ps1 +++ b/run.ps1 @@ -52,8 +52,8 @@ in the file are overridden by command line parameters. Example config file: ```json { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev", + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", + "channel": "master", "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" } ``` @@ -192,7 +192,7 @@ if (!$DotNetHome) { else { Join-Path $PSScriptRoot '.dotnet'} } -if (!$Channel) { $Channel = 'dev' } +if (!$Channel) { $Channel = 'master' } if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } # Execute diff --git a/run.sh b/run.sh index 02aac15874..4c1fed5646 100755 --- a/run.sh +++ b/run.sh @@ -220,7 +220,7 @@ if [ -f "$config_file" ]; then config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" else - _error "$config_file contains invalid JSON." + __error "$config_file contains invalid JSON." exit 1 fi elif __machine_has python ; then @@ -228,7 +228,7 @@ if [ -f "$config_file" ]; then config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" else - _error "$config_file contains invalid JSON." + __error "$config_file contains invalid JSON." exit 1 fi elif __machine_has python3 ; then @@ -236,11 +236,11 @@ if [ -f "$config_file" ]; then config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" else - _error "$config_file contains invalid JSON." + __error "$config_file contains invalid JSON." exit 1 fi else - _error 'Missing required command: jq or python. Could not parse the JSON file.' + __error 'Missing required command: jq or python. Could not parse the JSON file.' exit 1 fi @@ -248,7 +248,7 @@ if [ -f "$config_file" ]; then [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" fi -[ -z "$channel" ] && channel='dev' +[ -z "$channel" ] && channel='master' [ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' get_korebuild From 52c7f5fb98b0fd32495854e4f1f4eaf21d67ed71 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 30 Sep 2018 12:14:34 -0700 Subject: [PATCH 66/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 60 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 97c99b8a98..b09c3954c4 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,38 +3,38 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180918.1 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 - 2.2.0-preview3-35301 + 2.2.0-preview1-20180928.5 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 + 2.2.0-preview3-35359 2.0.9 2.1.3 - 2.2.0-preview2-26905-02 + 2.2.0-preview3-26927-02 1.0.1 15.6.1 4.7.49 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 8491de70e6..0507680073 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180918.1 -commithash:ad5e3fc53442741a0dd49bce437d2ac72f4b5800 +version:2.2.0-preview1-20180928.5 +commithash:43faa29f679f47b88689d645b39e6be5e0055d70 From e30ae8cc3dbe4e59ae999a870c99c7cda9898f77 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Fri, 5 Oct 2018 10:11:04 -0500 Subject: [PATCH 67/70] Fix typo (#1559) --- src/Microsoft.Extensions.Hosting.Abstractions/IHostLifetime.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Extensions.Hosting.Abstractions/IHostLifetime.cs b/src/Microsoft.Extensions.Hosting.Abstractions/IHostLifetime.cs index 129fb44c8a..2788478d83 100644 --- a/src/Microsoft.Extensions.Hosting.Abstractions/IHostLifetime.cs +++ b/src/Microsoft.Extensions.Hosting.Abstractions/IHostLifetime.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.Hosting public interface IHostLifetime { /// - /// Called at the start of which will wait until it's compete before + /// Called at the start of which will wait until it's complete before /// continuing. This can be used to delay startup until signaled by an external event. /// Task WaitForStartAsync(CancellationToken cancellationToken); From dd2056ae1afdc729adfea584d7de79ef7f1534c0 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 7 Oct 2018 19:15:05 +0000 Subject: [PATCH 68/70] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 62 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +-- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index b09c3954c4..af90a17bb7 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,44 +3,44 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 2.2.0-preview1-20180928.5 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 - 2.2.0-preview3-35359 + 2.2.0-preview2-20181004.6 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 + 2.2.0-preview3-35425 2.0.9 2.1.3 - 2.2.0-preview3-26927-02 + 2.2.0-preview3-27001-02 1.0.1 15.6.1 4.7.49 2.0.3 1.4.0 - 3.2.0 + 4.0.0 4.5.0 4.5.0 1.6.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 0507680073..3e92dd5543 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180928.5 -commithash:43faa29f679f47b88689d645b39e6be5e0055d70 +version:2.2.0-preview2-20181004.6 +commithash:c04c4b2f5018632647f96210ab01876661302dac From 27e4e1aca3863389098b9be6dd9c5b7c030180b8 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 9 Oct 2018 10:41:52 -0700 Subject: [PATCH 69/70] Remove RestoreOnPublish parameter (#1533) --- .../ApplicationPublisher.cs | 4 +--- .../CachingApplicationPublisher.cs | 5 ----- .../Common/DeploymentParameters.cs | 5 ----- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs index 1af71c3ae9..4d576db725 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/ApplicationPublisher.cs @@ -35,9 +35,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting + $" --output \"{publishDirectory.FullName}\"" + $" --framework {deploymentParameters.TargetFramework}" + $" --configuration {deploymentParameters.Configuration}" - + (deploymentParameters.RestoreOnPublish - ? string.Empty - : " --no-restore -p:VerifyMatchingImplicitPackageVersion=false"); + + " --no-restore -p:VerifyMatchingImplicitPackageVersion=false"; // Set VerifyMatchingImplicitPackageVersion to disable errors when Microsoft.NETCore.App's version is overridden externally // This verification doesn't matter if we are skipping restore during tests. diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs index 582297ccc7..e32d8e22db 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/CachingApplicationPublisher.cs @@ -35,11 +35,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting throw new InvalidOperationException("DeploymentParameters.PublishedApplicationRootPath not supported"); } - if (deploymentParameters.RestoreOnPublish) - { - throw new InvalidOperationException("DeploymentParameters.RestoreOnPublish not supported"); - } - var dotnetPublishParameters = new DotnetPublishParameters { TargetFramework = deploymentParameters.TargetFramework, diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs index 4b94657743..5e347e4933 100644 --- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs +++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/DeploymentParameters.cs @@ -147,11 +147,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting ///
public string AdditionalPublishParameters { get; set; } - /// - /// Publish restores by default, this property opts out by default. - /// - public bool RestoreOnPublish { get; set; } - /// /// To publish the application before deployment. /// From 0724e6cde1149ee1a19bfec9c13a2c9327b71213 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Tue, 16 Oct 2018 12:48:14 -0700 Subject: [PATCH 70/70] Update package branding for 2.2 RTM --- version.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.props b/version.props index b07397dad4..6421e625f3 100644 --- a/version.props +++ b/version.props @@ -1,10 +1,10 @@ 2.2.0 - preview3 + rtm 0.6.0 - preview3 + rtm $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final