diff --git a/IISIntegration.NoV1.sln b/IISIntegration.NoV1.sln
index 04bda53889..b9b82faf5a 100644
--- a/IISIntegration.NoV1.sln
+++ b/IISIntegration.NoV1.sln
@@ -111,6 +111,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandlerLib", "src\As
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test\IIS.FunctionalTests\IIS.FunctionalTests.csproj", "{D182103F-8405-4647-B158-C36F598657EF}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IntegrationTesting.IIS", "src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj", "{34135ED7-313D-4E68-860C-D6B51AA28523}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -367,6 +369,18 @@ Global
{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
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Debug|x64.Build.0 = Debug|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Debug|x86.Build.0 = Debug|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x64.ActiveCfg = Release|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x64.Build.0 = Release|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x86.ActiveCfg = Release|Any CPU
+ {34135ED7-313D-4E68-860C-D6B51AA28523}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -396,6 +410,7 @@ Global
{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}
+ {34135ED7-313D-4E68-860C-D6B51AA28523} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
diff --git a/IISIntegration.sln b/IISIntegration.sln
index d3e7ca4de0..c21a81482f 100644
--- a/IISIntegration.sln
+++ b/IISIntegration.sln
@@ -118,6 +118,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RequestHandlerLib", "src\As
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.FunctionalTests", "test\IIS.FunctionalTests\IIS.FunctionalTests.csproj", "{1F0C8D9B-F47B-41F3-9FC9-6954B6DC7712}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IntegrationTesting.IIS", "src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj", "{CE4FB142-91FB-4B34-BC96-A31120EF4009}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -394,6 +396,18 @@ Global
{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
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Debug|x64.Build.0 = Debug|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Debug|x86.Build.0 = Debug|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x64.ActiveCfg = Release|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x64.Build.0 = Release|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x86.ActiveCfg = Release|Any CPU
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -426,6 +440,7 @@ Global
{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}
+ {CE4FB142-91FB-4B34-BC96-A31120EF4009} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB4F868D-E1AE-4FD7-9333-69FA15B268C5}
diff --git a/build/dependencies.props b/build/dependencies.props
index 18a4940549..289811b4d3 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -22,7 +22,6 @@
15.6.82
15.6.82
3.0.0-alpha1-10044
- 3.0.0-alpha1-10044
3.0.0-alpha1-10044
3.0.0-alpha1-10044
3.0.0-alpha1-10044
@@ -32,9 +31,8 @@
3.0.0-alpha1-10044
3.0.0-alpha1-10044
3.0.0-alpha1-10044
- 3.0.0-alpha1-10044
- 2.0.0
- 2.1.0
+ 2.0.7
+ 2.1.1
2.2.0-preview1-26618-02
3.0.0-alpha1-10044
15.6.1
diff --git a/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj
index 1a80711d26..c0d926bd35 100644
--- a/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj
+++ b/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj
@@ -79,7 +79,7 @@
Level4
Disabled
WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
$(IntDir)$(TargetName).pch
..\IISLib;.\Inc;..\CommonLib
ProgramDatabase
@@ -97,7 +97,7 @@
true
true
stdcpp17
- precomp.hxx
+ stdafx.h
Windows
@@ -115,7 +115,7 @@
Level4
Disabled
WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
$(IntDir)$(TargetName).pch
..\IISLib;.\Inc;..\CommonLib
ProgramDatabase
@@ -133,7 +133,7 @@
true
true
stdcpp17
- precomp.hxx
+ stdafx.h
Windows
@@ -155,7 +155,7 @@
true
WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)
..\IISLib;.\Inc;..\CommonLib
- precomp.hxx
+ stdafx.h
MultiThreaded
true
true
@@ -170,7 +170,7 @@
true
true
stdcpp17
- precomp.hxx
+ stdafx.h
Windows
@@ -193,7 +193,7 @@
true
true
WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
..\IISLib;.\Inc;..\CommonLib
MultiThreaded
true
@@ -209,7 +209,7 @@
true
true
stdcpp17
- precomp.hxx
+ stdafx.h
Windows
@@ -225,26 +225,26 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
Create
Create
Create
Create
-
+
diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp b/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp
rename to src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp
diff --git a/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationinfo.h b/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.h
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/Inc/applicationinfo.h
rename to src/AspNetCoreModuleV2/AspNetCore/applicationinfo.h
diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx b/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp
similarity index 97%
rename from src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx
rename to src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp
index 71fb2e464f..c65222b10e 100644
--- a/src/AspNetCoreModuleV2/AspNetCore/src/applicationmanager.cxx
+++ b/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp
@@ -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/Inc/applicationmanager.h b/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.h
similarity index 94%
rename from src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h
rename to src/AspNetCoreModuleV2/AspNetCore/applicationmanager.h
index 5245af06d5..cd565e2c01 100644
--- a/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h
+++ b/src/AspNetCoreModuleV2/AspNetCore/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/aspnetcore_shim_config.cpp b/src/AspNetCoreModuleV2/AspNetCore/aspnetcore_shim_config.cpp
similarity index 98%
rename from src/AspNetCoreModuleV2/AspNetCore/src/aspnetcore_shim_config.cpp
rename to src/AspNetCoreModuleV2/AspNetCore/aspnetcore_shim_config.cpp
index 9fb17be078..a857706142 100644
--- a/src/AspNetCoreModuleV2/AspNetCore/src/aspnetcore_shim_config.cpp
+++ b/src/AspNetCoreModuleV2/AspNetCore/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/Inc/aspnetcore_shim_config.h b/src/AspNetCoreModuleV2/AspNetCore/aspnetcore_shim_config.h
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/Inc/aspnetcore_shim_config.h
rename to src/AspNetCoreModuleV2/AspNetCore/aspnetcore_shim_config.h
diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp b/src/AspNetCoreModuleV2/AspNetCore/dllmain.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp
rename to src/AspNetCoreModuleV2/AspNetCore/dllmain.cpp
index 03196a316d..d185ad4be4 100644
--- a/src/AspNetCoreModuleV2/AspNetCore/src/dllmain.cpp
+++ b/src/AspNetCoreModuleV2/AspNetCore/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/AspNetCore/src/globalmodule.cpp b/src/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/src/globalmodule.cpp
rename to src/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp
diff --git a/src/AspNetCoreModuleV2/AspNetCore/Inc/globalmodule.h b/src/AspNetCoreModuleV2/AspNetCore/globalmodule.h
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/Inc/globalmodule.h
rename to src/AspNetCoreModuleV2/AspNetCore/globalmodule.h
diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/proxymodule.cxx b/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/src/proxymodule.cxx
rename to src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp
diff --git a/src/AspNetCoreModuleV2/AspNetCore/Inc/proxymodule.h b/src/AspNetCoreModuleV2/AspNetCore/proxymodule.h
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/Inc/proxymodule.h
rename to src/AspNetCoreModuleV2/AspNetCore/proxymodule.h
diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/precomp.cpp b/src/AspNetCoreModuleV2/AspNetCore/stdafx.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/src/precomp.cpp
rename to src/AspNetCoreModuleV2/AspNetCore/stdafx.cpp
diff --git a/src/AspNetCoreModuleV2/AspNetCore/Inc/precomp.hxx b/src/AspNetCoreModuleV2/AspNetCore/stdafx.h
similarity index 100%
rename from src/AspNetCoreModuleV2/AspNetCore/Inc/precomp.hxx
rename to src/AspNetCoreModuleV2/AspNetCore/stdafx.h
diff --git a/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj b/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj
index efeb7f1ddc..2be58bcc5c 100644
--- a/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj
+++ b/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj
@@ -217,7 +217,7 @@
-
+
@@ -231,7 +231,7 @@
Create
Create
-
+
diff --git a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc b/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc
index 13781f7c82..c15047b235 100644
--- a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc
+++ b/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc
@@ -218,6 +218,12 @@ Language=English
%1
.
+Messageid=1032
+SymbolicName=ASPNETCORE_EVENT_INPROCESS_START_SUCCESS
+Language=English
+%1
+.
+
;
;#endif // _ASPNETCORE_MODULE_MSG_H_
;
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/CommonLib/fx_ver.cxx b/src/AspNetCoreModuleV2/CommonLib/fx_ver.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/CommonLib/fx_ver.cxx
rename to src/AspNetCoreModuleV2/CommonLib/fx_ver.cpp
diff --git a/src/AspNetCoreModuleV2/CommonLib/resources.h b/src/AspNetCoreModuleV2/CommonLib/resources.h
index 4620fa7e17..2956cce581 100644
--- a/src/AspNetCoreModuleV2/CommonLib/resources.h
+++ b/src/AspNetCoreModuleV2/CommonLib/resources.h
@@ -51,3 +51,4 @@
#define ASPNETCORE_EVENT_INVALID_PROCESS_PATH_MSG L"Invalid or unknown processPath provided in web.config: processPath = %s, ErrorCode = '0x%x'."
#define ASPNETCORE_EVENT_INPROCESS_RH_MISSING_MSG L"Could not find the assembly '%s' for in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application."
#define ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG L"Could not find the assembly '%s' for out-of-process application. Please confirm the assembly is installed correctly for IIS or IISExpress."
+#define ASPNETCORE_EVENT_INPROCESS_START_SUCCESS_MSG L"Application '%s' started the coreclr in-process successfully."
diff --git a/src/AspNetCoreModuleV2/CommonLib/utility.cxx b/src/AspNetCoreModuleV2/CommonLib/utility.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/CommonLib/utility.cxx
rename to src/AspNetCoreModuleV2/CommonLib/utility.cpp
diff --git a/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj b/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj
index 6d947fcb58..96b722d328 100644
--- a/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj
+++ b/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj
@@ -187,7 +187,7 @@
-
+
@@ -196,7 +196,7 @@
-
+
diff --git a/src/AspNetCoreModuleV2/IISLib/acache.cxx b/src/AspNetCoreModuleV2/IISLib/acache.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/IISLib/acache.cxx
rename to src/AspNetCoreModuleV2/IISLib/acache.cpp
diff --git a/src/AspNetCoreModuleV2/IISLib/util.cxx b/src/AspNetCoreModuleV2/IISLib/util.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/IISLib/util.cxx
rename to src/AspNetCoreModuleV2/IISLib/util.cpp
diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj b/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj
index c96aaa7000..6531befa35 100644
--- a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj
+++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj
@@ -87,7 +87,7 @@
Level4
Disabled
WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
$(IntDir)$(TargetName).pch
ProgramDatabase
MultiThreadedDebug
@@ -104,7 +104,7 @@
CompileAsCpp
true
stdcpp17
- precomp.hxx
+ stdafx.h
true
@@ -121,7 +121,7 @@
Level4
Disabled
WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
$(IntDir)$(TargetName).pch
ProgramDatabase
MultiThreadedDebug
@@ -138,7 +138,7 @@
CompileAsCpp
true
stdcpp17
- precomp.hxx
+ stdafx.h
true
@@ -157,7 +157,7 @@
true
true
WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
MultiThreaded
..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib
true
@@ -172,7 +172,7 @@
CompileAsCpp
true
stdcpp17
- precomp.hxx
+ stdafx.h
true
@@ -193,7 +193,7 @@
true
true
NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
MultiThreaded
..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib
true
@@ -208,7 +208,7 @@
CompileAsCpp
true
stdcpp17
- precomp.hxx
+ stdafx.h
true
@@ -226,17 +226,17 @@
-
+
-
+
-
-
+
+
Create
Create
Create
diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx b/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp
similarity index 94%
rename from src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx
rename to src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp
index e1bc9ac143..f7b985aa0b 100644
--- a/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cxx
+++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp
@@ -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/InProcessRequestHandler/inprocessapplication.cpp b/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp
index ad0f6a35a6..bb56b01419 100644
--- a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp
+++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp
@@ -221,6 +221,11 @@ IN_PROCESS_APPLICATION::SetCallbackHandles(
m_pLoggerProvider->NotifyStartupComplete();
// Can't check the std err handle as it isn't a critical error
// Initialization complete
+ UTILITY::LogEventF(g_hEventLog,
+ EVENTLOG_INFORMATION_TYPE,
+ ASPNETCORE_EVENT_INPROCESS_START_SUCCESS,
+ ASPNETCORE_EVENT_INPROCESS_START_SUCCESS_MSG,
+ m_pConfig->QueryApplicationPhysicalPath()->QueryStr());
SetEvent(m_pInitalizeEvent);
m_fInitialized = TRUE;
}
diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cxx b/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cxx
rename to src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp
diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/precomp.cpp b/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp
similarity index 100%
rename from src/AspNetCoreModuleV2/InProcessRequestHandler/precomp.cpp
rename to src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp
diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/precomp.hxx b/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h
similarity index 100%
rename from src/AspNetCoreModuleV2/InProcessRequestHandler/precomp.hxx
rename to src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj
index 41f2612683..c34aa8d3a3 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj
@@ -83,11 +83,11 @@
- NotUsing
+ Use
Level4
Disabled
WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
$(IntDir)$(TargetName).pch
ProgramDatabase
MultiThreadedDebug
@@ -105,6 +105,7 @@
true
true
stdcpp17
+ stdafx.h
Windows
@@ -116,11 +117,11 @@
- NotUsing
+ Use
Level4
Disabled
WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
$(IntDir)$(TargetName).pch
ProgramDatabase
MultiThreadedDebug
@@ -138,6 +139,7 @@
true
true
stdcpp17
+ stdafx.h
Windows
@@ -150,12 +152,12 @@
Level4
- NotUsing
+ Use
MaxSpeed
true
true
WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
MultiThreaded
..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib
true
@@ -171,6 +173,7 @@
true
true
stdcpp17
+ stdafx.h
Windows
@@ -185,12 +188,12 @@
Level4
- NotUsing
+ Use
MaxSpeed
true
true
NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- precomp.hxx
+ stdafx.h
MultiThreaded
..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib
true
@@ -206,6 +209,7 @@
true
true
stdcpp17
+ stdafx.h
Windows
@@ -221,28 +225,34 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp
index e2d5c1ec3c..710be75262 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp
@@ -1,5 +1,5 @@
// dllmain.cpp : Defines the entry point for the DLL application.
-#include "precomp.hxx"
+
#include
#include
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwarderconnection.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp
similarity index 97%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwarderconnection.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp
index 99990f938c..0369edcce9 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwarderconnection.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp
@@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-#include "..\precomp.hxx"
+#include "forwarderconnection.h"
FORWARDER_CONNECTION::FORWARDER_CONNECTION(
VOID
@@ -49,4 +49,4 @@ FORWARDER_CONNECTION::Initialize(
Finished:
return hr;
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwarderconnection.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwarderconnection.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwardinghandler.cpp b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwardinghandler.cpp
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp
index bfe689fe58..8b41b72ee4 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwardinghandler.cpp
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp
@@ -1,4 +1,7 @@
-#include "..\precomp.hxx"
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+#include "forwardinghandler.h"
// Just to be aware of the FORWARDING_HANDLER object size.
C_ASSERT(sizeof(FORWARDING_HANDLER) <= 632);
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwardinghandler.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/forwardinghandler.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/outprocessapplication.cpp b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp
similarity index 93%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/outprocessapplication.cpp
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp
index ce29fd4745..90d75b2991 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/outprocessapplication.cpp
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp
@@ -1,4 +1,8 @@
-#include "..\precomp.hxx"
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+#include "outprocessapplication.h"
+
#include "SRWExclusiveLock.h"
OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION(
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/outprocessapplication.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/outprocessapplication.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/processmanager.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/processmanager.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp
index 85160dc55b..5619319c22 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/processmanager.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp
@@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-#include "..\precomp.hxx"
+#include "processmanager.h"
volatile BOOL PROCESS_MANAGER::sm_fWSAStartupDone = FALSE;
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/processmanager.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/processmanager.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/protocolconfig.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp
similarity index 97%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/protocolconfig.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp
index bb59a5ff3d..0f75a9d072 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/protocolconfig.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp
@@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-#include "..\precomp.hxx"
+#include "protocolconfig.h"
HRESULT
PROTOCOL_CONFIG::Initialize()
@@ -45,4 +45,4 @@ PROTOCOL_CONFIG::OverrideConfig(
)
{
m_msTimeout = pAspNetCoreConfig->QueryRequestTimeoutInMS();
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/protocolconfig.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/protocolconfig.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/responseheaderhash.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/responseheaderhash.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp
index f2fae274d5..d8c77eccb0 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/responseheaderhash.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp
@@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-#include "..\precomp.hxx"
+#include "responseheaderhash.h"
HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] =
{
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/responseheaderhash.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/responseheaderhash.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/serverprocess.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/serverprocess.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp
index cedbd0ba12..12be084681 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/serverprocess.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp
@@ -1,7 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-#include "..\precomp.hxx"
+#include "serverprocess.h"
+
#include
//#include
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/serverprocess.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/serverprocess.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp
new file mode 100644
index 0000000000..12fcb1d436
--- /dev/null
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp
@@ -0,0 +1,4 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+// Do not remove this file. It is used for precompiled header generation
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/precomp.hxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h
similarity index 86%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/precomp.hxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h
index e77b603820..7cdcfa0146 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/precomp.hxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h
@@ -64,15 +64,15 @@
#include "requesthandler_config.h"
#include "sttimer.h"
-#include ".\outofprocess\websockethandler.h"
-#include ".\outofprocess\responseheaderhash.h"
-#include ".\outofprocess\protocolconfig.h"
-#include ".\outofprocess\forwarderconnection.h"
-#include ".\outofprocess\serverprocess.h"
-#include ".\outofprocess\processmanager.h"
-#include ".\outofprocess\forwardinghandler.h"
-#include ".\outofprocess\outprocessapplication.h"
-#include ".\outofprocess\winhttphelper.h"
+#include "websockethandler.h"
+#include "responseheaderhash.h"
+#include "protocolconfig.h"
+#include "forwarderconnection.h"
+#include "serverprocess.h"
+#include "processmanager.h"
+#include "forwardinghandler.h"
+#include "outprocessapplication.h"
+#include "winhttphelper.h"
#include "environmentvariablehelpers.h"
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/websockethandler.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/websockethandler.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp
index 4d86fe592e..f58d599f98 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/websockethandler.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp
@@ -27,7 +27,7 @@ This prevents the need for data buffering at the Asp.Net Core Module level.
--*/
-#include "..\precomp.hxx"
+#include "websockethandler.h"
SRWLOCK WEBSOCKET_HANDLER::sm_RequestsListLock;
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/websockethandler.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/websockethandler.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/winhttphelper.cxx b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp
similarity index 99%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/winhttphelper.cxx
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp
index 1796e63081..8d14ffc417 100644
--- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/winhttphelper.cxx
+++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp
@@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-#include "..\precomp.hxx"
+#include "winhttphelper.h"
PFN_WINHTTP_WEBSOCKET_COMPLETE_UPGRADE
WINHTTP_HELPER::sm_pfnWinHttpWebSocketCompleteUpgrade;
diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/winhttphelper.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h
similarity index 100%
rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocess/winhttphelper.h
rename to src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h
diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h b/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h
index 35155faedf..b65c32ee29 100644
--- a/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h
+++ b/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h
@@ -3,8 +3,6 @@
#pragma once
-#include "precomp.hxx"
-
class ENVIRONMENT_VAR_HELPERS
{
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/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj
index f45796256a..76c3ecfe5c 100644
--- a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj
+++ b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj
@@ -13,7 +13,6 @@
-
diff --git a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets
index fe0dbb05d5..85d3751b69 100644
--- a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets
+++ b/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets
@@ -3,7 +3,11 @@
Capability that enables Visual Studio support for hosting Asp.Net Core applications in the IIS process
-->
-
+
+
+ V2
+
+
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj b/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj
index f816c8de3f..faae91cdbf 100644
--- a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj
@@ -23,7 +23,7 @@
-
+
-
\ No newline at end of file
+
diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets b/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets
new file mode 100644
index 0000000000..67c6152880
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets
@@ -0,0 +1,7 @@
+
+
+
+ V2
+
+
+
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs
new file mode 100644
index 0000000000..aaec90971e
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs
@@ -0,0 +1,44 @@
+// 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.IIS;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.Server.IntegrationTesting
+{
+ ///
+ /// Factory to create an appropriate deployer based on .
+ ///
+ public class IISApplicationDeployerFactory
+ {
+ ///
+ /// Creates a deployer instance based on settings in .
+ ///
+ ///
+ ///
+ ///
+ public static ApplicationDeployer Create(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory)
+ {
+ if (deploymentParameters == null)
+ {
+ throw new ArgumentNullException(nameof(deploymentParameters));
+ }
+
+ if (loggerFactory == null)
+ {
+ throw new ArgumentNullException(nameof(loggerFactory));
+ }
+
+ switch (deploymentParameters.ServerType)
+ {
+ case ServerType.IISExpress:
+ return new IIS.IISExpressDeployer(deploymentParameters, loggerFactory);
+ case ServerType.IIS:
+ return new IISDeployer(deploymentParameters, loggerFactory);
+ default:
+ return ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory);
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/DotNetCommands.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/DotNetCommands.cs
new file mode 100644
index 0000000000..aaa7ade405
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/DotNetCommands.cs
@@ -0,0 +1,73 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.AspNetCore.Server.IntegrationTesting
+{
+ // Copied from hosting
+ // TODO: make public while removing IISExpressDeployer
+ public static class DotNetCommands
+ {
+ private const string _dotnetFolderName = ".dotnet";
+
+ internal static string DotNetHome { get; } = GetDotNetHome();
+
+ // Compare to https://github.com/aspnet/BuildTools/blob/314c98e4533217a841ff9767bb38e144eb6c93e4/tools/KoreBuild.Console/Commands/CommandContext.cs#L76
+ private static string GetDotNetHome()
+ {
+ var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME");
+ var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
+ var home = Environment.GetEnvironmentVariable("HOME");
+
+ var result = Path.Combine(Directory.GetCurrentDirectory(), _dotnetFolderName);
+ if (!string.IsNullOrEmpty(dotnetHome))
+ {
+ result = dotnetHome;
+ }
+ else if (!string.IsNullOrEmpty(userProfile))
+ {
+ result = Path.Combine(userProfile, _dotnetFolderName);
+ }
+ else if (!string.IsNullOrEmpty(home))
+ {
+ result = home;
+ }
+
+ return result;
+ }
+
+ internal static string GetDotNetInstallDir(RuntimeArchitecture arch)
+ {
+ var dotnetDir = DotNetHome;
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ dotnetDir = Path.Combine(dotnetDir, arch.ToString());
+ }
+
+ return dotnetDir;
+ }
+
+ public static string GetDotNetExecutable(RuntimeArchitecture arch)
+ {
+ var dotnetDir = GetDotNetInstallDir(arch);
+
+ var dotnetFile = "dotnet";
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ dotnetFile += ".exe";
+ }
+
+ return Path.Combine(dotnetDir, dotnetFile);
+ }
+
+ internal static bool IsRunningX86OnX64(RuntimeArchitecture arch)
+ {
+ return (RuntimeInformation.OSArchitecture == Architecture.X64 || RuntimeInformation.OSArchitecture == Architecture.Arm64)
+ && arch == RuntimeArchitecture.x86;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config
new file mode 100644
index 0000000000..4508dea843
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config
@@ -0,0 +1,1034 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Common.FunctionalTests/Utilities/IISApplication.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs
similarity index 93%
rename from test/Common.FunctionalTests/Utilities/IISApplication.cs
rename to src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs
index 662f9315a6..3fafd7c8f9 100644
--- a/test/Common.FunctionalTests/Utilities/IISApplication.cs
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISApplication.cs
@@ -8,7 +8,6 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Xml.Linq;
-using Microsoft.Extensions.CommandLineUtils;
using Microsoft.Extensions.Logging;
using Microsoft.Web.Administration;
@@ -72,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
if (_deploymentParameters.ApplicationType == ApplicationType.Portable)
{
- ModifyAspNetCoreSectionInWebConfig("processPath", DotNetMuxer.MuxerPathOrDefault());
+ ModifyAspNetCoreSectionInWebConfig("processPath", DotNetCommands.GetDotNetExecutable(_deploymentParameters.RuntimeArchitecture));
}
_serverManager.CommitChanges();
@@ -199,9 +198,20 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
e => _logger.LogWarning($"Failed to delete file : {e.Message}"));
}
- RetryFileOperation(
- () => File.Move(_apphostConfigBackupPath, _apphostConfigPath),
- e => _logger.LogError($"Failed to backup apphost.config: {e.Message}"));
+ if (File.Exists(_apphostConfigBackupPath))
+ {
+ RetryFileOperation(
+ () => File.Move(_apphostConfigBackupPath, _apphostConfigPath),
+ e => _logger.LogError($"Failed to backup apphost.config: {e.Message}"));
+ }
+ else
+ {
+ // Test failed to create backup config file, put a default one from IIS.config there instead.
+ // An apphost.config file is required to be replaced because we use it for removing the app pool.
+ RetryFileOperation(
+ () => File.WriteAllText(_apphostConfigPath, File.ReadAllText("IIS.config")),
+ e => _logger.LogWarning($"Failed to copy IIS.config to apphost.config: {e.Message}"));
+ }
_logger.LogInformation($"Restored {_apphostConfigPath}.");
}
@@ -221,6 +231,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 +255,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/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs
similarity index 88%
rename from test/Common.FunctionalTests/Utilities/IISDeployer.cs
rename to src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs
index f3f9d8e7b9..6df58dd736 100644
--- a/test/Common.FunctionalTests/Utilities/IISDeployer.cs
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs
@@ -1,15 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
+using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
using Microsoft.Extensions.Logging;
-namespace Microsoft.AspNetCore.Server.IntegrationTesting
+namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
{
///
/// Deployer for IIS.
@@ -56,16 +56,17 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
_application = new IISApplication(DeploymentParameters, Logger);
- // For now, only support using published output
+ // For now, only support using published output
DeploymentParameters.PublishApplicationBeforeDeployment = true;
-
if (DeploymentParameters.PublishApplicationBeforeDeployment)
{
DotnetPublish();
contentRoot = DeploymentParameters.PublishedApplicationRootPath;
}
- var uri = TestIISUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint);
+ WebConfigHelpers.AddDebugLogToWebConfig(contentRoot, Path.Combine(contentRoot, $"{_application.WebSiteName}.txt"));
+
+ var uri = TestUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint);
// To prevent modifying the IIS setup concurrently.
await _application.StartIIS(uri, contentRoot);
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs
new file mode 100644
index 0000000000..0cd67cc132
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs
@@ -0,0 +1,436 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
+using Microsoft.AspNetCore.Testing;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
+{
+ ///
+ /// Deployment helper for IISExpress.
+ ///
+ public class IISExpressDeployer : ApplicationDeployer
+ {
+ private const string IISExpressRunningMessage = "IIS Express is running.";
+ private const string FailedToInitializeBindingsMessage = "Failed to initialize site bindings";
+ private const string UnableToStartIISExpressMessage = "Unable to start iisexpress.";
+ private const int MaximumAttempts = 5;
+
+ private static readonly Regex UrlDetectorRegex = new Regex(@"^\s*Successfully registered URL ""(?[^""]+)"" for site.*$");
+
+ private Process _hostProcess;
+
+ public IISExpressDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory)
+ : base(deploymentParameters, loggerFactory)
+ {
+ }
+
+ public override async Task DeployAsync()
+ {
+ using (Logger.BeginScope("Deployment"))
+ {
+ // Start timer
+ StartTimer();
+
+ // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/net461/
+ // and contentRoot points to the project directory so you get things like static assets.
+ // For a published app both point to the publish directory.
+ var dllRoot = CheckIfPublishIsRequired();
+ var contentRoot = string.Empty;
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ DotnetPublish();
+ contentRoot = DeploymentParameters.PublishedApplicationRootPath;
+ dllRoot = contentRoot;
+ }
+ else
+ {
+ // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable.
+ // Update processPath and arguments for our current scenario
+ contentRoot = DeploymentParameters.ApplicationPath;
+
+ var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ".exe";
+ var entryPoint = Path.Combine(dllRoot, DeploymentParameters.ApplicationName + executableExtension);
+
+ var executableName = string.Empty;
+ var executableArgs = string.Empty;
+
+ if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable)
+ {
+ executableName = GetDotNetExeForArchitecture();
+ executableArgs = entryPoint;
+ }
+ else
+ {
+ executableName = entryPoint;
+ }
+
+ Logger.LogInformation("Executing: {exe} {args}", executableName, executableArgs);
+ DeploymentParameters.EnvironmentVariables["LAUNCHER_PATH"] = executableName;
+ DeploymentParameters.EnvironmentVariables["LAUNCHER_ARGS"] = executableArgs;
+
+ // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead.
+ Logger.LogInformation("ContentRoot: {path}", DeploymentParameters.ApplicationPath);
+ DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath;
+ }
+
+ var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint);
+
+ // Launch the host process.
+ var (actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot, dllRoot);
+
+ Logger.LogInformation("Application ready at URL: {appUrl}", actualUri);
+
+ // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.
+ return new DeploymentResult(
+ LoggerFactory,
+ DeploymentParameters,
+ applicationBaseUri: actualUri.ToString(),
+ contentRoot: contentRoot,
+ hostShutdownToken: hostExitToken);
+ }
+ }
+
+ private string CheckIfPublishIsRequired()
+ {
+ var targetFramework = DeploymentParameters.TargetFramework;
+
+ // IISIntegration uses this layout
+ var dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.RuntimeArchitecture.ToString(),
+ DeploymentParameters.Configuration, targetFramework);
+
+ if (!Directory.Exists(dllRoot))
+ {
+ // Most repos use this layout
+ dllRoot = Path.Combine(DeploymentParameters.ApplicationPath, "bin", DeploymentParameters.Configuration, targetFramework);
+
+ if (!Directory.Exists(dllRoot))
+ {
+ // The bits we need weren't pre-compiled, compile on publish
+ DeploymentParameters.PublishApplicationBeforeDeployment = true;
+ }
+ else if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr
+ && DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86)
+ {
+ // x64 is the default. Publish to rebuild for the right bitness
+ DeploymentParameters.PublishApplicationBeforeDeployment = true;
+ }
+ }
+
+ if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr
+ && DeploymentParameters.ApplicationType == ApplicationType.Standalone)
+ {
+ // Publish is always required to get the correct standalone files in the output directory
+ DeploymentParameters.PublishApplicationBeforeDeployment = true;
+ }
+
+ return dllRoot;
+ }
+
+ private async Task<(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot, string dllRoot)
+ {
+ using (Logger.BeginScope("StartIISExpress"))
+ {
+ var port = uri.Port;
+ if (port == 0)
+ {
+ port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort();
+ }
+
+ Logger.LogInformation("Attempting to start IIS Express on port: {port}", port);
+ PrepareConfig(contentRoot, dllRoot, port);
+
+ var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ?
+ string.Format("/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) :
+ string.Format("/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation);
+
+ var iisExpressPath = GetIISExpressPath();
+
+ for (var attempt = 0; attempt < MaximumAttempts; attempt++)
+ {
+ Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters);
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = iisExpressPath,
+ Arguments = parameters,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ RedirectStandardError = true,
+ RedirectStandardOutput = true
+ };
+
+ AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables);
+
+ Uri url = null;
+ var started = new TaskCompletionSource();
+
+ var process = new Process() { StartInfo = startInfo };
+ process.OutputDataReceived += (sender, dataArgs) =>
+ {
+ if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage))
+ {
+ // We completely failed to start and we don't really know why
+ started.TrySetException(new InvalidOperationException("Failed to start IIS Express"));
+ }
+ else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage))
+ {
+ started.TrySetResult(false);
+ }
+ else if (string.Equals(dataArgs.Data, IISExpressRunningMessage))
+ {
+ started.TrySetResult(true);
+ }
+ else if (!string.IsNullOrEmpty(dataArgs.Data))
+ {
+ var m = UrlDetectorRegex.Match(dataArgs.Data);
+ if (m.Success)
+ {
+ url = new Uri(m.Groups["url"].Value);
+ }
+ }
+ };
+
+ process.EnableRaisingEvents = true;
+ var hostExitTokenSource = new CancellationTokenSource();
+ process.Exited += (sender, e) =>
+ {
+ Logger.LogInformation("iisexpress Process {pid} shut down", process.Id);
+
+ // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want
+ started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}"));
+
+ TriggerHostShutdown(hostExitTokenSource);
+ };
+ process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger);
+ Logger.LogInformation("iisexpress Process {pid} started", process.Id);
+
+ if (process.HasExited)
+ {
+ Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode);
+ throw new Exception("Failed to start host");
+ }
+
+ // Wait for the app to start
+ // The timeout here is large, because we don't know how long the test could need
+ // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build
+ // just in case we missed one -anurse
+ if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10)))
+ {
+ Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port);
+
+ // Wait for the process to exit and try again
+ process.WaitForExit(30 * 1000);
+ await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up
+ }
+ else
+ {
+ _hostProcess = process;
+ Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port);
+ return (url: url, hostExitToken: hostExitTokenSource.Token);
+ }
+ }
+
+ var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port";
+ Logger.LogError(message);
+ throw new TimeoutException(message);
+ }
+ }
+
+ private void PrepareConfig(string contentRoot, string dllRoot, int port)
+ {
+ // Config is required. If not present then fall back to one we carry with us.
+ if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent))
+ {
+ using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.AspNetCore.Server.IntegrationTesting.IIS.Http.config"))
+ using (var reader = new StreamReader(stream))
+ {
+ DeploymentParameters.ServerConfigTemplateContent = reader.ReadToEnd();
+ }
+ }
+
+ var serverConfig = DeploymentParameters.ServerConfigTemplateContent;
+
+ // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config
+ // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo.
+ serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMPath]", dllName: "aspnetcore.dll", serverConfig, dllRoot);
+ serverConfig = ModifyANCMPathInConfig(replaceFlag: "[ANCMV2Path]", dllName: "aspnetcorev2.dll", serverConfig, dllRoot);
+
+ serverConfig = ReplacePlaceholder(serverConfig, "[PORT]", port.ToString(CultureInfo.InvariantCulture));
+ serverConfig = ReplacePlaceholder(serverConfig, "[ApplicationPhysicalPath]", contentRoot);
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ // For published apps, prefer the content in the web.config, but update it.
+ ModifyAspNetCoreSectionInWebConfig(key: "hostingModel",
+ value: DeploymentParameters.HostingModel == HostingModel.InProcess ? "inprocess" : "");
+ ModifyHandlerSectionInWebConfig(key: "modules", value: DeploymentParameters.AncmVersion.ToString());
+ ModifyDotNetExePathInWebConfig();
+ serverConfig = RemoveRedundantElements(serverConfig);
+ }
+ else
+ {
+ // The elements normally in the web.config are in the applicationhost.config for unpublished apps.
+ serverConfig = ReplacePlaceholder(serverConfig, "[HostingModel]", DeploymentParameters.HostingModel.ToString());
+ serverConfig = ReplacePlaceholder(serverConfig, "[AspNetCoreModule]", DeploymentParameters.AncmVersion.ToString());
+ }
+
+ DeploymentParameters.ServerConfigLocation = Path.GetTempFileName();
+ Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation);
+
+ File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig);
+ }
+
+ private string ReplacePlaceholder(string content, string field, string value)
+ {
+ if (content.Contains(field))
+ {
+ content = content.Replace(field, value);
+ Logger.LogDebug("Writing {field} '{value}' to config", field, value);
+ }
+ return content;
+ }
+
+ private string ModifyANCMPathInConfig(string replaceFlag, string dllName, string serverConfig, string dllRoot)
+ {
+ if (serverConfig.Contains(replaceFlag))
+ {
+ var arch = DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64 ? $@"x64\{dllName}" : $@"x86\{dllName}";
+ var ancmFile = Path.Combine(dllRoot, arch);
+ if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile)))
+ {
+ ancmFile = Path.Combine(dllRoot, dllName);
+ if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmFile)))
+ {
+ throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmFile);
+ }
+ }
+
+ Logger.LogDebug($"Writing '{replaceFlag}' '{ancmFile}' to config");
+ return serverConfig.Replace(replaceFlag, ancmFile);
+ }
+ return serverConfig;
+ }
+
+ private string GetIISExpressPath()
+ {
+ var programFiles = "Program Files";
+ if (DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture))
+ {
+ programFiles = "Program Files (x86)";
+ }
+
+ // Get path to program files
+ var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + "\\", programFiles, "IIS Express", "iisexpress.exe");
+
+ if (!File.Exists(iisExpressPath))
+ {
+ throw new Exception("Unable to find IISExpress on the machine: " + iisExpressPath);
+ }
+
+ return iisExpressPath;
+ }
+
+ public override void Dispose()
+ {
+ using (Logger.BeginScope("Dispose"))
+ {
+ ShutDownIfAnyHostProcess(_hostProcess);
+
+ if (!string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation)
+ && File.Exists(DeploymentParameters.ServerConfigLocation))
+ {
+ // Delete the temp applicationHostConfig that we created.
+ Logger.LogDebug("Deleting applicationHost.config file from {configLocation}", DeploymentParameters.ServerConfigLocation);
+ try
+ {
+ File.Delete(DeploymentParameters.ServerConfigLocation);
+ }
+ catch (Exception exception)
+ {
+ // Ignore delete failures - just write a log.
+ Logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", DeploymentParameters.ServerConfigLocation, exception.Message);
+ }
+ }
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ CleanPublishedOutput();
+ }
+
+ InvokeUserApplicationCleanup();
+
+ StopTimer();
+ }
+
+ // If by this point, the host process is still running (somehow), throw an error.
+ // A test failure is better than a silent hang and unknown failure later on
+ if (_hostProcess != null && !_hostProcess.HasExited)
+ {
+ throw new Exception($"iisexpress Process {_hostProcess.Id} failed to shutdown");
+ }
+ }
+
+ private void ModifyDotNetExePathInWebConfig()
+ {
+ // We assume the x64 dotnet.exe is on the path so we need to provide an absolute path for x86 scenarios.
+ // Only do it for scenarios that rely on dotnet.exe (Core, portable, etc.).
+ if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr
+ && DeploymentParameters.ApplicationType == ApplicationType.Portable
+ && DotNetCommands.IsRunningX86OnX64(DeploymentParameters.RuntimeArchitecture))
+ {
+ var executableName = DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture);
+ if (!File.Exists(executableName))
+ {
+ throw new Exception($"Unable to find '{executableName}'.'");
+ }
+ ModifyAspNetCoreSectionInWebConfig("processPath", executableName);
+ }
+ }
+
+ // Transforms the web.config file to set attributes like hostingModel="inprocess" element
+ private void ModifyAspNetCoreSectionInWebConfig(string key, string value)
+ {
+ var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config");
+ var config = XDocument.Load(webConfigFile);
+ var element = config.Descendants("aspNetCore").FirstOrDefault();
+ element.SetAttributeValue(key, value);
+ config.Save(webConfigFile);
+ }
+
+ private void ModifyHandlerSectionInWebConfig(string key, string value)
+ {
+ var webConfigFile = Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config");
+ var config = XDocument.Load(webConfigFile);
+ var element = config.Descendants("handlers").FirstOrDefault().Descendants("add").FirstOrDefault();
+ element.SetAttributeValue(key, value);
+ config.Save(webConfigFile);
+ }
+
+ // These elements are duplicated in the web.config if you publish. Remove them from the host.config.
+ private string RemoveRedundantElements(string serverConfig)
+ {
+ var hostConfig = XDocument.Parse(serverConfig);
+
+ var coreElement = hostConfig.Descendants("aspNetCore").FirstOrDefault();
+ coreElement?.Remove();
+
+ var handlersElement = hostConfig.Descendants("handlers").First();
+ var handlerElement = handlersElement.Descendants("add")
+ .Where(x => x.Attribute("name").Value == "aspNetCore").FirstOrDefault();
+ handlerElement?.Remove();
+
+ return hostConfig.ToString();
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj
new file mode 100644
index 0000000000..0891a315dc
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj
@@ -0,0 +1,21 @@
+
+
+
+ netstandard2.0
+ Microsoft.AspNetCore.Server.IntegrationTesting.IIS
+ Provides support for integration testing using IIS based servers.
+ $(NoWarn);CS1591
+ true
+ aspnetcore;iis
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Common.FunctionalTests/Utilities/TestIISUriHelper.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/TestUriHelper.cs
similarity index 52%
rename from test/Common.FunctionalTests/Utilities/TestIISUriHelper.cs
rename to src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/TestUriHelper.cs
index b8c37ddd93..fe1b351ba4 100644
--- a/test/Common.FunctionalTests/Utilities/TestIISUriHelper.cs
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/TestUriHelper.cs
@@ -2,26 +2,20 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Net;
-using System.Net.Sockets;
-namespace Microsoft.AspNetCore.Server.IntegrationTesting
+namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
{
- // Copied from Hosting for now https://github.com/aspnet/Hosting/blob/970bc8a30d66dd6894f8f662e5fdab9e68d57777/src/Microsoft.AspNetCore.Server.IntegrationTesting/Common/TestUriHelper.cs
- internal static class TestIISUriHelper
+ internal static class TestUriHelper
{
- internal static Uri BuildTestUri(ServerType serverType)
- {
- return BuildTestUri(serverType, hint: null);
- }
-
internal static Uri BuildTestUri(ServerType serverType, string hint)
{
// Assume status messages are enabled for Kestrel and disabled for all other servers.
- return BuildTestUri(serverType, hint, statusMessagesEnabled: serverType == ServerType.Kestrel);
+ var statusMessagesEnabled = (serverType == ServerType.Kestrel);
+
+ return BuildTestUri(serverType, Uri.UriSchemeHttp, hint, statusMessagesEnabled);
}
- internal static Uri BuildTestUri(ServerType serverType, string hint, bool statusMessagesEnabled)
+ internal static Uri BuildTestUri(ServerType serverType, string scheme, string hint, bool statusMessagesEnabled)
{
if (string.IsNullOrEmpty(hint))
{
@@ -32,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
// once and never released. Binding to dynamic port "0" on "localhost" (both IPv4 and IPv6) is not
// supported, so the port is only bound on "127.0.0.1" (IPv4). If a test explicitly requires IPv6,
// it should provide a hint URL with "localhost" (IPv4 and IPv6) or "[::1]" (IPv6-only).
- return new UriBuilder("http", "127.0.0.1", 0).Uri;
+ return new UriBuilder(scheme, "127.0.0.1", 0).Uri;
}
else
{
@@ -40,7 +34,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
// from which to scrape the assigned port, so the less reliable GetNextPort() must be used. The
// port is bound on "localhost" (both IPv4 and IPv6), since this is supported when using a specific
// (non-zero) port.
- return new UriBuilder("http", "localhost", GetNextPort()).Uri;
+ return new UriBuilder(scheme, "localhost", TestPortHelper.GetNextPort()).Uri;
}
}
else
@@ -51,7 +45,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
// Only a few tests use this codepath, so it's fine to use the less reliable GetNextPort() for simplicity.
// The tests using this codepath will be reviewed to see if they can be changed to directly bind to dynamic
// port "0" on "127.0.0.1" and scrape the assigned port from the status message (the default codepath).
- return new UriBuilder(uriHint) { Port = GetNextPort() }.Uri;
+ return new UriBuilder(uriHint) { Port = TestPortHelper.GetNextPort() }.Uri;
}
else
{
@@ -60,25 +54,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
}
}
}
-
- // Copied from https://github.com/aspnet/KestrelHttpServer/blob/47f1db20e063c2da75d9d89653fad4eafe24446c/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs#L508
- //
- // This method is an attempt to safely get a free port from the OS. Most of the time,
- // when binding to dynamic port "0" the OS increments the assigned port, so it's safe
- // to re-use the assigned port in another process. However, occasionally the OS will reuse
- // a recently assigned port instead of incrementing, which causes flaky tests with AddressInUse
- // exceptions. This method should only be used when the application itself cannot use
- // dynamic port "0" (e.g. IISExpress). Most functional tests using raw Kestrel
- // (with status messages enabled) should directly bind to dynamic port "0" and scrape
- // the assigned port from the status message, which should be 100% reliable since the port
- // is bound once and never released.
- internal static int GetNextPort()
- {
- using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
- {
- socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
- return ((IPEndPoint)socket.LocalEndPoint).Port;
- }
- }
}
}
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs
new file mode 100644
index 0000000000..e5c13225b5
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs
@@ -0,0 +1,50 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using Microsoft.AspNetCore.Server.IntegrationTesting;
+using Microsoft.AspNetCore.Testing;
+
+namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
+{
+ public class WebConfigHelpers
+ {
+ 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);
+ }
+ }
+}
diff --git a/test/Common.FunctionalTests/Inprocess/EventLogTests.cs b/test/Common.FunctionalTests/Inprocess/EventLogTests.cs
new file mode 100644
index 0000000000..1ae8aa5d57
--- /dev/null
+++ b/test/Common.FunctionalTests/Inprocess/EventLogTests.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
+using Microsoft.AspNetCore.Testing.xunit;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
+{
+ public class EventLogTests : IISFunctionalTestBase
+ {
+ [ConditionalFact]
+ public async Task CheckStartupEventLogMessage()
+ {
+ var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
+ var deploymentResult = await DeployAsync(deploymentParameters);
+ await Helpers.AssertStarts(deploymentResult, "/HelloWorld");
+
+ StopServer();
+
+ EventLogHelpers.VerifyEventLogEvent(TestSink, "Application '.+' started the coreclr in-process successfully.");
+ }
+ }
+}
diff --git a/test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs b/test/Common.FunctionalTests/Inprocess/LoggingTests.cs
similarity index 72%
rename from test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs
rename to test/Common.FunctionalTests/Inprocess/LoggingTests.cs
index 6d8e73a15c..6b4b2278a4 100644
--- a/test/IISExpress.FunctionalTests/InProcess/LoggingTests.cs
+++ b/test/Common.FunctionalTests/Inprocess/LoggingTests.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
+using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging;
using Xunit;
@@ -91,5 +92,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);
+ WebConfigHelpers.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/EventLogHelpers.cs b/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs
new file mode 100644
index 0000000000..1d53ba6843
--- /dev/null
+++ b/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs
@@ -0,0 +1,18 @@
+// 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.Text.RegularExpressions;
+using Microsoft.Extensions.Logging.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
+{
+ public class EventLogHelpers
+ {
+ public static void VerifyEventLogEvent(ITestSink testSink, string expectedRegexMatchString)
+ {
+ var eventLogRegex = new Regex($"Event Log: {expectedRegexMatchString}");
+ Assert.Contains(testSink.Writes, context => eventLogRegex.IsMatch(context.Message));
+ }
+ }
+}
diff --git a/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs b/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs
index c2a9c3682a..4827fcaecc 100644
--- a/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs
+++ b/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs
@@ -25,17 +25,13 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
parameters.EnvironmentVariables[DebugEnvironmentVariable] = "4";
}
- if (parameters.ServerType == ServerType.IIS)
- {
- // Currently hosting throws if the Servertype = IIS.
- _deployer = new IISDeployer(parameters, LoggerFactory);
- }
- else if (parameters.ServerType == ServerType.IISExpress)
+ if (parameters.ServerType == ServerType.IISExpress)
{
parameters.ServerConfigTemplateContent = parameters.ServerConfigTemplateContent ?? File.ReadAllText("IISExpress.config");
- _deployer = new IISExpressDeployer(parameters, LoggerFactory);
}
+ _deployer = IISApplicationDeployerFactory.Create(parameters, LoggerFactory);
+
var result = await _deployer.DeployAsync();
return new IISDeploymentResult(result, Logger);
diff --git a/test/Common.FunctionalTests/Utilities/Helpers.cs b/test/Common.FunctionalTests/Utilities/Helpers.cs
index f4114730b3..e512dd6d83 100644
--- a/test/Common.FunctionalTests/Utilities/Helpers.cs
+++ b/test/Common.FunctionalTests/Utilities/Helpers.cs
@@ -4,9 +4,11 @@
using System;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Testing;
+using Xunit;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
@@ -60,7 +62,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
site = hostingModel == HostingModel.InProcess ? "InProcessWebSite" : "OutOfProcessWebSite";
}
- return new DeploymentParameters(Helpers.GetTestWebSitePath(site), DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
+ return new DeploymentParameters(GetTestWebSitePath(site), DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
{
TargetFramework = Tfm.NetCoreApp22,
ApplicationType = ApplicationType.Portable,
@@ -72,5 +74,14 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
private static string GetWebConfigFile(IISDeploymentResult deploymentResult)
=> Path.Combine(deploymentResult.DeploymentResult.ContentRoot, "web.config");
+
+ public static async Task AssertStarts(IISDeploymentResult deploymentResult, string path = "/HelloWorld")
+ {
+ var response = await deploymentResult.RetryingHttpClient.GetAsync(path);
+
+ var responseText = await response.Content.ReadAsStringAsync();
+
+ Assert.Equal("Hello World", responseText);
+ }
}
}
diff --git a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs
index 1a60e85246..d8fd3342ed 100644
--- a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs
+++ b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs
@@ -3,12 +3,10 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Net.Http;
using System.Threading;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Testing;
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
@@ -36,15 +34,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
_forwardingProvider = new ForwardingProvider();
var loggerFactory = logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture));
loggerFactory.AddProvider(_forwardingProvider);
- if (deploymentParameters.ServerType == ServerType.IIS)
- {
- // Currently hosting throws if the Servertype = IIS.
- _deployer = new IISDeployer(deploymentParameters, loggerFactory);
- }
- else if (deploymentParameters.ServerType == ServerType.IISExpress)
- {
- _deployer = new IISExpressDeployer(deploymentParameters, loggerFactory);
- }
+
+ _deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory);
DeploymentResult = _deployer.DeployAsync().Result;
Client = DeploymentResult.HttpClient;
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/CommonLibTests.vcxproj b/test/CommonLibTests/CommonLibTests.vcxproj
index 85cc1d39be..c3947b45b3 100644
--- a/test/CommonLibTests/CommonLibTests.vcxproj
+++ b/test/CommonLibTests/CommonLibTests.vcxproj
@@ -101,7 +101,8 @@
true
Console
..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\;
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;precomp.obj;%(AdditionalDependencies)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
@@ -127,7 +128,8 @@
true
Console
..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\;
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;precomp.obj;%(AdditionalDependencies)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
@@ -153,7 +155,8 @@
true
true
..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\;
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;precomp.obj;%(AdditionalDependencies)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
@@ -179,7 +182,8 @@
true
true
..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\;
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;precomp.obj;%(AdditionalDependencies)
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
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/IIS.FunctionalTests.csproj b/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj
index cc02e6d69e..bbe5ffe049 100644
--- a/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj
+++ b/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj
@@ -12,6 +12,7 @@
+
False
@@ -32,10 +33,8 @@
-
-
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/IISExpress.FunctionalTests.csproj b/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj
index 718053f101..c2e7b815f9 100644
--- a/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj
+++ b/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj
@@ -11,6 +11,7 @@
+
False
@@ -31,10 +32,8 @@
-
-
diff --git a/test/IISExpress.FunctionalTests/InProcess/StartupTests.cs b/test/IISExpress.FunctionalTests/InProcess/StartupTests.cs
index 5fbc821d29..4de6ceba3d 100644
--- a/test/IISExpress.FunctionalTests/InProcess/StartupTests.cs
+++ b/test/IISExpress.FunctionalTests/InProcess/StartupTests.cs
@@ -9,7 +9,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Testing.xunit;
-using Microsoft.Extensions.CommandLineUtils;
using Xunit;
using Xunit.Abstractions;
@@ -17,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{
public class StartupTests : IISFunctionalTestBase
{
- private readonly string _dotnetLocation = DotNetMuxer.MuxerPathOrDefault();
+ private readonly string _dotnetLocation = DotNetCommands.GetDotNetExecutable(RuntimeArchitecture.x64);
public StartupTests(ITestOutputHelper output) : base(output)
{
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 @@
+
+
+
+
+
+
+
+
+
+