diff --git a/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h b/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h index 5245af06d5..cd565e2c01 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h +++ b/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h @@ -111,7 +111,8 @@ private: // we currently limit the size of m_pstrErrorInfo to 5000, be careful if you want to change its payload // APPLICATION_MANAGER() : m_pApplicationInfoHash(NULL), - m_hostingModel(HOSTING_UNKNOWN) + m_hostingModel(HOSTING_UNKNOWN), + m_fDebugInitialize(FALSE) { InitializeSRWLock(&m_srwLock); } @@ -120,4 +121,5 @@ private: static APPLICATION_MANAGER *sm_pApplicationManager; SRWLOCK m_srwLock; APP_HOSTING_MODEL m_hostingModel; + BOOL m_fDebugInitialize; }; diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx b/src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx index 71fb2e464f..c65222b10e 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx +++ b/src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx @@ -38,6 +38,15 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo( *ppApplicationInfo = NULL; + if (!m_fDebugInitialize) + { + SRWExclusiveLock lock(m_srwLock); + if (!m_fDebugInitialize) + { + DebugInitializeFromConfig(*pServer, *pHttpContext->GetApplication()); + m_fDebugInitialize = TRUE; + } + } // The configuration path is unique for each application and is used for the // key in the applicationInfoHash. pszApplicationId = pHttpContext->GetApplication()->GetApplicationId(); diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/aspnetcore_shim_config.cpp b/src/AspNetCoreModuleV2/AspNetCore/src/aspnetcore_shim_config.cpp index 9fb17be078..a857706142 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/aspnetcore_shim_config.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/src/aspnetcore_shim_config.cpp @@ -58,7 +58,7 @@ ASPNETCORE_SHIM_CONFIG::Populate( if (m_hostingModel == HOSTING_OUT_PROCESS) { - RETURN_IF_FAILED(ConfigUtility::FindHandlerVersion(pAspNetCoreElement, &m_struHandlerVersion)); + RETURN_IF_FAILED(ConfigUtility::FindHandlerVersion(pAspNetCoreElement, m_struHandlerVersion)); } return S_OK; diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp b/src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp index 03196a316d..d185ad4be4 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp @@ -25,6 +25,7 @@ BOOL g_fAspnetcoreRHLoadedError = FALSE; BOOL g_fInShutdown = FALSE; DWORD g_dwActiveServerProcesses = 0; SRWLOCK g_srwLock; + PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication; VOID diff --git a/src/AspNetCoreModuleV2/CommonLib/config_utility.h b/src/AspNetCoreModuleV2/CommonLib/config_utility.h index 5585d14614..ae4aeb0466 100644 --- a/src/AspNetCoreModuleV2/CommonLib/config_utility.h +++ b/src/AspNetCoreModuleV2/CommonLib/config_utility.h @@ -7,24 +7,49 @@ #include "ahutil.h" #include "stringu.h" #include "exceptions.h" +#include "atlbase.h" class ConfigUtility { #define CS_ASPNETCORE_HANDLER_SETTINGS L"handlerSettings" #define CS_ASPNETCORE_HANDLER_VERSION L"handlerVersion" + #define CS_ASPNETCORE_DEBUG_FILE L"debugFile" + #define CS_ASPNETCORE_DEBUG_LEVEL L"debugLevel" #define CS_ASPNETCORE_HANDLER_SETTINGS_NAME L"name" #define CS_ASPNETCORE_HANDLER_SETTINGS_VALUE L"value" public: static HRESULT - FindHandlerVersion(IAppHostElement* pElement, STRU* strHandlerVersionValue) + FindHandlerVersion(IAppHostElement* pElement, STRU& strHandlerVersionValue) + { + return FindKeyValuePair(pElement, CS_ASPNETCORE_HANDLER_VERSION, strHandlerVersionValue); + } + + static + HRESULT + FindDebugFile(IAppHostElement* pElement, STRU& strDebugFile) + { + return FindKeyValuePair(pElement, CS_ASPNETCORE_DEBUG_FILE, strDebugFile); + } + + static + HRESULT + FindDebugLevel(IAppHostElement* pElement, STRU& strDebugFile) + { + return FindKeyValuePair(pElement, CS_ASPNETCORE_DEBUG_LEVEL, strDebugFile); + } + +private: + static + HRESULT + FindKeyValuePair(IAppHostElement* pElement, PCWSTR key, STRU& strHandlerVersionValue) { HRESULT hr; CComPtr pHandlerSettings = nullptr; CComPtr pHandlerSettingsCollection = nullptr; CComPtr pHandlerVar = nullptr; - ENUM_INDEX index {}; + ENUM_INDEX index{}; STRU strHandlerName; STRU strHandlerValue; @@ -43,9 +68,9 @@ public: RETURN_IF_FAILED(GetElementStringProperty(pHandlerVar, CS_ASPNETCORE_HANDLER_SETTINGS_NAME, &strHandlerName)); RETURN_IF_FAILED(GetElementStringProperty(pHandlerVar, CS_ASPNETCORE_HANDLER_SETTINGS_VALUE, &strHandlerValue)); - if (strHandlerName.Equals(CS_ASPNETCORE_HANDLER_VERSION, TRUE)) + if (strHandlerName.Equals(key, TRUE)) { - RETURN_IF_FAILED(strHandlerVersionValue->Copy(strHandlerValue)); + RETURN_IF_FAILED(strHandlerVersionValue.Copy(strHandlerValue)); break; } diff --git a/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp b/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp index cd8ca3ea05..09becc9010 100644 --- a/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp +++ b/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp @@ -10,9 +10,12 @@ #include "dbgutil.h" #include "Environment.h" #include "SRWExclusiveLock.h" +#include "exceptions.h" +#include "atlbase.h" +#include "config_utility.h" -inline HANDLE g_hStandardOutput; -inline HANDLE g_logFile; +inline HANDLE g_hStandardOutput = INVALID_HANDLE_VALUE; +inline HANDLE g_logFile = INVALID_HANDLE_VALUE; inline SRWLOCK g_logFileLock; VOID @@ -21,6 +24,8 @@ DebugInitialize() g_hStandardOutput = GetStdHandle(STD_OUTPUT_HANDLE); HKEY hKey; + InitializeSRWLock(&g_logFileLock); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module V2\\Parameters", @@ -47,18 +52,9 @@ DebugInitialize() RegCloseKey(hKey); } - // We expect single digit value and a null char - const size_t environmentVariableValueSize = 2; - std::wstring environmentVariableValue(environmentVariableValueSize, '\0'); - try { - const auto value = std::stoi(Environment::GetEnvironmentVariableValue(L"ASPNETCORE_MODULE_DEBUG").value_or(L"0")); - - if (value >= 1) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_ERROR; - if (value >= 2) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_WARNING; - if (value >= 3) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_INFO; - if (value >= 4) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_CONSOLE; + SetDebugFlags(Environment::GetEnvironmentVariableValue(L"ASPNETCORE_MODULE_DEBUG").value_or(L"0")); } catch (...) { @@ -69,9 +65,73 @@ DebugInitialize() { const auto debugOutputFile = Environment::GetEnvironmentVariableValue(L"ASPNETCORE_MODULE_DEBUG_FILE"); - if (debugOutputFile.has_value()) + CreateDebugLogFile(debugOutputFile.value_or(L"")); + } + catch (...) + { + // ignore + } +} + +HRESULT +DebugInitializeFromConfig(IHttpServer& pHttpServer, IHttpApplication& pHttpApplication) +{ + CComPtr pAspNetCoreElement; + + const CComBSTR bstrAspNetCoreSection = L"system.webServer/aspNetCore"; + CComBSTR bstrConfigPath = pHttpApplication.GetAppConfigPath(); + + RETURN_IF_FAILED(pHttpServer.GetAdminManager()->GetAdminSection(bstrAspNetCoreSection, + bstrConfigPath, + &pAspNetCoreElement)); + + STRU debugFile; + RETURN_IF_FAILED(ConfigUtility::FindDebugFile(pAspNetCoreElement, debugFile)); + + STRU debugValue; + RETURN_IF_FAILED(ConfigUtility::FindDebugLevel(pAspNetCoreElement, debugValue)); + + SetDebugFlags(debugFile.QueryStr()); + + CreateDebugLogFile(debugFile.QueryStr()); + + return S_OK; +} + +void SetDebugFlags(const std::wstring &debugValue) +{ + try + { + if (!debugValue.empty()) { - g_logFile = CreateFileW(debugOutputFile.value().c_str(), + const auto value = std::stoi(debugValue.c_str()); + + if (value >= 1) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_ERROR; + if (value >= 2) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_WARNING; + if (value >= 3) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_INFO; + if (value >= 4) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_CONSOLE; + } + } + catch (...) + { + // ignore + } +} + +void CreateDebugLogFile(const std::wstring &debugOutputFile) +{ + try + { + if (!debugOutputFile.empty()) + { + if (g_logFile != INVALID_HANDLE_VALUE) + { + WLOG_INFOF(L"Switching debug log files to %s", debugOutputFile.c_str()); + CloseHandle(g_logFile); + DEBUG_FLAGS_VAR &= ~ASPNETCORE_DEBUG_FLAG_FILE; + + } + g_logFile = CreateFileW(debugOutputFile.c_str(), (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), nullptr, @@ -81,11 +141,9 @@ DebugInitialize() ); if (g_logFile != INVALID_HANDLE_VALUE) { - InitializeSRWLock(&g_logFileLock); DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_FILE; } } - } catch (...) { diff --git a/src/AspNetCoreModuleV2/CommonLib/debugutil.h b/src/AspNetCoreModuleV2/CommonLib/debugutil.h index 0a21a6d51a..b5f4075de2 100644 --- a/src/AspNetCoreModuleV2/CommonLib/debugutil.h +++ b/src/AspNetCoreModuleV2/CommonLib/debugutil.h @@ -3,6 +3,8 @@ #pragma once +#include "stdafx.h" +#include "stringu.h" #include #include "dbgutil.h" @@ -27,6 +29,14 @@ VOID DebugInitialize(); +VOID +CreateDebugLogFile(const std::wstring &debugOutputFile); + +HRESULT +DebugInitializeFromConfig(IHttpServer& pHttpServer, IHttpApplication& pHttpApplication); + +void SetDebugFlags(const std::wstring &value); + VOID DebugStop(); diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx b/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx index e1bc9ac143..f7b985aa0b 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx @@ -25,7 +25,8 @@ HANDLE g_hEventLog = NULL; HRESULT InitializeGlobalConfiguration( - IHttpServer * pServer + IHttpServer * pServer, + IHttpApplication* pHttpApplication ) { if (!g_fGlobalInitialize) @@ -48,6 +49,8 @@ InitializeGlobalConfiguration( } DebugInitialize(); + DebugInitializeFromConfig(*pServer, *pHttpApplication); + g_fGlobalInitialize = TRUE; } } @@ -87,10 +90,9 @@ CreateApplication( _Out_ IAPPLICATION **ppApplication ) { - try { - RETURN_IF_FAILED(InitializeGlobalConfiguration(pServer)); + RETURN_IF_FAILED(InitializeGlobalConfiguration(pServer, pHttpApplication)); REQUESTHANDLER_CONFIG *pConfig = nullptr; RETURN_IF_FAILED(REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(pServer, pHttpApplication, &pConfig)); diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp b/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp index 4f5a253f9e..0af41d0f1c 100644 --- a/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp +++ b/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp @@ -5,6 +5,9 @@ #include "requesthandler_config.h" #include "debugutil.h" #include "environmentvariablehash.h" +#include "exceptions.h" +#include "config_utility.h" + REQUESTHANDLER_CONFIG::~REQUESTHANDLER_CONFIG() { diff --git a/test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs b/test/Common.FunctionalTests/Inprocess/LoggingTests.cs similarity index 73% rename from test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs rename to test/Common.FunctionalTests/Inprocess/LoggingTests.cs index 6d8e73a15c..1ac8c9e1d8 100644 --- a/test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs +++ b/test/Common.FunctionalTests/Inprocess/LoggingTests.cs @@ -91,5 +91,36 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests } } + [ConditionalFact] + [SkipIIS] + public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig() + { + var firstTempFile = Path.GetTempFileName(); + var secondTempFile = Path.GetTempFileName(); + + try + { + var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true); + deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG_FILE"] = firstTempFile; + + var deploymentResult = await DeployAsync(deploymentParameters); + Helpers.AddDebugLogToWebConfig(deploymentParameters.PublishedApplicationRootPath, secondTempFile); + + var response = await deploymentResult.RetryingHttpClient.GetAsync("/"); + + StopServer(); + var logContents = File.ReadAllText(firstTempFile); + Assert.Contains("Switching debug log files to", logContents); + + var secondLogContents = File.ReadAllText(secondTempFile); + Assert.Contains("[aspnetcorev2.dll]", logContents); + Assert.Contains("[aspnetcorev2_inprocess.dll]", logContents); + } + finally + { + File.Delete(firstTempFile); + File.Delete(secondTempFile); + } + } } } diff --git a/test/IISExpress.FunctionalTests/InProcess/StartupExceptionTests.cs b/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs similarity index 84% rename from test/IISExpress.FunctionalTests/InProcess/StartupExceptionTests.cs rename to test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs index 00b75c3a7c..d39ed68c24 100644 --- a/test/IISExpress.FunctionalTests/InProcess/StartupExceptionTests.cs +++ b/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs @@ -10,16 +10,18 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { - public class StartupExceptionTests : IISFunctionalTestBase { - // TODO FileNotFound here. [ConditionalTheory] [InlineData("CheckLogFile")] [InlineData("CheckErrLogFile")] public async Task CheckStdoutWithRandomNumber(string path) { - var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite"); + // Forcing publish for now to have parity between IIS and IISExpress + // Reason is because by default for IISExpress, we expect there to not be a web.config file. + // However, for IIS, we need a web.config file because the default on generated on publish + // doesn't include V2. We can remove the publish flag once IIS supports non-publish running + var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite", publish: true); deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_STARTUP_VALUE"] = path; var randomNumberString = new Random(Guid.NewGuid().GetHashCode()).Next(10000000).ToString(); deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_RANDOM_VALUE"] = randomNumberString; @@ -42,9 +44,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests [InlineData("CheckOversizedStdOutWrites")] public async Task CheckStdoutWithLargeWrites(string path) { - // Need a web.config - // Also publish issues. - var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite"); + var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite", publish: true); deploymentParameters.EnvironmentVariables["ASPNETCORE_INPROCESS_STARTUP_VALUE"] = path; var deploymentResult = await DeployAsync(deploymentParameters); @@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests [ConditionalFact] public async Task Gets500_30_ErrorPage() { - var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite"); + var deploymentParameters = Helpers.GetBaseDeploymentParameters("StartupExceptionWebsite", publish: true); var deploymentResult = await DeployAsync(deploymentParameters); diff --git a/test/Common.FunctionalTests/Utilities/Helpers.cs b/test/Common.FunctionalTests/Utilities/Helpers.cs index f4114730b3..8ab128e15f 100644 --- a/test/Common.FunctionalTests/Utilities/Helpers.cs +++ b/test/Common.FunctionalTests/Utilities/Helpers.cs @@ -52,6 +52,41 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests config.Save(webConfigFile); } + public static void AddDebugLogToWebConfig(string contentRoot, string filename) + { + var path = Path.Combine(contentRoot, "web.config"); + var webconfig = XDocument.Load(path); + var xElement = webconfig.Descendants("aspNetCore").Single(); + + var element = xElement.Descendants("handlerSettings").SingleOrDefault(); + if (element == null) + { + element = new XElement("handlerSettings"); + xElement.Add(element); + } + + CreateOrSetElement(element, "debugLevel", "4"); + + CreateOrSetElement(element, "debugFile", Path.Combine(contentRoot, filename)); + + webconfig.Save(path); + } + + private static void CreateOrSetElement(XElement rootElement, string name, string value) + { + if (rootElement.Descendants() + .Attributes() + .Where(attribute => attribute.Value == name) + .Any()) + { + return; + } + var element = new XElement("handlerSetting"); + element.SetAttributeValue("name", name); + element.SetAttributeValue("value", value); + rootElement.Add(element); + } + // Defaults to inprocess specific deployment parameters public static DeploymentParameters GetBaseDeploymentParameters(string site = null, HostingModel hostingModel = HostingModel.InProcess, bool publish = false) { @@ -72,5 +107,6 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests private static string GetWebConfigFile(IISDeploymentResult deploymentResult) => Path.Combine(deploymentResult.DeploymentResult.ContentRoot, "web.config"); + } } diff --git a/test/Common.FunctionalTests/Utilities/IISApplication.cs b/test/Common.FunctionalTests/Utilities/IISApplication.cs index 662f9315a6..ea8a95b99d 100644 --- a/test/Common.FunctionalTests/Utilities/IISApplication.cs +++ b/test/Common.FunctionalTests/Utilities/IISApplication.cs @@ -221,6 +221,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting var pool = _serverManager.ApplicationPools.Add(AppPoolName); pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem; pool.ManagedRuntimeVersion = string.Empty; + pool.StartMode = StartMode.AlwaysRunning; AddEnvironmentVariables(contentRoot, pool); @@ -244,7 +245,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { AddEnvironmentVariableToAppPool(envCollection, tuple.Key, tuple.Value); } - AddEnvironmentVariableToAppPool(envCollection, "ASPNETCORE_MODULE_DEBUG_FILE", $"{WebSiteName}.txt"); } catch (COMException comException) { diff --git a/test/Common.FunctionalTests/Utilities/IISDeployer.cs b/test/Common.FunctionalTests/Utilities/IISDeployer.cs index f3f9d8e7b9..8104a47a1c 100644 --- a/test/Common.FunctionalTests/Utilities/IISDeployer.cs +++ b/test/Common.FunctionalTests/Utilities/IISDeployer.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Server.IntegrationTesting @@ -58,13 +59,14 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting // For now, only support using published output DeploymentParameters.PublishApplicationBeforeDeployment = true; - if (DeploymentParameters.PublishApplicationBeforeDeployment) { DotnetPublish(); contentRoot = DeploymentParameters.PublishedApplicationRootPath; } + Helpers.AddDebugLogToWebConfig(contentRoot, Path.Combine(contentRoot, $"{_application.WebSiteName}.txt")); + var uri = TestIISUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint); // To prevent modifying the IIS setup concurrently. await _application.StartIIS(uri, contentRoot); diff --git a/test/Common.FunctionalTests/Utilities/SkipIISAttribute.cs b/test/Common.FunctionalTests/Utilities/SkipIISAttribute.cs new file mode 100644 index 0000000000..da90b513f8 --- /dev/null +++ b/test/Common.FunctionalTests/Utilities/SkipIISAttribute.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 SkipIISAttribute : Attribute, ITestCondition + { + public bool IsMet => DeployerSelector.ServerType == ServerType.IIS; + + public string SkipReason => "Cannot run test on full IIS."; + } +} diff --git a/test/CommonLibTests/ConfigUtilityTests.cpp b/test/CommonLibTests/ConfigUtilityTests.cpp index dac87240e1..9b5bf6e9e6 100644 --- a/test/CommonLibTests/ConfigUtilityTests.cpp +++ b/test/CommonLibTests/ConfigUtilityTests.cpp @@ -13,7 +13,7 @@ namespace ConfigUtilityTests class ConfigUtilityTest : public Test { protected: - void Test(std::wstring key, std::wstring value, std::wstring expected) + void TestHandlerVersion(std::wstring key, std::wstring value, std::wstring expected, HRESULT(*func)(IAppHostElement*, STRU&)) { IAppHostElement* retElement = NULL; @@ -40,7 +40,7 @@ namespace ConfigUtilityTests .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(key.c_str())), testing::Return(S_OK))) .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(value.c_str())), testing::Return(S_OK))); - HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), &handlerVersion); + HRESULT hr = func(element.get(), handlerVersion); EXPECT_EQ(hr, S_OK); EXPECT_STREQ(handlerVersion.QueryStr(), expected.c_str()); @@ -49,12 +49,29 @@ namespace ConfigUtilityTests TEST_F(ConfigUtilityTest, CheckHandlerVersionKeysAndValues) { - Test(L"handlerVersion", L"value", L"value"); - Test(L"handlerversion", L"value", L"value"); - Test(L"HandlerversioN", L"value", L"value"); - Test(L"randomvalue", L"value", L""); - Test(L"", L"value", L""); - Test(L"", L"", L""); + auto func = ConfigUtility::FindHandlerVersion; + TestHandlerVersion(L"handlerVersion", L"value", L"value", func); + TestHandlerVersion(L"handlerversion", L"value", L"value", func); + TestHandlerVersion(L"HandlerversioN", L"value", L"value", func); + TestHandlerVersion(L"randomvalue", L"value", L"", func); + TestHandlerVersion(L"", L"value", L"", func); + TestHandlerVersion(L"", L"", L"", func); + } + + TEST_F(ConfigUtilityTest, CheckDebugLogFile) + { + auto func = ConfigUtility::FindDebugFile; + + TestHandlerVersion(L"debugFile", L"value", L"value", func); + TestHandlerVersion(L"debugFILE", L"value", L"value", func); + } + + TEST_F(ConfigUtilityTest, CheckDebugLevel) + { + auto func = ConfigUtility::FindDebugLevel; + + TestHandlerVersion(L"debugLevel", L"value", L"value", func); + TestHandlerVersion(L"debugLEVEL", L"value", L"value", func); } TEST(ConfigUtilityTestSingle, MultipleElements) @@ -84,7 +101,7 @@ namespace ConfigUtilityTests .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"handlerVersion")), testing::Return(S_OK))) .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"value2")), testing::Return(S_OK))); - HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), &handlerVersion); + HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), handlerVersion); EXPECT_EQ(hr, S_OK); EXPECT_STREQ(handlerVersion.QueryStr(), L"value2"); @@ -98,7 +115,7 @@ namespace ConfigUtilityTests ON_CALL(*element, GetElementByName(_, _)) .WillByDefault(DoAll(testing::SetArgPointee<1>(nullptr), testing::Return(HRESULT_FROM_WIN32( ERROR_INVALID_INDEX )))); - HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), &handlerVersion); + HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), handlerVersion); EXPECT_EQ(hr, S_OK); EXPECT_STREQ(handlerVersion.QueryStr(), L""); diff --git a/test/IIS.FunctionalTests/SkipIISTestAttribute.cs b/test/IIS.FunctionalTests/RequiresAttribute.cs similarity index 100% rename from test/IIS.FunctionalTests/SkipIISTestAttribute.cs rename to test/IIS.FunctionalTests/RequiresAttribute.cs diff --git a/test/IISExpress.FunctionalTests/SkipIISTestAttribute.cs b/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs similarity index 100% rename from test/IISExpress.FunctionalTests/SkipIISTestAttribute.cs rename to test/IISExpress.FunctionalTests/RequiresIISAttribute.cs diff --git a/test/WebSites/StartupExceptionWebSite/web.config b/test/WebSites/StartupExceptionWebSite/web.config new file mode 100644 index 0000000000..0c7405e4d1 --- /dev/null +++ b/test/WebSites/StartupExceptionWebSite/web.config @@ -0,0 +1,10 @@ + + + + + + + + + +