Make inprocess not set CaptureStartupErrors and let ANCM handle it. (#9859)

This commit is contained in:
Justin Kotalik 2019-05-07 12:03:11 -07:00 committed by GitHub
parent e401f35b45
commit 18faf4ad7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 4 deletions

View File

@ -45,6 +45,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
private ILogger _logger;
private bool _stopped;
private bool _startedServer;
// Used for testing only
internal WebHostOptions Options => _options;
@ -151,6 +152,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
var hostingApp = new HostingApplication(application, _logger, diagnosticSource, httpContextFactory);
await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false);
_startedServer = true;
// Fire IApplicationLifetime.Started
_applicationLifetime?.NotifyStarted();
@ -330,13 +332,13 @@ namespace Microsoft.AspNetCore.Hosting.Internal
// Fire IApplicationLifetime.Stopping
_applicationLifetime?.StopApplication();
if (Server != null)
if (Server != null && _startedServer)
{
await Server.StopAsync(cancellationToken).ConfigureAwait(false);
}
// Fire the IHostedService.Stop
if (_hostedServiceExecutor != null)
if (_hostedServiceExecutor != null && _startedServer)
{
await _hostedServiceExecutor.StopAsync(cancellationToken).ConfigureAwait(false);
}

View File

@ -1024,6 +1024,46 @@ namespace Microsoft.AspNetCore.Hosting
providerMock.Verify(c => c.Dispose(), Times.AtLeastOnce());
}
[Fact]
public async Task DoesNotCallServerStopIfServerStartHasNotBeenCalled()
{
var server = new Mock<IServer>();
using (var host = CreateBuilder()
.ConfigureServices(services =>
{
services.AddSingleton(server.Object);
})
.UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build())
{
await host.StopAsync();
}
server.VerifyNoOtherCalls();
}
[Fact]
public async Task DoesNotCallServerStopIfServerStartHasNotBeenCalledIHostedService()
{
var server = new Mock<IServer>();
using (var host = CreateBuilder()
.ConfigureServices(services =>
{
services.AddSingleton(server.Object);
services.AddSingleton<IHostedService, TestHostedService>();
})
.UseStartup("Microsoft.AspNetCore.Hosting.Tests")
.Build())
{
var svc = (TestHostedService)host.Services.GetRequiredService<IHostedService>();
await svc.StopAsync(default);
}
server.VerifyNoOtherCalls();
}
public class BadConfigureServicesStartup
{
public void ConfigureServices(IServiceCollection services, int gunk) { }

View File

@ -30,8 +30,6 @@ namespace Microsoft.AspNetCore.Hosting
// Check if in process
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && NativeMethods.IsAspNetCoreModuleLoaded())
{
hostBuilder.CaptureStartupErrors(true);
var iisConfigData = NativeMethods.HttpGetApplicationProperties();
// Trim trailing slash to be consistent with other servers
var contentRoot = iisConfigData.pwzFullApplicationPath.TrimEnd(Path.DirectorySeparatorChar);

View File

@ -604,6 +604,30 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
VerifyDotnetRuntimeEventLog(deploymentResult);
}
[ConditionalTheory]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
[RequiresNewHandler]
[InlineData("ThrowInStartup")]
[InlineData("ThrowInStartupGenericHost")]
public async Task ExceptionIsLoggedToEventLogAndPutInResponseDuringHostingStartupProcess(string startupType)
{
var deploymentParameters = Fixture.GetBaseDeploymentParameters();
deploymentParameters.TransformArguments((a, _) => $"{a} {startupType}");
var deploymentResult = await DeployAsync(deploymentParameters);
var result = await deploymentResult.HttpClient.GetAsync("/");
Assert.False(result.IsSuccessStatusCode);
var content = await result.Content.ReadAsStringAsync();
Assert.Contains("InvalidOperationException", content);
Assert.Contains("TestSite.Program.Main", content);
Assert.Contains("From Configure", content);
StopServer();
VerifyDotnetRuntimeEventLog(deploymentResult);
}
[ConditionalFact]
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
[RequiresNewHandler]

View File

@ -25,6 +25,7 @@
<Reference Include="Microsoft.AspNetCore.WebUtilities" />
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<Reference Include="Microsoft.Extensions.Configuration.Json" />
<Reference Include="Microsoft.Extensions.Hosting" />
<Reference Include="Microsoft.Extensions.Logging.Console" />
<Reference Include="xunit.assert" />
</ItemGroup>

View File

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace TestSite
@ -121,6 +122,41 @@ namespace TestSite
break;
}
#endif
case "ThrowInStartup":
{
var host = new WebHostBuilder()
.ConfigureLogging((_, factory) =>
{
factory.AddConsole();
factory.AddFilter("Console", level => level >= LogLevel.Information);
})
.UseIIS()
.UseStartup<ThrowingStartup>()
.Build();
host.Run();
}
return 0;
case "ThrowInStartupGenericHost":
{
#if !FORWARDCOMPAT
var host = new HostBuilder().ConfigureWebHost((c) =>
{
c.ConfigureLogging((_, factory) =>
{
factory.AddConsole();
factory.AddFilter("Console", level => level >= LogLevel.Information);
})
.UseIIS()
.UseStartup<ThrowingStartup>();
});
host.Build().Run();
#endif
}
return 0;
default:
return StartServer();

View File

@ -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.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace TestSite
{
public class ThrowingStartup
{
public void Configure(IApplicationBuilder app)
{
throw new InvalidOperationException("From Configure");
}
}
}