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,
"environmentVariables": {
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
"ANCM_PATH": "$(AncmPath)",
"ANCMV2_PATH": "$(AncmV2Path)",
"ANCM_PATH": "$(TargetDir)\\$(AncmPath)",
"ANCMV2_PATH": "$(TargetDir)\\$(AncmV2Path)",
"LAUNCHER_ARGS": "$(TargetPath)",
"ASPNETCORE_ENVIRONMENT": "Development",
"LAUNCHER_PATH": "$(DotNetPath)",

View File

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

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\build\testsite.props" />
@ -9,10 +9,13 @@
<ItemGroup>
<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>
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
</ItemGroup>
<PropertyGroup>

View File

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

View File

@ -14,8 +14,15 @@ namespace NativeIISSample
{
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.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAuthenticationSchemeProvider authSchemeProvider)
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Run(async (context) =>
{
@ -41,8 +48,11 @@ namespace NativeIISSample
await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine);
var scheme = await authSchemeProvider.GetSchemeAsync(IISServerDefaults.AuthenticationScheme);
await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine);
if (_authSchemeProvider != null)
{
var scheme = await _authSchemeProvider.GetSchemeAsync(IISServerDefaults.AuthenticationScheme);
await context.Response.WriteAsync("DisplayName: " + scheme?.DisplayName + Environment.NewLine);
}
await context.Response.WriteAsync(Environment.NewLine);
@ -98,7 +108,9 @@ namespace NativeIISSample
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseIIS()
.UseIISIntegration()
.UseStartup<Startup>()
.Build();

View File

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

View File

@ -116,7 +116,7 @@ APPLICATION_MANAGER::FindConfigChangedApplication(
BOOL fChanged = pstruConfigPath->StartsWith(pContext->pstrPath, true);
if (fChanged)
{
DWORD dwLen = (DWORD)wcslen(pContext->pstrPath);
auto dwLen = wcslen(pContext->pstrPath);
WCHAR wChar = pstruConfigPath->QueryStr()[dwLen];
// 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
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.
@ -211,15 +205,10 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
APPLICATION_INFO* pRecord;
// Application got recycled. Log an event
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG,
path)))
{
EventLog::Info(
EventLog::Info(
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION,
strEventMsg.QueryStr());
}
ASPNETCORE_EVENT_RECYCLE_CONFIGURATION_MSG,
path);
table->FindKey(path, &pRecord);
DBG_ASSERT(pRecord != NULL);
@ -241,15 +230,10 @@ Finished:
if (FAILED(hr))
{
// Failed to recycle an application. Log an event
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG,
pszApplicationId)))
{
EventLog::Error(
EventLog::Error(
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
if (!g_fRecycleProcessCalled)
{

View File

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

View File

@ -76,13 +76,13 @@ GlobalVersionUtility::FindHighestGlobalVersion(PCWSTR pwzAspNetCoreFolderPath)
{
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);
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());

View File

@ -5,6 +5,7 @@ using System.Net;
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 Xunit;
@ -54,5 +55,24 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
// Verify that worker process gets restarted with new process id
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 document = XDocument.Load(webConfigPath);
action(document.Root);
document.Save(webConfigPath);
}

View File

@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
@ -144,6 +145,20 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
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()
{
return _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);

View File

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

View File

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

View File

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

View File

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

View File

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