Add hosting model switch tests (#1245)

This commit is contained in:
Pavel Krymets 2018-08-15 16:47:47 -07:00 committed by GitHub
parent 56236f6a74
commit 6440545c4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 83 additions and 54 deletions

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",

View File

@ -36,8 +36,8 @@
<IISExpressArguments>/config:"$(IISExpressAppHostConfig)" /systray:false</IISExpressArguments> <IISExpressArguments>/config:"$(IISExpressAppHostConfig)" /systray:false</IISExpressArguments>
<IISArguments>-h "$(IISAppHostConfig)"</IISArguments> <IISArguments>-h "$(IISAppHostConfig)"</IISArguments>
<AncmPath>$(AspNetCoreModuleV1ShimDll)</AncmPath> <AncmPath>$(NativePlatform)\aspnetcore.dll</AncmPath>
<AncmV2Path>$(AspNetCoreModuleV2ShimDll)</AncmV2Path> <AncmV2Path>$(NativePlatform)\aspnetcorev2.dll</AncmV2Path>
<AncmInProcessRHPath>aspnetcorev2_inprocess.dll</AncmInProcessRHPath> <AncmInProcessRHPath>aspnetcorev2_inprocess.dll</AncmInProcessRHPath>
<DotNetPath>$(userprofile)\.dotnet\$(NativePlatform)\dotnet.exe</DotNetPath> <DotNetPath>$(userprofile)\.dotnet\$(NativePlatform)\dotnet.exe</DotNetPath>
</PropertyGroup> </PropertyGroup>

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\build\testsite.props" /> <Import Project="..\..\build\testsite.props" />
@ -9,10 +9,13 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" /> <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IISIntegration\Microsoft.AspNetCore.Server.IISIntegration.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",

View File

@ -14,8 +14,15 @@ namespace NativeIISSample
{ {
public class Startup public class Startup
{ {
private readonly IAuthenticationSchemeProvider _authSchemeProvider;
public Startup(IAuthenticationSchemeProvider authSchemeProvider = null)
{
_authSchemeProvider = authSchemeProvider;
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAuthenticationSchemeProvider authSchemeProvider) public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
app.Run(async (context) => app.Run(async (context) =>
{ {
@ -41,8 +48,11 @@ namespace NativeIISSample
await context.Response.WriteAsync(Environment.NewLine); await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine); await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine);
var scheme = await authSchemeProvider.GetSchemeAsync(IISServerDefaults.AuthenticationScheme); if (_authSchemeProvider != null)
await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine); {
var scheme = await _authSchemeProvider.GetSchemeAsync(IISServerDefaults.AuthenticationScheme);
await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine);
}
await context.Response.WriteAsync(Environment.NewLine); await context.Response.WriteAsync(Environment.NewLine);
@ -98,7 +108,9 @@ namespace NativeIISSample
public static void Main(string[] args) public static void Main(string[] args)
{ {
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseKestrel()
.UseIIS() .UseIIS()
.UseIISIntegration()
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();

View File

@ -157,13 +157,10 @@ HandlerResolver::FindNativeAssemblyFromGlobalLocation(
} }
catch (...) catch (...)
{ {
STRU struEvent; EventLog::Info(
if (SUCCEEDED(struEvent.Copy(ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG)))
{
EventLog::Info(
ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING, ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING,
struEvent.QueryStr()); ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING_MSG,
} pstrHandlerDllName);
return OBSERVE_CAUGHT_EXCEPTION(); return OBSERVE_CAUGHT_EXCEPTION();
} }

View File

@ -116,7 +116,7 @@ APPLICATION_MANAGER::FindConfigChangedApplication(
BOOL fChanged = pstruConfigPath->StartsWith(pContext->pstrPath, true); BOOL fChanged = pstruConfigPath->StartsWith(pContext->pstrPath, true);
if (fChanged) if (fChanged)
{ {
DWORD dwLen = (DWORD)wcslen(pContext->pstrPath); auto dwLen = wcslen(pContext->pstrPath);
WCHAR wChar = pstruConfigPath->QueryStr()[dwLen]; WCHAR wChar = pstruConfigPath->QueryStr()[dwLen];
// We need to check that the last character of the config path // We need to check that the last character of the config path
@ -189,12 +189,6 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
// Removed the applications which are impacted by the configurtion change // Removed the applications which are impacted by the configurtion change
m_pApplicationInfoHash->DeleteIf(FindConfigChangedApplication, (PVOID)&context); m_pApplicationInfoHash->DeleteIf(FindConfigChangedApplication, (PVOID)&context);
if (m_pApplicationInfoHash->Count() == 0 && m_hostingModel == HOSTING_OUT_PROCESS)
{
// reuse current process
m_hostingModel = HOSTING_UNKNOWN;
}
} }
// If we receive a request at this point. // If we receive a request at this point.
@ -211,15 +205,10 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
APPLICATION_INFO* pRecord; APPLICATION_INFO* pRecord;
// Application got recycled. Log an event // Application got recycled. Log an event
STACK_STRU(strEventMsg, 256); EventLog::Info(
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG,
path)))
{
EventLog::Info(
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION, ASPNETCORE_EVENT_RECYCLE_CONFIGURATION,
strEventMsg.QueryStr()); ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG,
} path);
table->FindKey(path, &pRecord); table->FindKey(path, &pRecord);
DBG_ASSERT(pRecord != NULL); DBG_ASSERT(pRecord != NULL);
@ -241,15 +230,10 @@ Finished:
if (FAILED(hr)) if (FAILED(hr))
{ {
// Failed to recycle an application. Log an event // Failed to recycle an application. Log an event
STACK_STRU(strEventMsg, 256); EventLog::Error(
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG,
pszApplicationId)))
{
EventLog::Error(
ASPNETCORE_EVENT_RECYCLE_APP_FAILURE, ASPNETCORE_EVENT_RECYCLE_APP_FAILURE,
strEventMsg.QueryStr()); ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG,
} pszApplicationId);
// Need to recycle the process as we cannot recycle the application // Need to recycle the process as we cannot recycle the application
if (!g_fRecycleProcessCalled) if (!g_fRecycleProcessCalled)
{ {

View File

@ -112,7 +112,6 @@ public:
private: private:
APPLICATION_MANAGER(HMODULE hModule, IHttpServer& pHttpServer) : APPLICATION_MANAGER(HMODULE hModule, IHttpServer& pHttpServer) :
m_pApplicationInfoHash(NULL), m_pApplicationInfoHash(NULL),
m_hostingModel(HOSTING_UNKNOWN),
m_fDebugInitialize(FALSE), m_fDebugInitialize(FALSE),
m_pHttpServer(pHttpServer), m_pHttpServer(pHttpServer),
m_handlerResolver(hModule, pHttpServer) m_handlerResolver(hModule, pHttpServer)
@ -123,7 +122,6 @@ private:
APPLICATION_INFO_HASH *m_pApplicationInfoHash; APPLICATION_INFO_HASH *m_pApplicationInfoHash;
static APPLICATION_MANAGER *sm_pApplicationManager; static APPLICATION_MANAGER *sm_pApplicationManager;
SRWLOCK m_srwLock {}; SRWLOCK m_srwLock {};
APP_HOSTING_MODEL m_hostingModel;
BOOL m_fDebugInitialize; BOOL m_fDebugInitialize;
IHttpServer &m_pHttpServer; IHttpServer &m_pHttpServer;
HandlerResolver m_handlerResolver; HandlerResolver m_handlerResolver;

View File

@ -76,13 +76,13 @@ GlobalVersionUtility::FindHighestGlobalVersion(PCWSTR pwzAspNetCoreFolderPath)
{ {
if (pwzAspNetCoreFolderPath == NULL) if (pwzAspNetCoreFolderPath == NULL)
{ {
throw new std::invalid_argument("pwzAspNetCoreFolderPath is NULL"); throw std::invalid_argument("pwzAspNetCoreFolderPath is NULL");
} }
std::vector<fx_ver_t> versionsInDirectory = GetRequestHandlerVersions(pwzAspNetCoreFolderPath); std::vector<fx_ver_t> versionsInDirectory = GetRequestHandlerVersions(pwzAspNetCoreFolderPath);
if (versionsInDirectory.empty()) if (versionsInDirectory.empty())
{ {
throw new std::runtime_error("Cannot find request handler next to aspnetcorev2.dll. Verify a version of the request handler is installed in a version folder."); throw std::runtime_error("Cannot find request handler next to aspnetcorev2.dll. Verify a version of the request handler is installed in a version folder.");
} }
std::sort(versionsInDirectory.begin(), versionsInDirectory.end()); std::sort(versionsInDirectory.begin(), versionsInDirectory.end());

View File

@ -5,6 +5,7 @@ using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Server.IntegrationTesting;
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Xunit; using Xunit;
@ -54,5 +55,24 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
// Verify that worker process gets restarted with new process id // Verify that worker process gets restarted with new process id
await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore); await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore);
} }
[ConditionalFact]
public async Task OutOfProcessToInProcessHostingModelSwitchWorks()
{
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
var deploymentResult = await DeployAsync(deploymentParameters);
await deploymentResult.AssertStarts();
deploymentResult.ModifyWebConfig(element => element
.GetOrAdd("system.webServer")
.GetOrAdd("aspNetCore")
.SetAttributeValue("hostingModel", "inprocess"));
// Have to retry here to allow ANCM to receive notification and react to it
// Verify that worker process gets restarted with new process id
await deploymentResult.HttpClient.RetryRequestAsync("/HelloWorld", r => r.StatusCode == HttpStatusCode.InternalServerError);
}
} }
} }

View File

@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
{ {
var webConfigPath = Path.Combine(deploymentResult.ContentRoot, "web.config"); var webConfigPath = Path.Combine(deploymentResult.ContentRoot, "web.config");
var document = XDocument.Load(webConfigPath); var document = XDocument.Load(webConfigPath);
action(document.Root);
document.Save(webConfigPath); document.Save(webConfigPath);
} }

View File

@ -3,6 +3,7 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
@ -144,6 +145,20 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
AssertLoadedVersion(version); AssertLoadedVersion(version);
} }
[ConditionalFact]
public async Task DoesNotCrashWhenNoVersionsAvailable()
{
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
CopyShimToOutput(deploymentParameters);
var deploymentResult = await DeployAsync(deploymentParameters);
var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20);
Directory.Delete(originalANCMPath, true);
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
}
private IISDeploymentParameters GetGlobalVersionBaseDeploymentParameters() private IISDeploymentParameters GetGlobalVersionBaseDeploymentParameters()
{ {
return _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); return _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",

View File

@ -15,8 +15,8 @@
"nativeDebugging": true, "nativeDebugging": true,
"environmentVariables": { "environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)", "ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)", "ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)", "LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)", "LAUNCHER_PATH": "$(DotNetPath)",