From 31f1e170d04c2a77d0eb3e07dd9e5c4a7ff4070e Mon Sep 17 00:00:00 2001 From: John Luo Date: Mon, 15 Oct 2018 00:26:52 -0700 Subject: [PATCH] Add interop tests with headless chrome --- .gitattributes | 2 +- KestrelHttpServer.sln | 42 +++--- build/dependencies.props | 46 +++--- .../H2SpecTests.cs | 5 +- .../Kestrel.H2Spec.FunctionalTests.csproj | 1 + .../HttpsTests.cs | 22 +-- .../LoggingConnectionAdapterTests.cs | 2 +- .../KestrelConfigurationBuilderTests.cs | 8 +- .../AddressRegistrationTests.cs | 8 +- .../ChromeConstants.cs | 28 ++++ .../ChromeTests.cs | 139 ++++++++++++++++++ .../ResponseTests.cs | 2 +- .../SkipIfChromeUnavailableAttribute.cs | 17 +++ test/shared/TestCertificates/testCert.pfx | Bin 2483 -> 1403 bytes 14 files changed, 254 insertions(+), 68 deletions(-) create mode 100644 test/Kestrel.Transport.FunctionalTests/ChromeConstants.cs create mode 100644 test/Kestrel.Transport.FunctionalTests/ChromeTests.cs create mode 100644 test/Kestrel.Transport.FunctionalTests/SkipIfChromeUnavailableAttribute.cs diff --git a/.gitattributes b/.gitattributes index c2f0f84273..5e91d85057 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,7 +13,7 @@ *.png binary *.gif binary -*.cs text=auto diff=csharp +*.cs text=auto diff=csharp *.vb text=auto *.resx text=auto *.c text=auto diff --git a/KestrelHttpServer.sln b/KestrelHttpServer.sln index c9679e5676..baa0ee92f4 100644 --- a/KestrelHttpServer.sln +++ b/KestrelHttpServer.sln @@ -2,26 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2010 MinimumVisualStudioVersion = 15.0.26730.03 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7972A5D6-3385-4127-9277-428506DD44FF}" - ProjectSection(SolutionItems) = preProject - .appveyor.yml = .appveyor.yml - .gitattributes = .gitattributes - .gitignore = .gitignore - .travis.yml = .travis.yml - build.cmd = build.cmd - build.ps1 = build.ps1 - build.sh = build.sh - CONTRIBUTING.md = CONTRIBUTING.md - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets - LICENSE.txt = LICENSE.txt - NuGet.Config = NuGet.Config - NuGetPackageVerifier.json = NuGetPackageVerifier.json - README.md = README.md - ToProjectReferences.ps1 = ToProjectReferences.ps1 - version.xml = version.xml - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2D5D5227-4DBD-499A-96B1-76A36B03B750}" ProjectSection(SolutionItems) = preProject src\Directory.Build.props = src\Directory.Build.props @@ -136,6 +116,28 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kestrel.Transport.Libuv.Bin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kestrel.H2Spec.FunctionalTests", "test\Kestrel.H2Spec.FunctionalTests\Kestrel.H2Spec.FunctionalTests.csproj", "{C4123E55-5760-4557-B89B-39E1258FD7F9}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{B19F67B8-7635-42C3-B5BF-00D1CC47FA64}" + ProjectSection(SolutionItems) = preProject + .gitattributes = .gitattributes + .gitignore = .gitignore + build.cmd = build.cmd + build.sh = build.sh + CONTRIBUTING.md = CONTRIBUTING.md + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + korebuild-lock.txt = korebuild-lock.txt + korebuild.json = korebuild.json + LICENSE.txt = LICENSE.txt + NuGet.config = NuGet.config + NuGetPackageVerifier.json = NuGetPackageVerifier.json + README.md = README.md + run.cmd = run.cmd + run.ps1 = run.ps1 + run.sh = run.sh + ToProjectReferences.ps1 = ToProjectReferences.ps1 + version.props = version.props + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/build/dependencies.props b/build/dependencies.props index 9bc48d05f8..c89f6ff48e 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,33 +5,33 @@ 0.10.13 - 2.2.0-preview3-35457 + 2.2.0-rtm-35536 2.2.0-preview2-20181011.2 1.10.0 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 - 2.2.0-preview3-35457 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 + 2.2.0-rtm-35536 2.1.1 2.1.3 - 2.2.0-preview3-27008-03 - 2.2.0-preview3-35457 + 2.2.0-preview3-27014-02 + 2.2.0-rtm-35536 15.6.1 4.10.0 2.0.3 diff --git a/test/Kestrel.H2Spec.FunctionalTests/H2SpecTests.cs b/test/Kestrel.H2Spec.FunctionalTests/H2SpecTests.cs index 45e66cbf47..c2560335d3 100644 --- a/test/Kestrel.H2Spec.FunctionalTests/H2SpecTests.cs +++ b/test/Kestrel.H2Spec.FunctionalTests/H2SpecTests.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing.xunit; using Microsoft.Extensions.Logging.Testing; using Xunit; @@ -23,8 +24,6 @@ namespace H2Spec.FunctionalTests SkipReason = "Missing Windows ALPN support: https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation#Support")] public class H2SpecTests : LoggedTest { - private static readonly string _testCertPath = Path.Combine(Directory.GetCurrentDirectory(), "shared", "TestCertificates", "testCert.pfx"); - [ConditionalTheory] [MemberData(nameof(H2SpecTestCases))] public async Task RunIndividualTestCase(H2SpecTestCase testCase) @@ -37,7 +36,7 @@ namespace H2Spec.FunctionalTests listenOptions.Protocols = HttpProtocols.Http2; if (testCase.Https) { - listenOptions.UseHttps(_testCertPath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); } }); }) diff --git a/test/Kestrel.H2Spec.FunctionalTests/Kestrel.H2Spec.FunctionalTests.csproj b/test/Kestrel.H2Spec.FunctionalTests/Kestrel.H2Spec.FunctionalTests.csproj index 5b45607b50..06e4138c78 100644 --- a/test/Kestrel.H2Spec.FunctionalTests/Kestrel.H2Spec.FunctionalTests.csproj +++ b/test/Kestrel.H2Spec.FunctionalTests/Kestrel.H2Spec.FunctionalTests.csproj @@ -11,6 +11,7 @@ + diff --git a/test/Kestrel.InMemory.FunctionalTests/HttpsTests.cs b/test/Kestrel.InMemory.FunctionalTests/HttpsTests.cs index da2df11053..5928f5d661 100644 --- a/test/Kestrel.InMemory.FunctionalTests/HttpsTests.cs +++ b/test/Kestrel.InMemory.FunctionalTests/HttpsTests.cs @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests public void UseHttpsDefaultsToDefaultCert() { var serverOptions = CreateServerOptions(); - var defaultCert = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + var defaultCert = TestResources.GetTestCertificate(); serverOptions.DefaultCertificate = defaultCert; serverOptions.ListenLocalhost(5000, options => @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests public void ConfigureHttpsDefaultsNeverLoadsDefaultCert() { var serverOptions = CreateServerOptions(); - var testCert = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + var testCert = TestResources.GetTestCertificate(); serverOptions.ConfigureHttpsDefaults(options => { Assert.Null(options.ServerCertificate); @@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests public void ConfigureCertSelectorNeverLoadsDefaultCert() { var serverOptions = CreateServerOptions(); - var testCert = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + var testCert = TestResources.GetTestCertificate(); serverOptions.ConfigureHttpsDefaults(options => { Assert.Null(options.ServerCertificate); @@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) @@ -151,7 +151,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) @@ -195,7 +195,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) @@ -238,7 +238,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) @@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) @@ -295,7 +295,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) @@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests { listenOptions.UseHttps(o => { - o.ServerCertificate = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + o.ServerCertificate = new X509Certificate2(TestResources.GetTestCertificate()); o.OnHandshakeStarted = () => handshakeStartedTcs.SetResult(null); handshakeTimeout = o.HandshakeTimeout; @@ -359,7 +359,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); })) { using (var connection = server.CreateConnection()) diff --git a/test/Kestrel.InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs b/test/Kestrel.InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs index 5eca246b35..cba0db84bd 100644 --- a/test/Kestrel.InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs +++ b/test/Kestrel.InMemory.FunctionalTests/LoggingConnectionAdapterTests.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests listenOptions => { listenOptions.UseConnectionLogging(); - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); listenOptions.UseConnectionLogging(); })) { diff --git a/test/Kestrel.Tests/KestrelConfigurationBuilderTests.cs b/test/Kestrel.Tests/KestrelConfigurationBuilderTests.cs index d763b0dd64..c3f7171bb2 100644 --- a/test/Kestrel.Tests/KestrelConfigurationBuilderTests.cs +++ b/test/Kestrel.Tests/KestrelConfigurationBuilderTests.cs @@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests serverOptions.ConfigureHttpsDefaults(opt => { - opt.ServerCertificate = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + opt.ServerCertificate = TestResources.GetTestCertificate(); opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate; }); @@ -179,7 +179,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests serverOptions.ConfigureEndpointDefaults(opt => { opt.NoDelay = false; - opt.UseHttps(new X509Certificate2(TestResources.TestCertificatePath, "testPassword")); + opt.UseHttps(TestResources.GetTestCertificate()); }); serverOptions.ConfigureHttpsDefaults(opt => @@ -335,7 +335,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests serverOptions.ConfigureHttpsDefaults(opt => { - opt.ServerCertificate = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + opt.ServerCertificate = TestResources.GetTestCertificate(); opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate; }); @@ -391,7 +391,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests serverOptions.ConfigureHttpsDefaults(opt => { - opt.ServerCertificate = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + opt.ServerCertificate = TestResources.GetTestCertificate(); opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate; }); diff --git a/test/Kestrel.Transport.BindTests/AddressRegistrationTests.cs b/test/Kestrel.Transport.BindTests/AddressRegistrationTests.cs index 98abbc3a5c..972941e72d 100644 --- a/test/Kestrel.Transport.BindTests/AddressRegistrationTests.cs +++ b/test/Kestrel.Transport.BindTests/AddressRegistrationTests.cs @@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests { if (testUrl.StartsWith("https")) { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); } }); }) @@ -461,7 +461,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests { if (mockHttps) { - options.DefaultCertificate = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + options.DefaultCertificate = TestResources.GetTestCertificate(); } }) .Configure(ConfigureEchoAddress); @@ -545,7 +545,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests { options.Listen(new IPEndPoint(IPAddress.Loopback, 0), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); }); }) .UseUrls(useUrlsAddress) @@ -622,7 +622,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests { options.Listen(new IPEndPoint(IPAddress.Loopback, 0), listenOptions => { - listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword"); + listenOptions.UseHttps(TestResources.GetTestCertificate()); }); }) .PreferHostingUrls(true) diff --git a/test/Kestrel.Transport.FunctionalTests/ChromeConstants.cs b/test/Kestrel.Transport.FunctionalTests/ChromeConstants.cs new file mode 100644 index 0000000000..e6f19feb73 --- /dev/null +++ b/test/Kestrel.Transport.FunctionalTests/ChromeConstants.cs @@ -0,0 +1,28 @@ +// 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 Interop.FunctionalTests +{ + public static class ChromeConstants + { + public static string ExecutablePath { get; } = ResolveChromeExecutablePath(); + + private static string ResolveChromeExecutablePath() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Google", "Chrome", "Application", "chrome.exe"); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return Path.Combine("/usr", "bin", "chromium-browser"); + } + + throw new PlatformNotSupportedException(); + } + } +} diff --git a/test/Kestrel.Transport.FunctionalTests/ChromeTests.cs b/test/Kestrel.Transport.FunctionalTests/ChromeTests.cs new file mode 100644 index 0000000000..89b16a8077 --- /dev/null +++ b/test/Kestrel.Transport.FunctionalTests/ChromeTests.cs @@ -0,0 +1,139 @@ +// 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. + +#if NETCOREAPP2_2 + +using System; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.AspNetCore.Server.Kestrel.FunctionalTests; +using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Xunit; + +namespace Interop.FunctionalTests +{ + [SkipIfChromeUnavailable] + public class ChromeTests : LoggedTest + { + private static readonly string _postHtml = +@" + + + + + +
+
+ +"; + + private string NetLogPath { get; set; } + private string StartupLogPath { get; set; } + private string ShutdownLogPath { get; set; } + private string ChromeArgs { get; set; } + + private void InitializeArgs() + { + NetLogPath = Path.Combine(ResolvedLogOutputDirectory, $"{ResolvedTestMethodName}.nl.json"); + StartupLogPath = Path.Combine(ResolvedLogOutputDirectory, $"{ResolvedTestMethodName}.su.json"); + ShutdownLogPath = Path.Combine(ResolvedLogOutputDirectory, $"{ResolvedTestMethodName}.sd.json"); + + ChromeArgs = $"--headless " + + $"--disable-gpu " + + $"--allow-insecure-localhost " + + $"--enable-logging " + + $"--dump-dom " + + $"--virtual-time-budget=10000 " + + $"--log-net-log={NetLogPath} " + + $"--trace-startup --trace-startup-file={StartupLogPath} " + + $"--trace-shutdown --trace-shutdown-file={ShutdownLogPath}"; + } + + [ConditionalTheory] + [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win81, SkipReason = "Missing Windows ALPN support: https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation#Support")] + [InlineData("", "Interop HTTP/2 GET")] + [InlineData("?TestMethod=POST", "Interop HTTP/2 POST")] + public async Task Http2(string requestSuffix, string expectedResponse) + { + InitializeArgs(); + + using (var server = new TestServer(async context => + { + if (string.Equals(context.Request.Query["TestMethod"], "POST", StringComparison.OrdinalIgnoreCase)) + { + await context.Response.WriteAsync(_postHtml); + } + else + { + await context.Response.WriteAsync($"Interop {context.Request.Protocol} {context.Request.Method}"); + } + }, + new TestServiceContext(LoggerFactory), + options => options.Listen(IPAddress.Loopback, 0, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http2; + listenOptions.UseHttps(TestResources.GetTestCertificate()); + }))) + { + var chromeOutput = await RunHeadlessChrome($"https://localhost:{server.Port}/{requestSuffix}"); + + AssertExpectedResponseOrShowDebugInstructions(expectedResponse, chromeOutput); + } + } + + private async Task RunHeadlessChrome(string testUrl) + { + var chromeArgs = $"{ChromeArgs} {testUrl}"; + var chromeStartInfo = new ProcessStartInfo + { + FileName = ChromeConstants.ExecutablePath, + Arguments = chromeArgs, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardError = true, + RedirectStandardOutput = true + }; + + Logger.LogInformation($"Staring chrome: {ChromeConstants.ExecutablePath} {chromeArgs}"); + + var headlessChromeProcess = Process.Start(chromeStartInfo); + var chromeOutput = await headlessChromeProcess.StandardOutput.ReadToEndAsync(); + + headlessChromeProcess.WaitForExit(); + + return chromeOutput; + } + + private void AssertExpectedResponseOrShowDebugInstructions(string expectedResponse, string actualResponse) + { + try + { + Assert.Contains(expectedResponse, actualResponse); + } + catch + { + Logger.LogError("Chrome interop tests failed. Please consult the following logs:"); + Logger.LogError($"Network logs: {NetLogPath}"); + Logger.LogError($"Startup logs: {StartupLogPath}"); + Logger.LogError($"Shutdown logs: {ShutdownLogPath}"); + throw; + } + } + } +} + +#elif NET461 // No ALPN support +#else +#error TFMs need updating +#endif diff --git a/test/Kestrel.Transport.FunctionalTests/ResponseTests.cs b/test/Kestrel.Transport.FunctionalTests/ResponseTests.cs index 3b50a8071b..d9aa983cac 100644 --- a/test/Kestrel.Transport.FunctionalTests/ResponseTests.cs +++ b/test/Kestrel.Transport.FunctionalTests/ResponseTests.cs @@ -560,7 +560,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests const int chunks = 256 * 1024; var chunkData = new byte[chunkSize]; - var certificate = new X509Certificate2(TestResources.TestCertificatePath, "testPassword"); + var certificate = TestResources.GetTestCertificate(); var responseRateTimeoutMessageLogged = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var connectionStopMessageLogged = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); diff --git a/test/Kestrel.Transport.FunctionalTests/SkipIfChromeUnavailableAttribute.cs b/test/Kestrel.Transport.FunctionalTests/SkipIfChromeUnavailableAttribute.cs new file mode 100644 index 0000000000..0820eab7d9 --- /dev/null +++ b/test/Kestrel.Transport.FunctionalTests/SkipIfChromeUnavailableAttribute.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 System.IO; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Interop.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)] + public class SkipIfChromeUnavailableAttribute : Attribute, ITestCondition + { + public bool IsMet => string.IsNullOrEmpty(Environment.GetEnvironmentVariable("JENKINS_HOME")) && (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI")) || File.Exists(ChromeConstants.ExecutablePath)); + + public string SkipReason => "This is running on Jenkins or Chrome/Chromium is not installed and this is a dev environment."; + } +} diff --git a/test/shared/TestCertificates/testCert.pfx b/test/shared/TestCertificates/testCert.pfx index 7118908c2d730670c16e9f8b2c532a262c951989..888ccb032a97ac6d36afdf569ea5a7ddb15d1111 100644 GIT binary patch literal 1403 zcmXqLVl8K4WHxAGHD=?~YV&CO&dbQoxS)wug{6sA0VphE(8Tx`MT+qqOB3TOpzt#w ze#FKN)y2cb$h4sGk3r*40~t0hm>|$-J{FGUht3{YZd@71#KeAqrSZm11(&cnPAfwl zX1aFU|ILVKRdSQy- z2e!P4PsNH>x|lM#?2tN^u!OtsfyA#vHJ9&i(-)s?)TWnwcKOj)d$0B8{MztM`n%q| z{M9mBORWq;!#mbWatr7EcMEIZ*4a?}=x6n>tpRI(B{{?~YMHHDZ=^4pw$LMjck7I! zzvaINOS^^Uruf~=&E8?7V|LlUW|HCQxevMbf3gl*&Zjy5$@e5btT;st*;rT@85kH0ViAHOh5>SZ3?&Sy47v;k43-Qj4CX-E zj3J334JeYzV8UR^U<_oLFc>i;G9&|8mO$DVES3mlr2y5X0c9WqN8QWz3J#%r@N zvM@H83o?R@_hrZgYAs^OXD9~ZG@x|~48c%VInarMD*}qAgT({D zI?I4&qyYIv22IT3aQCybEofrq01B}%F)|o5F(D@n%y|D%?IOCx)9)xK-W!^jE<{h@ zzRS8(=PhHipURGk)u%p0dmpSmyuxYW{=ZK;@@v;tW*6QvI&pvUzn#nCmEG+(*OaEY zHxyaA$}FzmBM{?rk!9XSmC#1RXUU6B9DMJ%;BbQNIu(-%91(Bi1(NdJtYiL`@IGhA zymKkomSs`&Uz4m!k3&o!JUAh?!Q#QD&0np^X~?&+OfDO}h40Y?O!j zm+pF&LXT;0D;CUJ{}3h zV=+TtLHRF*V;_PYSBA>=_B;HRT5ZqPx~O3B#ecWfUQ`N+{Z zHz=;g;q`anh}wB4zjfZ3E4-jitMBI#j_b+4d0NjkdpS5x{qcHna;er`w{2xzHP5Zr zD&3qSZl%|@=-sy&?CeTA)jc}0p9EZ5|Fin@5x#gvcCPO70Noeu z@wbEw&a=P1_dH|K#j4X&B#)n*m$*J9S&DJz`WYV`w#1pbC5ZgotXi%3+&@ji$iH2g zv4S=Abj$Qi?LQ|je3Ll1)vhhMB<0@21zEE$lmu>lRDDD5pW^)NA7`h3_PLk6;-sH% zm%OvjeamWTnc45;N{7w|~ZryW7oH-#!yqnq&3MUig`wfZDsXX`GjNc&tH zTox#|;gN~NB(75l+b115bTNbVf=qjk$Bf-)P0FshsX8@Gx+^DLdwhjTxV_?1HaFF6 zk|m#OWi>>ab5q>se9O>3d-2GAkLS@>eRgCh7+4#~8?dvnYV$EONwJ8uv-NfrpVt4B r?jsp}XX2cX|BhL`WD&_^IHf-$@%m29k1q?q&7B#jKP_$tC_?}MhAKx! literal 2483 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