Automation for h2spec functional tests #2640
This commit is contained in:
parent
324565772c
commit
61e16e2b31
|
|
@ -5,48 +5,49 @@
|
||||||
<!-- This files is typically managed by automation. Execute 'run.ps1 upgrade deps' to update these variables to the last-known-good versions. -->
|
<!-- This files is typically managed by automation. Execute 'run.ps1 upgrade deps' to update these variables to the last-known-good versions. -->
|
||||||
<PropertyGroup Label="Package Versions">
|
<PropertyGroup Label="Package Versions">
|
||||||
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
|
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
|
||||||
<InternalAspNetCoreAnalyzersPackageVersion>2.2.0-preview1-34484</InternalAspNetCoreAnalyzersPackageVersion>
|
<InternalAspNetCoreAnalyzersPackageVersion>2.2.0-preview1-34492</InternalAspNetCoreAnalyzersPackageVersion>
|
||||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview1-17087</InternalAspNetCoreSdkPackageVersion>
|
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview1-17087</InternalAspNetCoreSdkPackageVersion>
|
||||||
<LibuvPackageVersion>1.10.0</LibuvPackageVersion>
|
<LibuvPackageVersion>1.10.0</LibuvPackageVersion>
|
||||||
<MicrosoftAspNetCoreAllPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreAllPackageVersion>
|
<MicrosoftAspNetCoreAllPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreAllPackageVersion>
|
||||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||||
<MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>
|
<MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>
|
||||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||||
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreHostingPackageVersion>
|
<MicrosoftAspNetCoreHostingPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreHostingPackageVersion>
|
||||||
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
|
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
|
||||||
<MicrosoftAspNetCoreHttpFeaturesPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreHttpFeaturesPackageVersion>
|
<MicrosoftAspNetCoreHttpFeaturesPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreHttpFeaturesPackageVersion>
|
||||||
<MicrosoftAspNetCoreHttpPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreHttpPackageVersion>
|
<MicrosoftAspNetCoreHttpPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreHttpPackageVersion>
|
||||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreTestingPackageVersion>
|
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreTestingPackageVersion>
|
||||||
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.2.0-preview1-34484</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
|
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.2.0-preview1-34492</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
|
||||||
<MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>
|
<MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>
|
<MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsBuffersMemoryPoolSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsBuffersSourcesPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsBuffersSourcesPackageVersion>
|
<MicrosoftExtensionsBuffersSourcesPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsBuffersSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsBuffersTestingSourcesPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsBuffersTestingSourcesPackageVersion>
|
<MicrosoftExtensionsBuffersTestingSourcesPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsBuffersTestingSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
<MicrosoftExtensionsConfigurationBinderPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsLoggingConsolePackageVersion>
|
<MicrosoftExtensionsLoggingConsolePackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||||
<MicrosoftExtensionsLoggingPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsLoggingPackageVersion>
|
<MicrosoftExtensionsLoggingPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsLoggingPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsLoggingTestingPackageVersion>
|
<MicrosoftExtensionsLoggingTestingPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||||
<MicrosoftExtensionsOptionsPackageVersion>2.2.0-preview1-34484</MicrosoftExtensionsOptionsPackageVersion>
|
<MicrosoftExtensionsOptionsPackageVersion>2.2.0-preview1-34492</MicrosoftExtensionsOptionsPackageVersion>
|
||||||
|
<MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>2.1.1</MicrosoftInternalAspNetCoreH2SpecAllPackageVersion>
|
||||||
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
|
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
|
||||||
<MicrosoftNETCoreApp21PackageVersion>2.1.0</MicrosoftNETCoreApp21PackageVersion>
|
<MicrosoftNETCoreApp21PackageVersion>2.1.0</MicrosoftNETCoreApp21PackageVersion>
|
||||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26614-02</MicrosoftNETCoreApp22PackageVersion>
|
<MicrosoftNETCoreApp22PackageVersion>2.2.0-preview1-26618-02</MicrosoftNETCoreApp22PackageVersion>
|
||||||
<MicrosoftNetHttpHeadersPackageVersion>2.2.0-preview1-34484</MicrosoftNetHttpHeadersPackageVersion>
|
<MicrosoftNetHttpHeadersPackageVersion>2.2.0-preview1-34492</MicrosoftNetHttpHeadersPackageVersion>
|
||||||
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
||||||
<MoqPackageVersion>4.7.49</MoqPackageVersion>
|
<MoqPackageVersion>4.7.49</MoqPackageVersion>
|
||||||
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||||
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
|
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
|
||||||
<SystemBuffersPackageVersion>4.6.0-preview1-26613-07</SystemBuffersPackageVersion>
|
<SystemBuffersPackageVersion>4.6.0-preview1-26617-01</SystemBuffersPackageVersion>
|
||||||
<SystemIOPipelinesPackageVersion>4.6.0-preview1-26613-07</SystemIOPipelinesPackageVersion>
|
<SystemIOPipelinesPackageVersion>4.6.0-preview1-26617-01</SystemIOPipelinesPackageVersion>
|
||||||
<SystemMemoryPackageVersion>4.6.0-preview1-26613-07</SystemMemoryPackageVersion>
|
<SystemMemoryPackageVersion>4.6.0-preview1-26617-01</SystemMemoryPackageVersion>
|
||||||
<SystemNetHttpWinHttpHandlerPackageVersion>4.6.0-preview1-26613-07</SystemNetHttpWinHttpHandlerPackageVersion>
|
<SystemNetHttpWinHttpHandlerPackageVersion>4.6.0-preview1-26617-01</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||||
<SystemNumericsVectorsPackageVersion>4.6.0-preview1-26613-07</SystemNumericsVectorsPackageVersion>
|
<SystemNumericsVectorsPackageVersion>4.6.0-preview1-26617-01</SystemNumericsVectorsPackageVersion>
|
||||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.6.0-preview1-26613-07</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.6.0-preview1-26617-01</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||||
<SystemSecurityCryptographyCngPackageVersion>4.6.0-preview1-26613-07</SystemSecurityCryptographyCngPackageVersion>
|
<SystemSecurityCryptographyCngPackageVersion>4.6.0-preview1-26617-01</SystemSecurityCryptographyCngPackageVersion>
|
||||||
<SystemThreadingTasksExtensionsPackageVersion>4.6.0-preview1-26613-07</SystemThreadingTasksExtensionsPackageVersion>
|
<SystemThreadingTasksExtensionsPackageVersion>4.6.0-preview1-26617-01</SystemThreadingTasksExtensionsPackageVersion>
|
||||||
<Utf8JsonPackageVersion>1.3.7</Utf8JsonPackageVersion>
|
<Utf8JsonPackageVersion>1.3.7</Utf8JsonPackageVersion>
|
||||||
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>
|
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>
|
||||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,29 @@ namespace Http2SampleApp
|
||||||
// Run callbacks on the transport thread
|
// Run callbacks on the transport thread
|
||||||
options.ApplicationSchedulingMode = SchedulingMode.Inline;
|
options.ApplicationSchedulingMode = SchedulingMode.Inline;
|
||||||
|
|
||||||
|
// Http/1.1 endpoint for comparison
|
||||||
options.Listen(IPAddress.Any, basePort, listenOptions =>
|
options.Listen(IPAddress.Any, basePort, listenOptions =>
|
||||||
|
{
|
||||||
|
listenOptions.Protocols = HttpProtocols.Http1;
|
||||||
|
listenOptions.UseConnectionLogging();
|
||||||
|
});
|
||||||
|
|
||||||
|
// TLS Http/1.1 or HTTP/2 endpoint negotiated via ALPN
|
||||||
|
options.Listen(IPAddress.Any, basePort + 1, listenOptions =>
|
||||||
{
|
{
|
||||||
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
|
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
|
||||||
listenOptions.UseHttps("testCert.pfx", "testPassword");
|
listenOptions.UseHttps("testCert.pfx", "testPassword");
|
||||||
listenOptions.UseConnectionLogging();
|
listenOptions.UseConnectionLogging();
|
||||||
listenOptions.ConnectionAdapters.Add(new TlsFilterAdapter());
|
listenOptions.ConnectionAdapters.Add(new TlsFilterAdapter());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Prior knowledge, no TLS handshake. WARNING: Not supported by browsers
|
||||||
|
// but useful for the h2spec tests
|
||||||
|
options.Listen(IPAddress.Any, basePort + 5, listenOptions =>
|
||||||
|
{
|
||||||
|
listenOptions.Protocols = HttpProtocols.Http2;
|
||||||
|
listenOptions.UseConnectionLogging();
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseStartup<Startup>();
|
.UseStartup<Startup>();
|
||||||
|
|
|
||||||
|
|
@ -521,4 +521,7 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l
|
||||||
<data name="Http2ErrorMinTlsVersion" xml:space="preserve">
|
<data name="Http2ErrorMinTlsVersion" xml:space="preserve">
|
||||||
<value>Tls 1.2 or later must be used for HTTP/2. {protocol} was negotiated.</value>
|
<value>Tls 1.2 or later must be used for HTTP/2. {protocol} was negotiated.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Http2ErrorInvalidPreface" xml:space="preserve">
|
||||||
|
<value>Invalid HTTP/2 connection preface.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -272,7 +272,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||||
{
|
{
|
||||||
if (ClientPreface[i] != span[i])
|
if (ClientPreface[i] != span[i])
|
||||||
{
|
{
|
||||||
throw new Exception("Invalid HTTP/2 connection preface.");
|
throw new Http2ConnectionErrorException(CoreStrings.Http2ErrorInvalidPreface, Http2ErrorCode.PROTOCOL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1890,6 +1890,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
||||||
internal static string FormatHttp2ErrorMinTlsVersion(object protocol)
|
internal static string FormatHttp2ErrorMinTlsVersion(object protocol)
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("Http2ErrorMinTlsVersion", "protocol"), protocol);
|
=> string.Format(CultureInfo.CurrentCulture, GetString("Http2ErrorMinTlsVersion", "protocol"), protocol);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid HTTP/2 connection preface.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Http2ErrorInvalidPreface
|
||||||
|
{
|
||||||
|
get => GetString("Http2ErrorInvalidPreface");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid HTTP/2 connection preface.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatHttp2ErrorInvalidPreface()
|
||||||
|
=> GetString("Http2ErrorInvalidPreface");
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
// 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.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
|
||||||
|
{
|
||||||
|
[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")]
|
||||||
|
public class H2SpecTests : TestApplicationErrorLoggerLoggedTest
|
||||||
|
{
|
||||||
|
[ConditionalTheory]
|
||||||
|
[MemberData(nameof(H2SpecTestCases))]
|
||||||
|
public async Task RunIndividualTestCase(H2SpecTestCase testCase)
|
||||||
|
{
|
||||||
|
var hostBuilder = TransportSelector.GetWebHostBuilder()
|
||||||
|
.UseKestrel(options =>
|
||||||
|
{
|
||||||
|
options.Listen(IPAddress.Loopback, 0, listenOptions =>
|
||||||
|
{
|
||||||
|
listenOptions.Protocols = HttpProtocols.Http2;
|
||||||
|
if (testCase.Https)
|
||||||
|
{
|
||||||
|
listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.ConfigureServices(AddTestLogging)
|
||||||
|
.Configure(ConfigureHelloWorld);
|
||||||
|
|
||||||
|
using (var host = hostBuilder.Build())
|
||||||
|
{
|
||||||
|
await host.StartAsync();
|
||||||
|
|
||||||
|
H2SpecCommands.RunTest(testCase.Id, host.GetPort(), testCase.Https, Logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<H2SpecTestCase> H2SpecTestCases
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var dataset = new TheoryData<H2SpecTestCase>();
|
||||||
|
var toSkip = new[] { "hpack/4.2/1", "http2/5.1/8", "http2/6.9.1/2", "http2/6.9.1/3", "http2/8.1.2.3/1",
|
||||||
|
"http2/8.1.2.6/1", "http2/8.1.2.6/2" };
|
||||||
|
|
||||||
|
foreach (var testcase in H2SpecCommands.EnumerateTestCases())
|
||||||
|
{
|
||||||
|
string skip = null;
|
||||||
|
if (toSkip.Contains(testcase.Item1))
|
||||||
|
{
|
||||||
|
skip = "https://github.com/aspnet/KestrelHttpServer/issues/2154";
|
||||||
|
}
|
||||||
|
|
||||||
|
dataset.Add(new H2SpecTestCase()
|
||||||
|
{
|
||||||
|
Id = testcase.Item1,
|
||||||
|
Description = testcase.Item2,
|
||||||
|
Https = false,
|
||||||
|
Skip = skip,
|
||||||
|
});
|
||||||
|
|
||||||
|
dataset.Add(new H2SpecTestCase()
|
||||||
|
{
|
||||||
|
Id = testcase.Item1,
|
||||||
|
Description = testcase.Item2,
|
||||||
|
Https = true,
|
||||||
|
Skip = skip,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class H2SpecTestCase : IXunitSerializable
|
||||||
|
{
|
||||||
|
// For the serializer
|
||||||
|
public H2SpecTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public bool Https { get; set; }
|
||||||
|
public string Skip { get; set; }
|
||||||
|
|
||||||
|
public void Deserialize(IXunitSerializationInfo info)
|
||||||
|
{
|
||||||
|
Id = info.GetValue<string>(nameof(Id));
|
||||||
|
Description = info.GetValue<string>(nameof(Description));
|
||||||
|
Https = info.GetValue<bool>(nameof(Https));
|
||||||
|
Skip = info.GetValue<string>(nameof(Skip));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Serialize(IXunitSerializationInfo info)
|
||||||
|
{
|
||||||
|
info.AddValue(nameof(Id), Id, typeof(string));
|
||||||
|
info.AddValue(nameof(Description), Description, typeof(string));
|
||||||
|
info.AddValue(nameof(Https), Https, typeof(bool));
|
||||||
|
info.AddValue(nameof(Skip), Skip, typeof(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Id}, HTTPS:{Https}, {Description}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureHelloWorld(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(context =>
|
||||||
|
{
|
||||||
|
return context.Request.Body.CopyToAsync(context.Response.Body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif NET461 // HTTP/2 is not supported
|
||||||
|
#else
|
||||||
|
#error TFMs need updating
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,222 @@
|
||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Xml;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
{
|
||||||
|
public static class H2SpecCommands
|
||||||
|
{
|
||||||
|
private static string GetToolLocation()
|
||||||
|
{
|
||||||
|
var root = Path.Combine(Environment.CurrentDirectory, "h2spec");
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
return Path.Combine(root, "windows", "h2spec.exe");
|
||||||
|
}
|
||||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
|
{
|
||||||
|
return Path.Combine(root, "linux", "h2spec");
|
||||||
|
}
|
||||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||||
|
{
|
||||||
|
return Path.Combine(root, "darwin", "h2spec");
|
||||||
|
}
|
||||||
|
throw new NotImplementedException("Invalid OS");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<Tuple<string, string>> EnumerateTestCases()
|
||||||
|
{
|
||||||
|
var testCases = new List<Tuple<string, string>>();
|
||||||
|
var processOptions = new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
FileName = GetToolLocation(),
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
Arguments = "--strict --dryrun",
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
};
|
||||||
|
using (var process = Process.Start(processOptions))
|
||||||
|
{
|
||||||
|
// https://github.com/summerwind/h2spec#running-a-specific-test-case
|
||||||
|
//Hypertext Transfer Protocol Version 2(HTTP / 2)
|
||||||
|
// 3.Starting HTTP / 2
|
||||||
|
// 3.5.HTTP / 2 Connection Preface
|
||||||
|
// 1: Sends client connection preface
|
||||||
|
// 2: Sends invalid connection preface
|
||||||
|
//Generic tests for HTTP / 2 server
|
||||||
|
// 1.Starting HTTP / 2
|
||||||
|
// 1: Sends a client connection preface
|
||||||
|
|
||||||
|
// Expected output: "http2/3.5/1", "Sends client connection preface"
|
||||||
|
var groupName = string.Empty; // http2, generic, or hpack
|
||||||
|
var sectionId = string.Empty; // 3 or 3.5
|
||||||
|
|
||||||
|
var line = string.Empty;
|
||||||
|
while (line != null)
|
||||||
|
{
|
||||||
|
line = process.StandardOutput.ReadLine();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(line))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsGroupLine(line, out var group))
|
||||||
|
{
|
||||||
|
groupName = group;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsSectionLine(line, out var section))
|
||||||
|
{
|
||||||
|
sectionId = section;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsTestLine(line, out var testNumber, out var description))
|
||||||
|
{
|
||||||
|
testCases.Add(new Tuple<string, string>($"{groupName}/{sectionId}/{testNumber}", description));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Unrecognized line: " + line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return testCases;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsGroupLine(string line, out string groupName)
|
||||||
|
{
|
||||||
|
if (line.StartsWith(" "))
|
||||||
|
{
|
||||||
|
groupName = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.StartsWith("Hypertext"))
|
||||||
|
{
|
||||||
|
groupName = "http2";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (line.StartsWith("Generic"))
|
||||||
|
{
|
||||||
|
groupName = "generic";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (line.StartsWith("HPACK"))
|
||||||
|
{
|
||||||
|
groupName = "hpack";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw new InvalidOperationException("Unrecognized line: " + line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "8.1.2.1. Pseudo-Header Fields"
|
||||||
|
private static bool IsSectionLine(string line, out string section)
|
||||||
|
{
|
||||||
|
line = line.TrimStart();
|
||||||
|
var firstSpace = line.IndexOf(" ");
|
||||||
|
if (firstSpace < 2) // Minimum: "8. description"
|
||||||
|
{
|
||||||
|
section = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As opposed to test cases that are marked with :
|
||||||
|
if (line[firstSpace - 1] == '.')
|
||||||
|
{
|
||||||
|
section = line.Substring(0, firstSpace - 1); // Drop the trailing dot.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
section = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "1: Sends a DATA frame"
|
||||||
|
private static bool IsTestLine(string line, out string testNumber, out string description)
|
||||||
|
{
|
||||||
|
line = line.TrimStart();
|
||||||
|
var firstSpace = line.IndexOf(" ");
|
||||||
|
if (firstSpace < 2) // Minimum: "8: description"
|
||||||
|
{
|
||||||
|
testNumber = string.Empty;
|
||||||
|
description = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As opposed to test cases that are marked with :
|
||||||
|
if (line[firstSpace - 1] == ':')
|
||||||
|
{
|
||||||
|
testNumber = line.Substring(0, firstSpace - 1); // Drop the trailing colon.
|
||||||
|
description = line.Substring(firstSpace + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
testNumber = string.Empty;
|
||||||
|
description = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RunTest(string testId, int port, bool https, ILogger logger)
|
||||||
|
{
|
||||||
|
var tempFile = Path.GetTempPath() + Guid.NewGuid() + ".xml";
|
||||||
|
var processOptions = new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
FileName = GetToolLocation(),
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
Arguments = $"{testId} -p {port.ToString(CultureInfo.InvariantCulture)} --strict -j {tempFile} --timeout 15"
|
||||||
|
+ (https ? " --tls --insecure" : ""),
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var process = Process.Start(processOptions))
|
||||||
|
{
|
||||||
|
var data = process.StandardOutput.ReadToEnd();
|
||||||
|
logger.LogDebug(data);
|
||||||
|
|
||||||
|
var results = File.ReadAllText(tempFile);
|
||||||
|
File.Delete(tempFile);
|
||||||
|
|
||||||
|
var xml = new XmlDocument();
|
||||||
|
xml.LoadXml(results);
|
||||||
|
// <testsuites>
|
||||||
|
// <testsuite name="4.2. Maximum Table Size" package="hpack/4.2" id="4.2" tests="1" skipped="0" failures="0" errors="1">
|
||||||
|
var foundTests = false;
|
||||||
|
var failures = new List<string>();
|
||||||
|
foreach (XmlNode node in xml.GetElementsByTagName("testsuite"))
|
||||||
|
{
|
||||||
|
if (node.Attributes["errors"].Value != "0")
|
||||||
|
{
|
||||||
|
// This does not list the individual sub-tests in each section
|
||||||
|
failures.Add("Test failed: " + node.Attributes["package"].Value + "; " + node.Attributes["name"].Value);
|
||||||
|
}
|
||||||
|
if (node.Attributes["tests"].Value != "0")
|
||||||
|
{
|
||||||
|
foundTests = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures.Count > 0)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Join(Environment.NewLine, failures));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundTests)
|
||||||
|
{
|
||||||
|
logger.LogDebug(results);
|
||||||
|
throw new InvalidOperationException("No test case results found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Internal.AspNetCore.H2Spec.All" Version="$(MicrosoftInternalAspNetCoreH2SpecAllPackageVersion)" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
||||||
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="$(SystemNetHttpWinHttpHandlerPackageVersion)" />
|
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="$(SystemNetHttpWinHttpHandlerPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.Internal.AspNetCore.H2Spec.All" Version="$(MicrosoftInternalAspNetCoreH2SpecAllPackageVersion)" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
||||||
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="$(SystemNetHttpWinHttpHandlerPackageVersion)" />
|
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="$(SystemNetHttpWinHttpHandlerPackageVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue