From 3bdb33ccd4dbe5baa3162ca3d3778df1883db093 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Tue, 3 Jul 2018 16:46:39 -0700 Subject: [PATCH 1/4] Sync native calls --- .../Core/IISHttpContext.FeatureCollection.cs | 9 ++- .../Core/IISHttpContext.cs | 20 ++--- .../Core/IO/AsyncIOEngine.cs | 10 ++- .../Core/IO/WebSocketsAsyncIOEngine.cs | 79 +++++++++++-------- .../NativeMethods.cs | 13 +-- 5 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs b/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs index 05c376de0e..a2cd22d113 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs @@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core bool IHttpResponseFeature.HasStarted => HasResponseStarted; - bool IHttpUpgradeFeature.IsUpgradableRequest => _server.IsWebSocketAvailable(_pInProcessHandler); + bool IHttpUpgradeFeature.IsUpgradableRequest => true; bool IFeatureCollection.IsReadOnly => false; @@ -205,7 +205,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core return null; } - return NativeMethods.HttpTryGetServerVariable(_pInProcessHandler, variableName, out var value) ? value : null; + lock (_contextLock) + { + return NativeMethods.HttpTryGetServerVariable(_pInProcessHandler, variableName, out var value) ? value : null; + } } } @@ -265,7 +268,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core _hasRequestReadingStarted = false; // Upgrade async will cause the stream processing to go into duplex mode - AsyncIO = new WebSocketsAsyncIOEngine(_pInProcessHandler); + AsyncIO = new WebSocketsAsyncIOEngine(_contextLock, _pInProcessHandler); await InitializeResponse(flushHeaders: true); diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs b/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs index 1866967527..15c69432ed 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs @@ -28,7 +28,6 @@ namespace Microsoft.AspNetCore.Server.IIS.Core private const int PauseWriterThreshold = 65536; private const int ResumeWriterTheshold = PauseWriterThreshold / 2; - protected readonly IntPtr _pInProcessHandler; private readonly IISServerOptions _options; @@ -38,8 +37,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core private int _statusCode; private string _reasonPhrase; - private readonly object _onStartingSync = new object(); - private readonly object _onCompletedSync = new object(); + // Used to synchronize callback registration and native method calls + private readonly object _contextLock = new object(); protected Stack, object>> _onStarting; protected Stack, object>> _onCompleted; @@ -241,7 +240,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core // If at this point request was not upgraded just start a normal IO engine if (AsyncIO == null) { - AsyncIO = new AsyncIOEngine(_pInProcessHandler); + AsyncIO = new AsyncIOEngine(_contextLock, _pInProcessHandler); } } @@ -341,7 +340,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core public void OnStarting(Func callback, object state) { - lock (_onStartingSync) + lock (_contextLock) { if (HasResponseStarted) { @@ -358,7 +357,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core public void OnCompleted(Func callback, object state) { - lock (_onCompletedSync) + lock (_contextLock) { if (_onCompleted == null) { @@ -371,7 +370,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core protected async Task FireOnStarting() { Stack, object>> onStarting = null; - lock (_onStartingSync) + lock (_contextLock) { onStarting = _onStarting; _onStarting = null; @@ -395,7 +394,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core protected async Task FireOnCompleted() { Stack, object>> onCompleted = null; - lock (_onCompletedSync) + lock (_contextLock) { onCompleted = _onCompleted; _onCompleted = null; @@ -438,11 +437,6 @@ namespace Microsoft.AspNetCore.Server.IIS.Core NativeMethods.HttpPostCompletion(_pInProcessHandler, 0); } - public void IndicateCompletion(NativeMethods.REQUEST_NOTIFICATION_STATUS notificationStatus) - { - NativeMethods.HttpIndicateCompletion(_pInProcessHandler, notificationStatus); - } - internal void OnAsyncCompletion(int hr, int bytes) { AsyncIO.NotifyCompletion(hr, bytes); diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs b/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs index 614367255a..b07d411630 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs @@ -12,6 +12,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO { internal partial class AsyncIOEngine : IAsyncIOEngine { + private readonly object _contextSync; private readonly IntPtr _handler; private bool _stopped; @@ -23,8 +24,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO private AsyncWriteOperation _cachedAsyncWriteOperation; private AsyncFlushOperation _cachedAsyncFlushOperation; - public AsyncIOEngine(IntPtr handler) + public AsyncIOEngine(object contextSync, IntPtr handler) { + this._contextSync = contextSync; _handler = handler; } @@ -46,7 +48,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO private void Run(AsyncIOOperation ioOperation) { - lock (this) + lock (_contextSync) { if (_stopped) { @@ -99,7 +101,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO AsyncIOOperation.AsyncContinuation continuation; AsyncIOOperation.AsyncContinuation? nextContinuation = null; - lock (this) + lock (_contextSync) { Debug.Assert(_runningOperation != null); @@ -135,7 +137,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO public void Dispose() { - lock (this) + lock (_contextSync) { _stopped = true; NativeMethods.HttpTryCancelIO(_handler); diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs b/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs index 0c04523cb0..38c737dbce 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs @@ -10,6 +10,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO { internal partial class WebSocketsAsyncIOEngine: IAsyncIOEngine { + private readonly object _contextLock; + private readonly IntPtr _handler; private bool _isInitialized; @@ -22,55 +24,65 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO private AsyncInitializeOperation _cachedAsyncInitializeOperation; - public WebSocketsAsyncIOEngine(IntPtr handler) + public WebSocketsAsyncIOEngine(object contextLock, IntPtr handler) { + _contextLock = contextLock; _handler = handler; } public ValueTask ReadAsync(Memory memory) { - ThrowIfNotInitialized(); + lock (_contextLock) + { + ThrowIfNotInitialized(); - var read = GetReadOperation(); - read.Initialize(_handler, memory); - read.Invoke(); - return new ValueTask(read, 0); + var read = GetReadOperation(); + read.Initialize(_handler, memory); + read.Invoke(); + return new ValueTask(read, 0); + } } public ValueTask WriteAsync(ReadOnlySequence data) { - ThrowIfNotInitialized(); + lock (_contextLock) + { + ThrowIfNotInitialized(); - var write = GetWriteOperation(); - write.Initialize(_handler, data); - write.Invoke(); - return new ValueTask(write, 0); + var write = GetWriteOperation(); + write.Initialize(_handler, data); + write.Invoke(); + return new ValueTask(write, 0); + } } public ValueTask FlushAsync() { - if (_isInitialized) + lock (_contextLock) { - return new ValueTask(Task.CompletedTask); + if (_isInitialized) + { + return new ValueTask(Task.CompletedTask); + } + + NativeMethods.HttpEnableWebsockets(_handler); + + var init = GetInitializeOperation(); + init.Initialize(_handler); + + var continuation = init.Invoke(); + + if (continuation != null) + { + _isInitialized = true; + } + else + { + _initializationFlush = init; + } + + return new ValueTask(init, 0); } - - NativeMethods.HttpEnableWebsockets(_handler); - - var init = GetInitializeOperation(); - init.Initialize(_handler); - - var continuation = init.Invoke(); - - if (continuation != null) - { - _isInitialized = true; - } - else - { - _initializationFlush = init; - } - - return new ValueTask(init, 0); } public void NotifyCompletion(int hr, int bytes) @@ -100,7 +112,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO public void Dispose() { - NativeMethods.HttpTryCancelIO(_handler); + lock (_contextLock) + { + NativeMethods.HttpTryCancelIO(_handler); + } } private WebSocketReadOperation GetReadOperation() => diff --git a/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs b/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs index 55b8084e59..de7bcb0562 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs @@ -70,9 +70,6 @@ namespace Microsoft.AspNetCore.Server.IIS [DllImport(AspNetCoreModuleDll)] private static extern int http_stop_incoming_requests(IntPtr pInProcessApplication); - [DllImport(AspNetCoreModuleDll)] - private static extern unsafe HttpApiTypes.HTTP_RESPONSE_V2* http_get_raw_response(IntPtr pInProcessHandler); - [DllImport(AspNetCoreModuleDll, CharSet = CharSet.Ansi)] private static extern int http_set_response_status_code(IntPtr pInProcessHandler, ushort statusCode, string pszReason); @@ -138,10 +135,6 @@ namespace Microsoft.AspNetCore.Server.IIS Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus)); } - public static void HttpIndicateCompletion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus) - { - http_indicate_completion(pInProcessHandler, notificationStatus); - } public static void HttpRegisterCallbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext) { Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, asyncCallback, pvRequestContext, pvShutdownContext)); @@ -156,6 +149,7 @@ namespace Microsoft.AspNetCore.Server.IIS { return http_flush_response_bytes(pInProcessHandler, out fCompletionExpected); } + public static unsafe HttpApiTypes.HTTP_REQUEST_V2* HttpGetRawRequest(IntPtr pInProcessHandler) { return http_get_raw_request(pInProcessHandler); @@ -171,11 +165,6 @@ namespace Microsoft.AspNetCore.Server.IIS Validate(http_stop_incoming_requests(pInProcessApplication)); } - public static unsafe HttpApiTypes.HTTP_RESPONSE_V2* HttpGetRawResponse(IntPtr pInProcessHandler) - { - return http_get_raw_response(pInProcessHandler); - } - public static void HttpSetResponseStatusCode(IntPtr pInProcessHandler, ushort statusCode, string pszReason) { Validate(http_set_response_status_code(pInProcessHandler, statusCode, pszReason)); From b280597c689e5e4ae457d8050cda999b5b93f738 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Thu, 5 Jul 2018 09:01:47 -0700 Subject: [PATCH 2/4] fb --- .../Core/IISHttpContext.FeatureCollection.cs | 1 + src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs b/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs index a2cd22d113..4c2d4342b9 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs @@ -205,6 +205,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core return null; } + // Synchronize access to native methods that might run in parallel with IO loops lock (_contextLock) { return NativeMethods.HttpTryGetServerVariable(_pInProcessHandler, variableName, out var value) ? value : null; diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs b/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs index b07d411630..e7a01b331d 100644 --- a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs +++ b/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs @@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core.IO public AsyncIOEngine(object contextSync, IntPtr handler) { - this._contextSync = contextSync; + _contextSync = contextSync; _handler = handler; } From 5f02de1e2c9963bc4e108c1309f0477b5250f738 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Fri, 6 Jul 2018 11:36:51 -0700 Subject: [PATCH 3/4] Test --- .../AspNetCore/src/applicationinfo.cpp | 6 ----- .../Inprocess/ServerVariablesTest.cs | 26 +++++++++++++++++++ test/WebSites/InProcessWebSite/Startup.cs | 16 ++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp b/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp index ccbd586f3e..2919b7cf4c 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp @@ -187,12 +187,6 @@ APPLICATION_INFO::EnsureApplicationCreated( // one optimization for failure scenario is to reduce the lock scope SRWExclusiveLock lock(m_srwLock); - if (m_fDoneAppCreation) - { - // application is NULL and CreateApplication failed previously - FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE); - } - else { if (m_pApplication != NULL) { diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs b/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs index 56b04c208e..020ef00213 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs +++ b/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs @@ -1,6 +1,8 @@ // 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.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; @@ -38,5 +40,29 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { Assert.DoesNotContain(@"\\?\", await _fixture.Client.GetStringAsync("/BasePath")); } + + [ConditionalFact] + public async Task GetServerVariableDoesNotCrash() + { + async Task RunRequests() + { + var client = new HttpClient() { BaseAddress = _fixture.Client.BaseAddress }; + + for (int j = 0; j < 10; j++) + { + var response = await client.GetStringAsync("/GetServerVariableStress"); + Assert.StartsWith("Response Begin", response); + Assert.EndsWith("Response End", response); + } + } + + List tasks = new List(); + for (int i = 0; i < 10; i++) + { + tasks.Add(Task.Run(RunRequests)); + } + + await Task.WhenAll(tasks); + } } } diff --git a/test/WebSites/InProcessWebSite/Startup.cs b/test/WebSites/InProcessWebSite/Startup.cs index 3aaba9b44f..2bf89384f8 100644 --- a/test/WebSites/InProcessWebSite/Startup.cs +++ b/test/WebSites/InProcessWebSite/Startup.cs @@ -738,5 +738,21 @@ namespace IISTestSite ctx.RequestServices.GetService().StopApplication(); }); } + + private async Task GetServerVariableStress(HttpContext context) + { + // This test simulates the scenario where native Flush call is being + // executed on background thread while request thread calls GetServerVariable + // concurrent native calls may cause native object corruption + + await context.Response.WriteAsync("Response Begin"); + for (int i = 0; i < 1000; i++) + { + await context.Response.WriteAsync(context.GetIISServerVariable("REMOTE_PORT")); + await context.Response.Body.FlushAsync(); + } + await context.Response.WriteAsync("Response End"); + } + } } From 8ad64d2a35bd4cfb73aa4de3ddce86b7a19e76bb Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 6 Jul 2018 16:16:29 -0700 Subject: [PATCH 4/4] Port IISExpress tests to run on both IIS and IISExpress (#1010) --- IISIntegration.NoV1.sln | 17 +- IISIntegration.sln | 17 +- .../IIS.Performance/IIS.Performance.csproj | 4 +- .../IIS.Performance/StartupTimeBenchmark.cs | 2 +- build/repo.props | 5 - .../AspNetCoreModuleTests.vcxproj | 178 ----- test/AspNetCoreModuleTests/stdafx.h | 56 -- .../AppHostConfig/HostableWebCore.config} | 0 .../AppHostConfig/IIS.config | 741 ++++++++++++++++++ .../AppHostConfig/IISExpress.config} | 11 - .../Inprocess/EnvironmentVariableTests.cs | 2 - .../Inprocess/FeatureCollectionTests.cs | 3 - .../Inprocess/HelloWorldTests.cs | 3 - .../InvalidReadWriteOperationTests.cs | 2 - .../Inprocess/LargeResponseBodyTests.cs | 2 - .../Inprocess/ResponseHeaderTests.cs | 3 - .../Inprocess/ResponseInvalidOrderingTests.cs | 1 - .../Inprocess/ServerVariablesTest.cs | 1 - .../Inprocess/SynchronousReadAndWriteTests.cs | 1 - .../OutOfProcess/HelloWorldTest.cs | 13 +- .../Properties/AssemblyInfo.cs | 3 +- .../Utilities/FunctionalTestsBase.cs | 8 +- .../Utilities/Helpers.cs | 2 +- .../Utilities/IISApplication.cs | 68 +- .../Utilities/IISDeployer.cs | 6 +- .../Utilities/IISDeploymentResult.cs | 0 .../Utilities/IISFunctionalTestBase.cs | 15 +- .../Utilities/IISTestSiteCollection.cs | 0 .../Utilities/IISTestSiteFixture.cs | 13 +- .../Utilities/LoggingHandler.cs | 0 .../Utilities/RetryHandler.cs | 0 ...pIfHostableWebCoreNotAvailibleAttribute.cs | 0 .../Utilities/TestConnections.cs | 0 .../Utilities/TestIISUriHelper.cs | 0 .../Utilities/TestServer.cs | 4 +- test/IIS.FunctionalTests/DeployerSelector.cs | 12 + .../IIS.FunctionalTests.csproj} | 18 +- .../SkipIISTestAttribute.cs} | 5 +- .../DeployerSelector.cs | 12 + .../IISExpress.FunctionalTests.csproj | 55 ++ .../InProcess}/AppOfflineTests.cs | 6 +- .../InProcess}/AuthenticationTests.cs | 26 +- .../InProcess}/LoggingTests.cs | 7 +- .../InProcess}/ShutdownTests.cs | 4 +- .../InProcess}/StartupExceptionTests.cs | 12 +- .../InProcess}/StartupTests.cs | 7 +- .../InProcess}/TestServerTest.cs | 2 +- .../InProcess}/WebSocketTests.cs | 0 .../OutOfProcess/GlobalVersionTests.cs | 4 +- .../OutOfProcess/HttpsTest.cs | 5 +- .../OutOfProcess/NtlmAuthentationTest.cs | 9 +- .../OutOfProcess/WindowsAuthTests.cs | 45 ++ .../SkipIISTestAttribute.cs | 17 + .../UpgradeFeatureDetectionTests.cs | 26 +- .../Inprocess/IISTests.cs | 40 - .../InProcessWebSite/Startup.WebSockets.cs | 2 +- test/WebSites/OutOfProcessWebSite/Startup.cs | 1 + test/WebSites/StressTestWebSite/Startup.cs | 2 +- test/WebSites/shared/WebSockets/Constants.cs | 2 +- .../shared/WebSockets/HandshakeHelpers.cs | 2 +- 60 files changed, 1087 insertions(+), 415 deletions(-) delete mode 100644 test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj delete mode 100644 test/AspNetCoreModuleTests/stdafx.h rename test/{IISIntegration.FunctionalTests/AppHostConfig/TestServer.config => Common.FunctionalTests/AppHostConfig/HostableWebCore.config} (100%) create mode 100644 test/Common.FunctionalTests/AppHostConfig/IIS.config rename test/{IISIntegration.FunctionalTests/AppHostConfig/Http.config => Common.FunctionalTests/AppHostConfig/IISExpress.config} (99%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/EnvironmentVariableTests.cs (95%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/FeatureCollectionTests.cs (89%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/HelloWorldTests.cs (89%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/InvalidReadWriteOperationTests.cs (97%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/LargeResponseBodyTests.cs (92%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/ResponseHeaderTests.cs (96%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/ResponseInvalidOrderingTests.cs (95%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/ServerVariablesTest.cs (98%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Inprocess/SynchronousReadAndWriteTests.cs (99%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/OutOfProcess/HelloWorldTest.cs (85%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Properties/AssemblyInfo.cs (72%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/FunctionalTestsBase.cs (79%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/Helpers.cs (97%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/IISApplication.cs (83%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/IISDeployer.cs (93%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/IISDeploymentResult.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/IISFunctionalTestBase.cs (66%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/IISTestSiteCollection.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/IISTestSiteFixture.cs (75%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/LoggingHandler.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/RetryHandler.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/TestConnections.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/TestIISUriHelper.cs (100%) rename test/{IISIntegration.FunctionalTests => Common.FunctionalTests}/Utilities/TestServer.cs (97%) create mode 100644 test/IIS.FunctionalTests/DeployerSelector.cs rename test/{IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj => IIS.FunctionalTests/IIS.FunctionalTests.csproj} (90%) rename test/{IISIntegration.FunctionalTests/Utilities/SkipIfIISCannotRunAttribute.cs => IIS.FunctionalTests/SkipIISTestAttribute.cs} (92%) create mode 100644 test/IISExpress.FunctionalTests/DeployerSelector.cs create mode 100644 test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/AppOfflineTests.cs (95%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/AuthenticationTests.cs (71%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/LoggingTests.cs (95%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/ShutdownTests.cs (86%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/StartupExceptionTests.cs (91%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/StartupTests.cs (96%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/TestServerTest.cs (95%) rename test/{IISIntegration.FunctionalTests/Inprocess => IISExpress.FunctionalTests/InProcess}/WebSocketTests.cs (100%) rename test/{IISIntegration.FunctionalTests => IISExpress.FunctionalTests}/OutOfProcess/GlobalVersionTests.cs (97%) rename test/{IISIntegration.FunctionalTests => IISExpress.FunctionalTests}/OutOfProcess/HttpsTest.cs (97%) rename test/{IISIntegration.FunctionalTests => IISExpress.FunctionalTests}/OutOfProcess/NtlmAuthentationTest.cs (88%) create mode 100644 test/IISExpress.FunctionalTests/OutOfProcess/WindowsAuthTests.cs create mode 100644 test/IISExpress.FunctionalTests/SkipIISTestAttribute.cs rename test/{IISIntegration.FunctionalTests => IISExpress.FunctionalTests}/UpgradeFeatureDetectionTests.cs (81%) delete mode 100644 test/IISIntegration.FunctionalTests/Inprocess/IISTests.cs diff --git a/IISIntegration.NoV1.sln b/IISIntegration.NoV1.sln index c2bd1b9ade..04bda53889 100644 --- a/IISIntegration.NoV1.sln +++ b/IISIntegration.NoV1.sln @@ -49,7 +49,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7E80C58E build\testsite.props = build\testsite.props EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.FunctionalTests", "test\IISIntegration.FunctionalTests\IISIntegration.FunctionalTests.csproj", "{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISExpress.FunctionalTests", "test\IISExpress.FunctionalTests\IISExpress.FunctionalTests.csproj", "{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}" ProjectSection(ProjectDependencies) = postProject {7F87406C-A3C8-4139-A68D-E4C344294A67} = {7F87406C-A3C8-4139-A68D-E4C344294A67} EndProjectSection @@ -109,6 +109,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "test\gtest\gtest.v EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandlerLib", "src\AspNetCoreModuleV2\RequestHandlerLib\RequestHandlerLib.vcxproj", "{1533E271-F61B-441B-8B74-59FB61DF0552}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test\IIS.FunctionalTests\IIS.FunctionalTests.csproj", "{D182103F-8405-4647-B158-C36F598657EF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -353,6 +355,18 @@ Global {1533E271-F61B-441B-8B74-59FB61DF0552}.Release|x64.Build.0 = Release|x64 {1533E271-F61B-441B-8B74-59FB61DF0552}.Release|x86.ActiveCfg = Release|Win32 {1533E271-F61B-441B-8B74-59FB61DF0552}.Release|x86.Build.0 = Release|Win32 + {D182103F-8405-4647-B158-C36F598657EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Debug|x64.Build.0 = Debug|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Debug|x86.Build.0 = Debug|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Release|Any CPU.Build.0 = Release|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Release|x64.ActiveCfg = Release|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Release|x64.Build.0 = Release|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Release|x86.ActiveCfg = Release|Any CPU + {D182103F-8405-4647-B158-C36F598657EF}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -381,6 +395,7 @@ Global {340C59FC-C682-4CBA-81F8-791821EC8EDE} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520} {CAC1267B-8778-4257-AAC6-CAF481723B01} = {EF30B533-D715-421A-92B7-92FEF460AC9C} {1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E} + {D182103F-8405-4647-B158-C36F598657EF} = {EF30B533-D715-421A-92B7-92FEF460AC9C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5} diff --git a/IISIntegration.sln b/IISIntegration.sln index 86393ab4b7..d3e7ca4de0 100644 --- a/IISIntegration.sln +++ b/IISIntegration.sln @@ -49,7 +49,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7E80C58E build\testsite.props = build\testsite.props EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISIntegration.FunctionalTests", "test\IISIntegration.FunctionalTests\IISIntegration.FunctionalTests.csproj", "{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISExpress.FunctionalTests", "test\IISExpress.FunctionalTests\IISExpress.FunctionalTests.csproj", "{4E3E1F5C-CD52-4CC0-A35F-D1FA1685D2FA}" ProjectSection(ProjectDependencies) = postProject {7F87406C-A3C8-4139-A68D-E4C344294A67} = {7F87406C-A3C8-4139-A68D-E4C344294A67} EndProjectSection @@ -116,6 +116,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "test\gtest\gtest.v EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandlerLib", "src\AspNetCoreModuleV2\RequestHandlerLib\RequestHandlerLib.vcxproj", "{1533E271-F61B-441B-8B74-59FB61DF0552}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test\IIS.FunctionalTests\IIS.FunctionalTests.csproj", "{1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -380,6 +382,18 @@ Global {1533E271-F61B-441B-8B74-59FB61DF0552}.Release|x64.Build.0 = Release|x64 {1533E271-F61B-441B-8B74-59FB61DF0552}.Release|x86.ActiveCfg = Release|Win32 {1533E271-F61B-441B-8B74-59FB61DF0552}.Release|x86.Build.0 = Release|Win32 + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Debug|x64.ActiveCfg = Debug|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Debug|x64.Build.0 = Debug|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Debug|x86.ActiveCfg = Debug|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Debug|x86.Build.0 = Debug|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Release|Any CPU.Build.0 = Release|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Release|x64.ActiveCfg = Release|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Release|x64.Build.0 = Release|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Release|x86.ActiveCfg = Release|Any CPU + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -411,6 +425,7 @@ Global {340C59FC-C682-4CBA-81F8-791821EC8EDE} = {744ACDC6-F6A0-4FF9-9421-F25C5F2DC520} {CAC1267B-8778-4257-AAC6-CAF481723B01} = {EF30B533-D715-421A-92B7-92FEF460AC9C} {1533E271-F61B-441B-8B74-59FB61DF0552} = {06CA2C2B-83B0-4D83-905A-E0C74790009E} + {1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712} = {EF30B533-D715-421A-92B7-92FEF460AC9C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5} diff --git a/benchmarks/IIS.Performance/IIS.Performance.csproj b/benchmarks/IIS.Performance/IIS.Performance.csproj index 179e042514..87102ca7ed 100644 --- a/benchmarks/IIS.Performance/IIS.Performance.csproj +++ b/benchmarks/IIS.Performance/IIS.Performance.csproj @@ -12,7 +12,7 @@ - + @@ -24,7 +24,7 @@ - + False diff --git a/benchmarks/IIS.Performance/StartupTimeBenchmark.cs b/benchmarks/IIS.Performance/StartupTimeBenchmark.cs index 4e16e33b49..ef66b6b671 100644 --- a/benchmarks/IIS.Performance/StartupTimeBenchmark.cs +++ b/benchmarks/IIS.Performance/StartupTimeBenchmark.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Performance RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { - ServerConfigTemplateContent = File.ReadAllText("Http.config"), + ServerConfigTemplateContent = File.ReadAllText("IISExpress.config"), SiteName = "HttpTestSite", TargetFramework = "netcoreapp2.1", ApplicationType = ApplicationType.Portable, diff --git a/build/repo.props b/build/repo.props index 93ca7cd881..ba3cca9388 100644 --- a/build/repo.props +++ b/build/repo.props @@ -9,11 +9,6 @@ - - - - - diff --git a/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj b/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj deleted file mode 100644 index fe6851d189..0000000000 --- a/test/AspNetCoreModuleTests/AspNetCoreModuleTests.vcxproj +++ /dev/null @@ -1,178 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {0692D963-DB10-4387-B3EA-460FBB9BD9A3} - Win32Proj - AspNetCoreModuleTests - 10.0.15063.0 - NativeUnitTestProject - - - - DynamicLibrary - true - v141 - Unicode - false - - - DynamicLibrary - false - v141 - true - Unicode - false - - - DynamicLibrary - true - v141 - Unicode - false - - - DynamicLibrary - false - v141 - true - Unicode - false - - - - - - - - - - - - - - - - - - - - - true - - - true - - - true - - - true - - - - Use - Level3 - Disabled - $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\CommonLib;..\..\src\AspNetCoreModuleV2\IISLib - _DEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDebug - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Use - Level3 - Disabled - $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\CommonLib;..\..\src\AspNetCoreModuleV2\IISLib - WIN32;_DEBUG;%(PreprocessorDefinitions) - true - MultiThreadedDebug - - - Windows - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\CommonLib;..\..\src\AspNetCoreModuleV2\IISLib - WIN32;NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - - - Windows - true - true - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - Use - MaxSpeed - true - true - $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\CommonLib;..\..\src\AspNetCoreModuleV2\IISLib - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - - - Windows - true - true - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - - - - - - - - - {55494e58-e061-4c4c-a0a8-837008e72f85} - - - {4787a64f-9a3e-4867-a55a-70cb4b2b2ffe} - - - - - - - \ No newline at end of file diff --git a/test/AspNetCoreModuleTests/stdafx.h b/test/AspNetCoreModuleTests/stdafx.h deleted file mode 100644 index 67bd5aa27b..0000000000 --- a/test/AspNetCoreModuleTests/stdafx.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -#pragma once - -#include "targetver.h" - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "stringa.h" -#include "stringu.h" -#include "dbgutil.h" -#include "ahutil.h" -#include "multisz.h" -#include "multisza.h" -#include "base64.h" -#include -#include -#include -#include -#include - -#include "..\..\src\AspNetCoreModuleV2\IISLib\hashtable.h" -#include "..\..\src\AspNetCoreModuleV2\IISLib\stringu.h" -#include "..\..\src\AspNetCoreModuleV2\IISLib\stringa.h" -#include "..\..\src\AspNetCoreModuleV2\IISLib\multisz.h" -#include "..\..\src\AspNetCoreModuleV2\IISLib\dbgutil.h" -#include "..\..\src\AspNetCoreModuleV2\IISLib\ahutil.h" -#include "..\..\src\AspNetCoreModuleV2\IISLib\hashfn.h" - -#include "..\..\src\AspNetCoreModuleV2\CommonLib\hostfxr_utility.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\environmentvariablehash.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\aspnetcoreconfig.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\application.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\utility.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\debugutil.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\requesthandler.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\resources.h" -#include "..\..\src\AspNetCoreModuleV2\CommonLib\aspnetcore_msg.h" - -#include "CppUnitTest.h" diff --git a/test/IISIntegration.FunctionalTests/AppHostConfig/TestServer.config b/test/Common.FunctionalTests/AppHostConfig/HostableWebCore.config similarity index 100% rename from test/IISIntegration.FunctionalTests/AppHostConfig/TestServer.config rename to test/Common.FunctionalTests/AppHostConfig/HostableWebCore.config diff --git a/test/Common.FunctionalTests/AppHostConfig/IIS.config b/test/Common.FunctionalTests/AppHostConfig/IIS.config new file mode 100644 index 0000000000..4d30d2ad0f --- /dev/null +++ b/test/Common.FunctionalTests/AppHostConfig/IIS.config @@ -0,0 +1,741 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/IISIntegration.FunctionalTests/AppHostConfig/Http.config b/test/Common.FunctionalTests/AppHostConfig/IISExpress.config similarity index 99% rename from test/IISIntegration.FunctionalTests/AppHostConfig/Http.config rename to test/Common.FunctionalTests/AppHostConfig/IISExpress.config index b0de53397c..9dfe324091 100644 --- a/test/IISIntegration.FunctionalTests/AppHostConfig/Http.config +++ b/test/Common.FunctionalTests/AppHostConfig/IISExpress.config @@ -344,7 +344,6 @@ - @@ -1033,14 +1032,4 @@ - - - - - - - - - - diff --git a/test/IISIntegration.FunctionalTests/Inprocess/EnvironmentVariableTests.cs b/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs similarity index 95% rename from test/IISIntegration.FunctionalTests/Inprocess/EnvironmentVariableTests.cs rename to test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs index 16467095d8..413aa4c35f 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/EnvironmentVariableTests.cs +++ b/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs @@ -2,14 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class EnvironmentVariableTests { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/FeatureCollectionTests.cs b/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs similarity index 89% rename from test/IISIntegration.FunctionalTests/Inprocess/FeatureCollectionTests.cs rename to test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs index b946446db7..e31dc3dbaa 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/FeatureCollectionTests.cs +++ b/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs @@ -1,16 +1,13 @@ // 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.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class FeatureCollectionTest { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/HelloWorldTests.cs b/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs similarity index 89% rename from test/IISIntegration.FunctionalTests/Inprocess/HelloWorldTests.cs rename to test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs index ebc67312df..1b2ad70600 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/HelloWorldTests.cs +++ b/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs @@ -1,16 +1,13 @@ // 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.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class HelloWorldInProcessTests { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs b/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs similarity index 97% rename from test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs rename to test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs index ae27eb426e..95c05308bd 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs +++ b/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs @@ -3,14 +3,12 @@ using System.Net.Http; using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class InvalidReadWriteOperationTests { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/LargeResponseBodyTests.cs b/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs similarity index 92% rename from test/IISIntegration.FunctionalTests/Inprocess/LargeResponseBodyTests.cs rename to test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs index 3578718ef6..40db2cfdb8 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/LargeResponseBodyTests.cs +++ b/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs @@ -2,14 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class LargeResponseBodyTests { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs b/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs similarity index 96% rename from test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs rename to test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs index 09e3688fbf..3f433b155f 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/ResponseHeaderTests.cs +++ b/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs @@ -1,11 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Linq; using System.Net; using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Net.Http.Headers; using Xunit; @@ -13,7 +11,6 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class ResponseHeaders { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs b/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs similarity index 95% rename from test/IISIntegration.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs rename to test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs index 1bf0f1a483..c39e155e77 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs +++ b/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs @@ -9,7 +9,6 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class ResponseInvalidOrderingTest { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs b/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs similarity index 98% rename from test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs rename to test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs index 020ef00213..74af2e00cb 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/ServerVariablesTest.cs +++ b/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs @@ -11,7 +11,6 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class ServerVariablesTest { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs b/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs similarity index 99% rename from test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs rename to test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs index 122b67f005..9b57d4996b 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs +++ b/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs @@ -13,7 +13,6 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] public class SynchronousReadAndWriteTests { private readonly IISTestSiteFixture _fixture; diff --git a/test/IISIntegration.FunctionalTests/OutOfProcess/HelloWorldTest.cs b/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs similarity index 85% rename from test/IISIntegration.FunctionalTests/OutOfProcess/HelloWorldTest.cs rename to test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs index 659487f51d..876b8e010f 100644 --- a/test/IISIntegration.FunctionalTests/OutOfProcess/HelloWorldTest.cs +++ b/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs @@ -1,8 +1,9 @@ // 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.IO; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; @@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests } public static TestMatrix TestVariants - => TestMatrix.ForServers(ServerType.IISExpress) + => TestMatrix.ForServers(DeployerSelector.ServerType) .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) .WithAllApplicationTypes() .WithAllAncmVersions(); @@ -26,9 +27,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests [MemberData(nameof(TestVariants))] public async Task HelloWorld(TestVariant variant) { + // The default in hosting sets windows auth to true. + // Set it to the IISExpress.config file var deploymentParameters = new DeploymentParameters(variant) { - ApplicationPath = Helpers.GetOutOfProcessTestSitesPath(), + ApplicationPath = Helpers.GetOutOfProcessTestSitesPath() }; var deploymentResult = await DeployAsync(deploymentParameters); @@ -53,9 +56,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests response = await deploymentResult.HttpClient.GetAsync("/Auth"); responseText = await response.Content.ReadAsStringAsync(); - // We adapted the Http.config file to be used for inprocess too. We specify WindowsAuth is enabled - // We now expect that windows auth is enabled rather than disabled. - Assert.True("backcompat;Windows".Equals(responseText) || "latest;Windows".Equals(responseText), "Auth"); + Assert.True("backcompat;Windows".Equals(responseText) || "latest;null".Equals(responseText), "Auth"); } } } diff --git a/test/IISIntegration.FunctionalTests/Properties/AssemblyInfo.cs b/test/Common.FunctionalTests/Properties/AssemblyInfo.cs similarity index 72% rename from test/IISIntegration.FunctionalTests/Properties/AssemblyInfo.cs rename to test/Common.FunctionalTests/Properties/AssemblyInfo.cs index a150572c1f..a3ad8b187e 100644 --- a/test/IISIntegration.FunctionalTests/Properties/AssemblyInfo.cs +++ b/test/Common.FunctionalTests/Properties/AssemblyInfo.cs @@ -1,7 +1,8 @@ // 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. -// All functional tests in this project require a version of IIS express with an updated schema +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; using Xunit; [assembly: CollectionBehavior(DisableTestParallelization = true)] +[assembly: RequiresIIS] diff --git a/test/IISIntegration.FunctionalTests/Utilities/FunctionalTestsBase.cs b/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs similarity index 79% rename from test/IISIntegration.FunctionalTests/Utilities/FunctionalTestsBase.cs rename to test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs index a30387f0dd..c2a9c3682a 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/FunctionalTestsBase.cs +++ b/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs @@ -1,6 +1,7 @@ // 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.IO; using System.Threading.Tasks; using Microsoft.Extensions.Logging.Testing; using Xunit.Abstractions; @@ -24,14 +25,15 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting parameters.EnvironmentVariables[DebugEnvironmentVariable] = "4"; } - // Currently hosting throws if the Servertype = IIS. if (parameters.ServerType == ServerType.IIS) { + // Currently hosting throws if the Servertype = IIS. _deployer = new IISDeployer(parameters, LoggerFactory); } - else + else if (parameters.ServerType == ServerType.IISExpress) { - _deployer = ApplicationDeployerFactory.Create(parameters, LoggerFactory); + parameters.ServerConfigTemplateContent = parameters.ServerConfigTemplateContent ?? File.ReadAllText("IISExpress.config"); + _deployer = new IISExpressDeployer(parameters, LoggerFactory); } var result = await _deployer.DeployAsync(); diff --git a/test/IISIntegration.FunctionalTests/Utilities/Helpers.cs b/test/Common.FunctionalTests/Utilities/Helpers.cs similarity index 97% rename from test/IISIntegration.FunctionalTests/Utilities/Helpers.cs rename to test/Common.FunctionalTests/Utilities/Helpers.cs index cfee3377f2..6915d955ec 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/Helpers.cs +++ b/test/Common.FunctionalTests/Utilities/Helpers.cs @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests // Defaults to inprocess specific deployment parameters public static DeploymentParameters GetBaseDeploymentParameters(string site = "InProcessWebSite") { - return new DeploymentParameters(Helpers.GetTestWebSitePath(site), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) + return new DeploymentParameters(Helpers.GetTestWebSitePath(site), DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { TargetFramework = Tfm.NetCoreApp22, ApplicationType = ApplicationType.Portable, diff --git a/test/IISIntegration.FunctionalTests/Utilities/IISApplication.cs b/test/Common.FunctionalTests/Utilities/IISApplication.cs similarity index 83% rename from test/IISIntegration.FunctionalTests/Utilities/IISApplication.cs rename to test/Common.FunctionalTests/Utilities/IISApplication.cs index faba405c06..662f9315a6 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/IISApplication.cs +++ b/test/Common.FunctionalTests/Utilities/IISApplication.cs @@ -19,13 +19,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting /// internal class IISApplication { - private static readonly TimeSpan _timeout = TimeSpan.FromSeconds(2); - private static readonly TimeSpan _retryDelay = TimeSpan.FromMilliseconds(100); + private static readonly TimeSpan _timeout = TimeSpan.FromSeconds(5); + private static readonly TimeSpan _retryDelay = TimeSpan.FromMilliseconds(200); private readonly ServerManager _serverManager = new ServerManager(); private readonly DeploymentParameters _deploymentParameters; private readonly ILogger _logger; private readonly string _ancmVersion; - private readonly object _syncLock = new object(); + private readonly string _ancmDllName; private readonly string _apphostConfigBackupPath; private static readonly string _apphostConfigPath = Path.Combine( Environment.SystemDirectory, @@ -38,6 +38,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting _deploymentParameters = deploymentParameters; _logger = logger; _ancmVersion = deploymentParameters.AncmVersion.ToString(); + _ancmDllName = deploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2 ? "aspnetcorev2.dll" : "aspnetcore.dll"; WebSiteName = CreateTestSiteName(); AppPoolName = $"{WebSiteName}Pool"; _apphostConfigBackupPath = Path.Combine( @@ -56,12 +57,12 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // Backup currently deployed apphost.config file using (_logger.BeginScope("StartIIS")) { - AddTemporaryAppHostConfig(); var port = uri.Port; if (port == 0) { throw new NotSupportedException("Cannot set port 0 for IIS."); } + AddTemporaryAppHostConfig(); ConfigureAppPool(contentRoot); @@ -177,32 +178,60 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting private void AddTemporaryAppHostConfig() { - File.Copy(_apphostConfigPath, _apphostConfigBackupPath); + RetryFileOperation(() => File.Move(_apphostConfigPath, _apphostConfigBackupPath), + e => _logger.LogWarning($"Failed to backup apphost.config: {e.Message}")); + _logger.LogInformation($"Backed up {_apphostConfigPath} to {_apphostConfigBackupPath}"); + + RetryFileOperation( + () => File.WriteAllText(_apphostConfigPath, _deploymentParameters.ServerConfigTemplateContent ?? File.ReadAllText("IIS.config")), + e => _logger.LogWarning($"Failed to copy IIS.config to apphost.config: {e.Message}")); + + _logger.LogInformation($"Copied contents of IIS.config to {_apphostConfigPath}"); } private void RestoreAppHostConfig() { - RetryHelper.RetryOperation( - () => File.Delete(_apphostConfigPath), - e => _logger.LogWarning($"Failed to delete directory : {e.Message}"), - retryCount: 3, - retryDelayMilliseconds: 100); + if (File.Exists(_apphostConfigPath)) + { + RetryFileOperation( + () => File.Delete(_apphostConfigPath), + e => _logger.LogWarning($"Failed to delete file : {e.Message}")); + } + + RetryFileOperation( + () => File.Move(_apphostConfigBackupPath, _apphostConfigPath), + e => _logger.LogError($"Failed to backup apphost.config: {e.Message}")); - File.Move(_apphostConfigBackupPath, _apphostConfigPath); _logger.LogInformation($"Restored {_apphostConfigPath}."); } + private void RetryFileOperation(Action retryBlock, Action exceptionBlock) + { + RetryHelper.RetryOperation(retryBlock, + exceptionBlock, + retryCount: 10, + retryDelayMilliseconds: 100); + } + private ApplicationPool ConfigureAppPool(string contentRoot) { - var pool = _serverManager.ApplicationPools.Add(AppPoolName); - pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem; - pool.ManagedRuntimeVersion = string.Empty; + try + { + var pool = _serverManager.ApplicationPools.Add(AppPoolName); + pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem; + pool.ManagedRuntimeVersion = string.Empty; - AddEnvironmentVariables(contentRoot, pool); + AddEnvironmentVariables(contentRoot, pool); - _logger.LogInformation($"Configured AppPool {AppPoolName}"); - return pool; + _logger.LogInformation($"Configured AppPool {AppPoolName}"); + return pool; + } + catch (COMException comException) + { + _logger.LogError(File.ReadAllText(_apphostConfigPath)); + throw comException; + } } private void AddEnvironmentVariables(string contentRoot, ApplicationPool pool) @@ -215,6 +244,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { AddEnvironmentVariableToAppPool(envCollection, tuple.Key, tuple.Value); } + AddEnvironmentVariableToAppPool(envCollection, "ASPNETCORE_MODULE_DEBUG_FILE", $"{WebSiteName}.txt"); } catch (COMException comException) { @@ -301,11 +331,11 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting private string GetAncmLocation(string dllRoot) { - var arch = _deploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? @"x64\aspnetcorev2.dll" : @"x86\aspnetcorev2.dll"; + var arch = _deploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{_ancmDllName}" : $@"x86\{_ancmDllName}"; var ancmFile = Path.Combine(dllRoot, arch); if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) { - ancmFile = Path.Combine(dllRoot, "aspnetcorev2.dll"); + ancmFile = Path.Combine(dllRoot, _ancmDllName); if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile))) { throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile); diff --git a/test/IISIntegration.FunctionalTests/Utilities/IISDeployer.cs b/test/Common.FunctionalTests/Utilities/IISDeployer.cs similarity index 93% rename from test/IISIntegration.FunctionalTests/Utilities/IISDeployer.cs rename to test/Common.FunctionalTests/Utilities/IISDeployer.cs index 4f0d5252c9..f3f9d8e7b9 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/IISDeployer.cs +++ b/test/Common.FunctionalTests/Utilities/IISDeployer.cs @@ -49,6 +49,11 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting StartTimer(); var contentRoot = string.Empty; + if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent)) + { + DeploymentParameters.ServerConfigTemplateContent = File.ReadAllText("IIS.config"); + } + _application = new IISApplication(DeploymentParameters, Logger); // For now, only support using published output @@ -90,6 +95,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting Logger.LogInformation(line); } } - } } diff --git a/test/IISIntegration.FunctionalTests/Utilities/IISDeploymentResult.cs b/test/Common.FunctionalTests/Utilities/IISDeploymentResult.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/IISDeploymentResult.cs rename to test/Common.FunctionalTests/Utilities/IISDeploymentResult.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/IISFunctionalTestBase.cs b/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs similarity index 66% rename from test/IISIntegration.FunctionalTests/Utilities/IISFunctionalTestBase.cs rename to test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs index 9c6ba61513..d4c74c551b 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/IISFunctionalTestBase.cs +++ b/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs @@ -5,10 +5,11 @@ using System; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; using Microsoft.AspNetCore.Server.IntegrationTesting; using Xunit.Abstractions; -namespace IISIntegration.FunctionalTests.Utilities +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities { public class IISFunctionalTestBase : FunctionalTestsBase { @@ -18,7 +19,7 @@ namespace IISIntegration.FunctionalTests.Utilities protected string GetServerConfig(Action transform) { - var doc = XDocument.Load("AppHostConfig/Http.config"); + var doc = XDocument.Load(DeployerSelector.ServerType == ServerType.IIS ? "IIS.config" : "IISExpress.config"); transform?.Invoke(doc.Root); return doc.ToString(); } @@ -36,5 +37,15 @@ namespace IISIntegration.FunctionalTests.Utilities .SetAttributeValue("sslFlags", "Ssl, SslNegotiateCert"); }); } + + protected string GetWindowsAuthConfig() + { + return GetServerConfig( + element => { + element.Descendants("windowsAuthentication") + .Single() + .SetAttributeValue("enabled", "true"); + }); + } } } diff --git a/test/IISIntegration.FunctionalTests/Utilities/IISTestSiteCollection.cs b/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/IISTestSiteCollection.cs rename to test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/IISTestSiteFixture.cs b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs similarity index 75% rename from test/IISIntegration.FunctionalTests/Utilities/IISTestSiteFixture.cs rename to test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs index 3cbaefa9e6..d19dad36d0 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/IISTestSiteFixture.cs +++ b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests var logging = AssemblyTestLog.ForAssembly(typeof(IISTestSiteFixture).Assembly); var deploymentParameters = new DeploymentParameters(Helpers.GetInProcessTestSitesPath(), - ServerType.IISExpress, + DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { @@ -30,7 +30,16 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests PublishApplicationBeforeDeployment = true, }; - _deployer = ApplicationDeployerFactory.Create(deploymentParameters, logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture))); + if (deploymentParameters.ServerType == ServerType.IIS) + { + // Currently hosting throws if the Servertype = IIS. + _deployer = new IISDeployer(deploymentParameters, logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture))); + } + else if (deploymentParameters.ServerType == ServerType.IISExpress) + { + _deployer = new IISExpressDeployer(deploymentParameters, logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture))); + } + DeploymentResult = _deployer.DeployAsync().Result; Client = DeploymentResult.HttpClient; BaseUri = DeploymentResult.ApplicationBaseUri; diff --git a/test/IISIntegration.FunctionalTests/Utilities/LoggingHandler.cs b/test/Common.FunctionalTests/Utilities/LoggingHandler.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/LoggingHandler.cs rename to test/Common.FunctionalTests/Utilities/LoggingHandler.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/RetryHandler.cs b/test/Common.FunctionalTests/Utilities/RetryHandler.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/RetryHandler.cs rename to test/Common.FunctionalTests/Utilities/RetryHandler.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs b/test/Common.FunctionalTests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs rename to test/Common.FunctionalTests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/TestConnections.cs b/test/Common.FunctionalTests/Utilities/TestConnections.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/TestConnections.cs rename to test/Common.FunctionalTests/Utilities/TestConnections.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/TestIISUriHelper.cs b/test/Common.FunctionalTests/Utilities/TestIISUriHelper.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Utilities/TestIISUriHelper.cs rename to test/Common.FunctionalTests/Utilities/TestIISUriHelper.cs diff --git a/test/IISIntegration.FunctionalTests/Utilities/TestServer.cs b/test/Common.FunctionalTests/Utilities/TestServer.cs similarity index 97% rename from test/IISIntegration.FunctionalTests/Utilities/TestServer.cs rename to test/Common.FunctionalTests/Utilities/TestServer.cs index 6cd61b1459..5eaaaf3440 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/TestServer.cs +++ b/test/Common.FunctionalTests/Utilities/TestServer.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests private static readonly SemaphoreSlim WebCoreLock = new SemaphoreSlim(1, 1); - // Currently this is hardcoded in TestServer.config + // Currently this is hardcoded in HostableWebCore.config private static readonly int BasePort = 50691; private static readonly Uri BaseUri = new Uri("http://localhost:" + BasePort); @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests LoadLibrary(AspNetCoreModuleDll); set_main_handler(Main); - var startResult = WebCoreActivate(Path.GetFullPath("AppHostConfig/TestServer.config"), null, "Instance"); + var startResult = WebCoreActivate(Path.GetFullPath("HostableWebCore.config"), null, "Instance"); if (startResult != 0) { throw new InvalidOperationException($"Error while running WebCoreActivate: {startResult}"); diff --git a/test/IIS.FunctionalTests/DeployerSelector.cs b/test/IIS.FunctionalTests/DeployerSelector.cs new file mode 100644 index 0000000000..2032b716b9 --- /dev/null +++ b/test/IIS.FunctionalTests/DeployerSelector.cs @@ -0,0 +1,12 @@ +// 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 Microsoft.AspNetCore.Server.IntegrationTesting; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class DeployerSelector + { + public static ServerType ServerType => ServerType.IIS; + } +} diff --git a/test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj b/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj similarity index 90% rename from test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj rename to test/IIS.FunctionalTests/IIS.FunctionalTests.csproj index 544cde26ee..718053f101 100644 --- a/test/IISIntegration.FunctionalTests/IISIntegration.FunctionalTests.csproj +++ b/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj @@ -5,10 +5,7 @@ - - - Never - + @@ -19,6 +16,10 @@ + + + + @@ -26,9 +27,6 @@ - - - @@ -45,7 +43,11 @@ - + + + + + PreserveNewest diff --git a/test/IISIntegration.FunctionalTests/Utilities/SkipIfIISCannotRunAttribute.cs b/test/IIS.FunctionalTests/SkipIISTestAttribute.cs similarity index 92% rename from test/IISIntegration.FunctionalTests/Utilities/SkipIfIISCannotRunAttribute.cs rename to test/IIS.FunctionalTests/SkipIISTestAttribute.cs index aa6c3abd75..6602d1125c 100644 --- a/test/IISIntegration.FunctionalTests/Utilities/SkipIfIISCannotRunAttribute.cs +++ b/test/IIS.FunctionalTests/SkipIISTestAttribute.cs @@ -7,13 +7,12 @@ using System.Linq; using System.Runtime.InteropServices; using System.Security.Principal; using System.Xml.Linq; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] - public sealed class SkipIfIISCannotRunAttribute : Attribute, ITestCondition + public sealed class RequiresIISAttribute : Attribute, ITestCondition { private static readonly bool _isMet; public static readonly string _skipReason; @@ -21,7 +20,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests public bool IsMet => _isMet; public string SkipReason => _skipReason; - static SkipIfIISCannotRunAttribute() + static RequiresIISAttribute() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { diff --git a/test/IISExpress.FunctionalTests/DeployerSelector.cs b/test/IISExpress.FunctionalTests/DeployerSelector.cs new file mode 100644 index 0000000000..5344cbacf0 --- /dev/null +++ b/test/IISExpress.FunctionalTests/DeployerSelector.cs @@ -0,0 +1,12 @@ +// 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 Microsoft.AspNetCore.Server.IntegrationTesting; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class DeployerSelector + { + public static ServerType ServerType => ServerType.IISExpress; + } +} diff --git a/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj b/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj new file mode 100644 index 0000000000..718053f101 --- /dev/null +++ b/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj @@ -0,0 +1,55 @@ + + + + netcoreapp2.2 + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/test/IISIntegration.FunctionalTests/Inprocess/AppOfflineTests.cs b/test/IISExpress.FunctionalTests/InProcess/AppOfflineTests.cs similarity index 95% rename from test/IISIntegration.FunctionalTests/Inprocess/AppOfflineTests.cs rename to test/IISExpress.FunctionalTests/InProcess/AppOfflineTests.cs index d88fad5d21..5cfd7fe7c0 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/AppOfflineTests.cs +++ b/test/IISExpress.FunctionalTests/InProcess/AppOfflineTests.cs @@ -6,7 +6,7 @@ using System.IO; using System.Net; using System.Net.Http; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; using Microsoft.AspNetCore.Server.IntegrationTesting; @@ -14,11 +14,11 @@ using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging; using Xunit; -namespace IISIntegration.FunctionalTests.Inprocess +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Inprocess { - [SkipIfIISExpressSchemaMissingInProcess] public class AppOfflineTests : IISFunctionalTestBase { + // TODO these will differ between IIS and IISExpress [ConditionalFact] public async Task AppOfflineDroppedWhileSiteIsDown_SiteReturns503() { diff --git a/test/IISIntegration.FunctionalTests/Inprocess/AuthenticationTests.cs b/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs similarity index 71% rename from test/IISIntegration.FunctionalTests/Inprocess/AuthenticationTests.cs rename to test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs index a9cc151e6f..c3540d51ee 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/AuthenticationTests.cs +++ b/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs @@ -4,50 +4,48 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Testing.xunit; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { - [Collection(IISTestSiteCollection.Name)] - [SkipIfIISExpressSchemaMissingInProcess] - public class AuthenticationTests + public class AuthenticationTests : IISFunctionalTestBase { - private readonly IISTestSiteFixture _fixture; - public AuthenticationTests(IISTestSiteFixture fixture) - { - _fixture = fixture; - } [ConditionalFact] public async Task Authentication_InProcess() { - var response = await _fixture.Client.GetAsync("/AuthenticationAnonymous"); + var deploymentParameters = Helpers.GetBaseDeploymentParameters(); + deploymentParameters.ServerConfigTemplateContent = GetWindowsAuthConfig(); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.RetryingHttpClient.GetAsync("/AuthenticationAnonymous"); var responseText = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("Anonymous?True", responseText); - response = await _fixture.Client.GetAsync("/AuthenticationRestricted"); + response = await deploymentResult.RetryingHttpClient.GetAsync("/AuthenticationRestricted"); responseText = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString()); Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString()); - response = await _fixture.Client.GetAsync("/AuthenticationRestrictedNTLM"); + response = await deploymentResult.RetryingHttpClient.GetAsync("/AuthenticationRestrictedNTLM"); responseText = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString()); // Note we can't restrict a challenge to a specific auth type, the native auth modules always add themselves. Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString()); - response = await _fixture.Client.GetAsync("/AuthenticationForbidden"); + response = await deploymentResult.RetryingHttpClient.GetAsync("/AuthenticationForbidden"); responseText = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; - var httpClient = _fixture.DeploymentResult.CreateHttpClient(httpClientHandler); + var httpClient = deploymentResult.DeploymentResult.CreateHttpClient(httpClientHandler); response = await httpClient.GetAsync("/AuthenticationAnonymous"); responseText = await response.Content.ReadAsStringAsync(); diff --git a/test/IISIntegration.FunctionalTests/Inprocess/LoggingTests.cs b/test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs similarity index 95% rename from test/IISIntegration.FunctionalTests/Inprocess/LoggingTests.cs rename to test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs index 611434f560..856bf1669f 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/LoggingTests.cs +++ b/test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs @@ -5,8 +5,9 @@ using System; using System.IO; using System.Linq; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging; using Xunit; @@ -14,7 +15,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { public class LoggingTests : IISFunctionalTestBase { - [Theory] + [ConditionalTheory] [InlineData("CheckErrLogFile")] [InlineData("CheckLogFile")] public async Task CheckStdoutLogging(string path) @@ -66,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests } } - [Fact] + [ConditionalFact] public async Task StartupMessagesAreLoggedIntoDebugLogFile() { var tempFile = Path.GetTempFileName(); diff --git a/test/IISIntegration.FunctionalTests/Inprocess/ShutdownTests.cs b/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs similarity index 86% rename from test/IISIntegration.FunctionalTests/Inprocess/ShutdownTests.cs rename to test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs index 9b1eb28eab..69eacfbc43 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/ShutdownTests.cs +++ b/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs @@ -2,15 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; -using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Testing.xunit; using Xunit; using Xunit.Abstractions; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { - [SkipIfIISExpressSchemaMissingInProcess] public class ShutdownTests : IISFunctionalTestBase { diff --git a/test/IISIntegration.FunctionalTests/Inprocess/StartupExceptionTests.cs b/test/IISExpress.FunctionalTests/InProcess/StartupExceptionTests.cs similarity index 91% rename from test/IISIntegration.FunctionalTests/Inprocess/StartupExceptionTests.cs rename to test/IISExpress.FunctionalTests/InProcess/StartupExceptionTests.cs index 0b09c7a465..00b75c3a7c 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/StartupExceptionTests.cs +++ b/test/IISExpress.FunctionalTests/InProcess/StartupExceptionTests.cs @@ -4,15 +4,17 @@ using System; using System.Net; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { + public class StartupExceptionTests : IISFunctionalTestBase { // TODO FileNotFound here. - [Theory] + [ConditionalTheory] [InlineData("CheckLogFile")] [InlineData("CheckErrLogFile")] public async Task CheckStdoutWithRandomNumber(string path) @@ -33,13 +35,15 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests Assert.Contains(TestSink.Writes, context => context.Message.Contains($"Random number: {randomNumberString}")); } - [Theory] + [ConditionalTheory] [InlineData("CheckLargeStdErrWrites")] [InlineData("CheckLargeStdOutWrites")] [InlineData("CheckOversizedStdErrWrites")] [InlineData("CheckOversizedStdOutWrites")] public async Task CheckStdoutWithLargeWrites(string path) { + // Need a web.config + // Also publish issues. var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite"); deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_STARTUP_VALUE"] = path; @@ -54,7 +58,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests Assert.Contains(TestSink.Writes, context => context.Message.Contains(new string('a', 4096))); } - [Fact] + [ConditionalFact] public async Task Gets500_30_ErrorPage() { var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite"); diff --git a/test/IISIntegration.FunctionalTests/Inprocess/StartupTests.cs b/test/IISExpress.FunctionalTests/InProcess/StartupTests.cs similarity index 96% rename from test/IISIntegration.FunctionalTests/Inprocess/StartupTests.cs rename to test/IISExpress.FunctionalTests/InProcess/StartupTests.cs index eda231066a..14bdceb024 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/StartupTests.cs +++ b/test/IISExpress.FunctionalTests/InProcess/StartupTests.cs @@ -6,7 +6,7 @@ using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.CommandLineUtils; @@ -15,7 +15,6 @@ using Xunit.Abstractions; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { - [SkipIfIISExpressSchemaMissingInProcess] public class StartupTests : IISFunctionalTestBase { private readonly string _dotnetLocation = DotNetMuxer.MuxerPathOrDefault(); @@ -98,7 +97,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests } public static TestMatrix TestVariants - => TestMatrix.ForServers(ServerType.IISExpress) + => TestMatrix.ForServers(DeployerSelector.ServerType) .WithTfms(Tfm.NetCoreApp22) .WithAllApplicationTypes() .WithAncmV2InProcess(); @@ -136,7 +135,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests // Defaults to inprocess specific deployment parameters public static DeploymentParameters GetBaseDeploymentParameters(string site = "InProcessWebSite") { - return new DeploymentParameters(Helpers.GetTestWebSitePath(site), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) + return new DeploymentParameters(Helpers.GetTestWebSitePath(site), DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { TargetFramework = Tfm.NetCoreApp22, ApplicationType = ApplicationType.Portable, diff --git a/test/IISIntegration.FunctionalTests/Inprocess/TestServerTest.cs b/test/IISExpress.FunctionalTests/InProcess/TestServerTest.cs similarity index 95% rename from test/IISIntegration.FunctionalTests/Inprocess/TestServerTest.cs rename to test/IISExpress.FunctionalTests/InProcess/TestServerTest.cs index 4b4d3f25c8..a9a7b89fe7 100644 --- a/test/IISIntegration.FunctionalTests/Inprocess/TestServerTest.cs +++ b/test/IISExpress.FunctionalTests/InProcess/TestServerTest.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging.Testing; diff --git a/test/IISIntegration.FunctionalTests/Inprocess/WebSocketTests.cs b/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs similarity index 100% rename from test/IISIntegration.FunctionalTests/Inprocess/WebSocketTests.cs rename to test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs diff --git a/test/IISIntegration.FunctionalTests/OutOfProcess/GlobalVersionTests.cs b/test/IISExpress.FunctionalTests/OutOfProcess/GlobalVersionTests.cs similarity index 97% rename from test/IISIntegration.FunctionalTests/OutOfProcess/GlobalVersionTests.cs rename to test/IISExpress.FunctionalTests/OutOfProcess/GlobalVersionTests.cs index 2bef2b3c16..3edfdafb22 100644 --- a/test/IISIntegration.FunctionalTests/OutOfProcess/GlobalVersionTests.cs +++ b/test/IISExpress.FunctionalTests/OutOfProcess/GlobalVersionTests.cs @@ -6,7 +6,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Xunit; using Xunit.Abstractions; @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests private DeploymentParameters GetGlobalVersionBaseDeploymentParameters() { - return new DeploymentParameters(Helpers.GetOutOfProcessTestSitesPath(), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) + return new DeploymentParameters(Helpers.GetOutOfProcessTestSitesPath(), DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { TargetFramework = Tfm.NetCoreApp22, ApplicationType = ApplicationType.Portable, diff --git a/test/IISIntegration.FunctionalTests/OutOfProcess/HttpsTest.cs b/test/IISExpress.FunctionalTests/OutOfProcess/HttpsTest.cs similarity index 97% rename from test/IISIntegration.FunctionalTests/OutOfProcess/HttpsTest.cs rename to test/IISExpress.FunctionalTests/OutOfProcess/HttpsTest.cs index 15f3c5f3b9..543481ee14 100644 --- a/test/IISIntegration.FunctionalTests/OutOfProcess/HttpsTest.cs +++ b/test/IISExpress.FunctionalTests/OutOfProcess/HttpsTest.cs @@ -4,7 +4,7 @@ using System.Net.Http; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting.Common; using Microsoft.AspNetCore.Testing.xunit; @@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests // IIS Express preregisteres 44300-44399 ports with SSL bindings. // So these 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 + // Test specific to IISExpress public class HttpsTest : IISFunctionalTestBase { public HttpsTest(ITestOutputHelper output) : base(output) @@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests } public static TestMatrix TestVariants - => TestMatrix.ForServers(ServerType.IISExpress) + => TestMatrix.ForServers(DeployerSelector.ServerType) .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) .WithAllAncmVersions(); diff --git a/test/IISIntegration.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs b/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs similarity index 88% rename from test/IISIntegration.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs rename to test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs index 39ae2fe0e3..9aab93a56f 100644 --- a/test/IISIntegration.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs +++ b/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs @@ -4,7 +4,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; @@ -14,12 +14,16 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { public class NtlmAuthenticationTests : IISFunctionalTestBase { + // Test only runs on IISExpress today as our CI machines do not have + // Windows auth installed globally. + // TODO either enable windows auth on our CI or use containers to test this + // behavior public NtlmAuthenticationTests(ITestOutputHelper output) : base(output) { } public static TestMatrix TestVariants - => TestMatrix.ForServers(ServerType.IISExpress) + => TestMatrix.ForServers(DeployerSelector.ServerType) .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) .WithAllAncmVersions(); @@ -31,6 +35,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { ApplicationPath = Helpers.GetOutOfProcessTestSitesPath(), ApplicationBaseUriHint = $"http://localhost:0/", + ServerConfigTemplateContent = GetWindowsAuthConfig() }; var result = await DeployAsync(deploymentParameters); diff --git a/test/IISExpress.FunctionalTests/OutOfProcess/WindowsAuthTests.cs b/test/IISExpress.FunctionalTests/OutOfProcess/WindowsAuthTests.cs new file mode 100644 index 0000000000..83d6a8e20a --- /dev/null +++ b/test/IISExpress.FunctionalTests/OutOfProcess/WindowsAuthTests.cs @@ -0,0 +1,45 @@ +// 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.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class WindowsAuthTests : IISFunctionalTestBase + { + public WindowsAuthTests(ITestOutputHelper output = null) : base(output) + { + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) + .WithAllApplicationTypes() + .WithAllAncmVersions(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task WindowsAuthTest(TestVariant variant) + { + var deploymentParameters = new DeploymentParameters(variant) + { + ApplicationPath = Helpers.GetOutOfProcessTestSitesPath(), + ServerConfigTemplateContent = GetWindowsAuthConfig() + }; + + // The default in hosting sets windows auth to true. + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/Auth"); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.True("backcompat;Windows".Equals(responseText) || "latest;Windows".Equals(responseText), "Auth"); + } + } +} diff --git a/test/IISExpress.FunctionalTests/SkipIISTestAttribute.cs b/test/IISExpress.FunctionalTests/SkipIISTestAttribute.cs new file mode 100644 index 0000000000..15bbb9c26c --- /dev/null +++ b/test/IISExpress.FunctionalTests/SkipIISTestAttribute.cs @@ -0,0 +1,17 @@ +// 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.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class RequiresIISAttribute : Attribute, ITestCondition + { + public bool IsMet => IISExpressAncmSchema.SupportsInProcessHosting; + + public string SkipReason => IISExpressAncmSchema.SkipReason; + } +} diff --git a/test/IISIntegration.FunctionalTests/UpgradeFeatureDetectionTests.cs b/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs similarity index 81% rename from test/IISIntegration.FunctionalTests/UpgradeFeatureDetectionTests.cs rename to test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs index bc54543067..dc64262d00 100644 --- a/test/IISIntegration.FunctionalTests/UpgradeFeatureDetectionTests.cs +++ b/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs @@ -2,11 +2,11 @@ // 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.Threading.Tasks; -using IISIntegration.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; using Xunit; using Xunit.Abstractions; @@ -20,17 +20,18 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { } - [Fact] - public Task UpgradeFeatureDetectionDisabled_InProcess_IISExpress() + [ConditionalFact] + public Task UpgradeFeatureDetectionDisabled_InProcess() { + // fails due to not modifying the apphost.config file. return UpgradeFeatureDetectionDeployer( disableWebSocket: true, Helpers.GetInProcessTestSitesPath(), "Disabled", HostingModel.InProcess); } - [Fact] - public Task UpgradeFeatureDetectionEnabled_InProcess_IISExpress() + [ConditionalFact] + public Task UpgradeFeatureDetectionEnabled_InProcess() { return UpgradeFeatureDetectionDeployer( disableWebSocket: false, @@ -38,8 +39,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests _isWebsocketsSupported, HostingModel.InProcess); } - [Fact] - public Task UpgradeFeatureDetectionDisabled_OutOfProcess_IISExpress() + [ConditionalFact] + public Task UpgradeFeatureDetectionDisabled_OutOfProcess() { return UpgradeFeatureDetectionDeployer( disableWebSocket: true, @@ -47,8 +48,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests "Disabled", HostingModel.OutOfProcess); } - [Fact] - public Task UpgradeFeatureDetectionEnabled_OutOfProcess_IISExpress() + [ConditionalFact] + public Task UpgradeFeatureDetectionEnabled_OutOfProcess() { return UpgradeFeatureDetectionDeployer( disableWebSocket: false, @@ -58,17 +59,18 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests private async Task UpgradeFeatureDetectionDeployer(bool disableWebSocket, string sitePath, string expected, HostingModel hostingModel) { - var deploymentParameters = new DeploymentParameters(sitePath, ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) + var deploymentParameters = new DeploymentParameters(sitePath, DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { TargetFramework = Tfm.NetCoreApp22, ApplicationType = ApplicationType.Portable, AncmVersion = AncmVersion.AspNetCoreModuleV2, HostingModel = hostingModel, - PublishApplicationBeforeDeployment = hostingModel == HostingModel.InProcess, + PublishApplicationBeforeDeployment = hostingModel == HostingModel.InProcess }; if (disableWebSocket) { + // For IIS, we need to modify the apphost.config file deploymentParameters.ServerConfigTemplateContent = GetServerConfig( element => element.Descendants("webSocket") .Single() diff --git a/test/IISIntegration.FunctionalTests/Inprocess/IISTests.cs b/test/IISIntegration.FunctionalTests/Inprocess/IISTests.cs deleted file mode 100644 index 040f03fcad..0000000000 --- a/test/IISIntegration.FunctionalTests/Inprocess/IISTests.cs +++ /dev/null @@ -1,40 +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.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; -using Microsoft.AspNetCore.Testing.xunit; -using Xunit; - -namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests -{ - [SkipIfIISCannotRun] - public class IISTests : FunctionalTestsBase - { - [ConditionalFact] - public Task HelloWorld_IIS_CoreClr_X64_Standalone() - { - return HelloWorld(RuntimeFlavor.CoreClr, ApplicationType.Standalone); - } - - [ConditionalFact] - public Task HelloWorld_IIS_CoreClr_X64_Portable() - { - return HelloWorld(RuntimeFlavor.CoreClr, ApplicationType.Portable); - } - - private async Task HelloWorld(RuntimeFlavor runtimeFlavor, ApplicationType applicationType) - { - var deploymentParameters = Helpers.GetBaseDeploymentParameters(); - deploymentParameters.ServerType = ServerType.IIS; - deploymentParameters.ApplicationType = applicationType; - - var deploymentResult = await DeployAsync(deploymentParameters); - - var response = await deploymentResult.RetryingHttpClient.GetAsync("HelloWorld"); - var responseText = await response.Content.ReadAsStringAsync(); - - Assert.Equal("Hello World", responseText); - } - } -} diff --git a/test/WebSites/InProcessWebSite/Startup.WebSockets.cs b/test/WebSites/InProcessWebSite/Startup.WebSockets.cs index f3fcdb3a1d..e83ae2a72f 100644 --- a/test/WebSites/InProcessWebSite/Startup.WebSockets.cs +++ b/test/WebSites/InProcessWebSite/Startup.WebSockets.cs @@ -8,7 +8,7 @@ using System.Net.WebSockets; using System.Text; using System.Threading; using System.Threading.Tasks; -using IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; diff --git a/test/WebSites/OutOfProcessWebSite/Startup.cs b/test/WebSites/OutOfProcessWebSite/Startup.cs index fc7021c992..185aecb7f4 100644 --- a/test/WebSites/OutOfProcessWebSite/Startup.cs +++ b/test/WebSites/OutOfProcessWebSite/Startup.cs @@ -98,6 +98,7 @@ namespace TestSites } catch(UnauthorizedAccessException) { + // TODO calling delete on the file will succeed when running with IIS return context.Response.WriteAsync("Hello World"); } diff --git a/test/WebSites/StressTestWebSite/Startup.cs b/test/WebSites/StressTestWebSite/Startup.cs index 41eea8728c..68f6eb1f77 100644 --- a/test/WebSites/StressTestWebSite/Startup.cs +++ b/test/WebSites/StressTestWebSite/Startup.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using System.Threading; using System.Text; using System.Net.WebSockets; -using IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; diff --git a/test/WebSites/shared/WebSockets/Constants.cs b/test/WebSites/shared/WebSockets/Constants.cs index 3a27d854f5..95b53003cc 100644 --- a/test/WebSites/shared/WebSockets/Constants.cs +++ b/test/WebSites/shared/WebSockets/Constants.cs @@ -1,7 +1,7 @@ // 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 IISIntegration.FunctionalTests +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { public static class Constants { diff --git a/test/WebSites/shared/WebSockets/HandshakeHelpers.cs b/test/WebSites/shared/WebSockets/HandshakeHelpers.cs index d477f9113b..b079ea3f85 100644 --- a/test/WebSites/shared/WebSockets/HandshakeHelpers.cs +++ b/test/WebSites/shared/WebSockets/HandshakeHelpers.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Security.Cryptography; using System.Text; -namespace IISIntegration.FunctionalTests +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { internal static class HandshakeHelpers {